diff options
author | Colin Foster <colin.foster@in-advantage.com> | 2022-09-05 09:21:25 -0700 |
---|---|---|
committer | Lee Jones <lee@kernel.org> | 2022-09-09 07:54:25 +0100 |
commit | bb5721f063ba63cd54cc5916881a706c21e6abc6 (patch) | |
tree | bc59af384056b34c5edab1fa879039219c061688 | |
parent | 568035b01cfb107af8d2e4bd2fb9aea22cf5b868 (diff) | |
download | linux-bb5721f063ba63cd54cc5916881a706c21e6abc6.tar.bz2 |
mfd: ocelot: Add helper to get regmap from a resource
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>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Lee Jones <lee@kernel.org>
Link: https://lore.kernel.org/r/20220905162132.2943088-2-colin.foster@in-advantage.com
-rw-r--r-- | MAINTAINERS | 5 | ||||
-rw-r--r-- | include/linux/mfd/ocelot.h | 62 |
2 files changed, 67 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 8a5012ba6ff9..e0732e9f9090 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14741,6 +14741,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..dd72073d2d4f --- /dev/null +++ b/include/linux/mfd/ocelot.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* Copyright 2022 Innovative Advantage Inc. */ + +#ifndef _LINUX_MFD_OCELOT_H +#define _LINUX_MFD_OCELOT_H + +#include <linux/err.h> +#include <linux/errno.h> +#include <linux/ioport.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; + void __iomem *regs; + + /* + * Don't use _get_and_ioremap_resource() here, since that will invoke + * prints of "invalid resource" which will 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); +} + +#endif |