summaryrefslogtreecommitdiff
path: root/drivers/pinctrl/freescale
diff options
context:
space:
mode:
authorMarkus Pargmann <mpa@pengutronix.de>2015-04-10 16:22:38 +0200
committerLinus Walleij <linus.walleij@linaro.org>2015-05-06 15:30:24 +0200
commit5fcdf6a7ed95ef3feef2678c39c906cfc5572cfa (patch)
treec45ed85b8e41e8b482860ebc755460da9a62fcc8 /drivers/pinctrl/freescale
parent83a21727c3fb23844de38f85fb4250bd21961c25 (diff)
pinctrl: imx: 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 intention was to define all pin functions in a single dtsi file and just reference the correct ones in the board files. This idea was rejected some time ago leading to the current design to have all the pinfunctions defined in the board files. So we don't need the function device nodes anymore. This patch changes the pinctrl driver to accept devicetrees which do not have the first hierarchy level, function device nodes. For example karo-tx25 already has such a devicetree. Old devicetrees are still parsed and supported. Signed-off-by: Markus Pargmann <mpa@pengutronix.de> Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Acked-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/freescale')
-rw-r--r--drivers/pinctrl/freescale/pinctrl-imx.c55
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;
}