pinctrl: imx1: Allow parsing DT without function nodes

The old format to define pinctrl settings for imx in DT has two hierarchy
levels. The first level are function device nodes. The second level are
pingroups which contain a property fsl,pins. The original ntention was to
define all pin functions in a single dtsi file and just reference the
correct ones in the board files.

The commit ("5fcdf6a7ed95e pinctrl: imx: Allow parsing DT without function
nodes") already make moden i.MX chip support flatten layout.

Make legacy chipes (more than 15 years) support this flatten layout also.

Fixes: e948cbdc41 ("ARM: dts: imx: remove redundant intermediate node in pinmux hierarchy")
Tested-by: Sébastien Szymanski <sebastien.szymanski@armadeus.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Linus Walleij <linusw@kernel.org>
This commit is contained in:
Frank Li 2026-05-05 12:09:02 -04:00 committed by Linus Walleij
parent 7cf4846a2a
commit 63d2059cd6

View File

@ -540,10 +540,34 @@ static int imx1_pinctrl_parse_functions(struct device_node *np,
return 0; return 0;
} }
/*
* Check if the DT contains pins in the direct child nodes. This indicates the
* newer DT format to store pins. This function returns true if the first found
* fsl,pins property is in a child of np. Otherwise false is returned.
*/
static bool imx1_pinctrl_dt_is_flat_functions(struct device_node *np)
{
struct device_node *function_np;
struct device_node *pinctrl_np;
for_each_child_of_node(np, function_np) {
if (of_property_present(function_np, "fsl,pins"))
return true;
for_each_child_of_node(function_np, pinctrl_np) {
if (of_property_present(pinctrl_np, "fsl,pins"))
return false;
}
}
return true;
}
static int imx1_pinctrl_parse_dt(struct platform_device *pdev, static int imx1_pinctrl_parse_dt(struct platform_device *pdev,
struct imx1_pinctrl *pctl, struct imx1_pinctrl_soc_info *info) struct imx1_pinctrl *pctl, struct imx1_pinctrl_soc_info *info)
{ {
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
bool flat_funcs;
int ret; int ret;
u32 nfuncs = 0; u32 nfuncs = 0;
u32 ngroups = 0; u32 ngroups = 0;
@ -552,9 +576,15 @@ static int imx1_pinctrl_parse_dt(struct platform_device *pdev,
if (!np) if (!np)
return -ENODEV; return -ENODEV;
for_each_child_of_node_scoped(np, child) { flat_funcs = imx1_pinctrl_dt_is_flat_functions(np);
++nfuncs; if (flat_funcs) {
ngroups += of_get_child_count(child); nfuncs = 1;
ngroups = of_get_child_count(np);
} else {
for_each_child_of_node_scoped(np, child) {
++nfuncs;
ngroups += of_get_child_count(child);
}
} }
if (!nfuncs) { if (!nfuncs) {
@ -574,10 +604,14 @@ static int imx1_pinctrl_parse_dt(struct platform_device *pdev,
if (!info->functions || !info->groups) if (!info->functions || !info->groups)
return -ENOMEM; return -ENOMEM;
for_each_child_of_node_scoped(np, child) { if (flat_funcs) {
ret = imx1_pinctrl_parse_functions(child, info, ifunc++); imx1_pinctrl_parse_functions(np, info, 0);
if (ret == -ENOMEM) } else {
return -ENOMEM; for_each_child_of_node_scoped(np, child) {
ret = imx1_pinctrl_parse_functions(child, info, ifunc++);
if (ret == -ENOMEM)
return -ENOMEM;
}
} }
return 0; return 0;