aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-at91rm9200/gpio.c
diff options
context:
space:
mode:
authorAndrew Victor <andrew@sanpeople.com>2006-09-27 08:23:00 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-09-28 06:53:47 -0400
commitf21738341ca330ec83ef978ee63ffa5ecf13f082 (patch)
treebe42abeb9ef2509a5a0c4187f4aa076d8f3c2dee /arch/arm/mach-at91rm9200/gpio.c
parent2eeaaa21de68cb8869d3a54438a9224321d3dd03 (diff)
[ARM] 3867/1: AT91 GPIO update
This patch makes the AT91 gpio.c support processor-generic (AT91RM9200 and AT91SAM9xxx). The GPIO controllers supported by a particular AT91 processor are defined in the processor-specific file and are registered with gpio.c at startup. Signed-off-by: Andrew Victor <andrew@sanpeople.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-at91rm9200/gpio.c')
-rw-r--r--arch/arm/mach-at91rm9200/gpio.c89
1 files changed, 51 insertions, 38 deletions
diff --git a/arch/arm/mach-at91rm9200/gpio.c b/arch/arm/mach-at91rm9200/gpio.c
index 8476cb8856c9..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
23static const u32 pio_controller_offset[4] = { 24#include "generic.h"
24 AT91_PIOA, 25
25 AT91_PIOB, 26
26 AT91_PIOC, 27static struct at91_gpio_bank *gpio;
27 AT91_PIOD, 28static int gpio_banks;
28}; 29
29 30
30static inline void __iomem *pin_to_controller(unsigned pin) 31static 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
219static u32 wakeups[BGA_GPIO_BANKS]; 219static u32 wakeups[MAX_GPIO_BANKS];
220static u32 backups[BGA_GPIO_BANKS]; 220static u32 backups[MAX_GPIO_BANKS];
221 221
222static int gpio_irq_set_wake(unsigned pin, unsigned state) 222static 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(AT91RM9200_ID_PIOA + i); 264 disable_irq_wake(gpio[i].id);
265 at91_sys_write(AT91_PMC_PCDR, 1 << (AT91RM9200_ID_PIOA + i)); 265 at91_sys_write(AT91_PMC_PCDR, 1 << gpio[i].id);
266 } else { 266 } else {
267 enable_irq_wake(AT91RM9200_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 << AT91RM9200_ID_PIOA) 283 at91_sys_write(pio + PIO_IER, backups[i]);
286 | (1 << AT91RM9200_ID_PIOB) 284 at91_sys_write(AT91_PMC_PCER, 1 << gpio[i].id);
287 | (1 << AT91RM9200_ID_PIOC) 285 }
288 | (1 << AT91RM9200_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/*--------------------------------------------------------------------------*/
381void __init at91_gpio_irq_setup(unsigned banks) 378
379/*
380 * Called from the processor-specific init to enable GPIO interrupt support.
381 */
382void __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 = AT91RM9200_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 */
419void __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}