There are a few Ocelot chips that contain pinctrl logic, but can be controlled externally. Specifically the VSC7511, 7512, 7513 and 7514. In the externally controlled configurations these registers are not memory-mapped. Add support for these non-memory-mapped configurations. Signed-off-by: Colin Foster <colin.foster@xxxxxxxxxxxxxxxx> --- drivers/pinctrl/pinctrl-ocelot.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c index 30577fedb7fc..4995c90019c5 100644 --- a/drivers/pinctrl/pinctrl-ocelot.c +++ b/drivers/pinctrl/pinctrl-ocelot.c @@ -20,6 +20,7 @@ #include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/slab.h> +#include <soc/mscc/ocelot.h> #include "core.h" #include "pinconf.h" @@ -1215,6 +1216,9 @@ static int lan966x_pinmux_set_mux(struct pinctrl_dev *pctldev, return 0; } +#if defined(REG) +#undef REG +#endif #define REG(r, info, p) ((r) * (info)->stride + (4 * ((p) / 32))) static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev, @@ -1908,6 +1912,7 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct ocelot_pinctrl *info; struct regmap *pincfg; + struct resource *res; void __iomem *base; int ret; struct regmap_config regmap_config = { @@ -1922,16 +1927,28 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev) info->desc = (struct pinctrl_desc *)device_get_match_data(dev); - base = devm_ioremap_resource(dev, - platform_get_resource(pdev, IORESOURCE_MEM, 0)); - if (IS_ERR(base)) - return PTR_ERR(base); + base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); + if (IS_ERR(base)) { + /* + * Fall back to using IORESOURCE_REG, which is possible in an + * MFD configuration + */ + res = platform_get_resource(pdev, IORESOURCE_REG, 0); + if (!res) { + dev_err(dev, "Failed to get resource\n"); + return -ENODEV; + } - info->stride = 1 + (info->desc->npins - 1) / 32; + info->map = ocelot_init_regmap_from_resource(dev, res); + } else { + regmap_config.max_register = + OCELOT_GPIO_SD_MAP * info->stride + 15 * 4; - regmap_config.max_register = OCELOT_GPIO_SD_MAP * info->stride + 15 * 4; + info->map = devm_regmap_init_mmio(dev, base, ®map_config); + } + + info->stride = 1 + (info->desc->npins - 1) / 32; - info->map = devm_regmap_init_mmio(dev, base, ®map_config); if (IS_ERR(info->map)) { dev_err(dev, "Failed to create regmap\n"); return PTR_ERR(info->map); -- 2.25.1