/** * pinctrl_select_state_full() - full implementation of pinctrl_select_state * * @dev: peripheral device * @statename: state name, like "default" * @return: 0 on success, or negative error code on failure */ static int pinctrl_select_state_full(struct udevice *dev, const char *statename) { const void *fdt = gd->fdt_blob; int node = dev->of_offset; char propname[32]; /* long enough */ const fdt32_t *list; uint32_t phandle; int config_node; struct udevice *config; int state, size, i, ret; state = fdt_find_string(fdt, node, "pinctrl-names", statename); if (state < 0) { char *end; /* * If statename is not found in "pinctrl-names", * assume statename is just the integer state ID. */ state = simple_strtoul(statename, &end, 10); if (*end) return -EINVAL; } snprintf(propname, sizeof(propname), "pinctrl-%d", state); list = fdt_getprop(fdt, node, propname, &size); if (!list) return -EINVAL; size /= sizeof(*list); for (i = 0; i < size; i++) { phandle = fdt32_to_cpu(*list++); config_node = fdt_node_offset_by_phandle(fdt, phandle); if (config_node < 0) { dev_err(dev, "prop %s index %d invalid phandle\n", propname, i); return -EINVAL; } ret = uclass_get_device_by_of_offset(UCLASS_PINCONFIG, config_node, &config); if (ret) return ret; ret = pinctrl_config_one(config); if (ret) return ret; } return 0; }
/** * pinctrl_select_state_full() - full implementation of pinctrl_select_state * * @dev: peripheral device * @statename: state name, like "default" * @return: 0 on success, or negative error code on failure */ static int pinctrl_select_state_full(struct udevice *dev, const char *statename) { char propname[32]; /* long enough */ const fdt32_t *list; uint32_t phandle; struct udevice *config; int state, size, i, ret; state = dev_read_stringlist_search(dev, "pinctrl-names", statename); if (state < 0) { char *end; /* * If statename is not found in "pinctrl-names", * assume statename is just the integer state ID. */ state = simple_strtoul(statename, &end, 10); if (*end) return -EINVAL; } snprintf(propname, sizeof(propname), "pinctrl-%d", state); list = dev_read_prop(dev, propname, &size); if (!list) return -EINVAL; size /= sizeof(*list); for (i = 0; i < size; i++) { phandle = fdt32_to_cpu(*list++); ret = uclass_get_device_by_phandle_id(UCLASS_PINCONFIG, phandle, &config); if (ret) return ret; ret = pinctrl_config_one(config); if (ret) return ret; } return 0; }
int of_pinctrl_select_state(struct device_node *np, const char *name) { int state, ret; char propname[sizeof("pinctrl-4294967295")]; const __be32 *list; int size, config; phandle phandle; struct device_node *np_config; const char *statename; if (!of_find_property(np, "pinctrl-0", NULL)) return 0; /* For each defined state ID */ for (state = 0; ; state++) { /* Retrieve the pinctrl-* property */ sprintf(propname, "pinctrl-%d", state); list = of_get_property(np, propname, &size); if (!list) { ret = -ENODEV; break; } size /= sizeof(*list); /* Determine whether pinctrl-names property names the state */ ret = of_property_read_string_index(np, "pinctrl-names", state, &statename); /* * If not, statename is just the integer state ID. But rather * than dynamically allocate it and have to free it later, * just point part way into the property name for the string. */ if (ret < 0) { /* strlen("pinctrl-") == 8 */ statename = &propname[8]; } if (strcmp(name, statename)) continue; /* For every referenced pin configuration node in it */ for (config = 0; config < size; config++) { phandle = be32_to_cpup(list++); /* Look up the pin configuration node */ np_config = of_find_node_by_phandle(phandle); if (!np_config) { pr_err("prop %s %s index %i invalid phandle\n", np->full_name, propname, config); ret = -EINVAL; goto err; } /* Parse the node */ ret = pinctrl_config_one(np_config); if (ret < 0) goto err; } return 0; } err: return ret; }