From: David Lechner Date: Tue, 6 Jan 2026 22:05:19 +0000 (-0600) Subject: pinctrl: mediatek: support mediatek,pctl-regmap property X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=424ceba18bfb4c9bc324618fc572066833e38d88;p=thirdparty%2Fu-boot.git pinctrl: mediatek: support mediatek,pctl-regmap property Add support for the mediatek,pctl-regmap devicetree property to the common MediaTek pinctrl driver. In upstream devicetrees from Linux, the pinctrl nodes may be on the interrupt controller register address space rather than the pinctrl register address space. In this case, there is a syscon node linking to the actual pinctrl registers. This uses a common property name of mediatek,pctl-regmap for the phandle to the syscon node. The logic here is that if this property is present, we look up the syscon node and use it's address as the base address of the pinctrl registers and ignore the pinctrl node's own reg property. (Support for interrupts could be added later if needed.) There is also at least one SoC in Linux that has two syscon phandles in this property. This implementation support parsing this, but doesn't do anything with the second syscon yet (the 2nd syscon is for interrupts which we are saving for later). Signed-off-by: David Lechner --- diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c index 4aecb84504a..0483d532800 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c @@ -809,9 +809,47 @@ int mtk_pinctrl_common_probe(struct udevice *dev, fdt_addr_t addr; u32 base_calc = soc->base_calc; u32 nbase_names = soc->nbase_names; + int num_regmaps; priv->soc = soc; + /* + * Some controllers have 1 or 2 syscon nodes where the actual pinctl + * registers reside. In this case, dev is an interrupt controller which + * isn't supported at this time. The optional 2nd syscon node is also + * for the interrupt controller, so we only use the 1st one currently. + */ + num_regmaps = dev_count_phandle_with_args(dev, "mediatek,pctl-regmap", NULL, 0); + if (num_regmaps > ARRAY_SIZE(priv->base)) + return -EINVAL; + + if (num_regmaps > 0) { + for (i = 0; i < num_regmaps; i++) { + struct ofnode_phandle_args args; + struct udevice *syscon_dev; + int ret; + + ret = dev_read_phandle_with_args(dev, "mediatek,pctl-regmap", + NULL, 0, i, &args); + if (ret) + return ret; + + ret = uclass_get_device_by_ofnode(UCLASS_SYSCON, + args.node, + &syscon_dev); + if (ret) + return ret; + + addr = dev_read_addr_index(syscon_dev, 0); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->base[i] = (void __iomem *)addr; + } + + return 0; + } + if (!base_calc) nbase_names = 1;