aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpio/gpiolib-of.c12
-rw-r--r--drivers/gpio/gpiolib.c32
-rw-r--r--include/asm-generic/gpio.h6
-rw-r--r--include/linux/gpio.h3
4 files changed, 47 insertions, 6 deletions
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index a40cd84c5c10..d542a141811a 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -238,8 +238,20 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
238 if (!pctldev) 238 if (!pctldev)
239 break; 239 break;
240 240
241 /*
242 * This assumes that the n GPIO pins are consecutive in the
243 * GPIO number space, and that the pins are also consecutive
244 * in their local number space. Currently it is not possible
245 * to add different ranges for one and the same GPIO chip,
246 * as the code assumes that we have one consecutive range
247 * on both, mapping 1-to-1.
248 *
249 * TODO: make the OF bindings handle multiple sparse ranges
250 * on the same GPIO chip.
251 */
241 ret = gpiochip_add_pin_range(chip, 252 ret = gpiochip_add_pin_range(chip,
242 pinctrl_dev_get_name(pctldev), 253 pinctrl_dev_get_name(pctldev),
254 0, /* offset in gpiochip */
243 pinspec.args[0], 255 pinspec.args[0],
244 pinspec.args[1]); 256 pinspec.args[1]);
245 257
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index c5f650095faa..6d13bea4778a 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1187,24 +1187,45 @@ EXPORT_SYMBOL_GPL(gpiochip_find);
1187 1187
1188#ifdef CONFIG_PINCTRL 1188#ifdef CONFIG_PINCTRL
1189 1189
1190/**
1191 * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping
1192 * @chip: the gpiochip to add the range for
1193 * @pinctrl_name: the dev_name() of the pin controller to map to
1194 * @offset: the start offset in the current gpio_chip number space
1195 * @pin_base: the start offset in the pin controller number space
1196 * @npins: the number of pins from the offset of each pin space (GPIO and
1197 * pin controller) to accumulate in this range
1198 */
1190int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, 1199int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
1191 unsigned int pin_base, unsigned int npins) 1200 unsigned int offset, unsigned int pin_base,
1201 unsigned int npins)
1192{ 1202{
1193 struct gpio_pin_range *pin_range; 1203 struct gpio_pin_range *pin_range;
1194 1204
1195 pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range), GFP_KERNEL); 1205 pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL);
1196 if (!pin_range) { 1206 if (!pin_range) {
1197 pr_err("%s: GPIO chip: failed to allocate pin ranges\n", 1207 pr_err("%s: GPIO chip: failed to allocate pin ranges\n",
1198 chip->label); 1208 chip->label);
1199 return -ENOMEM; 1209 return -ENOMEM;
1200 } 1210 }
1201 1211
1212 /* Use local offset as range ID */
1213 pin_range->range.id = offset;
1214 pin_range->range.gc = chip;
1202 pin_range->range.name = chip->label; 1215 pin_range->range.name = chip->label;
1203 pin_range->range.base = chip->base; 1216 pin_range->range.base = chip->base + offset;
1204 pin_range->range.pin_base = pin_base; 1217 pin_range->range.pin_base = pin_base;
1205 pin_range->range.npins = npins; 1218 pin_range->range.npins = npins;
1206 pin_range->pctldev = find_pinctrl_and_add_gpio_range(pinctl_name, 1219 pin_range->pctldev = find_pinctrl_and_add_gpio_range(pinctl_name,
1207 &pin_range->range); 1220 &pin_range->range);
1221 if (!pin_range->pctldev) {
1222 pr_err("%s: GPIO chip: could not create pin range\n",
1223 chip->label);
1224 kfree(pin_range);
1225 }
1226 pr_debug("%s: GPIO chip: created GPIO range %d->%d ==> PIN %d->%d\n",
1227 chip->label, offset, offset + npins - 1,
1228 pin_base, pin_base + npins - 1);
1208 1229
1209 list_add_tail(&pin_range->node, &chip->pin_ranges); 1230 list_add_tail(&pin_range->node, &chip->pin_ranges);
1210 1231
@@ -1212,6 +1233,10 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
1212} 1233}
1213EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); 1234EXPORT_SYMBOL_GPL(gpiochip_add_pin_range);
1214 1235
1236/**
1237 * gpiochip_remove_pin_ranges() - remove all the GPIO <-> pin mappings
1238 * @chip: the chip to remove all the mappings for
1239 */
1215void gpiochip_remove_pin_ranges(struct gpio_chip *chip) 1240void gpiochip_remove_pin_ranges(struct gpio_chip *chip)
1216{ 1241{
1217 struct gpio_pin_range *pin_range, *tmp; 1242 struct gpio_pin_range *pin_range, *tmp;
@@ -1220,6 +1245,7 @@ void gpiochip_remove_pin_ranges(struct gpio_chip *chip)
1220 list_del(&pin_range->node); 1245 list_del(&pin_range->node);
1221 pinctrl_remove_gpio_range(pin_range->pctldev, 1246 pinctrl_remove_gpio_range(pin_range->pctldev,
1222 &pin_range->range); 1247 &pin_range->range);
1248 kfree(pin_range);
1223 } 1249 }
1224} 1250}
1225EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges); 1251EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges);
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 2b84fc32fae2..ec58fdbddb59 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -283,14 +283,16 @@ struct gpio_pin_range {
283}; 283};
284 284
285int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, 285int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
286 unsigned int pin_base, unsigned int npins); 286 unsigned int offset, unsigned int pin_base,
287 unsigned int npins);
287void gpiochip_remove_pin_ranges(struct gpio_chip *chip); 288void gpiochip_remove_pin_ranges(struct gpio_chip *chip);
288 289
289#else 290#else
290 291
291static inline int 292static inline int
292gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, 293gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
293 unsigned int pin_base, unsigned int npins) 294 unsigned int offset, unsigned int pin_base,
295 unsigned int npins)
294{ 296{
295 return 0; 297 return 0;
296} 298}
diff --git a/include/linux/gpio.h b/include/linux/gpio.h
index 7ba2762abbc9..99861c65dd8b 100644
--- a/include/linux/gpio.h
+++ b/include/linux/gpio.h
@@ -233,7 +233,8 @@ static inline int irq_to_gpio(unsigned irq)
233 233
234static inline int 234static inline int
235gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, 235gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
236 unsigned int pin_base, unsigned int npins) 236 unsigned int offset, unsigned int pin_base,
237 unsigned int npins)
237{ 238{
238 WARN_ON(1); 239 WARN_ON(1);
239 return -EINVAL; 240 return -EINVAL;