From 391c970c0dd1100e3b9e1681f7d0f20aac35455a Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Tue, 8 Jun 2010 07:48:17 -0600 Subject: of/gpio: add default of_xlate function if device has a node pointer Implement generic OF gpio hooks and thus make device-enabled GPIO chips (i.e. the ones that have gpio_chip->dev specified) automatically attach to the OpenFirmware subsystem. Which means that now we can handle I2C and SPI GPIO chips almost* transparently. * "Almost" because some chips still require platform data, and for these chips OF-glue is still needed, though with this change the glue will be much smaller. Signed-off-by: Anton Vorontsov Signed-off-by: Grant Likely Cc: David Brownell Cc: Bill Gatliff Cc: Dmitry Eremin-Solenikov Cc: Benjamin Herrenschmidt Cc: Jean Delvare Cc: Andrew Morton CC: linux-kernel@vger.kernel.org CC: devicetree-discuss@lists.ozlabs.org --- drivers/of/gpio.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index c8618d3282cf..09f05a178668 100644 --- a/drivers/of/gpio.c +++ b/drivers/of/gpio.c @@ -125,8 +125,8 @@ EXPORT_SYMBOL(of_gpio_count); * gpio chips. This function performs only one sanity check: whether gpio * is less than ngpios (that is specified in the gpio_chip). */ -int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, - const void *gpio_spec, u32 *flags) +static int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, + const void *gpio_spec, u32 *flags) { const __be32 *gpio = gpio_spec; const u32 n = be32_to_cpup(gpio); @@ -150,7 +150,6 @@ int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, return n; } -EXPORT_SYMBOL(of_gpio_simple_xlate); /** * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank) @@ -187,9 +186,6 @@ int of_mm_gpiochip_add(struct device_node *np, gc->base = -1; - if (!gc->of_xlate) - gc->of_xlate = of_gpio_simple_xlate; - if (mm_gc->save_regs) mm_gc->save_regs(mm_gc); @@ -199,9 +195,6 @@ int of_mm_gpiochip_add(struct device_node *np, if (ret) goto err2; - /* We don't want to lose the node and its ->data */ - of_node_get(np); - pr_debug("%s: registered as generic GPIO chip, base is %d\n", np->full_name, gc->base); return 0; @@ -216,6 +209,28 @@ err0: } EXPORT_SYMBOL(of_mm_gpiochip_add); +void of_gpiochip_add(struct gpio_chip *chip) +{ + if ((!chip->of_node) && (chip->dev)) + chip->of_node = chip->dev->of_node; + + if (!chip->of_node) + return; + + if (!chip->of_xlate) { + chip->of_gpio_n_cells = 2; + chip->of_xlate = of_gpio_simple_xlate; + } + + of_node_get(chip->of_node); +} + +void of_gpiochip_remove(struct gpio_chip *chip) +{ + if (chip->of_node) + of_node_put(chip->of_node); +} + /* Private function for resolving node pointer to gpio_chip */ static int of_gpiochip_is_match(struct gpio_chip *chip, void *data) { -- cgit v1.2.1