On 1/6/26 4:05 PM, David Lechner wrote:
> 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 <[email protected]>
> ---
>  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);

I did not realize that this is not robust against probe order. I got
lucky during initial testing, but it is failing now that I am working
on something else. So I will need to find a solution and send a v2.

> +                     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;
>  
> 

Reply via email to