diff options
author | Simon Glass <sjg@chromium.org> | 2014-10-23 07:37:01 +0400 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2014-10-24 05:29:07 +0400 |
commit | fe1ef503381c4c03c059de3324271ce21cae3078 (patch) | |
tree | 47449b3c0a6891985ad772992fcfb9e6cf499746 /drivers/gpio | |
parent | 5b3ee386fde82a1ba42ff09b95247842c9a1585e (diff) | |
download | u-boot-fe1ef503381c4c03c059de3324271ce21cae3078.tar.xz |
dm: gpio: Support numbered GPIOs
At present banks must be named and it is not possible to refer to GPIOs by
number in driver model. Some boards use numbering - e.g. OMAP. It is fairly
easy to support by detecting the absense of a bank name (which starts with
a letter).
Add support for numbered GPIOs in addition to the existing bank support.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Tom Rini <trini@ti.com>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpio-uclass.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index f1bbc58796..a5ffd85c42 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -8,6 +8,7 @@ #include <dm.h> #include <errno.h> #include <asm/gpio.h> +#include <linux/ctype.h> /** * gpio_to_device() - Convert global GPIO number to device, number @@ -43,35 +44,47 @@ static int gpio_to_device(unsigned int gpio, struct udevice **devp, int gpio_lookup_name(const char *name, struct udevice **devp, unsigned int *offsetp, unsigned int *gpiop) { - struct gpio_dev_priv *uc_priv; + struct gpio_dev_priv *uc_priv = NULL; struct udevice *dev; + ulong offset; + int numeric; int ret; if (devp) *devp = NULL; + numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1; for (ret = uclass_first_device(UCLASS_GPIO, &dev); dev; ret = uclass_next_device(&dev)) { - ulong offset; int len; uc_priv = dev->uclass_priv; + if (numeric != -1) { + offset = numeric - uc_priv->gpio_base; + /* Allow GPIOs to be numbered from 0 */ + if (offset >= 0 && offset < uc_priv->gpio_count) + break; + } + len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0; if (!strncasecmp(name, uc_priv->bank_name, len)) { - if (strict_strtoul(name + len, 10, &offset)) - continue; - if (devp) - *devp = dev; - if (offsetp) - *offsetp = offset; - if (gpiop) - *gpiop = uc_priv->gpio_base + offset; - return 0; + if (!strict_strtoul(name + len, 10, &offset)) + break; } } - return ret ? ret : -EINVAL; + if (!dev) + return ret ? ret : -EINVAL; + + if (devp) + *devp = dev; + if (offsetp) + *offsetp = offset; + if (gpiop) + *gpiop = uc_priv->gpio_base + offset; + + return 0; } /** |