diff options
author | Eric Miao <eric.miao@marvell.com> | 2009-01-06 04:37:37 -0500 |
---|---|---|
committer | Eric Miao <eric.miao@marvell.com> | 2009-03-09 09:22:37 -0400 |
commit | a58fbcd8ad17ddaa0c7aadbbbd20de4ebc807fa4 (patch) | |
tree | 00b0a13c0dbe7155d5b529f9d36cc423996a3e19 /arch/arm/mach-pxa/gpio.c | |
parent | 7ebc8d56f407184a457dd5fc739cf39e423a25aa (diff) |
[ARM] pxa: move IRQ handling of GPIO 0 and 1 outside of gpio.c
This is part of the work making gpio.c generic enough, the changes
include:
1. move IRQ handling of GPIO 0 and 1 outside (and back into irq.c)
2. pxa_init_gpio() accepts a range for muxed GPIO IRQs, and an IRQ
number for the muxed GPIOs
3. __gpio_is_occupied() and __gpio_is_inverted() are made inline,
and are moved into <mach/gpio.h> instead of generic gpio.c
Signed-off-by: Eric Miao <eric.miao@marvell.com>
Diffstat (limited to 'arch/arm/mach-pxa/gpio.c')
-rw-r--r-- | arch/arm/mach-pxa/gpio.c | 113 |
1 files changed, 25 insertions, 88 deletions
diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c index 5fec1e479cb3..198246019028 100644 --- a/arch/arm/mach-pxa/gpio.c +++ b/arch/arm/mach-pxa/gpio.c | |||
@@ -45,18 +45,6 @@ struct pxa_gpio_chip { | |||
45 | 45 | ||
46 | int pxa_last_gpio; | 46 | int pxa_last_gpio; |
47 | 47 | ||
48 | #ifdef CONFIG_CPU_PXA26x | ||
49 | /* GPIO86/87/88/89 on PXA26x have their direction bits in GPDR2 inverted, | ||
50 | * as well as their Alternate Function value being '1' for GPIO in GAFRx. | ||
51 | */ | ||
52 | static int __gpio_is_inverted(unsigned gpio) | ||
53 | { | ||
54 | return cpu_is_pxa25x() && gpio > 85; | ||
55 | } | ||
56 | #else | ||
57 | #define __gpio_is_inverted(gpio) (0) | ||
58 | #endif | ||
59 | |||
60 | /* | 48 | /* |
61 | * Configure pins for GPIO or other functions | 49 | * Configure pins for GPIO or other functions |
62 | */ | 50 | */ |
@@ -185,6 +173,20 @@ static struct pxa_gpio_chip pxa_gpio_chip[] = { | |||
185 | #endif | 173 | #endif |
186 | }; | 174 | }; |
187 | 175 | ||
176 | static void __init pxa_init_gpio_chip(int gpio_nr) | ||
177 | { | ||
178 | int i, gpio; | ||
179 | |||
180 | /* add a GPIO chip for each register bank. | ||
181 | * the last PXA25x register only contains 21 GPIOs | ||
182 | */ | ||
183 | for (gpio = 0, i = 0; gpio < gpio_nr; gpio += 32, i++) { | ||
184 | if (gpio + 32 > gpio_nr) | ||
185 | pxa_gpio_chip[i].chip.ngpio = gpio_nr - gpio; | ||
186 | gpiochip_add(&pxa_gpio_chip[i].chip); | ||
187 | } | ||
188 | } | ||
189 | |||
188 | /* | 190 | /* |
189 | * PXA GPIO edge detection for IRQs: | 191 | * PXA GPIO edge detection for IRQs: |
190 | * IRQs are generated on Falling-Edge, Rising-Edge, or both. | 192 | * IRQs are generated on Falling-Edge, Rising-Edge, or both. |
@@ -195,27 +197,6 @@ static unsigned long GPIO_IRQ_rising_edge[4]; | |||
195 | static unsigned long GPIO_IRQ_falling_edge[4]; | 197 | static unsigned long GPIO_IRQ_falling_edge[4]; |
196 | static unsigned long GPIO_IRQ_mask[4]; | 198 | static unsigned long GPIO_IRQ_mask[4]; |
197 | 199 | ||
198 | /* | ||
199 | * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate | ||
200 | * function of a GPIO, and GPDRx cannot be altered once configured. It | ||
201 | * is attributed as "occupied" here (I know this terminology isn't | ||
202 | * accurate, you are welcome to propose a better one :-) | ||
203 | */ | ||
204 | static int __gpio_is_occupied(unsigned gpio) | ||
205 | { | ||
206 | if (cpu_is_pxa27x() || cpu_is_pxa25x()) { | ||
207 | int af = (GAFR(gpio) >> ((gpio & 0xf) * 2)) & 0x3; | ||
208 | int dir = GPDR(gpio) & GPIO_bit(gpio); | ||
209 | |||
210 | if (__gpio_is_inverted(gpio)) | ||
211 | return af != 1 || dir == 0; | ||
212 | else | ||
213 | return af != 0 || dir != 0; | ||
214 | } | ||
215 | |||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) | 200 | static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) |
220 | { | 201 | { |
221 | int gpio, idx; | 202 | int gpio, idx; |
@@ -262,33 +243,6 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) | |||
262 | } | 243 | } |
263 | 244 | ||
264 | /* | 245 | /* |
265 | * GPIO IRQs must be acknowledged. This is for GPIO 0 and 1. | ||
266 | */ | ||
267 | |||
268 | static void pxa_ack_low_gpio(unsigned int irq) | ||
269 | { | ||
270 | GEDR0 = (1 << (irq - IRQ_GPIO0)); | ||
271 | } | ||
272 | |||
273 | static void pxa_mask_low_gpio(unsigned int irq) | ||
274 | { | ||
275 | ICMR &= ~(1 << (irq - PXA_IRQ(0))); | ||
276 | } | ||
277 | |||
278 | static void pxa_unmask_low_gpio(unsigned int irq) | ||
279 | { | ||
280 | ICMR |= 1 << (irq - PXA_IRQ(0)); | ||
281 | } | ||
282 | |||
283 | static struct irq_chip pxa_low_gpio_chip = { | ||
284 | .name = "GPIO-l", | ||
285 | .ack = pxa_ack_low_gpio, | ||
286 | .mask = pxa_mask_low_gpio, | ||
287 | .unmask = pxa_unmask_low_gpio, | ||
288 | .set_type = pxa_gpio_irq_type, | ||
289 | }; | ||
290 | |||
291 | /* | ||
292 | * Demux handler for GPIO>=2 edge detect interrupts | 246 | * Demux handler for GPIO>=2 edge detect interrupts |
293 | */ | 247 | */ |
294 | 248 | ||
@@ -352,48 +306,31 @@ static struct irq_chip pxa_muxed_gpio_chip = { | |||
352 | .set_type = pxa_gpio_irq_type, | 306 | .set_type = pxa_gpio_irq_type, |
353 | }; | 307 | }; |
354 | 308 | ||
355 | void __init pxa_init_gpio(int gpio_nr, set_wake_t fn) | 309 | void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn) |
356 | { | 310 | { |
357 | int irq, i, gpio; | 311 | int irq, i; |
358 | 312 | ||
359 | pxa_last_gpio = gpio_nr - 1; | 313 | pxa_last_gpio = end; |
360 | 314 | ||
361 | /* clear all GPIO edge detects */ | 315 | /* clear all GPIO edge detects */ |
362 | for (i = 0; i < gpio_nr; i += 32) { | 316 | for (i = start; i <= end; i += 32) { |
363 | GFER(i) = 0; | 317 | GFER(i) &= ~GPIO_IRQ_mask[i]; |
364 | GRER(i) = 0; | 318 | GRER(i) &= ~GPIO_IRQ_mask[i]; |
365 | GEDR(i) = GEDR(i); | 319 | GEDR(i) = GPIO_IRQ_mask[i]; |
366 | } | 320 | } |
367 | 321 | ||
368 | /* GPIO 0 and 1 must have their mask bit always set */ | 322 | for (irq = gpio_to_irq(start); irq <= gpio_to_irq(end); irq++) { |
369 | GPIO_IRQ_mask[0] = 3; | ||
370 | |||
371 | for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) { | ||
372 | set_irq_chip(irq, &pxa_low_gpio_chip); | ||
373 | set_irq_handler(irq, handle_edge_irq); | ||
374 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
375 | } | ||
376 | |||
377 | for (irq = IRQ_GPIO(2); irq < IRQ_GPIO(gpio_nr); irq++) { | ||
378 | set_irq_chip(irq, &pxa_muxed_gpio_chip); | 323 | set_irq_chip(irq, &pxa_muxed_gpio_chip); |
379 | set_irq_handler(irq, handle_edge_irq); | 324 | set_irq_handler(irq, handle_edge_irq); |
380 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 325 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
381 | } | 326 | } |
382 | 327 | ||
383 | /* Install handler for GPIO>=2 edge detect interrupts */ | 328 | /* Install handler for GPIO>=2 edge detect interrupts */ |
384 | set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler); | 329 | set_irq_chained_handler(mux_irq, pxa_gpio_demux_handler); |
385 | |||
386 | pxa_low_gpio_chip.set_wake = fn; | ||
387 | pxa_muxed_gpio_chip.set_wake = fn; | 330 | pxa_muxed_gpio_chip.set_wake = fn; |
388 | 331 | ||
389 | /* add a GPIO chip for each register bank. | 332 | /* Initialize GPIO chips */ |
390 | * the last PXA25x register only contains 21 GPIOs | 333 | pxa_init_gpio_chip(end + 1); |
391 | */ | ||
392 | for (gpio = 0, i = 0; gpio < gpio_nr; gpio += 32, i++) { | ||
393 | if (gpio + 32 > gpio_nr) | ||
394 | pxa_gpio_chip[i].chip.ngpio = gpio_nr - gpio; | ||
395 | gpiochip_add(&pxa_gpio_chip[i].chip); | ||
396 | } | ||
397 | } | 334 | } |
398 | 335 | ||
399 | #ifdef CONFIG_PM | 336 | #ifdef CONFIG_PM |