diff options
-rw-r--r-- | drivers/pinctrl/freescale/pinctrl-imx.c | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c index e261f1cf85c6..e73e1edb0fe1 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx.c @@ -606,6 +606,29 @@ static int imx_pinctrl_parse_functions(struct device_node *np, 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 imx_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_read_bool(function_np, "fsl,pins")) + return true; + + for_each_child_of_node(function_np, pinctrl_np) { + if (of_property_read_bool(pinctrl_np, "fsl,pins")) + return false; + } + } + + return true; +} + static int imx_pinctrl_probe_dt(struct platform_device *pdev, struct imx_pinctrl_soc_info *info) { @@ -613,14 +636,20 @@ static int imx_pinctrl_probe_dt(struct platform_device *pdev, struct device_node *child; u32 nfuncs = 0; u32 i = 0; + bool flat_funcs; if (!np) return -ENODEV; - nfuncs = of_get_child_count(np); - if (nfuncs <= 0) { - dev_err(&pdev->dev, "no functions defined\n"); - return -EINVAL; + flat_funcs = imx_pinctrl_dt_is_flat_functions(np); + if (flat_funcs) { + nfuncs = 1; + } else { + nfuncs = of_get_child_count(np); + if (nfuncs <= 0) { + dev_err(&pdev->dev, "no functions defined\n"); + return -EINVAL; + } } info->nfunctions = nfuncs; @@ -629,16 +658,24 @@ static int imx_pinctrl_probe_dt(struct platform_device *pdev, if (!info->functions) return -ENOMEM; - info->ngroups = 0; - for_each_child_of_node(np, child) - info->ngroups += of_get_child_count(child); + if (flat_funcs) { + info->ngroups = of_get_child_count(np); + } else { + info->ngroups = 0; + for_each_child_of_node(np, child) + info->ngroups += of_get_child_count(child); + } info->groups = devm_kzalloc(&pdev->dev, info->ngroups * sizeof(struct imx_pin_group), GFP_KERNEL); if (!info->groups) return -ENOMEM; - for_each_child_of_node(np, child) - imx_pinctrl_parse_functions(child, info, i++); + if (flat_funcs) { + imx_pinctrl_parse_functions(np, info, 0); + } else { + for_each_child_of_node(np, child) + imx_pinctrl_parse_functions(child, info, i++); + } return 0; } |