summaryrefslogtreecommitdiff
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2014-01-16 16:46:31 +0530
committerLaxman Dewangan <ldewangan@nvidia.com>2014-01-17 02:44:36 -0800
commit1dadda4b2b6c5c41e1c4d5ac40a548a6545f9d50 (patch)
tree261f4f86317f58b91c554f66dcf9ba782b02251b /drivers/gpio/gpiolib.c
parent6ace21fa56c01b94f72409d3dbeddac26a1a6ac3 (diff)
gpio: alias gpio base number for gpio from DT
Alias the gpio base number when registering the device from DT. This will help on assigning the base gpio number to gpio controller so that non-dt client of gpio can use these gpios. Change-Id: I12ce2108d21d21fa7c9a0c60d498d4136515add2 Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-on: http://git-master/r/356512
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r--drivers/gpio/gpiolib.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 6b50e05bc489..0e6c9bd34f53 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -184,11 +184,42 @@ struct gpio_chip *gpio_to_chip(unsigned gpio)
}
/* dynamic allocation of GPIOs, e.g. on a hotplugged device */
-static int gpiochip_find_base(int ngpio)
+static int gpiochip_find_base(struct gpio_chip *req_chip)
{
struct gpio_chip *chip;
- int base = ARCH_NR_GPIOS - ngpio;
+ int ngpio = req_chip->ngpio;
+ int base = -1;
+
+#ifdef CONFIG_OF
+ if (req_chip->of_node) {
+ int gpio_nr;
+
+ gpio_nr = of_alias_get_id(req_chip->of_node, "gpio");
+ if (gpio_nr >= 0) {
+ int start_gpio = gpio_nr;
+ int end_gpio = gpio_nr + req_chip->ngpio;
+
+ list_for_each_entry(chip, &gpio_chips, list) {
+ if (chip->base > end_gpio)
+ continue;
+
+ if ((chip->base < start_gpio) &&
+ ((chip->base + chip->ngpio) < start_gpio))
+ continue;
+ pr_err("GPIO %d to %d is already allocated\n",
+ start_gpio, end_gpio);
+ gpio_nr = -1;
+ break;
+ }
+ }
+ base = gpio_nr;
+ }
+#endif
+
+ if (base >= 0)
+ goto found;
+ base = ARCH_NR_GPIOS - ngpio;
list_for_each_entry_reverse(chip, &gpio_chips, list) {
/* found a free space? */
if (chip->base + chip->ngpio <= base)
@@ -198,6 +229,7 @@ static int gpiochip_find_base(int ngpio)
base = chip->base - ngpio;
}
+found:
if (gpio_is_valid(base)) {
pr_debug("%s: found new base at %d\n", __func__, base);
return base;
@@ -1184,7 +1216,7 @@ int gpiochip_add(struct gpio_chip *chip)
spin_lock_irqsave(&gpio_lock, flags);
if (base < 0) {
- base = gpiochip_find_base(chip->ngpio);
+ base = gpiochip_find_base(chip);
if (base < 0) {
status = base;
goto unlock;