static int __devinit mxs_pinctrl_probe_dt(struct platform_device *pdev, struct mxs_pinctrl_data *d) { struct mxs_pinctrl_soc_data *soc = d->soc; struct device_node *np = pdev->dev.of_node; struct device_node *child; struct mxs_function *f; const char *gpio_compat = "fsl,mxs-gpio"; const char *fn, *fnull = ""; int i = 0, idxf = 0, idxg = 0; int ret; u32 val; child = of_get_next_child(np, NULL); if (!child) { dev_err(&pdev->dev, "no group is defined\n"); return -ENOENT; } /* Count total functions and groups */ fn = fnull; for_each_child_of_node(np, child) { if (of_device_is_compatible(child, gpio_compat)) continue; soc->ngroups++; /* Skip pure pinconf node */ if (of_property_read_u32(child, "reg", &val)) continue; if (strcmp(fn, child->name)) { fn = child->name; soc->nfunctions++; } } soc->functions = devm_kzalloc(&pdev->dev, soc->nfunctions * sizeof(*soc->functions), GFP_KERNEL); if (!soc->functions) return -ENOMEM; soc->groups = devm_kzalloc(&pdev->dev, soc->ngroups * sizeof(*soc->groups), GFP_KERNEL); if (!soc->groups) return -ENOMEM; /* Count groups for each function */ fn = fnull; f = &soc->functions[idxf]; for_each_child_of_node(np, child) { if (of_device_is_compatible(child, gpio_compat)) continue; if (of_property_read_u32(child, "reg", &val)) continue; if (strcmp(fn, child->name)) { f = &soc->functions[idxf++]; f->name = fn = child->name; } f->ngroups++; }; /* Get groups for each function */ idxf = 0; fn = fnull; for_each_child_of_node(np, child) { if (of_device_is_compatible(child, gpio_compat)) continue; if (of_property_read_u32(child, "reg", &val)) { ret = mxs_pinctrl_parse_group(pdev, child, idxg++, NULL); if (ret) return ret; continue; } if (strcmp(fn, child->name)) { f = &soc->functions[idxf++]; f->groups = devm_kzalloc(&pdev->dev, f->ngroups * sizeof(*f->groups), GFP_KERNEL); if (!f->groups) return -ENOMEM; fn = child->name; i = 0; } ret = mxs_pinctrl_parse_group(pdev, child, idxg++, &f->groups[i++]); if (ret) return ret; } return 0; }
static int mxs_pinctrl_probe_dt(struct platform_device *pdev, struct mxs_pinctrl_data *d) { struct mxs_pinctrl_soc_data *soc = d->soc; struct device_node *np = pdev->dev.of_node; struct device_node *child; struct mxs_function *f; const char *gpio_compat = "fsl,mxs-gpio"; const char *fn, *fnull = ""; int i = 0, idxf = 0, idxg = 0; int ret; u32 val; child = of_get_next_child(np, NULL); if (!child) { dev_err(&pdev->dev, "no group is defined\n"); return -ENOENT; } /* Count total functions and groups */ fn = fnull; for_each_child_of_node(np, child) { if (of_device_is_compatible(child, gpio_compat)) continue; soc->ngroups++; /* Skip pure pinconf node */ if (of_property_read_u32(child, "reg", &val)) continue; if (strcmp(fn, child->name)) { fn = child->name; soc->nfunctions++; } } soc->functions = devm_kzalloc(&pdev->dev, soc->nfunctions * sizeof(*soc->functions), GFP_KERNEL); if (!soc->functions) return -ENOMEM; soc->groups = devm_kzalloc(&pdev->dev, soc->ngroups * sizeof(*soc->groups), GFP_KERNEL); if (!soc->groups) return -ENOMEM; /* Count groups for each function */ fn = fnull; f = &soc->functions[idxf]; for_each_child_of_node(np, child) { if (of_device_is_compatible(child, gpio_compat)) continue; if (of_property_read_u32(child, "reg", &val)) continue; if (strcmp(fn, child->name)) { struct device_node *child2; /* * This reference is dropped by * of_get_next_child(np, * child) */ of_node_get(child); /* * The logic parsing the functions from dt currently * doesn't handle if functions with the same name are * not grouped together. Only the first contiguous * cluster is usable for each function name. This is a * bug that is not trivial to fix, but at least warn * about it. */ for (child2 = of_get_next_child(np, child); child2 != NULL; child2 = of_get_next_child(np, child2)) { if (!strcmp(child2->name, fn)) dev_warn(&pdev->dev, "function nodes must be grouped by name (failed for: %s)", fn); } f = &soc->functions[idxf++]; f->name = fn = child->name; } f->ngroups++; } /* Get groups for each function */ idxf = 0; fn = fnull; for_each_child_of_node(np, child) { if (of_device_is_compatible(child, gpio_compat)) continue; if (of_property_read_u32(child, "reg", &val)) { ret = mxs_pinctrl_parse_group(pdev, child, idxg++, NULL); if (ret) return ret; continue; } if (strcmp(fn, child->name)) { f = &soc->functions[idxf++]; f->groups = devm_kzalloc(&pdev->dev, f->ngroups * sizeof(*f->groups), GFP_KERNEL); if (!f->groups) return -ENOMEM; fn = child->name; i = 0; } ret = mxs_pinctrl_parse_group(pdev, child, idxg++, &f->groups[i++]); if (ret) return ret; } return 0; }