Skip to content

Commit e818cd3

Browse files
Doug BergerBartosz Golaszewski
authored andcommitted
gpio: of: support gpio-ranges for multiple gpiochip devices
Some drivers (e.g. gpio-mt7621 and gpio-brcmstb) have multiple gpiochip banks within a single device. Unfortunately, the gpio-ranges property of the device node was being applied to every gpiochip of the device with device relative GPIO offset values rather than gpiochip relative GPIO offset values. This commit makes use of the gpio_chip offset value which can be non-zero for such devices to split the device node gpio-ranges property into GPIO offset ranges that can be applied to each of the relevant gpiochips of the device. Signed-off-by: Doug Berger <[email protected]> Acked-by: Florian Fainelli <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Bartosz Golaszewski <[email protected]>
1 parent 7c66f81 commit e818cd3

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

drivers/gpio/gpiolib-of.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
10371037
struct of_phandle_args pinspec;
10381038
struct pinctrl_dev *pctldev;
10391039
struct device_node *np;
1040-
int index = 0, ret;
1040+
int index = 0, ret, trim;
10411041
const char *name;
10421042
static const char group_names_propname[] = "gpio-ranges-group-names";
10431043
struct property *group_names;
@@ -1059,7 +1059,14 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
10591059
if (!pctldev)
10601060
return -EPROBE_DEFER;
10611061

1062+
/* Ignore ranges outside of this GPIO chip */
1063+
if (pinspec.args[0] >= (chip->offset + chip->ngpio))
1064+
continue;
1065+
if (pinspec.args[0] + pinspec.args[2] <= chip->offset)
1066+
continue;
1067+
10621068
if (pinspec.args[2]) {
1069+
/* npins != 0: linear range */
10631070
if (group_names) {
10641071
of_property_read_string_index(np,
10651072
group_names_propname,
@@ -1070,7 +1077,19 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
10701077
break;
10711078
}
10721079
}
1073-
/* npins != 0: linear range */
1080+
1081+
/* Trim the range to fit this GPIO chip */
1082+
if (chip->offset > pinspec.args[0]) {
1083+
trim = chip->offset - pinspec.args[0];
1084+
pinspec.args[2] -= trim;
1085+
pinspec.args[1] += trim;
1086+
pinspec.args[0] = 0;
1087+
} else {
1088+
pinspec.args[0] -= chip->offset;
1089+
}
1090+
if ((pinspec.args[0] + pinspec.args[2]) > chip->ngpio)
1091+
pinspec.args[2] = chip->ngpio - pinspec.args[0];
1092+
10741093
ret = gpiochip_add_pin_range(chip,
10751094
pinctrl_dev_get_devname(pctldev),
10761095
pinspec.args[0],

0 commit comments

Comments
 (0)