Commit 391c970c0dd1100e3b9e1681f7d0f20aac35455a
Committed by
Grant Likely
1 parent
594fa265e0
Exists in
master
and in
7 other branches
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
Showing 13 changed files with 34 additions and 26 deletions Side-by-side Diff
- arch/powerpc/platforms/52xx/mpc52xx_gpio.c
- arch/powerpc/platforms/52xx/mpc52xx_gpt.c
- arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
- arch/powerpc/sysdev/cpm1.c
- arch/powerpc/sysdev/cpm_common.c
- arch/powerpc/sysdev/mpc8xxx_gpio.c
- arch/powerpc/sysdev/ppc4xx_gpio.c
- arch/powerpc/sysdev/qe_lib/gpio.c
- arch/powerpc/sysdev/simple_gpio.c
- drivers/gpio/gpiolib.c
- drivers/gpio/xilinx_gpio.c
- drivers/of/gpio.c
- include/linux/of_gpio.h
arch/powerpc/platforms/52xx/mpc52xx_gpio.c
... | ... | @@ -161,7 +161,6 @@ |
161 | 161 | |
162 | 162 | gc = &chip->mmchip.gc; |
163 | 163 | |
164 | - gc->of_gpio_n_cells = 2; | |
165 | 164 | gc->ngpio = 8; |
166 | 165 | gc->direction_input = mpc52xx_wkup_gpio_dir_in; |
167 | 166 | gc->direction_output = mpc52xx_wkup_gpio_dir_out; |
... | ... | @@ -325,7 +324,6 @@ |
325 | 324 | |
326 | 325 | gc = &chip->mmchip.gc; |
327 | 326 | |
328 | - gc->of_gpio_n_cells = 2; | |
329 | 327 | gc->ngpio = 32; |
330 | 328 | gc->direction_input = mpc52xx_simple_gpio_dir_in; |
331 | 329 | gc->direction_output = mpc52xx_simple_gpio_dir_out; |
arch/powerpc/platforms/52xx/mpc52xx_gpt.c
... | ... | @@ -348,10 +348,7 @@ |
348 | 348 | gpt->gc.get = mpc52xx_gpt_gpio_get; |
349 | 349 | gpt->gc.set = mpc52xx_gpt_gpio_set; |
350 | 350 | gpt->gc.base = -1; |
351 | - gpt->gc.of_gpio_n_cells = 2; | |
352 | - gpt->gc.of_xlate = of_gpio_simple_xlate; | |
353 | 351 | gpt->gc.of_node = node; |
354 | - of_node_get(node); | |
355 | 352 | |
356 | 353 | /* Setup external pin in GPIO mode */ |
357 | 354 | clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK, |
arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
arch/powerpc/sysdev/cpm1.c
... | ... | @@ -633,7 +633,6 @@ |
633 | 633 | gc = &mm_gc->gc; |
634 | 634 | |
635 | 635 | mm_gc->save_regs = cpm1_gpio16_save_regs; |
636 | - gc->of_gpio_n_cells = 2; | |
637 | 636 | gc->ngpio = 16; |
638 | 637 | gc->direction_input = cpm1_gpio16_dir_in; |
639 | 638 | gc->direction_output = cpm1_gpio16_dir_out; |
... | ... | @@ -755,7 +754,6 @@ |
755 | 754 | gc = &mm_gc->gc; |
756 | 755 | |
757 | 756 | mm_gc->save_regs = cpm1_gpio32_save_regs; |
758 | - gc->of_gpio_n_cells = 2; | |
759 | 757 | gc->ngpio = 32; |
760 | 758 | gc->direction_input = cpm1_gpio32_dir_in; |
761 | 759 | gc->direction_output = cpm1_gpio32_dir_out; |
arch/powerpc/sysdev/cpm_common.c
arch/powerpc/sysdev/mpc8xxx_gpio.c
arch/powerpc/sysdev/ppc4xx_gpio.c
arch/powerpc/sysdev/qe_lib/gpio.c
arch/powerpc/sysdev/simple_gpio.c
drivers/gpio/gpiolib.c
... | ... | @@ -8,6 +8,7 @@ |
8 | 8 | #include <linux/debugfs.h> |
9 | 9 | #include <linux/seq_file.h> |
10 | 10 | #include <linux/gpio.h> |
11 | +#include <linux/of_gpio.h> | |
11 | 12 | #include <linux/idr.h> |
12 | 13 | #include <linux/slab.h> |
13 | 14 | |
... | ... | @@ -1099,6 +1100,8 @@ |
1099 | 1100 | } |
1100 | 1101 | } |
1101 | 1102 | |
1103 | + of_gpiochip_add(chip); | |
1104 | + | |
1102 | 1105 | unlock: |
1103 | 1106 | spin_unlock_irqrestore(&gpio_lock, flags); |
1104 | 1107 | |
... | ... | @@ -1132,6 +1135,8 @@ |
1132 | 1135 | unsigned id; |
1133 | 1136 | |
1134 | 1137 | spin_lock_irqsave(&gpio_lock, flags); |
1138 | + | |
1139 | + of_gpiochip_remove(chip); | |
1135 | 1140 | |
1136 | 1141 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { |
1137 | 1142 | if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) { |
drivers/gpio/xilinx_gpio.c
drivers/of/gpio.c
... | ... | @@ -125,8 +125,8 @@ |
125 | 125 | * gpio chips. This function performs only one sanity check: whether gpio |
126 | 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, | |
129 | - const void *gpio_spec, u32 *flags) | |
128 | +static int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, | |
129 | + const void *gpio_spec, u32 *flags) | |
130 | 130 | { |
131 | 131 | const __be32 *gpio = gpio_spec; |
132 | 132 | const u32 n = be32_to_cpup(gpio); |
... | ... | @@ -150,7 +150,6 @@ |
150 | 150 | |
151 | 151 | return n; |
152 | 152 | } |
153 | -EXPORT_SYMBOL(of_gpio_simple_xlate); | |
154 | 153 | |
155 | 154 | /** |
156 | 155 | * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank) |
... | ... | @@ -187,9 +186,6 @@ |
187 | 186 | |
188 | 187 | gc->base = -1; |
189 | 188 | |
190 | - if (!gc->of_xlate) | |
191 | - gc->of_xlate = of_gpio_simple_xlate; | |
192 | - | |
193 | 189 | if (mm_gc->save_regs) |
194 | 190 | mm_gc->save_regs(mm_gc); |
195 | 191 | |
... | ... | @@ -199,9 +195,6 @@ |
199 | 195 | if (ret) |
200 | 196 | goto err2; |
201 | 197 | |
202 | - /* We don't want to lose the node and its ->data */ | |
203 | - of_node_get(np); | |
204 | - | |
205 | 198 | pr_debug("%s: registered as generic GPIO chip, base is %d\n", |
206 | 199 | np->full_name, gc->base); |
207 | 200 | return 0; |
... | ... | @@ -215,6 +208,28 @@ |
215 | 208 | return ret; |
216 | 209 | } |
217 | 210 | EXPORT_SYMBOL(of_mm_gpiochip_add); |
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 | +} | |
218 | 233 | |
219 | 234 | /* Private function for resolving node pointer to gpio_chip */ |
220 | 235 | static int of_gpiochip_is_match(struct gpio_chip *chip, void *data) |
include/linux/of_gpio.h
... | ... | @@ -52,9 +52,9 @@ |
52 | 52 | |
53 | 53 | extern int of_mm_gpiochip_add(struct device_node *np, |
54 | 54 | struct of_mm_gpio_chip *mm_gc); |
55 | -extern int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, | |
56 | - const void *gpio_spec, u32 *flags); | |
57 | 55 | |
56 | +extern void of_gpiochip_add(struct gpio_chip *gc); | |
57 | +extern void of_gpiochip_remove(struct gpio_chip *gc); | |
58 | 58 | extern struct gpio_chip *of_node_to_gpiochip(struct device_node *np); |
59 | 59 | |
60 | 60 | #else /* CONFIG_OF_GPIO */ |
... | ... | @@ -70,6 +70,9 @@ |
70 | 70 | { |
71 | 71 | return 0; |
72 | 72 | } |
73 | + | |
74 | +static inline void of_gpiochip_add(struct gpio_chip *gc) { } | |
75 | +static inline void of_gpiochip_remove(struct gpio_chip *gc) { } | |
73 | 76 | |
74 | 77 | #endif /* CONFIG_OF_GPIO */ |
75 | 78 |