aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--arch/arm/mach-at91rm9200/at91rm9200.c39
-rw-r--r--arch/arm/mach-at91rm9200/board-1arm.c15
-rw-r--r--arch/arm/mach-at91rm9200/board-carmeva.c16
-rw-r--r--arch/arm/mach-at91rm9200/board-csb337.c15
-rw-r--r--arch/arm/mach-at91rm9200/board-csb637.c15
-rw-r--r--arch/arm/mach-at91rm9200/board-dk.c15
-rw-r--r--arch/arm/mach-at91rm9200/board-eb9200.c15
-rw-r--r--arch/arm/mach-at91rm9200/board-ek.c15
-rw-r--r--arch/arm/mach-at91rm9200/board-kafa.c15
-rw-r--r--arch/arm/mach-at91rm9200/board-kb9202.c15
-rw-r--r--arch/arm/mach-at91rm9200/generic.h16
-rw-r--r--arch/arm/mach-at91rm9200/gpio.c89
-rw-r--r--arch/arm/mach-at91rm9200/irq.c2
-rw-r--r--include/asm-arm/arch-at91rm9200/gpio.h16
14 files changed, 164 insertions, 134 deletions
diff --git a/arch/arm/mach-at91rm9200/at91rm9200.c b/arch/arm/mach-at91rm9200/at91rm9200.c
index ae04cbdf0bff..c32d0c996f90 100644
--- a/arch/arm/mach-at91rm9200/at91rm9200.c
+++ b/arch/arm/mach-at91rm9200/at91rm9200.c
@@ -243,11 +243,34 @@ static void __init at91rm9200_register_clocks(void)
243 clk_register(&pck3); 243 clk_register(&pck3);
244} 244}
245 245
246/* --------------------------------------------------------------------
247 * GPIO
248 * -------------------------------------------------------------------- */
249
250static struct at91_gpio_bank at91rm9200_gpio[] = {
251 {
252 .id = AT91RM9200_ID_PIOA,
253 .offset = AT91_PIOA,
254 .clock = &pioA_clk,
255 }, {
256 .id = AT91RM9200_ID_PIOB,
257 .offset = AT91_PIOB,
258 .clock = &pioB_clk,
259 }, {
260 .id = AT91RM9200_ID_PIOC,
261 .offset = AT91_PIOC,
262 .clock = &pioC_clk,
263 }, {
264 .id = AT91RM9200_ID_PIOD,
265 .offset = AT91_PIOD,
266 .clock = &pioD_clk,
267 }
268};
246 269
247/* -------------------------------------------------------------------- 270/* --------------------------------------------------------------------
248 * AT91RM9200 processor initialization 271 * AT91RM9200 processor initialization
249 * -------------------------------------------------------------------- */ 272 * -------------------------------------------------------------------- */
250void __init at91rm9200_initialize(unsigned long main_clock) 273void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks)
251{ 274{
252 /* Map peripherals */ 275 /* Map peripherals */
253 iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); 276 iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc));
@@ -257,8 +280,16 @@ void __init at91rm9200_initialize(unsigned long main_clock)
257 280
258 /* Register the processor-specific clocks */ 281 /* Register the processor-specific clocks */
259 at91rm9200_register_clocks(); 282 at91rm9200_register_clocks();
283
284 /* Initialize GPIO subsystem */
285 at91_gpio_init(at91rm9200_gpio, banks);
260} 286}
261 287
288
289/* --------------------------------------------------------------------
290 * Interrupt initialization
291 * -------------------------------------------------------------------- */
292
262/* 293/*
263 * The default interrupt priority levels (0 = lowest, 7 = highest). 294 * The default interrupt priority levels (0 = lowest, 7 = highest).
264 */ 295 */
@@ -297,10 +328,14 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
297 0 /* Advanced Interrupt Controller (IRQ6) */ 328 0 /* Advanced Interrupt Controller (IRQ6) */
298}; 329};
299 330
300void __init at91rm9200_init_irq(unsigned int priority[NR_AIC_IRQS]) 331void __init at91rm9200_init_interrupts(unsigned int priority[NR_AIC_IRQS])
301{ 332{
302 if (!priority) 333 if (!priority)
303 priority = at91rm9200_default_irq_priority; 334 priority = at91rm9200_default_irq_priority;
304 335
336 /* Initialize the AIC interrupt controller */
305 at91_aic_init(priority); 337 at91_aic_init(priority);
338
339 /* Enable GPIO interrupts */
340 at91_gpio_irq_setup();
306} 341}
diff --git a/arch/arm/mach-at91rm9200/board-1arm.c b/arch/arm/mach-at91rm9200/board-1arm.c
index d2aa9c4a8b24..36eecd7161f5 100644
--- a/arch/arm/mach-at91rm9200/board-1arm.c
+++ b/arch/arm/mach-at91rm9200/board-1arm.c
@@ -39,14 +39,6 @@
39 39
40#include "generic.h" 40#include "generic.h"
41 41
42static void __init onearm_init_irq(void)
43{
44 /* Initialize AIC controller */
45 at91rm9200_init_irq(NULL);
46
47 /* Set up the GPIO interrupts */
48 at91_gpio_irq_setup(PQFP_GPIO_BANKS);
49}
50 42
51/* 43/*
52 * Serial port configuration. 44 * Serial port configuration.
@@ -62,12 +54,17 @@ static struct at91_uart_config __initdata onearm_uart_config = {
62static void __init onearm_map_io(void) 54static void __init onearm_map_io(void)
63{ 55{
64 /* Initialize processor: 18.432 MHz crystal */ 56 /* Initialize processor: 18.432 MHz crystal */
65 at91rm9200_initialize(18432000); 57 at91rm9200_initialize(18432000, AT91RM9200_PQFP);
66 58
67 /* Setup the serial ports and console */ 59 /* Setup the serial ports and console */
68 at91_init_serial(&onearm_uart_config); 60 at91_init_serial(&onearm_uart_config);
69} 61}
70 62
63static void __init onearm_init_irq(void)
64{
65 at91rm9200_init_interrupts(NULL);
66}
67
71static struct at91_eth_data __initdata onearm_eth_data = { 68static struct at91_eth_data __initdata onearm_eth_data = {
72 .phy_irq_pin = AT91_PIN_PC4, 69 .phy_irq_pin = AT91_PIN_PC4,
73 .is_rmii = 1, 70 .is_rmii = 1,
diff --git a/arch/arm/mach-at91rm9200/board-carmeva.c b/arch/arm/mach-at91rm9200/board-carmeva.c
index 6af252bcb083..50e513681ae6 100644
--- a/arch/arm/mach-at91rm9200/board-carmeva.c
+++ b/arch/arm/mach-at91rm9200/board-carmeva.c
@@ -40,14 +40,6 @@
40 40
41#include "generic.h" 41#include "generic.h"
42 42
43static void __init carmeva_init_irq(void)
44{
45 /* Initialize AIC controller */
46 at91rm9200_init_irq(NULL);
47
48 /* Set up the GPIO interrupts */
49 at91_gpio_irq_setup(BGA_GPIO_BANKS);
50}
51 43
52/* 44/*
53 * Serial port configuration. 45 * Serial port configuration.
@@ -63,12 +55,18 @@ static struct at91_uart_config __initdata carmeva_uart_config = {
63static void __init carmeva_map_io(void) 55static void __init carmeva_map_io(void)
64{ 56{
65 /* Initialize processor: 20.000 MHz crystal */ 57 /* Initialize processor: 20.000 MHz crystal */
66 at91rm9200_initialize(20000000); 58 at91rm9200_initialize(20000000, AT91RM9200_BGA);
67 59
68 /* Setup the serial ports and console */ 60 /* Setup the serial ports and console */
69 at91_init_serial(&carmeva_uart_config); 61 at91_init_serial(&carmeva_uart_config);
70} 62}
71 63
64static void __init carmeva_init_irq(void)
65{
66 at91rm9200_init_interrupts(NULL);
67}
68
69
72static struct at91_eth_data __initdata carmeva_eth_data = { 70static struct at91_eth_data __initdata carmeva_eth_data = {
73 .phy_irq_pin = AT91_PIN_PC4, 71 .phy_irq_pin = AT91_PIN_PC4,
74 .is_rmii = 1, 72 .is_rmii = 1,
diff --git a/arch/arm/mach-at91rm9200/board-csb337.c b/arch/arm/mach-at91rm9200/board-csb337.c
index f74b483329c0..8eeae491ce71 100644
--- a/arch/arm/mach-at91rm9200/board-csb337.c
+++ b/arch/arm/mach-at91rm9200/board-csb337.c
@@ -39,14 +39,6 @@
39 39
40#include "generic.h" 40#include "generic.h"
41 41
42static void __init csb337_init_irq(void)
43{
44 /* Initialize AIC controller */
45 at91rm9200_init_irq(NULL);
46
47 /* Set up the GPIO interrupts */
48 at91_gpio_irq_setup(BGA_GPIO_BANKS);
49}
50 42
51/* 43/*
52 * Serial port configuration. 44 * Serial port configuration.
@@ -62,7 +54,7 @@ static struct at91_uart_config __initdata csb337_uart_config = {
62static void __init csb337_map_io(void) 54static void __init csb337_map_io(void)
63{ 55{
64 /* Initialize processor: 3.6864 MHz crystal */ 56 /* Initialize processor: 3.6864 MHz crystal */
65 at91rm9200_initialize(3686400); 57 at91rm9200_initialize(3686400, AT91RM9200_BGA);
66 58
67 /* Setup the LEDs */ 59 /* Setup the LEDs */
68 at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); 60 at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1);
@@ -71,6 +63,11 @@ static void __init csb337_map_io(void)
71 at91_init_serial(&csb337_uart_config); 63 at91_init_serial(&csb337_uart_config);
72} 64}
73 65
66static void __init csb337_init_irq(void)
67{
68 at91rm9200_init_interrupts(NULL);
69}
70
74static struct at91_eth_data __initdata csb337_eth_data = { 71static struct at91_eth_data __initdata csb337_eth_data = {
75 .phy_irq_pin = AT91_PIN_PC2, 72 .phy_irq_pin = AT91_PIN_PC2,
76 .is_rmii = 0, 73 .is_rmii = 0,
diff --git a/arch/arm/mach-at91rm9200/board-csb637.c b/arch/arm/mach-at91rm9200/board-csb637.c
index 880350997a3b..a29fa0e822ce 100644
--- a/arch/arm/mach-at91rm9200/board-csb637.c
+++ b/arch/arm/mach-at91rm9200/board-csb637.c
@@ -38,14 +38,6 @@
38 38
39#include "generic.h" 39#include "generic.h"
40 40
41static void __init csb637_init_irq(void)
42{
43 /* Initialize AIC controller */
44 at91rm9200_init_irq(NULL);
45
46 /* Set up the GPIO interrupts */
47 at91_gpio_irq_setup(BGA_GPIO_BANKS);
48}
49 41
50/* 42/*
51 * Serial port configuration. 43 * Serial port configuration.
@@ -61,7 +53,7 @@ static struct at91_uart_config __initdata csb637_uart_config = {
61static void __init csb637_map_io(void) 53static void __init csb637_map_io(void)
62{ 54{
63 /* Initialize processor: 3.6864 MHz crystal */ 55 /* Initialize processor: 3.6864 MHz crystal */
64 at91rm9200_initialize(3686400); 56 at91rm9200_initialize(3686400, AT91RM9200_BGA);
65 57
66 /* Setup the LEDs */ 58 /* Setup the LEDs */
67 at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); 59 at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
@@ -70,6 +62,11 @@ static void __init csb637_map_io(void)
70 at91_init_serial(&csb637_uart_config); 62 at91_init_serial(&csb637_uart_config);
71} 63}
72 64
65static void __init csb637_init_irq(void)
66{
67 at91rm9200_init_interrupts(NULL);
68}
69
73static struct at91_eth_data __initdata csb637_eth_data = { 70static struct at91_eth_data __initdata csb637_eth_data = {
74 .phy_irq_pin = AT91_PIN_PC0, 71 .phy_irq_pin = AT91_PIN_PC0,
75 .is_rmii = 0, 72 .is_rmii = 0,
diff --git a/arch/arm/mach-at91rm9200/board-dk.c b/arch/arm/mach-at91rm9200/board-dk.c
index 23ea9d63b986..54c32d00b610 100644
--- a/arch/arm/mach-at91rm9200/board-dk.c
+++ b/arch/arm/mach-at91rm9200/board-dk.c
@@ -42,14 +42,6 @@
42 42
43#include "generic.h" 43#include "generic.h"
44 44
45static void __init dk_init_irq(void)
46{
47 /* Initialize AIC controller */
48 at91rm9200_init_irq(NULL);
49
50 /* Set up the GPIO interrupts */
51 at91_gpio_irq_setup(BGA_GPIO_BANKS);
52}
53 45
54/* 46/*
55 * Serial port configuration. 47 * Serial port configuration.
@@ -65,7 +57,7 @@ static struct at91_uart_config __initdata dk_uart_config = {
65static void __init dk_map_io(void) 57static void __init dk_map_io(void)
66{ 58{
67 /* Initialize processor: 18.432 MHz crystal */ 59 /* Initialize processor: 18.432 MHz crystal */
68 at91rm9200_initialize(18432000); 60 at91rm9200_initialize(18432000, AT91RM9200_BGA);
69 61
70 /* Setup the LEDs */ 62 /* Setup the LEDs */
71 at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); 63 at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
@@ -74,6 +66,11 @@ static void __init dk_map_io(void)
74 at91_init_serial(&dk_uart_config); 66 at91_init_serial(&dk_uart_config);
75} 67}
76 68
69static void __init dk_init_irq(void)
70{
71 at91rm9200_init_interrupts(NULL);
72}
73
77static struct at91_eth_data __initdata dk_eth_data = { 74static struct at91_eth_data __initdata dk_eth_data = {
78 .phy_irq_pin = AT91_PIN_PC4, 75 .phy_irq_pin = AT91_PIN_PC4,
79 .is_rmii = 1, 76 .is_rmii = 1,
diff --git a/arch/arm/mach-at91rm9200/board-eb9200.c b/arch/arm/mach-at91rm9200/board-eb9200.c
index 2ceb267585ad..c6e0d51fbea0 100644
--- a/arch/arm/mach-at91rm9200/board-eb9200.c
+++ b/arch/arm/mach-at91rm9200/board-eb9200.c
@@ -40,14 +40,6 @@
40 40
41#include "generic.h" 41#include "generic.h"
42 42
43static void __init eb9200_init_irq(void)
44{
45 /* Initialize AIC controller */
46 at91rm9200_init_irq(NULL);
47
48 /* Set up the GPIO interrupts */
49 at91_gpio_irq_setup(BGA_GPIO_BANKS);
50}
51 43
52/* 44/*
53 * Serial port configuration. 45 * Serial port configuration.
@@ -63,12 +55,17 @@ static struct at91_uart_config __initdata eb9200_uart_config = {
63static void __init eb9200_map_io(void) 55static void __init eb9200_map_io(void)
64{ 56{
65 /* Initialize processor: 18.432 MHz crystal */ 57 /* Initialize processor: 18.432 MHz crystal */
66 at91rm9200_initialize(18432000); 58 at91rm9200_initialize(18432000, AT91RM9200_BGA);
67 59
68 /* Setup the serial ports and console */ 60 /* Setup the serial ports and console */
69 at91_init_serial(&eb9200_uart_config); 61 at91_init_serial(&eb9200_uart_config);
70} 62}
71 63
64static void __init eb9200_init_irq(void)
65{
66 at91rm9200_init_interrupts(NULL);
67}
68
72static struct at91_eth_data __initdata eb9200_eth_data = { 69static struct at91_eth_data __initdata eb9200_eth_data = {
73 .phy_irq_pin = AT91_PIN_PC4, 70 .phy_irq_pin = AT91_PIN_PC4,
74 .is_rmii = 1, 71 .is_rmii = 1,
diff --git a/arch/arm/mach-at91rm9200/board-ek.c b/arch/arm/mach-at91rm9200/board-ek.c
index 8cd83364cd80..830eb7932178 100644
--- a/arch/arm/mach-at91rm9200/board-ek.c
+++ b/arch/arm/mach-at91rm9200/board-ek.c
@@ -42,14 +42,6 @@
42 42
43#include "generic.h" 43#include "generic.h"
44 44
45static void __init ek_init_irq(void)
46{
47 /* Initialize AIC controller */
48 at91rm9200_init_irq(NULL);
49
50 /* Set up the GPIO interrupts */
51 at91_gpio_irq_setup(BGA_GPIO_BANKS);
52}
53 45
54/* 46/*
55 * Serial port configuration. 47 * Serial port configuration.
@@ -65,7 +57,7 @@ static struct at91_uart_config __initdata ek_uart_config = {
65static void __init ek_map_io(void) 57static void __init ek_map_io(void)
66{ 58{
67 /* Initialize processor: 18.432 MHz crystal */ 59 /* Initialize processor: 18.432 MHz crystal */
68 at91rm9200_initialize(18432000); 60 at91rm9200_initialize(18432000, AT91RM9200_BGA);
69 61
70 /* Setup the LEDs */ 62 /* Setup the LEDs */
71 at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); 63 at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
@@ -74,6 +66,11 @@ static void __init ek_map_io(void)
74 at91_init_serial(&ek_uart_config); 66 at91_init_serial(&ek_uart_config);
75} 67}
76 68
69static void __init ek_init_irq(void)
70{
71 at91rm9200_init_interrupts(NULL);
72}
73
77static struct at91_eth_data __initdata ek_eth_data = { 74static struct at91_eth_data __initdata ek_eth_data = {
78 .phy_irq_pin = AT91_PIN_PC4, 75 .phy_irq_pin = AT91_PIN_PC4,
79 .is_rmii = 1, 76 .is_rmii = 1,
diff --git a/arch/arm/mach-at91rm9200/board-kafa.c b/arch/arm/mach-at91rm9200/board-kafa.c
index d9a6b7e7d63a..91e301924f2c 100644
--- a/arch/arm/mach-at91rm9200/board-kafa.c
+++ b/arch/arm/mach-at91rm9200/board-kafa.c
@@ -39,14 +39,6 @@
39 39
40#include "generic.h" 40#include "generic.h"
41 41
42static void __init kafa_init_irq(void)
43{
44 /* Initialize AIC controller */
45 at91rm9200_init_irq(NULL);
46
47 /* Set up the GPIO interrupts */
48 at91_gpio_irq_setup(PQFP_GPIO_BANKS);
49}
50 42
51/* 43/*
52 * Serial port configuration. 44 * Serial port configuration.
@@ -62,7 +54,7 @@ static struct at91_uart_config __initdata kafa_uart_config = {
62static void __init kafa_map_io(void) 54static void __init kafa_map_io(void)
63{ 55{
64 /* Initialize processor: 18.432 MHz crystal */ 56 /* Initialize processor: 18.432 MHz crystal */
65 at91rm9200_initialize(18432000); 57 at91rm9200_initialize(18432000, AT91RM9200_PQFP);
66 58
67 /* Set up the LEDs */ 59 /* Set up the LEDs */
68 at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4); 60 at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4);
@@ -71,6 +63,11 @@ static void __init kafa_map_io(void)
71 at91_init_serial(&kafa_uart_config); 63 at91_init_serial(&kafa_uart_config);
72} 64}
73 65
66static void __init kafa_init_irq(void)
67{
68 at91rm9200_init_interrupts(NULL);
69}
70
74static struct at91_eth_data __initdata kafa_eth_data = { 71static struct at91_eth_data __initdata kafa_eth_data = {
75 .phy_irq_pin = AT91_PIN_PC4, 72 .phy_irq_pin = AT91_PIN_PC4,
76 .is_rmii = 0, 73 .is_rmii = 0,
diff --git a/arch/arm/mach-at91rm9200/board-kb9202.c b/arch/arm/mach-at91rm9200/board-kb9202.c
index 935238ffa330..55b08f9b9537 100644
--- a/arch/arm/mach-at91rm9200/board-kb9202.c
+++ b/arch/arm/mach-at91rm9200/board-kb9202.c
@@ -40,14 +40,6 @@
40 40
41#include "generic.h" 41#include "generic.h"
42 42
43static void __init kb9202_init_irq(void)
44{
45 /* Initialize AIC controller */
46 at91rm9200_init_irq(NULL);
47
48 /* Set up the GPIO interrupts */
49 at91_gpio_irq_setup(PQFP_GPIO_BANKS);
50}
51 43
52/* 44/*
53 * Serial port configuration. 45 * Serial port configuration.
@@ -63,7 +55,7 @@ static struct at91_uart_config __initdata kb9202_uart_config = {
63static void __init kb9202_map_io(void) 55static void __init kb9202_map_io(void)
64{ 56{
65 /* Initialize processor: 10 MHz crystal */ 57 /* Initialize processor: 10 MHz crystal */
66 at91rm9200_initialize(10000000); 58 at91rm9200_initialize(10000000, AT91RM9200_PQFP);
67 59
68 /* Set up the LEDs */ 60 /* Set up the LEDs */
69 at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18); 61 at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18);
@@ -72,6 +64,11 @@ static void __init kb9202_map_io(void)
72 at91_init_serial(&kb9202_uart_config); 64 at91_init_serial(&kb9202_uart_config);
73} 65}
74 66
67static void __init kb9202_init_irq(void)
68{
69 at91rm9200_init_interrupts(NULL);
70}
71
75static struct at91_eth_data __initdata kb9202_eth_data = { 72static struct at91_eth_data __initdata kb9202_eth_data = {
76 .phy_irq_pin = AT91_PIN_PB29, 73 .phy_irq_pin = AT91_PIN_PB29,
77 .is_rmii = 0, 74 .is_rmii = 0,
diff --git a/arch/arm/mach-at91rm9200/generic.h b/arch/arm/mach-at91rm9200/generic.h
index c44e0e074682..694e411e285f 100644
--- a/arch/arm/mach-at91rm9200/generic.h
+++ b/arch/arm/mach-at91rm9200/generic.h
@@ -9,12 +9,11 @@
9 */ 9 */
10 10
11 /* Processors */ 11 /* Processors */
12extern void __init at91rm9200_initialize(unsigned long main_clock); 12extern void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks);
13 13
14 /* Interrupts */ 14 /* Interrupts */
15extern void __init at91rm9200_init_irq(unsigned int priority[]); 15extern void __init at91rm9200_init_interrupts(unsigned int priority[]);
16extern void __init at91_aic_init(unsigned int priority[]); 16extern void __init at91_aic_init(unsigned int priority[]);
17extern void __init at91_gpio_irq_setup(unsigned banks);
18 17
19 /* Timer */ 18 /* Timer */
20struct sys_timer; 19struct sys_timer;
@@ -29,3 +28,14 @@ extern void __init at91_clock_associate(const char *id, struct device *dev, cons
29extern void at91_irq_suspend(void); 28extern void at91_irq_suspend(void);
30extern void at91_irq_resume(void); 29extern void at91_irq_resume(void);
31 30
31 /* GPIO */
32#define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */
33#define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */
34
35struct at91_gpio_bank {
36 unsigned short id; /* peripheral ID */
37 unsigned long offset; /* offset from system peripheral base */
38 struct clk *clock; /* associated clock */
39};
40extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks);
41extern void __init at91_gpio_irq_setup(void);
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}
diff --git a/arch/arm/mach-at91rm9200/irq.c b/arch/arm/mach-at91rm9200/irq.c
index 8cd60a99c5b8..3e488117ca91 100644
--- a/arch/arm/mach-at91rm9200/irq.c
+++ b/arch/arm/mach-at91rm9200/irq.c
@@ -34,8 +34,6 @@
34#include <asm/mach/irq.h> 34#include <asm/mach/irq.h>
35#include <asm/mach/map.h> 35#include <asm/mach/map.h>
36 36
37#include "generic.h"
38
39 37
40static void at91_aic_mask_irq(unsigned int irq) 38static void at91_aic_mask_irq(unsigned int irq)
41{ 39{
diff --git a/include/asm-arm/arch-at91rm9200/gpio.h b/include/asm-arm/arch-at91rm9200/gpio.h
index 6243f28a0b81..a011d27876a2 100644
--- a/include/asm-arm/arch-at91rm9200/gpio.h
+++ b/include/asm-arm/arch-at91rm9200/gpio.h
@@ -17,8 +17,7 @@
17 17
18#define PIN_BASE NR_AIC_IRQS 18#define PIN_BASE NR_AIC_IRQS
19 19
20#define PQFP_GPIO_BANKS 3 /* PQFP package has 3 banks */ 20#define MAX_GPIO_BANKS 4
21#define BGA_GPIO_BANKS 4 /* BGA package has 4 banks */
22 21
23/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */ 22/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */
24 23
@@ -180,17 +179,18 @@
180 179
181#ifndef __ASSEMBLY__ 180#ifndef __ASSEMBLY__
182/* setup setup routines, called from board init or driver probe() */ 181/* setup setup routines, called from board init or driver probe() */
183extern int at91_set_A_periph(unsigned pin, int use_pullup); 182extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup);
184extern int at91_set_B_periph(unsigned pin, int use_pullup); 183extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup);
185extern int at91_set_gpio_input(unsigned pin, int use_pullup); 184extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup);
186extern int at91_set_gpio_output(unsigned pin, int value); 185extern int __init_or_module at91_set_gpio_output(unsigned pin, int value);
187extern int at91_set_deglitch(unsigned pin, int is_on); 186extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on);
188extern int at91_set_multi_drive(unsigned pin, int is_on); 187extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on);
189 188
190/* callable at any time */ 189/* callable at any time */
191extern int at91_set_gpio_value(unsigned pin, int value); 190extern int at91_set_gpio_value(unsigned pin, int value);
192extern int at91_get_gpio_value(unsigned pin); 191extern int at91_get_gpio_value(unsigned pin);
193 192
193/* callable only from core power-management code */
194extern void at91_gpio_suspend(void); 194extern void at91_gpio_suspend(void);
195extern void at91_gpio_resume(void); 195extern void at91_gpio_resume(void);
196#endif 196#endif