/* Check for pin config node which has no 'reg' property */ if (of_property_read_u32(np, "reg", ®))
purecfg = true;
ret = of_property_read_u32(np, "fsl,drive-strength", &val); if (!ret)
config = val | MA_PRESENT;
ret = of_property_read_u32(np, "fsl,voltage", &val); if (!ret)
config |= val << VOL_SHIFT | VOL_PRESENT;
ret = of_property_read_u32(np, "fsl,pull-up", &val); if (!ret)
config |= val << PULL_SHIFT | PULL_PRESENT;
/* Check for group node which has both mux and config settings */ if (!purecfg && config)
new_num = 2;
new_map = kcalloc(new_num, sizeof(*new_map), GFP_KERNEL); if (!new_map) return -ENOMEM;
if (!purecfg) {
new_map[i].type = PIN_MAP_TYPE_MUX_GROUP;
new_map[i].data.mux.function = np->name;
/* Compose group name */
group = kzalloc(length, GFP_KERNEL); if (!group) {
ret = -ENOMEM; goto free;
}
snprintf(group, length, "%s.%d", np->name, reg);
new_map[i].data.mux.group = group;
i++;
}
if (config) {
pconfig = kmemdup(&config, sizeof(config), GFP_KERNEL); if (!pconfig) {
ret = -ENOMEM; goto free_group;
}
for (i = 0; i < num_maps; i++) { if (map[i].type == PIN_MAP_TYPE_MUX_GROUP)
kfree(map[i].data.mux.group); if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
kfree(map[i].data.configs.configs);
}
val = of_get_child_count(np); if (val == 0) {
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 (is_mxs_gpio(child)) 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_kcalloc(&pdev->dev,
soc->nfunctions, sizeof(*soc->functions),
GFP_KERNEL); if (!soc->functions) return -ENOMEM;
soc->groups = devm_kcalloc(&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 (is_mxs_gpio(child)) 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);
}
/* Get groups for each function */
idxf = 0;
fn = fnull;
for_each_child_of_node_scoped(np, child) { if (is_mxs_gpio(child)) 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_kcalloc(&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;
}
int mxs_pinctrl_probe(struct platform_device *pdev, struct mxs_pinctrl_soc_data *soc)
{ struct device_node *np = pdev->dev.of_node; struct mxs_pinctrl_data *d; int ret;
d = devm_kzalloc(&pdev->dev, sizeof(*d), GFP_KERNEL); if (!d) return -ENOMEM;
d->dev = &pdev->dev;
d->soc = soc;
d->base = of_iomap(np, 0); if (!d->base) return -EADDRNOTAVAIL;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.