diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2014-01-16 16:46:31 +0530 |
---|---|---|
committer | Laxman Dewangan <ldewangan@nvidia.com> | 2014-01-17 02:44:36 -0800 |
commit | 1dadda4b2b6c5c41e1c4d5ac40a548a6545f9d50 (patch) | |
tree | 261f4f86317f58b91c554f66dcf9ba782b02251b /drivers/gpio | |
parent | 6ace21fa56c01b94f72409d3dbeddac26a1a6ac3 (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')
-rw-r--r-- | drivers/gpio/gpiolib.c | 38 |
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; |