aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2012-11-20 06:40:15 -0500
committerLinus Walleij <linus.walleij@linaro.org>2012-11-21 02:55:03 -0500
commit3f0f8670608766ef26a178d4e80cad3ce030fecc (patch)
treed2f192a4a454bd677983c7eb0b88a0016f128bf6 /drivers/gpio/gpiolib.c
parent5212d096cbed2eae1e442b3f8bf448e6a577af6f (diff)
gpiolib: let gpiochip_add_pin_range() specify offset
Like with commit 3c739ad0df5eb41cd7adad879eda6aa09879eb76 it is not always enough to specify all the pins of a gpio_chip from offset zero to be added to a pin map range, since the mapping from GPIO to pin controller may not be linear at all, but need to be broken into a few consecutive sub-ranges or 1-pin entries for complicated cases. The ranges may also be sparse. This alters the signature of the function to accept offsets into both the GPIO-chip local pinspace and the pin controller local pinspace. Reviewed-by: Stephen Warren <swarren@nvidia.com> Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r--drivers/gpio/gpiolib.c32
1 files changed, 29 insertions, 3 deletions
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);