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 | |
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
-rw-r--r-- | arch/powerpc/platforms/52xx/mpc52xx_gpio.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/52xx/mpc52xx_gpt.c | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c | 2 | ||||
-rw-r--r-- | arch/powerpc/sysdev/cpm1.c | 2 | ||||
-rw-r--r-- | arch/powerpc/sysdev/cpm_common.c | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mpc8xxx_gpio.c | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/ppc4xx_gpio.c | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/gpio.c | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/simple_gpio.c | 1 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 5 | ||||
-rw-r--r-- | drivers/gpio/xilinx_gpio.c | 1 | ||||
-rw-r--r-- | drivers/of/gpio.c | 33 | ||||
-rw-r--r-- | include/linux/of_gpio.h | 7 |
13 files changed, 34 insertions, 26 deletions
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index fd0912eeffe2..0855e804fc0d 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c | |||
@@ -161,7 +161,6 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev, | |||
161 | 161 | ||
162 | gc = &chip->mmchip.gc; | 162 | gc = &chip->mmchip.gc; |
163 | 163 | ||
164 | gc->of_gpio_n_cells = 2; | ||
165 | gc->ngpio = 8; | 164 | gc->ngpio = 8; |
166 | gc->direction_input = mpc52xx_wkup_gpio_dir_in; | 165 | gc->direction_input = mpc52xx_wkup_gpio_dir_in; |
167 | gc->direction_output = mpc52xx_wkup_gpio_dir_out; | 166 | gc->direction_output = mpc52xx_wkup_gpio_dir_out; |
@@ -325,7 +324,6 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev, | |||
325 | 324 | ||
326 | gc = &chip->mmchip.gc; | 325 | gc = &chip->mmchip.gc; |
327 | 326 | ||
328 | gc->of_gpio_n_cells = 2; | ||
329 | gc->ngpio = 32; | 327 | gc->ngpio = 32; |
330 | gc->direction_input = mpc52xx_simple_gpio_dir_in; | 328 | gc->direction_input = mpc52xx_simple_gpio_dir_in; |
331 | gc->direction_output = mpc52xx_simple_gpio_dir_out; | 329 | gc->direction_output = mpc52xx_simple_gpio_dir_out; |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 6e82bd27132c..5d7d607617cd 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c | |||
@@ -348,10 +348,7 @@ mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) | |||
348 | gpt->gc.get = mpc52xx_gpt_gpio_get; | 348 | gpt->gc.get = mpc52xx_gpt_gpio_get; |
349 | gpt->gc.set = mpc52xx_gpt_gpio_set; | 349 | gpt->gc.set = mpc52xx_gpt_gpio_set; |
350 | gpt->gc.base = -1; | 350 | gpt->gc.base = -1; |
351 | gpt->gc.of_gpio_n_cells = 2; | ||
352 | gpt->gc.of_xlate = of_gpio_simple_xlate; | ||
353 | gpt->gc.of_node = node; | 351 | gpt->gc.of_node = node; |
354 | of_node_get(node); | ||
355 | 352 | ||
356 | /* Setup external pin in GPIO mode */ | 353 | /* Setup external pin in GPIO mode */ |
357 | clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK, | 354 | clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK, |
diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index f0dbace6185a..59b0ed1a56b1 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c | |||
@@ -90,8 +90,6 @@ static int mcu_gpiochip_add(struct mcu *mcu) | |||
90 | gc->base = -1; | 90 | gc->base = -1; |
91 | gc->set = mcu_gpio_set; | 91 | gc->set = mcu_gpio_set; |
92 | gc->direction_output = mcu_gpio_dir_out; | 92 | gc->direction_output = mcu_gpio_dir_out; |
93 | gc->of_gpio_n_cells = 2; | ||
94 | gc->of_xlate = of_gpio_simple_xlate; | ||
95 | gc->of_node = np; | 93 | gc->of_node = np; |
96 | 94 | ||
97 | return gpiochip_add(gc); | 95 | return gpiochip_add(gc); |
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index d5cf7d4ccf81..00852124ff4a 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c | |||
@@ -633,7 +633,6 @@ int cpm1_gpiochip_add16(struct device_node *np) | |||
633 | gc = &mm_gc->gc; | 633 | gc = &mm_gc->gc; |
634 | 634 | ||
635 | mm_gc->save_regs = cpm1_gpio16_save_regs; | 635 | mm_gc->save_regs = cpm1_gpio16_save_regs; |
636 | gc->of_gpio_n_cells = 2; | ||
637 | gc->ngpio = 16; | 636 | gc->ngpio = 16; |
638 | gc->direction_input = cpm1_gpio16_dir_in; | 637 | gc->direction_input = cpm1_gpio16_dir_in; |
639 | gc->direction_output = cpm1_gpio16_dir_out; | 638 | gc->direction_output = cpm1_gpio16_dir_out; |
@@ -755,7 +754,6 @@ int cpm1_gpiochip_add32(struct device_node *np) | |||
755 | gc = &mm_gc->gc; | 754 | gc = &mm_gc->gc; |
756 | 755 | ||
757 | mm_gc->save_regs = cpm1_gpio32_save_regs; | 756 | mm_gc->save_regs = cpm1_gpio32_save_regs; |
758 | gc->of_gpio_n_cells = 2; | ||
759 | gc->ngpio = 32; | 757 | gc->ngpio = 32; |
760 | gc->direction_input = cpm1_gpio32_dir_in; | 758 | gc->direction_input = cpm1_gpio32_dir_in; |
761 | gc->direction_output = cpm1_gpio32_dir_out; | 759 | gc->direction_output = cpm1_gpio32_dir_out; |
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 67e9b47dcf8e..2b69aa0315b3 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c | |||
@@ -337,7 +337,6 @@ int cpm2_gpiochip_add32(struct device_node *np) | |||
337 | gc = &mm_gc->gc; | 337 | gc = &mm_gc->gc; |
338 | 338 | ||
339 | mm_gc->save_regs = cpm2_gpio32_save_regs; | 339 | mm_gc->save_regs = cpm2_gpio32_save_regs; |
340 | gc->of_gpio_n_cells = 2; | ||
341 | gc->ngpio = 32; | 340 | gc->ngpio = 32; |
342 | gc->direction_input = cpm2_gpio32_dir_in; | 341 | gc->direction_input = cpm2_gpio32_dir_in; |
343 | gc->direction_output = cpm2_gpio32_dir_out; | 342 | gc->direction_output = cpm2_gpio32_dir_out; |
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c index ec8fcd42101e..2b69084d0f0c 100644 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c | |||
@@ -273,7 +273,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np) | |||
273 | gc = &mm_gc->gc; | 273 | gc = &mm_gc->gc; |
274 | 274 | ||
275 | mm_gc->save_regs = mpc8xxx_gpio_save_regs; | 275 | mm_gc->save_regs = mpc8xxx_gpio_save_regs; |
276 | gc->of_gpio_n_cells = 2; | ||
277 | gc->ngpio = MPC8XXX_GPIO_PINS; | 276 | gc->ngpio = MPC8XXX_GPIO_PINS; |
278 | gc->direction_input = mpc8xxx_gpio_dir_in; | 277 | gc->direction_input = mpc8xxx_gpio_dir_in; |
279 | gc->direction_output = mpc8xxx_gpio_dir_out; | 278 | gc->direction_output = mpc8xxx_gpio_dir_out; |
diff --git a/arch/powerpc/sysdev/ppc4xx_gpio.c b/arch/powerpc/sysdev/ppc4xx_gpio.c index 42e7a5eea665..fc65ad1b3293 100644 --- a/arch/powerpc/sysdev/ppc4xx_gpio.c +++ b/arch/powerpc/sysdev/ppc4xx_gpio.c | |||
@@ -194,7 +194,6 @@ static int __init ppc4xx_add_gpiochips(void) | |||
194 | mm_gc = &ppc4xx_gc->mm_gc; | 194 | mm_gc = &ppc4xx_gc->mm_gc; |
195 | gc = &mm_gc->gc; | 195 | gc = &mm_gc->gc; |
196 | 196 | ||
197 | gc->of_gpio_n_cells = 2; | ||
198 | gc->ngpio = 32; | 197 | gc->ngpio = 32; |
199 | gc->direction_input = ppc4xx_gpio_dir_in; | 198 | gc->direction_input = ppc4xx_gpio_dir_in; |
200 | gc->direction_output = ppc4xx_gpio_dir_out; | 199 | gc->direction_output = ppc4xx_gpio_dir_out; |
diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c index 32e9440010a1..36bf845df127 100644 --- a/arch/powerpc/sysdev/qe_lib/gpio.c +++ b/arch/powerpc/sysdev/qe_lib/gpio.c | |||
@@ -321,7 +321,6 @@ static int __init qe_add_gpiochips(void) | |||
321 | gc = &mm_gc->gc; | 321 | gc = &mm_gc->gc; |
322 | 322 | ||
323 | mm_gc->save_regs = qe_gpio_save_regs; | 323 | mm_gc->save_regs = qe_gpio_save_regs; |
324 | gc->of_gpio_n_cells = 2; | ||
325 | gc->ngpio = QE_PIO_PINS; | 324 | gc->ngpio = QE_PIO_PINS; |
326 | gc->direction_input = qe_gpio_dir_in; | 325 | gc->direction_input = qe_gpio_dir_in; |
327 | gc->direction_output = qe_gpio_dir_out; | 326 | gc->direction_output = qe_gpio_dir_out; |
diff --git a/arch/powerpc/sysdev/simple_gpio.c b/arch/powerpc/sysdev/simple_gpio.c index b7559aa0c165..b6defda5ccc9 100644 --- a/arch/powerpc/sysdev/simple_gpio.c +++ b/arch/powerpc/sysdev/simple_gpio.c | |||
@@ -103,7 +103,6 @@ static int __init u8_simple_gpiochip_add(struct device_node *np) | |||
103 | gc = &mm_gc->gc; | 103 | gc = &mm_gc->gc; |
104 | 104 | ||
105 | mm_gc->save_regs = u8_gpio_save_regs; | 105 | mm_gc->save_regs = u8_gpio_save_regs; |
106 | gc->of_gpio_n_cells = 2; | ||
107 | gc->ngpio = 8; | 106 | gc->ngpio = 8; |
108 | gc->direction_input = u8_gpio_dir_in; | 107 | gc->direction_input = u8_gpio_dir_in; |
109 | gc->direction_output = u8_gpio_dir_out; | 108 | gc->direction_output = u8_gpio_dir_out; |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 73fd328f6fe4..83cbc34e3a76 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/debugfs.h> | 8 | #include <linux/debugfs.h> |
9 | #include <linux/seq_file.h> | 9 | #include <linux/seq_file.h> |
10 | #include <linux/gpio.h> | 10 | #include <linux/gpio.h> |
11 | #include <linux/of_gpio.h> | ||
11 | #include <linux/idr.h> | 12 | #include <linux/idr.h> |
12 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
13 | 14 | ||
@@ -1099,6 +1100,8 @@ int gpiochip_add(struct gpio_chip *chip) | |||
1099 | } | 1100 | } |
1100 | } | 1101 | } |
1101 | 1102 | ||
1103 | of_gpiochip_add(chip); | ||
1104 | |||
1102 | unlock: | 1105 | unlock: |
1103 | spin_unlock_irqrestore(&gpio_lock, flags); | 1106 | spin_unlock_irqrestore(&gpio_lock, flags); |
1104 | 1107 | ||
@@ -1133,6 +1136,8 @@ int gpiochip_remove(struct gpio_chip *chip) | |||
1133 | 1136 | ||
1134 | spin_lock_irqsave(&gpio_lock, flags); | 1137 | spin_lock_irqsave(&gpio_lock, flags); |
1135 | 1138 | ||
1139 | of_gpiochip_remove(chip); | ||
1140 | |||
1136 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { | 1141 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { |
1137 | if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) { | 1142 | if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) { |
1138 | status = -EBUSY; | 1143 | status = -EBUSY; |
diff --git a/drivers/gpio/xilinx_gpio.c b/drivers/gpio/xilinx_gpio.c index 2993c40b48e1..709690995d0d 100644 --- a/drivers/gpio/xilinx_gpio.c +++ b/drivers/gpio/xilinx_gpio.c | |||
@@ -190,7 +190,6 @@ static int __devinit xgpio_of_probe(struct device_node *np) | |||
190 | 190 | ||
191 | spin_lock_init(&chip->gpio_lock); | 191 | spin_lock_init(&chip->gpio_lock); |
192 | 192 | ||
193 | chip->mmchip.gc.of_gpio_n_cells = 2; | ||
194 | chip->mmchip.gc.direction_input = xgpio_dir_in; | 193 | chip->mmchip.gc.direction_input = xgpio_dir_in; |
195 | chip->mmchip.gc.direction_output = xgpio_dir_out; | 194 | chip->mmchip.gc.direction_output = xgpio_dir_out; |
196 | chip->mmchip.gc.get = xgpio_get; | 195 | chip->mmchip.gc.get = xgpio_get; |
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 | { |
diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index 1020587efed1..6598c04dab01 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h | |||
@@ -52,9 +52,9 @@ extern unsigned int of_gpio_count(struct device_node *np); | |||
52 | 52 | ||
53 | extern int of_mm_gpiochip_add(struct device_node *np, | 53 | extern int of_mm_gpiochip_add(struct device_node *np, |
54 | struct of_mm_gpio_chip *mm_gc); | 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 | extern struct gpio_chip *of_node_to_gpiochip(struct device_node *np); | 58 | extern struct gpio_chip *of_node_to_gpiochip(struct device_node *np); |
59 | 59 | ||
60 | #else /* CONFIG_OF_GPIO */ | 60 | #else /* CONFIG_OF_GPIO */ |
@@ -71,6 +71,9 @@ static inline unsigned int of_gpio_count(struct device_node *np) | |||
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
74 | static inline void of_gpiochip_add(struct gpio_chip *gc) { } | ||
75 | static inline void of_gpiochip_remove(struct gpio_chip *gc) { } | ||
76 | |||
74 | #endif /* CONFIG_OF_GPIO */ | 77 | #endif /* CONFIG_OF_GPIO */ |
75 | 78 | ||
76 | /** | 79 | /** |