static void of_gpiochip_add_pin_range(struct gpio_chip *chip) { struct device_node *np = chip->of_node; struct of_phandle_args pinspec; struct pinctrl_dev *pctldev; int index = 0, ret; if (!np) return; for (;; index++) { ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, index, &pinspec); if (ret) break; pctldev = of_pinctrl_get(pinspec.np); if (!pctldev) break; ret = gpiochip_add_pin_range(chip, pinctrl_dev_get_devname(pctldev), pinspec.args[0], pinspec.args[1], pinspec.args[2]); if (ret) break; } }
static void of_gpiochip_add_pin_range(struct gpio_chip *chip) { struct device_node *np = chip->of_node; struct of_phandle_args pinspec; struct pinctrl_dev *pctldev; int index = 0, ret; if (!np) return; do { ret = of_parse_phandle_with_args(np, "gpio-ranges", "#gpio-range-cells", index, &pinspec); if (ret) break; pctldev = of_pinctrl_get(pinspec.np); if (!pctldev) break; /* * This assumes that the n GPIO pins are consecutive in the * GPIO number space, and that the pins are also consecutive * in their local number space. Currently it is not possible * to add different ranges for one and the same GPIO chip, * as the code assumes that we have one consecutive range * on both, mapping 1-to-1. * * TODO: make the OF bindings handle multiple sparse ranges * on the same GPIO chip. */ ret = gpiochip_add_pin_range(chip, pinctrl_dev_get_name(pctldev), 0, /* offset in gpiochip */ pinspec.args[0], pinspec.args[1]); if (ret) break; } while (index++); }
static void of_gpiochip_add_pin_range(struct gpio_chip *chip) { struct device_node *np = chip->of_node; struct of_phandle_args pinspec; struct pinctrl_dev *pctldev; int index = 0, ret; const char *name; static const char group_names_propname[] = "gpio-ranges-group-names"; struct property *group_names; if (!np) return; group_names = of_find_property(np, group_names_propname, NULL); for (;; index++) { ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, index, &pinspec); if (ret) break; pctldev = of_pinctrl_get(pinspec.np); if (!pctldev) break; if (pinspec.args[2]) { if (group_names) { ret = of_property_read_string_index(np, group_names_propname, index, &name); if (strlen(name)) { pr_err("%s: Group name of numeric GPIO ranges must be the empty string.\n", np->full_name); break; } } /* npins != 0: linear range */ ret = gpiochip_add_pin_range(chip, pinctrl_dev_get_devname(pctldev), pinspec.args[0], pinspec.args[1], pinspec.args[2]); if (ret) break; } else { /* npins == 0: special range */ if (pinspec.args[1]) { pr_err("%s: Illegal gpio-range format.\n", np->full_name); break; } if (!group_names) { pr_err("%s: GPIO group range requested but no %s property.\n", np->full_name, group_names_propname); break; } ret = of_property_read_string_index(np, group_names_propname, index, &name); if (ret) break; if (!strlen(name)) { pr_err("%s: Group name of GPIO group range cannot be the empty string.\n", np->full_name); break; } ret = gpiochip_add_pingroup_range(chip, pctldev, pinspec.args[0], name); if (ret) break; } } }