diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-28 17:40:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-28 17:40:39 -0400 |
commit | ebdea46fecae40c4d7effcd33f40918a37a1df4b (patch) | |
tree | e4312bf7f1f3d184738963a0ec300aa9fdfd55c1 /arch/arm/mach-at91rm9200/gpio.c | |
parent | fecf3404f4aba6d0edeba31eeb018cbb6326dff2 (diff) | |
parent | 250d375d1da45a5e08ab8baf5eaa7eb258afd82b (diff) |
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (130 commits)
[ARM] 3856/1: Add clocksource for Intel IXP4xx platforms
[ARM] 3855/1: Add generic time support
[ARM] 3873/1: S3C24XX: Add irq_chip names
[ARM] 3872/1: S3C24XX: Apply consistant tabbing to irq_chips
[ARM] 3871/1: S3C24XX: Fix ordering of EINT4..23
[ARM] nommu: confirms the CR_V bit in nommu mode
[ARM] nommu: abort handler fixup for !CPU_CP15_MMU cores.
[ARM] 3870/1: AT91: Start removing static memory mappings
[ARM] 3869/1: AT91: NAND support for DK and KB9202 boards
[ARM] 3868/1: AT91 hardware header update
[ARM] 3867/1: AT91 GPIO update
[ARM] 3866/1: AT91 clock update
[ARM] 3865/1: AT91RM9200 header updates
[ARM] 3862/2: S3C2410 - add basic power management support for AML M5900 series
[ARM] kthread: switch arch/arm/kernel/apm.c
[ARM] Off-by-one in arch/arm/common/icst*
[ARM] 3864/1: Refactore sharpsl_pm
[ARM] 3863/1: Add Locomo SPI Device
[ARM] 3847/2: Convert LOMOMO to use struct device for GPIOs
[ARM] Use CPU_CACHE_* where possible in asm/cacheflush.h
...
Diffstat (limited to 'arch/arm/mach-at91rm9200/gpio.c')
-rw-r--r-- | arch/arm/mach-at91rm9200/gpio.c | 89 |
1 files changed, 51 insertions, 38 deletions
diff --git a/arch/arm/mach-at91rm9200/gpio.c b/arch/arm/mach-at91rm9200/gpio.c index cec199fd6721..58c9bf5e9520 100644 --- a/arch/arm/mach-at91rm9200/gpio.c +++ b/arch/arm/mach-at91rm9200/gpio.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/clk.h> | ||
12 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
13 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
14 | #include <linux/irq.h> | 15 | #include <linux/irq.h> |
@@ -20,12 +21,12 @@ | |||
20 | #include <asm/hardware.h> | 21 | #include <asm/hardware.h> |
21 | #include <asm/arch/gpio.h> | 22 | #include <asm/arch/gpio.h> |
22 | 23 | ||
23 | static const u32 pio_controller_offset[4] = { | 24 | #include "generic.h" |
24 | AT91_PIOA, | 25 | |
25 | AT91_PIOB, | 26 | |
26 | AT91_PIOC, | 27 | static struct at91_gpio_bank *gpio; |
27 | AT91_PIOD, | 28 | static int gpio_banks; |
28 | }; | 29 | |
29 | 30 | ||
30 | static inline void __iomem *pin_to_controller(unsigned pin) | 31 | static inline void __iomem *pin_to_controller(unsigned pin) |
31 | { | 32 | { |
@@ -33,8 +34,8 @@ static inline void __iomem *pin_to_controller(unsigned pin) | |||
33 | 34 | ||
34 | pin -= PIN_BASE; | 35 | pin -= PIN_BASE; |
35 | pin /= 32; | 36 | pin /= 32; |
36 | if (likely(pin < BGA_GPIO_BANKS)) | 37 | if (likely(pin < gpio_banks)) |
37 | return sys_base + pio_controller_offset[pin]; | 38 | return sys_base + gpio[pin].offset; |
38 | 39 | ||
39 | return NULL; | 40 | return NULL; |
40 | } | 41 | } |
@@ -179,7 +180,6 @@ EXPORT_SYMBOL(at91_set_multi_drive); | |||
179 | 180 | ||
180 | /*--------------------------------------------------------------------------*/ | 181 | /*--------------------------------------------------------------------------*/ |
181 | 182 | ||
182 | |||
183 | /* | 183 | /* |
184 | * assuming the pin is muxed as a gpio output, set its value. | 184 | * assuming the pin is muxed as a gpio output, set its value. |
185 | */ | 185 | */ |
@@ -216,8 +216,8 @@ EXPORT_SYMBOL(at91_get_gpio_value); | |||
216 | 216 | ||
217 | #ifdef CONFIG_PM | 217 | #ifdef CONFIG_PM |
218 | 218 | ||
219 | static u32 wakeups[BGA_GPIO_BANKS]; | 219 | static u32 wakeups[MAX_GPIO_BANKS]; |
220 | static u32 backups[BGA_GPIO_BANKS]; | 220 | static u32 backups[MAX_GPIO_BANKS]; |
221 | 221 | ||
222 | static int gpio_irq_set_wake(unsigned pin, unsigned state) | 222 | static int gpio_irq_set_wake(unsigned pin, unsigned state) |
223 | { | 223 | { |
@@ -226,7 +226,7 @@ static int gpio_irq_set_wake(unsigned pin, unsigned state) | |||
226 | pin -= PIN_BASE; | 226 | pin -= PIN_BASE; |
227 | pin /= 32; | 227 | pin /= 32; |
228 | 228 | ||
229 | if (unlikely(pin >= BGA_GPIO_BANKS)) | 229 | if (unlikely(pin >= MAX_GPIO_BANKS)) |
230 | return -EINVAL; | 230 | return -EINVAL; |
231 | 231 | ||
232 | if (state) | 232 | if (state) |
@@ -241,8 +241,8 @@ void at91_gpio_suspend(void) | |||
241 | { | 241 | { |
242 | int i; | 242 | int i; |
243 | 243 | ||
244 | for (i = 0; i < BGA_GPIO_BANKS; i++) { | 244 | for (i = 0; i < gpio_banks; i++) { |
245 | u32 pio = pio_controller_offset[i]; | 245 | u32 pio = gpio[i].offset; |
246 | 246 | ||
247 | /* | 247 | /* |
248 | * Note: drivers should have disabled GPIO interrupts that | 248 | * Note: drivers should have disabled GPIO interrupts that |
@@ -257,14 +257,14 @@ void at91_gpio_suspend(void) | |||
257 | * first place! | 257 | * first place! |
258 | */ | 258 | */ |
259 | backups[i] = at91_sys_read(pio + PIO_IMR); | 259 | backups[i] = at91_sys_read(pio + PIO_IMR); |
260 | at91_sys_write(pio_controller_offset[i] + PIO_IDR, backups[i]); | 260 | at91_sys_write(pio + PIO_IDR, backups[i]); |
261 | at91_sys_write(pio_controller_offset[i] + PIO_IER, wakeups[i]); | 261 | at91_sys_write(pio + PIO_IER, wakeups[i]); |
262 | 262 | ||
263 | if (!wakeups[i]) { | 263 | if (!wakeups[i]) { |
264 | disable_irq_wake(AT91_ID_PIOA + i); | 264 | disable_irq_wake(gpio[i].id); |
265 | at91_sys_write(AT91_PMC_PCDR, 1 << (AT91_ID_PIOA + i)); | 265 | at91_sys_write(AT91_PMC_PCDR, 1 << gpio[i].id); |
266 | } else { | 266 | } else { |
267 | enable_irq_wake(AT91_ID_PIOA + i); | 267 | enable_irq_wake(gpio[i].id); |
268 | #ifdef CONFIG_PM_DEBUG | 268 | #ifdef CONFIG_PM_DEBUG |
269 | printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", "ABCD"[i], wakeups[i]); | 269 | printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", "ABCD"[i], wakeups[i]); |
270 | #endif | 270 | #endif |
@@ -276,16 +276,13 @@ void at91_gpio_resume(void) | |||
276 | { | 276 | { |
277 | int i; | 277 | int i; |
278 | 278 | ||
279 | for (i = 0; i < BGA_GPIO_BANKS; i++) { | 279 | for (i = 0; i < gpio_banks; i++) { |
280 | at91_sys_write(pio_controller_offset[i] + PIO_IDR, wakeups[i]); | 280 | u32 pio = gpio[i].offset; |
281 | at91_sys_write(pio_controller_offset[i] + PIO_IER, backups[i]); | ||
282 | } | ||
283 | 281 | ||
284 | at91_sys_write(AT91_PMC_PCER, | 282 | at91_sys_write(pio + PIO_IDR, wakeups[i]); |
285 | (1 << AT91_ID_PIOA) | 283 | at91_sys_write(pio + PIO_IER, backups[i]); |
286 | | (1 << AT91_ID_PIOB) | 284 | at91_sys_write(AT91_PMC_PCER, 1 << gpio[i].id); |
287 | | (1 << AT91_ID_PIOC) | 285 | } |
288 | | (1 << AT91_ID_PIOD)); | ||
289 | } | 286 | } |
290 | 287 | ||
291 | #else | 288 | #else |
@@ -377,20 +374,25 @@ static void gpio_irq_handler(unsigned irq, struct irqdesc *desc, struct pt_regs | |||
377 | /* now it may re-trigger */ | 374 | /* now it may re-trigger */ |
378 | } | 375 | } |
379 | 376 | ||
380 | /* call this from board-specific init_irq */ | 377 | /*--------------------------------------------------------------------------*/ |
381 | void __init at91_gpio_irq_setup(unsigned banks) | 378 | |
379 | /* | ||
380 | * Called from the processor-specific init to enable GPIO interrupt support. | ||
381 | */ | ||
382 | void __init at91_gpio_irq_setup(void) | ||
382 | { | 383 | { |
383 | unsigned pioc, pin, id; | 384 | unsigned pioc, pin; |
384 | 385 | ||
385 | if (banks > 4) | 386 | for (pioc = 0, pin = PIN_BASE; |
386 | banks = 4; | 387 | pioc < gpio_banks; |
387 | for (pioc = 0, pin = PIN_BASE, id = AT91_ID_PIOA; | 388 | pioc++) { |
388 | pioc < banks; | ||
389 | pioc++, id++) { | ||
390 | void __iomem *controller; | 389 | void __iomem *controller; |
390 | unsigned id = gpio[pioc].id; | ||
391 | unsigned i; | 391 | unsigned i; |
392 | 392 | ||
393 | controller = (void __iomem *) AT91_VA_BASE_SYS + pio_controller_offset[pioc]; | 393 | clk_enable(gpio[pioc].clock); /* enable PIO controller's clock */ |
394 | |||
395 | controller = (void __iomem *) AT91_VA_BASE_SYS + gpio[pioc].offset; | ||
394 | __raw_writel(~0, controller + PIO_IDR); | 396 | __raw_writel(~0, controller + PIO_IDR); |
395 | 397 | ||
396 | set_irq_data(id, (void *) pin); | 398 | set_irq_data(id, (void *) pin); |
@@ -408,5 +410,16 @@ void __init at91_gpio_irq_setup(unsigned banks) | |||
408 | 410 | ||
409 | set_irq_chained_handler(id, gpio_irq_handler); | 411 | set_irq_chained_handler(id, gpio_irq_handler); |
410 | } | 412 | } |
411 | pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, banks); | 413 | pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks); |
414 | } | ||
415 | |||
416 | /* | ||
417 | * Called from the processor-specific init to enable GPIO pin support. | ||
418 | */ | ||
419 | void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) | ||
420 | { | ||
421 | BUG_ON(nr_banks > MAX_GPIO_BANKS); | ||
422 | |||
423 | gpio = data; | ||
424 | gpio_banks = nr_banks; | ||
412 | } | 425 | } |