Message ID | 20220701192609.3970317-2-colin.foster@in-advantage.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | add support for VSC7512 control over SPI | expand |
On Fri, Jul 1, 2022 at 9:26 PM Colin Foster <colin.foster@in-advantage.com> 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. ... > + res = platform_get_resource(pdev, IORESOURCE_MEM, index); > + if (res) { > + regs = devm_ioremap_resource(dev, res); > + if (IS_ERR(regs)) > + return ERR_CAST(regs); Why can't it be devm_platform_get_and_ioremap_resource() here? regs = devm_platform_get_and_ioremap_resource(); if (res) { if (IS_ERR(regs)) return ERR_CAST(); return ... } > + return devm_regmap_init_mmio(dev, regs, config); > + } ... > + return (map) ? map : ERR_PTR(-ENOENT); Too many parentheses. Also you may use short form of ternary operator: return map ?: ERR_PTR(-ENOENT);
On Fri, Jul 01, 2022 at 10:23:36PM +0200, Andy Shevchenko wrote: > On Fri, Jul 1, 2022 at 9:26 PM Colin Foster > <colin.foster@in-advantage.com> 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. > > ... > > > + res = platform_get_resource(pdev, IORESOURCE_MEM, index); > > + if (res) { > > + regs = devm_ioremap_resource(dev, res); > > + if (IS_ERR(regs)) > > + return ERR_CAST(regs); > > Why can't it be devm_platform_get_and_ioremap_resource() here? It can... but it invokes prints of "invalid resource" during initialization. Here it was implied that I should break the function call out: https://patchwork.kernel.org/project/netdevbpf/patch/20220628081709.829811-2-colin.foster@in-advantage.com/#24917551 > > regs = devm_platform_get_and_ioremap_resource(); > if (res) { > if (IS_ERR(regs)) > return ERR_CAST(); > return ... > } > > > + return devm_regmap_init_mmio(dev, regs, config); > > + } > > ... > > > + return (map) ? map : ERR_PTR(-ENOENT); > > Too many parentheses. > > Also you may use short form of ternary operator: > > return map ?: ERR_PTR(-ENOENT); Agreed, and I didn't know about that operator. When Vladimir suggested it I thought it was a typo. I should've known better. > > -- > With Best Regards, > Andy Shevchenko
On Fri, Jul 1, 2022 at 10:35 PM Colin Foster <colin.foster@in-advantage.com> wrote: > On Fri, Jul 01, 2022 at 10:23:36PM +0200, Andy Shevchenko wrote: > > On Fri, Jul 1, 2022 at 9:26 PM Colin Foster > > <colin.foster@in-advantage.com> wrote: ... > > > + res = platform_get_resource(pdev, IORESOURCE_MEM, index); > > > + if (res) { > > > + regs = devm_ioremap_resource(dev, res); > > > + if (IS_ERR(regs)) > > > + return ERR_CAST(regs); > > > > Why can't it be devm_platform_get_and_ioremap_resource() here? > > It can... but it invokes prints of "invalid resource" during > initialization. > > Here it was implied that I should break the function call out: > https://patchwork.kernel.org/project/netdevbpf/patch/20220628081709.829811-2-colin.foster@in-advantage.com/#24917551 Perhaps a comment in the code, so nobody will try to optimize this in the future. > > > + return devm_regmap_init_mmio(dev, regs, config); > > > + } ... > > > + return (map) ? map : ERR_PTR(-ENOENT); > > > > Too many parentheses. > > > > Also you may use short form of ternary operator: > > > > return map ?: ERR_PTR(-ENOENT); > > Agreed, and I didn't know about that operator. When Vladimir suggested > it I thought it was a typo. I should've known better. It's easy to remember by thinking of "X ?: Y" as "X _or_ Y".
diff --git a/MAINTAINERS b/MAINTAINERS index 7c029ab73265..c2f61ed1b730 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14413,6 +14413,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@in-advantage.com> +S: Supported +F: include/linux/mfd/ocelot.h + OCXL (Open Coherent Accelerator Processor Interface OpenCAPI) DRIVER M: Frederic Barrat <fbarrat@linux.ibm.com> M: Andrew Donnellan <ajd@linux.ibm.com> diff --git a/include/linux/mfd/ocelot.h b/include/linux/mfd/ocelot.h new file mode 100644 index 000000000000..7e64870b75ca --- /dev/null +++ b/include/linux/mfd/ocelot.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* Copyright 2022 Innovative Advantage Inc. */ + +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/types.h> + +struct resource; + +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; + + 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) ? map : ERR_PTR(-ENOENT); +}
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@in-advantage.com> --- MAINTAINERS | 5 ++++ include/linux/mfd/ocelot.h | 51 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 include/linux/mfd/ocelot.h