/** * pinctrl_generic_set_state_subnode() - apply all settings in config node * * @dev: pin controller device * @config: pseudo device pointing to config node * @return: 0 on success, or negative error code on failure */ static int pinctrl_generic_set_state_subnode(struct udevice *dev, struct udevice *config) { const void *fdt = gd->fdt_blob; int node = config->of_offset; const char *subnode_target_type = "pins"; bool is_group = false; const char *name; int strings_count, selector, i, ret; strings_count = fdt_stringlist_count(fdt, node, subnode_target_type); if (strings_count < 0) { subnode_target_type = "groups"; is_group = true; strings_count = fdt_stringlist_count(fdt, node, subnode_target_type); if (strings_count < 0) { /* skip this node; may contain config child nodes */ return 0; } } for (i = 0; i < strings_count; i++) { name = fdt_stringlist_get(fdt, node, subnode_target_type, i, NULL); if (!name) return -EINVAL; if (is_group) selector = pinctrl_group_name_to_selector(dev, name); else selector = pinctrl_pin_name_to_selector(dev, name); if (selector < 0) return selector; ret = pinctrl_generic_set_state_one(dev, config, is_group, selector); if (ret) return ret; } return 0; }
/** * exynos_pinctrl_set_state: configure a pin state. * dev: the pinctrl device to be configured. * config: the state to be configured. */ int exynos_pinctrl_set_state(struct udevice *dev, struct udevice *config) { const void *fdt = gd->fdt_blob; int node = config->of_offset; unsigned int count, idx, pin_num; unsigned int pinfunc, pinpud, pindrv; unsigned long reg, value; const char *name; /* * refer to the following document for the pinctrl bindings * linux/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt */ count = fdt_stringlist_count(fdt, node, "samsung,pins"); if (count <= 0) return -EINVAL; pinfunc = fdtdec_get_int(fdt, node, "samsung,pin-function", -1); pinpud = fdtdec_get_int(fdt, node, "samsung,pin-pud", -1); pindrv = fdtdec_get_int(fdt, node, "samsung,pin-drv", -1); for (idx = 0; idx < count; idx++) { name = fdt_stringlist_get(fdt, node, "samsung,pins", idx, NULL); if (!name) continue; reg = pin_to_bank_base(dev, name, &pin_num); if (pinfunc != -1) { value = readl(reg + PIN_CON); value &= ~(0xf << (pin_num << 2)); value |= (pinfunc << (pin_num << 2)); writel(value, reg + PIN_CON); } if (pinpud != -1) { value = readl(reg + PIN_PUD); value &= ~(0x3 << (pin_num << 1)); value |= (pinpud << (pin_num << 1)); writel(value, reg + PIN_PUD); } if (pindrv != -1) { value = readl(reg + PIN_DRV); value &= ~(0x3 << (pin_num << 1)); value |= (pindrv << (pin_num << 1)); writel(value, reg + PIN_DRV); } } return 0; }
static void check_string_count(const void *fdt, const char *path, const char *property, int count) { int offset, err; offset = fdt_path_offset(fdt, path); if (offset < 0) FAIL("Couldn't find path %s", path); err = fdt_stringlist_count(fdt, offset, property); if (err < 0) FAIL("Couldn't count strings in property %s of node %s: %d\n", property, path, err); if (err != count) FAIL("String count for property %s of node %s is %d instead of %d\n", path, property, err, count); }
static int tegra_xusb_padctl_group_parse_dt(struct tegra_xusb_padctl *padctl, struct tegra_xusb_padctl_group *group, const void *fdt, int node) { unsigned int i; int len; group->name = fdt_get_name(fdt, node, &len); len = fdt_stringlist_count(fdt, node, "nvidia,lanes"); if (len < 0) { error("failed to parse \"nvidia,lanes\" property"); return -EINVAL; } group->num_pins = len; for (i = 0; i < group->num_pins; i++) { group->pins[i] = fdt_stringlist_get(fdt, node, "nvidia,lanes", i, NULL); if (!group->pins[i]) { error("failed to read string from \"nvidia,lanes\" property"); return -EINVAL; } } group->num_pins = len; group->func = fdt_stringlist_get(fdt, node, "nvidia,function", 0, NULL); if (!group->func) { error("failed to parse \"nvidia,func\" property"); return -EINVAL; } group->iddq = fdtdec_get_int(fdt, node, "nvidia,iddq", -1); return 0; }
static void check_expected_failure(const void *fdt, const char *path, const char *property) { int offset, err; offset = fdt_path_offset(fdt, "/"); if (offset < 0) FAIL("Couldn't find path %s", path); err = fdt_stringlist_count(fdt, offset, "#address-cells"); if (err != -FDT_ERR_BADVALUE) FAIL("unexpectedly succeeded in parsing #address-cells\n"); err = fdt_stringlist_search(fdt, offset, "#address-cells", "foo"); if (err != -FDT_ERR_BADVALUE) FAIL("found string in #address-cells: %d\n", err); /* * Note that the #address-cells property contains a small 32-bit * unsigned integer, hence some bytes will be zero, and searching for * the empty string will succeed. * * The reason for this oddity is that the function will exit when the * first occurrence of the string is found, but in order to determine * that the property does not contain a valid string list it would * need to process the whole value. */ err = fdt_stringlist_search(fdt, offset, "#address-cells", ""); if (err != 0) FAIL("empty string not found in #address-cells: %d\n", err); /* * fdt_get_string() can successfully extract strings from non-string * properties. This is because it doesn't necessarily parse the whole * property value, which would be necessary for it to determine if a * valid string or string list is present. */ }