diff options
author | Anton Vorontsov <avorontsov@ru.mvista.com> | 2010-06-08 09:48:17 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-07-05 18:14:30 -0400 |
commit | 391c970c0dd1100e3b9e1681f7d0f20aac35455a (patch) | |
tree | 05a42941269f77b22de6b640953df61f2da5d13c /drivers/of/gpio.c | |
parent | 594fa265e084073443390c5b93d5410fd28e9bcd (diff) |
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 <avorontsov@ru.mvista.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Bill Gatliff <bgat@billgatliff.com>
Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
CC: linux-kernel@vger.kernel.org
CC: devicetree-discuss@lists.ozlabs.org
Diffstat (limited to 'drivers/of/gpio.c')
-rw-r--r-- | drivers/of/gpio.c | 33 |
1 files changed, 24 insertions, 9 deletions
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); | |||
125 | * gpio chips. This function performs only one sanity check: whether gpio | 125 | * gpio chips. This function performs only one sanity check: whether gpio |
126 | * is less than ngpios (that is specified in the gpio_chip). | 126 | * is less than ngpios (that is specified in the gpio_chip). |
127 | */ | 127 | */ |
128 | int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, | 128 | static int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, |
129 | const void *gpio_spec, u32 *flags) | 129 | const void *gpio_spec, u32 *flags) |
130 | { | 130 | { |
131 | const __be32 *gpio = gpio_spec; | 131 | const __be32 *gpio = gpio_spec; |
132 | const u32 n = be32_to_cpup(gpio); | 132 | const u32 n = be32_to_cpup(gpio); |
@@ -150,7 +150,6 @@ int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, | |||
150 | 150 | ||
151 | return n; | 151 | return n; |
152 | } | 152 | } |
153 | EXPORT_SYMBOL(of_gpio_simple_xlate); | ||
154 | 153 | ||
155 | /** | 154 | /** |
156 | * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank) | 155 | * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank) |
@@ -187,9 +186,6 @@ int of_mm_gpiochip_add(struct device_node *np, | |||
187 | 186 | ||
188 | gc->base = -1; | 187 | gc->base = -1; |
189 | 188 | ||
190 | if (!gc->of_xlate) | ||
191 | gc->of_xlate = of_gpio_simple_xlate; | ||
192 | |||
193 | if (mm_gc->save_regs) | 189 | if (mm_gc->save_regs) |
194 | mm_gc->save_regs(mm_gc); | 190 | mm_gc->save_regs(mm_gc); |
195 | 191 | ||
@@ -199,9 +195,6 @@ int of_mm_gpiochip_add(struct device_node *np, | |||
199 | if (ret) | 195 | if (ret) |
200 | goto err2; | 196 | goto err2; |
201 | 197 | ||
202 | /* We don't want to lose the node and its ->data */ | ||
203 | of_node_get(np); | ||
204 | |||
205 | pr_debug("%s: registered as generic GPIO chip, base is %d\n", | 198 | pr_debug("%s: registered as generic GPIO chip, base is %d\n", |
206 | np->full_name, gc->base); | 199 | np->full_name, gc->base); |
207 | return 0; | 200 | return 0; |
@@ -216,6 +209,28 @@ err0: | |||
216 | } | 209 | } |
217 | EXPORT_SYMBOL(of_mm_gpiochip_add); | 210 | EXPORT_SYMBOL(of_mm_gpiochip_add); |
218 | 211 | ||
212 | void of_gpiochip_add(struct gpio_chip *chip) | ||
213 | { | ||
214 | if ((!chip->of_node) && (chip->dev)) | ||
215 | chip->of_node = chip->dev->of_node; | ||
216 | |||
217 | if (!chip->of_node) | ||
218 | return; | ||
219 | |||
220 | if (!chip->of_xlate) { | ||
221 | chip->of_gpio_n_cells = 2; | ||
222 | chip->of_xlate = of_gpio_simple_xlate; | ||
223 | } | ||
224 | |||
225 | of_node_get(chip->of_node); | ||
226 | } | ||
227 | |||
228 | void of_gpiochip_remove(struct gpio_chip *chip) | ||
229 | { | ||
230 | if (chip->of_node) | ||
231 | of_node_put(chip->of_node); | ||
232 | } | ||
233 | |||
219 | /* Private function for resolving node pointer to gpio_chip */ | 234 | /* Private function for resolving node pointer to gpio_chip */ |
220 | static int of_gpiochip_is_match(struct gpio_chip *chip, void *data) | 235 | static int of_gpiochip_is_match(struct gpio_chip *chip, void *data) |
221 | { | 236 | { |