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,
struct imx1_pinctrl *pctl, struct imx1_pinctrl_soc_info *info)
{
struct device_node *np = pdev->dev.of_node;
+ bool flat_funcs;
int ret;
u32 nfuncs = 0;
u32 ngroups = 0;
if (!np)
return -ENODEV;
- for_each_child_of_node_scoped(np, child) {
- ++nfuncs;
- ngroups += of_get_child_count(child);
+ flat_funcs = imx1_pinctrl_dt_is_flat_functions(np);
+ if (flat_funcs) {
+ 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 (!info->functions || !info->groups)
return -ENOMEM;
- for_each_child_of_node_scoped(np, child) {
- ret = imx1_pinctrl_parse_functions(child, info, ifunc++);
- if (ret == -ENOMEM)
- return -ENOMEM;
+ if (flat_funcs) {
+ imx1_pinctrl_parse_functions(np, info, 0);
+ } else {
+ for_each_child_of_node_scoped(np, child) {
+ ret = imx1_pinctrl_parse_functions(child, info, ifunc++);
+ if (ret == -ENOMEM)
+ return -ENOMEM;
+ }
}
return 0;