On Tue, Jul 05, 2022 at 01:47:35PM -0700, Colin Foster wrote: > Several ocelot-related modules are designed for MMIO / regmaps. As such, > they often use a combination of devm_platform_get_and_ioremap_resource and > devm_regmap_init_mmio. > > Operating in an MFD might be different, in that it could be memory mapped, > or it could be SPI, I2C... In these cases a fallback to use IORESOURCE_REG > instead of IORESOURCE_MEM becomes necessary. > > When this happens, there's redundant logic that needs to be implemented in > every driver. In order to avoid this redundancy, utilize a single function > that, if the MFD scenario is enabled, will perform this fallback logic. > > Signed-off-by: Colin Foster <colin.foster@xxxxxxxxxxxxxxxx> > --- To me this looks good, I'll just add a few minor comments which I think you don't necessarily need to address by resending, they're just things I noticed. Reviewed-by: Vladimir Oltean <vladimir.oltean@xxxxxxx> > MAINTAINERS | 5 ++++ > include/linux/mfd/ocelot.h | 55 ++++++++++++++++++++++++++++++++++++++ > 2 files changed, 60 insertions(+) > create mode 100644 include/linux/mfd/ocelot.h > > diff --git a/MAINTAINERS b/MAINTAINERS > index 28108e4fdb8f..f781caceeb38 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -14467,6 +14467,11 @@ F: net/dsa/tag_ocelot.c > F: net/dsa/tag_ocelot_8021q.c > F: tools/testing/selftests/drivers/net/ocelot/* > > +OCELOT EXTERNAL SWITCH CONTROL > +M: Colin Foster <colin.foster@xxxxxxxxxxxxxxxx> > +S: Supported > +F: include/linux/mfd/ocelot.h > + > OCXL (Open Coherent Accelerator Processor Interface OpenCAPI) DRIVER > M: Frederic Barrat <fbarrat@xxxxxxxxxxxxx> > M: Andrew Donnellan <ajd@xxxxxxxxxxxxx> > diff --git a/include/linux/mfd/ocelot.h b/include/linux/mfd/ocelot.h > new file mode 100644 > index 000000000000..353b7c2ee445 > --- /dev/null > +++ b/include/linux/mfd/ocelot.h > @@ -0,0 +1,55 @@ > +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ > +/* Copyright 2022 Innovative Advantage Inc. */ A header file should have ifdefs which should prevent double inclusion, like #ifndef _MFD_OCELOT_H #define _MFD_OCELOT_H ... #endif > + > +#include <linux/err.h> > +#include <linux/platform_device.h> > +#include <linux/regmap.h> > +#include <linux/types.h> > + > +struct resource; IMO if include/linux/platform_device.h doesn't provide "struct resource" that's a problem for that header to solve, not for its users. > + > +static inline struct regmap * > +ocelot_regmap_from_resource_optional(struct platform_device *pdev, > + unsigned int index, > + const struct regmap_config *config) > +{ > + struct device *dev = &pdev->dev; > + struct resource *res; > + u32 __iomem *regs; "regs" could be void *. > + > + /* > + * Don't use get_and_ioremap_resource here, since that will invoke > + * prints of "invalid resource" which simply add confusion > + */ > + res = platform_get_resource(pdev, IORESOURCE_MEM, index); > + if (res) { > + regs = devm_ioremap_resource(dev, res); > + if (IS_ERR(regs)) > + return ERR_CAST(regs); > + return devm_regmap_init_mmio(dev, regs, config); > + } > + > + /* > + * Fall back to using REG and getting the resource from the parent > + * device, which is possible in an MFD configuration > + */ > + if (dev->parent) { > + res = platform_get_resource(pdev, IORESOURCE_REG, index); > + if (!res) > + return NULL; > + > + return dev_get_regmap(dev->parent, res->name); > + } > + > + return NULL; > +} > + > +static inline struct regmap * > +ocelot_regmap_from_resource(struct platform_device *pdev, unsigned int index, > + const struct regmap_config *config) > +{ > + struct regmap *map; > + > + map = ocelot_regmap_from_resource_optional(pdev, index, config); > + return map ?: ERR_PTR(-ENOENT); > +} > -- > 2.25.1 >