summaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib-of.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2012-11-06 16:03:35 +0100
committerLinus Walleij <linus.walleij@linaro.org>2012-11-11 19:06:07 +0100
commit1e63d7b9363f0c57d00991f9f2e0af374dfc591a (patch)
tree6bea7bfdd9dbfbe21433629b3f2a9758c92447be /drivers/gpio/gpiolib-of.c
parentgpiolib: call pin removal in chip removal function (diff)
downloadlinux-1e63d7b9363f0c57d00991f9f2e0af374dfc591a.tar.xz
linux-1e63d7b9363f0c57d00991f9f2e0af374dfc591a.zip
gpiolib: separation of pin concerns
The fact that of_gpiochip_add_pin_range() and gpiochip_add_pin_range() share too much code is fragile and will invariably mean that bugs need to be fixed in two places instead of one. So separate the concerns of gpiolib.c and gpiolib-of.c and have the latter call the former as back-end. This is necessary also when going forward with other device descriptions such as ACPI. This is done by: - Adding a return code to gpiochip_add_pin_range() so we can reliably check whether this succeeds. - Get rid of the custom of_pinctrl_add_gpio_range() from pinctrl. Instead create of_pinctrl_get() to just retrive the pin controller per se from an OF node. This composite function was just begging to be deleted, it was way to purpose-specific. - Use pinctrl_dev_get_name() to get the name of the retrieved pin controller and use that to call back into the generic gpiochip_add_pin_range(). Now the pin range is only allocated and tied to a pin controller from the core implementation in gpiolib.c. Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpiolib-of.c')
-rw-r--r--drivers/gpio/gpiolib-of.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 67403e47e4dc..a40cd84c5c10 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -221,8 +221,8 @@ EXPORT_SYMBOL(of_mm_gpiochip_add);
static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
{
struct device_node *np = chip->of_node;
- struct gpio_pin_range *pin_range;
struct of_phandle_args pinspec;
+ struct pinctrl_dev *pctldev;
int index = 0, ret;
if (!np)
@@ -234,22 +234,17 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
if (ret)
break;
- pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range),
- GFP_KERNEL);
- if (!pin_range) {
- pr_err("%s: GPIO chip: failed to allocate pin ranges\n",
- chip->label);
+ pctldev = of_pinctrl_get(pinspec.np);
+ if (!pctldev)
break;
- }
- pin_range->range.name = chip->label;
- pin_range->range.base = chip->base;
- pin_range->range.pin_base = pinspec.args[0];
- pin_range->range.npins = pinspec.args[1];
- pin_range->pctldev = of_pinctrl_add_gpio_range(pinspec.np,
- &pin_range->range);
+ ret = gpiochip_add_pin_range(chip,
+ pinctrl_dev_get_name(pctldev),
+ pinspec.args[0],
+ pinspec.args[1]);
- list_add_tail(&pin_range->node, &chip->pin_ranges);
+ if (ret)
+ break;
} while (index++);
}