diff options
author | Christian Ruppert <christian.ruppert@abilis.com> | 2013-10-15 15:37:54 +0200 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2013-10-16 15:33:50 +0200 |
commit | 586a87e6edc936d6d3c3585af504b33b9c3f0a06 (patch) | |
tree | e3a8b9960ef9b6f9e28eaf235790889f5ddf886e /drivers/gpio/gpiolib.c | |
parent | c8ce878206076b159ee9488133aa51314570da38 (diff) | |
download | op-kernel-dev-586a87e6edc936d6d3c3585af504b33b9c3f0a06.zip op-kernel-dev-586a87e6edc936d6d3c3585af504b33b9c3f0a06.tar.gz |
pinctrl/gpio: non-linear GPIO ranges accesible from gpiolib
This patch adds the infrastructure required to register non-linear gpio
ranges through gpiolib and the standard GPIO device tree bindings.
Signed-off-by: Christian Ruppert <christian.ruppert@abilis.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r-- | drivers/gpio/gpiolib.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 86ef346..b83b7e4 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1320,6 +1320,53 @@ EXPORT_SYMBOL_GPL(gpiochip_find); #ifdef CONFIG_PINCTRL /** + * gpiochip_add_pingroup_range() - add a range for GPIO <-> pin mapping + * @chip: the gpiochip to add the range for + * @pinctrl: the dev_name() of the pin controller to map to + * @gpio_offset: the start offset in the current gpio_chip number space + * @pin_group: name of the pin group inside the pin controller + */ +int gpiochip_add_pingroup_range(struct gpio_chip *chip, + struct pinctrl_dev *pctldev, + unsigned int gpio_offset, const char *pin_group) +{ + struct gpio_pin_range *pin_range; + int ret; + + pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL); + if (!pin_range) { + pr_err("%s: GPIO chip: failed to allocate pin ranges\n", + chip->label); + return -ENOMEM; + } + + /* Use local offset as range ID */ + pin_range->range.id = gpio_offset; + pin_range->range.gc = chip; + pin_range->range.name = chip->label; + pin_range->range.base = chip->base + gpio_offset; + pin_range->pctldev = pctldev; + + ret = pinctrl_get_group_pins(pctldev, pin_group, + &pin_range->range.pins, + &pin_range->range.npins); + if (ret < 0) + return ret; + + pinctrl_add_gpio_range(pctldev, &pin_range->range); + + pr_debug("GPIO chip %s: created GPIO range %d->%d ==> %s PINGRP %s\n", + chip->label, gpio_offset, + gpio_offset + pin_range->range.npins - 1, + pinctrl_dev_get_devname(pctldev), pin_group); + + list_add_tail(&pin_range->node, &chip->pin_ranges); + + return 0; +} +EXPORT_SYMBOL_GPL(gpiochip_add_pingroup_range); + +/** * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping * @chip: the gpiochip to add the range for * @pinctrl_name: the dev_name() of the pin controller to map to |