[PATCH 1/3] pinctrl: mediatek: support mediatek,pctl-regmap property

David Lechner dlechner at baylibre.com
Tue Jan 6 23:05:19 CET 2026


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 <dlechner at baylibre.com>
---
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 38 +++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

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;
 

-- 
2.43.0



More information about the U-Boot mailing list