aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-at91rm9200
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-09-28 17:40:39 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-28 17:40:39 -0400
commitebdea46fecae40c4d7effcd33f40918a37a1df4b (patch)
treee4312bf7f1f3d184738963a0ec300aa9fdfd55c1 /arch/arm/mach-at91rm9200
parentfecf3404f4aba6d0edeba31eeb018cbb6326dff2 (diff)
parent250d375d1da45a5e08ab8baf5eaa7eb258afd82b (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')
-rw-r--r--arch/arm/mach-at91rm9200/at91rm9200.c250
-rw-r--r--arch/arm/mach-at91rm9200/board-1arm.c20
-rw-r--r--arch/arm/mach-at91rm9200/board-carmeva.c21
-rw-r--r--arch/arm/mach-at91rm9200/board-csb337.c20
-rw-r--r--arch/arm/mach-at91rm9200/board-csb637.c20
-rw-r--r--arch/arm/mach-at91rm9200/board-dk.c45
-rw-r--r--arch/arm/mach-at91rm9200/board-eb9200.c20
-rw-r--r--arch/arm/mach-at91rm9200/board-ek.c20
-rw-r--r--arch/arm/mach-at91rm9200/board-kafa.c20
-rw-r--r--arch/arm/mach-at91rm9200/board-kb9202.c45
-rw-r--r--arch/arm/mach-at91rm9200/clock.c324
-rw-r--r--arch/arm/mach-at91rm9200/clock.h30
-rw-r--r--arch/arm/mach-at91rm9200/devices.c72
-rw-r--r--arch/arm/mach-at91rm9200/generic.h20
-rw-r--r--arch/arm/mach-at91rm9200/gpio.c89
-rw-r--r--arch/arm/mach-at91rm9200/irq.c6
-rw-r--r--arch/arm/mach-at91rm9200/pm.c14
17 files changed, 546 insertions, 490 deletions
diff --git a/arch/arm/mach-at91rm9200/at91rm9200.c b/arch/arm/mach-at91rm9200/at91rm9200.c
index 0985b1c42c7c..dcf6136fedf9 100644
--- a/arch/arm/mach-at91rm9200/at91rm9200.c
+++ b/arch/arm/mach-at91rm9200/at91rm9200.c
@@ -17,6 +17,7 @@
17 17
18#include <asm/hardware.h> 18#include <asm/hardware.h>
19#include "generic.h" 19#include "generic.h"
20#include "clock.h"
20 21
21static struct map_desc at91rm9200_io_desc[] __initdata = { 22static struct map_desc at91rm9200_io_desc[] __initdata = {
22 { 23 {
@@ -26,87 +27,224 @@ static struct map_desc at91rm9200_io_desc[] __initdata = {
26 .type = MT_DEVICE, 27 .type = MT_DEVICE,
27 }, { 28 }, {
28 .virtual = AT91_VA_BASE_SPI, 29 .virtual = AT91_VA_BASE_SPI,
29 .pfn = __phys_to_pfn(AT91_BASE_SPI), 30 .pfn = __phys_to_pfn(AT91RM9200_BASE_SPI),
30 .length = SZ_16K,
31 .type = MT_DEVICE,
32 }, {
33 .virtual = AT91_VA_BASE_SSC2,
34 .pfn = __phys_to_pfn(AT91_BASE_SSC2),
35 .length = SZ_16K,
36 .type = MT_DEVICE,
37 }, {
38 .virtual = AT91_VA_BASE_SSC1,
39 .pfn = __phys_to_pfn(AT91_BASE_SSC1),
40 .length = SZ_16K,
41 .type = MT_DEVICE,
42 }, {
43 .virtual = AT91_VA_BASE_SSC0,
44 .pfn = __phys_to_pfn(AT91_BASE_SSC0),
45 .length = SZ_16K,
46 .type = MT_DEVICE,
47 }, {
48 .virtual = AT91_VA_BASE_US3,
49 .pfn = __phys_to_pfn(AT91_BASE_US3),
50 .length = SZ_16K,
51 .type = MT_DEVICE,
52 }, {
53 .virtual = AT91_VA_BASE_US2,
54 .pfn = __phys_to_pfn(AT91_BASE_US2),
55 .length = SZ_16K,
56 .type = MT_DEVICE,
57 }, {
58 .virtual = AT91_VA_BASE_US1,
59 .pfn = __phys_to_pfn(AT91_BASE_US1),
60 .length = SZ_16K,
61 .type = MT_DEVICE,
62 }, {
63 .virtual = AT91_VA_BASE_US0,
64 .pfn = __phys_to_pfn(AT91_BASE_US0),
65 .length = SZ_16K, 31 .length = SZ_16K,
66 .type = MT_DEVICE, 32 .type = MT_DEVICE,
67 }, { 33 }, {
68 .virtual = AT91_VA_BASE_EMAC, 34 .virtual = AT91_VA_BASE_EMAC,
69 .pfn = __phys_to_pfn(AT91_BASE_EMAC), 35 .pfn = __phys_to_pfn(AT91RM9200_BASE_EMAC),
70 .length = SZ_16K, 36 .length = SZ_16K,
71 .type = MT_DEVICE, 37 .type = MT_DEVICE,
72 }, { 38 }, {
73 .virtual = AT91_VA_BASE_TWI, 39 .virtual = AT91_VA_BASE_TWI,
74 .pfn = __phys_to_pfn(AT91_BASE_TWI), 40 .pfn = __phys_to_pfn(AT91RM9200_BASE_TWI),
75 .length = SZ_16K, 41 .length = SZ_16K,
76 .type = MT_DEVICE, 42 .type = MT_DEVICE,
77 }, { 43 }, {
78 .virtual = AT91_VA_BASE_MCI, 44 .virtual = AT91_VA_BASE_MCI,
79 .pfn = __phys_to_pfn(AT91_BASE_MCI), 45 .pfn = __phys_to_pfn(AT91RM9200_BASE_MCI),
80 .length = SZ_16K, 46 .length = SZ_16K,
81 .type = MT_DEVICE, 47 .type = MT_DEVICE,
82 }, { 48 }, {
83 .virtual = AT91_VA_BASE_UDP, 49 .virtual = AT91_VA_BASE_UDP,
84 .pfn = __phys_to_pfn(AT91_BASE_UDP), 50 .pfn = __phys_to_pfn(AT91RM9200_BASE_UDP),
85 .length = SZ_16K,
86 .type = MT_DEVICE,
87 }, {
88 .virtual = AT91_VA_BASE_TCB1,
89 .pfn = __phys_to_pfn(AT91_BASE_TCB1),
90 .length = SZ_16K,
91 .type = MT_DEVICE,
92 }, {
93 .virtual = AT91_VA_BASE_TCB0,
94 .pfn = __phys_to_pfn(AT91_BASE_TCB0),
95 .length = SZ_16K, 51 .length = SZ_16K,
96 .type = MT_DEVICE, 52 .type = MT_DEVICE,
97 }, { 53 }, {
98 .virtual = AT91_SRAM_VIRT_BASE, 54 .virtual = AT91_SRAM_VIRT_BASE,
99 .pfn = __phys_to_pfn(AT91_SRAM_BASE), 55 .pfn = __phys_to_pfn(AT91RM9200_SRAM_BASE),
100 .length = AT91_SRAM_SIZE, 56 .length = AT91RM9200_SRAM_SIZE,
101 .type = MT_DEVICE, 57 .type = MT_DEVICE,
102 }, 58 },
103}; 59};
104 60
105void __init at91rm9200_map_io(void) 61/* --------------------------------------------------------------------
62 * Clocks
63 * -------------------------------------------------------------------- */
64
65/*
66 * The peripheral clocks.
67 */
68static struct clk udc_clk = {
69 .name = "udc_clk",
70 .pmc_mask = 1 << AT91RM9200_ID_UDP,
71 .type = CLK_TYPE_PERIPHERAL,
72};
73static struct clk ohci_clk = {
74 .name = "ohci_clk",
75 .pmc_mask = 1 << AT91RM9200_ID_UHP,
76 .type = CLK_TYPE_PERIPHERAL,
77};
78static struct clk ether_clk = {
79 .name = "ether_clk",
80 .pmc_mask = 1 << AT91RM9200_ID_EMAC,
81 .type = CLK_TYPE_PERIPHERAL,
82};
83static struct clk mmc_clk = {
84 .name = "mci_clk",
85 .pmc_mask = 1 << AT91RM9200_ID_MCI,
86 .type = CLK_TYPE_PERIPHERAL,
87};
88static struct clk twi_clk = {
89 .name = "twi_clk",
90 .pmc_mask = 1 << AT91RM9200_ID_TWI,
91 .type = CLK_TYPE_PERIPHERAL,
92};
93static struct clk usart0_clk = {
94 .name = "usart0_clk",
95 .pmc_mask = 1 << AT91RM9200_ID_US0,
96 .type = CLK_TYPE_PERIPHERAL,
97};
98static struct clk usart1_clk = {
99 .name = "usart1_clk",
100 .pmc_mask = 1 << AT91RM9200_ID_US1,
101 .type = CLK_TYPE_PERIPHERAL,
102};
103static struct clk usart2_clk = {
104 .name = "usart2_clk",
105 .pmc_mask = 1 << AT91RM9200_ID_US2,
106 .type = CLK_TYPE_PERIPHERAL,
107};
108static struct clk usart3_clk = {
109 .name = "usart3_clk",
110 .pmc_mask = 1 << AT91RM9200_ID_US3,
111 .type = CLK_TYPE_PERIPHERAL,
112};
113static struct clk spi_clk = {
114 .name = "spi_clk",
115 .pmc_mask = 1 << AT91RM9200_ID_SPI,
116 .type = CLK_TYPE_PERIPHERAL,
117};
118static struct clk pioA_clk = {
119 .name = "pioA_clk",
120 .pmc_mask = 1 << AT91RM9200_ID_PIOA,
121 .type = CLK_TYPE_PERIPHERAL,
122};
123static struct clk pioB_clk = {
124 .name = "pioB_clk",
125 .pmc_mask = 1 << AT91RM9200_ID_PIOB,
126 .type = CLK_TYPE_PERIPHERAL,
127};
128static struct clk pioC_clk = {
129 .name = "pioC_clk",
130 .pmc_mask = 1 << AT91RM9200_ID_PIOC,
131 .type = CLK_TYPE_PERIPHERAL,
132};
133static struct clk pioD_clk = {
134 .name = "pioD_clk",
135 .pmc_mask = 1 << AT91RM9200_ID_PIOD,
136 .type = CLK_TYPE_PERIPHERAL,
137};
138
139static struct clk *periph_clocks[] __initdata = {
140 &pioA_clk,
141 &pioB_clk,
142 &pioC_clk,
143 &pioD_clk,
144 &usart0_clk,
145 &usart1_clk,
146 &usart2_clk,
147 &usart3_clk,
148 &mmc_clk,
149 &udc_clk,
150 &twi_clk,
151 &spi_clk,
152 // ssc 0 .. ssc2
153 // tc0 .. tc5
154 &ohci_clk,
155 &ether_clk,
156 // irq0 .. irq6
157};
158
159/*
160 * The four programmable clocks.
161 * You must configure pin multiplexing to bring these signals out.
162 */
163static struct clk pck0 = {
164 .name = "pck0",
165 .pmc_mask = AT91_PMC_PCK0,
166 .type = CLK_TYPE_PROGRAMMABLE,
167 .id = 0,
168};
169static struct clk pck1 = {
170 .name = "pck1",
171 .pmc_mask = AT91_PMC_PCK1,
172 .type = CLK_TYPE_PROGRAMMABLE,
173 .id = 1,
174};
175static struct clk pck2 = {
176 .name = "pck2",
177 .pmc_mask = AT91_PMC_PCK2,
178 .type = CLK_TYPE_PROGRAMMABLE,
179 .id = 2,
180};
181static struct clk pck3 = {
182 .name = "pck3",
183 .pmc_mask = AT91_PMC_PCK3,
184 .type = CLK_TYPE_PROGRAMMABLE,
185 .id = 3,
186};
187
188static void __init at91rm9200_register_clocks(void)
106{ 189{
190 int i;
191
192 for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
193 clk_register(periph_clocks[i]);
194
195 clk_register(&pck0);
196 clk_register(&pck1);
197 clk_register(&pck2);
198 clk_register(&pck3);
199}
200
201/* --------------------------------------------------------------------
202 * GPIO
203 * -------------------------------------------------------------------- */
204
205static struct at91_gpio_bank at91rm9200_gpio[] = {
206 {
207 .id = AT91RM9200_ID_PIOA,
208 .offset = AT91_PIOA,
209 .clock = &pioA_clk,
210 }, {
211 .id = AT91RM9200_ID_PIOB,
212 .offset = AT91_PIOB,
213 .clock = &pioB_clk,
214 }, {
215 .id = AT91RM9200_ID_PIOC,
216 .offset = AT91_PIOC,
217 .clock = &pioC_clk,
218 }, {
219 .id = AT91RM9200_ID_PIOD,
220 .offset = AT91_PIOD,
221 .clock = &pioD_clk,
222 }
223};
224
225/* --------------------------------------------------------------------
226 * AT91RM9200 processor initialization
227 * -------------------------------------------------------------------- */
228void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks)
229{
230 /* Map peripherals */
107 iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); 231 iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc));
232
233 /* Init clock subsystem */
234 at91_clock_init(main_clock);
235
236 /* Register the processor-specific clocks */
237 at91rm9200_register_clocks();
238
239 /* Initialize GPIO subsystem */
240 at91_gpio_init(at91rm9200_gpio, banks);
108} 241}
109 242
243
244/* --------------------------------------------------------------------
245 * Interrupt initialization
246 * -------------------------------------------------------------------- */
247
110/* 248/*
111 * The default interrupt priority levels (0 = lowest, 7 = highest). 249 * The default interrupt priority levels (0 = lowest, 7 = highest).
112 */ 250 */
@@ -145,10 +283,14 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
145 0 /* Advanced Interrupt Controller (IRQ6) */ 283 0 /* Advanced Interrupt Controller (IRQ6) */
146}; 284};
147 285
148void __init at91rm9200_init_irq(unsigned int priority[NR_AIC_IRQS]) 286void __init at91rm9200_init_interrupts(unsigned int priority[NR_AIC_IRQS])
149{ 287{
150 if (!priority) 288 if (!priority)
151 priority = at91rm9200_default_irq_priority; 289 priority = at91rm9200_default_irq_priority;
152 290
291 /* Initialize the AIC interrupt controller */
153 at91_aic_init(priority); 292 at91_aic_init(priority);
293
294 /* Enable GPIO interrupts */
295 at91_gpio_irq_setup();
154} 296}
diff --git a/arch/arm/mach-at91rm9200/board-1arm.c b/arch/arm/mach-at91rm9200/board-1arm.c
index dc79e0992af7..36eecd7161f5 100644
--- a/arch/arm/mach-at91rm9200/board-1arm.c
+++ b/arch/arm/mach-at91rm9200/board-1arm.c
@@ -34,20 +34,11 @@
34#include <asm/mach/map.h> 34#include <asm/mach/map.h>
35#include <asm/mach/irq.h> 35#include <asm/mach/irq.h>
36 36
37#include <asm/hardware.h>
38#include <asm/arch/board.h> 37#include <asm/arch/board.h>
39#include <asm/arch/gpio.h> 38#include <asm/arch/gpio.h>
40 39
41#include "generic.h" 40#include "generic.h"
42 41
43static void __init onearm_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 42
52/* 43/*
53 * Serial port configuration. 44 * Serial port configuration.
@@ -62,15 +53,18 @@ static struct at91_uart_config __initdata onearm_uart_config = {
62 53
63static void __init onearm_map_io(void) 54static void __init onearm_map_io(void)
64{ 55{
65 at91rm9200_map_io(); 56 /* Initialize processor: 18.432 MHz crystal */
66 57 at91rm9200_initialize(18432000, AT91RM9200_PQFP);
67 /* Initialize clocks: 18.432 MHz crystal */
68 at91_clock_init(18432000);
69 58
70 /* Setup the serial ports and console */ 59 /* Setup the serial ports and console */
71 at91_init_serial(&onearm_uart_config); 60 at91_init_serial(&onearm_uart_config);
72} 61}
73 62
63static void __init onearm_init_irq(void)
64{
65 at91rm9200_init_interrupts(NULL);
66}
67
74static struct at91_eth_data __initdata onearm_eth_data = { 68static struct at91_eth_data __initdata onearm_eth_data = {
75 .phy_irq_pin = AT91_PIN_PC4, 69 .phy_irq_pin = AT91_PIN_PC4,
76 .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 2c138b542ebe..50e513681ae6 100644
--- a/arch/arm/mach-at91rm9200/board-carmeva.c
+++ b/arch/arm/mach-at91rm9200/board-carmeva.c
@@ -35,20 +35,11 @@
35#include <asm/mach/map.h> 35#include <asm/mach/map.h>
36#include <asm/mach/irq.h> 36#include <asm/mach/irq.h>
37 37
38#include <asm/hardware.h>
39#include <asm/arch/board.h> 38#include <asm/arch/board.h>
40#include <asm/arch/gpio.h> 39#include <asm/arch/gpio.h>
41 40
42#include "generic.h" 41#include "generic.h"
43 42
44static void __init carmeva_init_irq(void)
45{
46 /* Initialize AIC controller */
47 at91rm9200_init_irq(NULL);
48
49 /* Set up the GPIO interrupts */
50 at91_gpio_irq_setup(BGA_GPIO_BANKS);
51}
52 43
53/* 44/*
54 * Serial port configuration. 45 * Serial port configuration.
@@ -63,15 +54,19 @@ static struct at91_uart_config __initdata carmeva_uart_config = {
63 54
64static void __init carmeva_map_io(void) 55static void __init carmeva_map_io(void)
65{ 56{
66 at91rm9200_map_io(); 57 /* Initialize processor: 20.000 MHz crystal */
67 58 at91rm9200_initialize(20000000, AT91RM9200_BGA);
68 /* Initialize clocks: 20.000 MHz crystal */
69 at91_clock_init(20000000);
70 59
71 /* Setup the serial ports and console */ 60 /* Setup the serial ports and console */
72 at91_init_serial(&carmeva_uart_config); 61 at91_init_serial(&carmeva_uart_config);
73} 62}
74 63
64static void __init carmeva_init_irq(void)
65{
66 at91rm9200_init_interrupts(NULL);
67}
68
69
75static struct at91_eth_data __initdata carmeva_eth_data = { 70static struct at91_eth_data __initdata carmeva_eth_data = {
76 .phy_irq_pin = AT91_PIN_PC4, 71 .phy_irq_pin = AT91_PIN_PC4,
77 .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 794d3fbb449b..8eeae491ce71 100644
--- a/arch/arm/mach-at91rm9200/board-csb337.c
+++ b/arch/arm/mach-at91rm9200/board-csb337.c
@@ -34,20 +34,11 @@
34#include <asm/mach/map.h> 34#include <asm/mach/map.h>
35#include <asm/mach/irq.h> 35#include <asm/mach/irq.h>
36 36
37#include <asm/hardware.h>
38#include <asm/arch/board.h> 37#include <asm/arch/board.h>
39#include <asm/arch/gpio.h> 38#include <asm/arch/gpio.h>
40 39
41#include "generic.h" 40#include "generic.h"
42 41
43static void __init csb337_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 42
52/* 43/*
53 * Serial port configuration. 44 * Serial port configuration.
@@ -62,10 +53,8 @@ static struct at91_uart_config __initdata csb337_uart_config = {
62 53
63static void __init csb337_map_io(void) 54static void __init csb337_map_io(void)
64{ 55{
65 at91rm9200_map_io(); 56 /* Initialize processor: 3.6864 MHz crystal */
66 57 at91rm9200_initialize(3686400, AT91RM9200_BGA);
67 /* Initialize clocks: 3.6864 MHz crystal */
68 at91_clock_init(3686400);
69 58
70 /* Setup the LEDs */ 59 /* Setup the LEDs */
71 at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); 60 at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1);
@@ -74,6 +63,11 @@ static void __init csb337_map_io(void)
74 at91_init_serial(&csb337_uart_config); 63 at91_init_serial(&csb337_uart_config);
75} 64}
76 65
66static void __init csb337_init_irq(void)
67{
68 at91rm9200_init_interrupts(NULL);
69}
70
77static struct at91_eth_data __initdata csb337_eth_data = { 71static struct at91_eth_data __initdata csb337_eth_data = {
78 .phy_irq_pin = AT91_PIN_PC2, 72 .phy_irq_pin = AT91_PIN_PC2,
79 .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 c8b6f334246a..a29fa0e822ce 100644
--- a/arch/arm/mach-at91rm9200/board-csb637.c
+++ b/arch/arm/mach-at91rm9200/board-csb637.c
@@ -33,20 +33,11 @@
33#include <asm/mach/map.h> 33#include <asm/mach/map.h>
34#include <asm/mach/irq.h> 34#include <asm/mach/irq.h>
35 35
36#include <asm/hardware.h>
37#include <asm/arch/board.h> 36#include <asm/arch/board.h>
38#include <asm/arch/gpio.h> 37#include <asm/arch/gpio.h>
39 38
40#include "generic.h" 39#include "generic.h"
41 40
42static void __init csb637_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 41
51/* 42/*
52 * Serial port configuration. 43 * Serial port configuration.
@@ -61,10 +52,8 @@ static struct at91_uart_config __initdata csb637_uart_config = {
61 52
62static void __init csb637_map_io(void) 53static void __init csb637_map_io(void)
63{ 54{
64 at91rm9200_map_io(); 55 /* Initialize processor: 3.6864 MHz crystal */
65 56 at91rm9200_initialize(3686400, AT91RM9200_BGA);
66 /* Initialize clocks: 3.6864 MHz crystal */
67 at91_clock_init(3686400);
68 57
69 /* Setup the LEDs */ 58 /* Setup the LEDs */
70 at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); 59 at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
@@ -73,6 +62,11 @@ static void __init csb637_map_io(void)
73 at91_init_serial(&csb637_uart_config); 62 at91_init_serial(&csb637_uart_config);
74} 63}
75 64
65static void __init csb637_init_irq(void)
66{
67 at91rm9200_init_interrupts(NULL);
68}
69
76static struct at91_eth_data __initdata csb637_eth_data = { 70static struct at91_eth_data __initdata csb637_eth_data = {
77 .phy_irq_pin = AT91_PIN_PC0, 71 .phy_irq_pin = AT91_PIN_PC0,
78 .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 65873037e02a..c699f3984d4b 100644
--- a/arch/arm/mach-at91rm9200/board-dk.c
+++ b/arch/arm/mach-at91rm9200/board-dk.c
@@ -37,20 +37,11 @@
37#include <asm/mach/map.h> 37#include <asm/mach/map.h>
38#include <asm/mach/irq.h> 38#include <asm/mach/irq.h>
39 39
40#include <asm/hardware.h>
41#include <asm/arch/board.h> 40#include <asm/arch/board.h>
42#include <asm/arch/gpio.h> 41#include <asm/arch/gpio.h>
43 42
44#include "generic.h" 43#include "generic.h"
45 44
46static void __init dk_init_irq(void)
47{
48 /* Initialize AIC controller */
49 at91rm9200_init_irq(NULL);
50
51 /* Set up the GPIO interrupts */
52 at91_gpio_irq_setup(BGA_GPIO_BANKS);
53}
54 45
55/* 46/*
56 * Serial port configuration. 47 * Serial port configuration.
@@ -65,10 +56,8 @@ static struct at91_uart_config __initdata dk_uart_config = {
65 56
66static void __init dk_map_io(void) 57static void __init dk_map_io(void)
67{ 58{
68 at91rm9200_map_io(); 59 /* Initialize processor: 18.432 MHz crystal */
69 60 at91rm9200_initialize(18432000, AT91RM9200_BGA);
70 /* Initialize clocks: 18.432 MHz crystal */
71 at91_clock_init(18432000);
72 61
73 /* Setup the LEDs */ 62 /* Setup the LEDs */
74 at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); 63 at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
@@ -77,6 +66,11 @@ static void __init dk_map_io(void)
77 at91_init_serial(&dk_uart_config); 66 at91_init_serial(&dk_uart_config);
78} 67}
79 68
69static void __init dk_init_irq(void)
70{
71 at91rm9200_init_interrupts(NULL);
72}
73
80static struct at91_eth_data __initdata dk_eth_data = { 74static struct at91_eth_data __initdata dk_eth_data = {
81 .phy_irq_pin = AT91_PIN_PC4, 75 .phy_irq_pin = AT91_PIN_PC4,
82 .is_rmii = 1, 76 .is_rmii = 1,
@@ -128,6 +122,29 @@ static struct spi_board_info dk_spi_devices[] = {
128#endif 122#endif
129}; 123};
130 124
125static struct mtd_partition __initdata dk_nand_partition[] = {
126 {
127 .name = "NAND Partition 1",
128 .offset = 0,
129 .size = MTDPART_SIZ_FULL,
130 },
131};
132
133static struct mtd_partition *nand_partitions(int size, int *num_partitions)
134{
135 *num_partitions = ARRAY_SIZE(dk_nand_partition);
136 return dk_nand_partition;
137}
138
139static struct at91_nand_data __initdata dk_nand_data = {
140 .ale = 22,
141 .cle = 21,
142 .det_pin = AT91_PIN_PB1,
143 .rdy_pin = AT91_PIN_PC2,
144 // .enable_pin = ... not there
145 .partition_info = nand_partitions,
146};
147
131static void __init dk_board_init(void) 148static void __init dk_board_init(void)
132{ 149{
133 /* Serial */ 150 /* Serial */
@@ -153,6 +170,8 @@ static void __init dk_board_init(void)
153 at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ 170 at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
154 at91_add_device_mmc(&dk_mmc_data); 171 at91_add_device_mmc(&dk_mmc_data);
155#endif 172#endif
173 /* NAND */
174 at91_add_device_nand(&dk_nand_data);
156 /* VGA */ 175 /* VGA */
157// dk_add_device_video(); 176// dk_add_device_video();
158} 177}
diff --git a/arch/arm/mach-at91rm9200/board-eb9200.c b/arch/arm/mach-at91rm9200/board-eb9200.c
index a3e2df968a66..c6e0d51fbea0 100644
--- a/arch/arm/mach-at91rm9200/board-eb9200.c
+++ b/arch/arm/mach-at91rm9200/board-eb9200.c
@@ -35,20 +35,11 @@
35#include <asm/mach/map.h> 35#include <asm/mach/map.h>
36#include <asm/mach/irq.h> 36#include <asm/mach/irq.h>
37 37
38#include <asm/hardware.h>
39#include <asm/arch/board.h> 38#include <asm/arch/board.h>
40#include <asm/arch/gpio.h> 39#include <asm/arch/gpio.h>
41 40
42#include "generic.h" 41#include "generic.h"
43 42
44static void __init eb9200_init_irq(void)
45{
46 /* Initialize AIC controller */
47 at91rm9200_init_irq(NULL);
48
49 /* Set up the GPIO interrupts */
50 at91_gpio_irq_setup(BGA_GPIO_BANKS);
51}
52 43
53/* 44/*
54 * Serial port configuration. 45 * Serial port configuration.
@@ -63,15 +54,18 @@ static struct at91_uart_config __initdata eb9200_uart_config = {
63 54
64static void __init eb9200_map_io(void) 55static void __init eb9200_map_io(void)
65{ 56{
66 at91rm9200_map_io(); 57 /* Initialize processor: 18.432 MHz crystal */
67 58 at91rm9200_initialize(18432000, AT91RM9200_BGA);
68 /* Initialize clocks: 18.432 MHz crystal */
69 at91_clock_init(18432000);
70 59
71 /* Setup the serial ports and console */ 60 /* Setup the serial ports and console */
72 at91_init_serial(&eb9200_uart_config); 61 at91_init_serial(&eb9200_uart_config);
73} 62}
74 63
64static void __init eb9200_init_irq(void)
65{
66 at91rm9200_init_interrupts(NULL);
67}
68
75static struct at91_eth_data __initdata eb9200_eth_data = { 69static struct at91_eth_data __initdata eb9200_eth_data = {
76 .phy_irq_pin = AT91_PIN_PC4, 70 .phy_irq_pin = AT91_PIN_PC4,
77 .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 868192351dda..830eb7932178 100644
--- a/arch/arm/mach-at91rm9200/board-ek.c
+++ b/arch/arm/mach-at91rm9200/board-ek.c
@@ -37,20 +37,11 @@
37#include <asm/mach/map.h> 37#include <asm/mach/map.h>
38#include <asm/mach/irq.h> 38#include <asm/mach/irq.h>
39 39
40#include <asm/hardware.h>
41#include <asm/arch/board.h> 40#include <asm/arch/board.h>
42#include <asm/arch/gpio.h> 41#include <asm/arch/gpio.h>
43 42
44#include "generic.h" 43#include "generic.h"
45 44
46static void __init ek_init_irq(void)
47{
48 /* Initialize AIC controller */
49 at91rm9200_init_irq(NULL);
50
51 /* Set up the GPIO interrupts */
52 at91_gpio_irq_setup(BGA_GPIO_BANKS);
53}
54 45
55/* 46/*
56 * Serial port configuration. 47 * Serial port configuration.
@@ -65,10 +56,8 @@ static struct at91_uart_config __initdata ek_uart_config = {
65 56
66static void __init ek_map_io(void) 57static void __init ek_map_io(void)
67{ 58{
68 at91rm9200_map_io(); 59 /* Initialize processor: 18.432 MHz crystal */
69 60 at91rm9200_initialize(18432000, AT91RM9200_BGA);
70 /* Initialize clocks: 18.432 MHz crystal */
71 at91_clock_init(18432000);
72 61
73 /* Setup the LEDs */ 62 /* Setup the LEDs */
74 at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); 63 at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
@@ -77,6 +66,11 @@ static void __init ek_map_io(void)
77 at91_init_serial(&ek_uart_config); 66 at91_init_serial(&ek_uart_config);
78} 67}
79 68
69static void __init ek_init_irq(void)
70{
71 at91rm9200_init_interrupts(NULL);
72}
73
80static struct at91_eth_data __initdata ek_eth_data = { 74static struct at91_eth_data __initdata ek_eth_data = {
81 .phy_irq_pin = AT91_PIN_PC4, 75 .phy_irq_pin = AT91_PIN_PC4,
82 .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 bf760c5e0c46..91e301924f2c 100644
--- a/arch/arm/mach-at91rm9200/board-kafa.c
+++ b/arch/arm/mach-at91rm9200/board-kafa.c
@@ -34,20 +34,11 @@
34#include <asm/mach/map.h> 34#include <asm/mach/map.h>
35#include <asm/mach/irq.h> 35#include <asm/mach/irq.h>
36 36
37#include <asm/hardware.h>
38#include <asm/arch/board.h> 37#include <asm/arch/board.h>
39#include <asm/arch/gpio.h> 38#include <asm/arch/gpio.h>
40 39
41#include "generic.h" 40#include "generic.h"
42 41
43static void __init kafa_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 42
52/* 43/*
53 * Serial port configuration. 44 * Serial port configuration.
@@ -62,10 +53,8 @@ static struct at91_uart_config __initdata kafa_uart_config = {
62 53
63static void __init kafa_map_io(void) 54static void __init kafa_map_io(void)
64{ 55{
65 at91rm9200_map_io(); 56 /* Initialize processor: 18.432 MHz crystal */
66 57 at91rm9200_initialize(18432000, AT91RM9200_PQFP);
67 /* Initialize clocks: 18.432 MHz crystal */
68 at91_clock_init(18432000);
69 58
70 /* Set up the LEDs */ 59 /* Set up the LEDs */
71 at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4); 60 at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4);
@@ -74,6 +63,11 @@ static void __init kafa_map_io(void)
74 at91_init_serial(&kafa_uart_config); 63 at91_init_serial(&kafa_uart_config);
75} 64}
76 65
66static void __init kafa_init_irq(void)
67{
68 at91rm9200_init_interrupts(NULL);
69}
70
77static struct at91_eth_data __initdata kafa_eth_data = { 71static struct at91_eth_data __initdata kafa_eth_data = {
78 .phy_irq_pin = AT91_PIN_PC4, 72 .phy_irq_pin = AT91_PIN_PC4,
79 .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 f06d2b54cc9a..272fe43bceca 100644
--- a/arch/arm/mach-at91rm9200/board-kb9202.c
+++ b/arch/arm/mach-at91rm9200/board-kb9202.c
@@ -35,20 +35,11 @@
35#include <asm/mach/map.h> 35#include <asm/mach/map.h>
36#include <asm/mach/irq.h> 36#include <asm/mach/irq.h>
37 37
38#include <asm/hardware.h>
39#include <asm/arch/board.h> 38#include <asm/arch/board.h>
40#include <asm/arch/gpio.h> 39#include <asm/arch/gpio.h>
41 40
42#include "generic.h" 41#include "generic.h"
43 42
44static void __init kb9202_init_irq(void)
45{
46 /* Initialize AIC controller */
47 at91rm9200_init_irq(NULL);
48
49 /* Set up the GPIO interrupts */
50 at91_gpio_irq_setup(PQFP_GPIO_BANKS);
51}
52 43
53/* 44/*
54 * Serial port configuration. 45 * Serial port configuration.
@@ -63,10 +54,8 @@ static struct at91_uart_config __initdata kb9202_uart_config = {
63 54
64static void __init kb9202_map_io(void) 55static void __init kb9202_map_io(void)
65{ 56{
66 at91rm9200_map_io(); 57 /* Initialize processor: 10 MHz crystal */
67 58 at91rm9200_initialize(10000000, AT91RM9200_PQFP);
68 /* Initialize clocks: 10 MHz crystal */
69 at91_clock_init(10000000);
70 59
71 /* Set up the LEDs */ 60 /* Set up the LEDs */
72 at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18); 61 at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18);
@@ -75,6 +64,11 @@ static void __init kb9202_map_io(void)
75 at91_init_serial(&kb9202_uart_config); 64 at91_init_serial(&kb9202_uart_config);
76} 65}
77 66
67static void __init kb9202_init_irq(void)
68{
69 at91rm9200_init_interrupts(NULL);
70}
71
78static struct at91_eth_data __initdata kb9202_eth_data = { 72static struct at91_eth_data __initdata kb9202_eth_data = {
79 .phy_irq_pin = AT91_PIN_PB29, 73 .phy_irq_pin = AT91_PIN_PB29,
80 .is_rmii = 0, 74 .is_rmii = 0,
@@ -95,6 +89,29 @@ static struct at91_mmc_data __initdata kb9202_mmc_data = {
95 .wire4 = 1, 89 .wire4 = 1,
96}; 90};
97 91
92static struct mtd_partition __initdata kb9202_nand_partition[] = {
93 {
94 .name = "nand_fs",
95 .offset = 0,
96 .size = MTDPART_SIZ_FULL,
97 },
98};
99
100static struct mtd_partition *nand_partitions(int size, int *num_partitions)
101{
102 *num_partitions = ARRAY_SIZE(kb9202_nand_partition);
103 return kb9202_nand_partition;
104}
105
106static struct at91_nand_data __initdata kb9202_nand_data = {
107 .ale = 22,
108 .cle = 21,
109 // .det_pin = ... not there
110 .rdy_pin = AT91_PIN_PC29,
111 .enable_pin = AT91_PIN_PC28,
112 .partition_info = nand_partitions,
113};
114
98static void __init kb9202_board_init(void) 115static void __init kb9202_board_init(void)
99{ 116{
100 /* Serial */ 117 /* Serial */
@@ -111,6 +128,8 @@ static void __init kb9202_board_init(void)
111 at91_add_device_i2c(); 128 at91_add_device_i2c();
112 /* SPI */ 129 /* SPI */
113 at91_add_device_spi(NULL, 0); 130 at91_add_device_spi(NULL, 0);
131 /* NAND */
132 at91_add_device_nand(&kb9202_nand_data);
114} 133}
115 134
116MACHINE_START(KB9200, "KB920x") 135MACHINE_START(KB9200, "KB920x")
diff --git a/arch/arm/mach-at91rm9200/clock.c b/arch/arm/mach-at91rm9200/clock.c
index edc2cc837ae6..a43b061a7c85 100644
--- a/arch/arm/mach-at91rm9200/clock.c
+++ b/arch/arm/mach-at91rm9200/clock.c
@@ -29,7 +29,7 @@
29 29
30#include <asm/hardware.h> 30#include <asm/hardware.h>
31 31
32#include "generic.h" 32#include "clock.h"
33 33
34 34
35/* 35/*
@@ -38,23 +38,15 @@
38 * PLLB be used at other rates (on boards that don't need USB), etc. 38 * PLLB be used at other rates (on boards that don't need USB), etc.
39 */ 39 */
40 40
41struct clk { 41#define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY)
42 const char *name; /* unique clock name */ 42#define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE)
43 const char *function; /* function of the clock */ 43#define clk_is_peripheral(x) ((x)->type & CLK_TYPE_PERIPHERAL)
44 struct device *dev; /* device associated with function */ 44
45 unsigned long rate_hz; 45
46 struct clk *parent; 46static LIST_HEAD(clocks);
47 u32 pmc_mask; 47static DEFINE_SPINLOCK(clk_lock);
48 void (*mode)(struct clk *, int);
49 unsigned id:2; /* PCK0..3, or 32k/main/a/b */
50 unsigned primary:1;
51 unsigned pll:1;
52 unsigned programmable:1;
53 u16 users;
54};
55 48
56static spinlock_t clk_lock; 49static u32 at91_pllb_usb_init;
57static u32 at91_pllb_usb_init;
58 50
59/* 51/*
60 * Four primary clock sources: two crystal oscillators (32K, main), and 52 * Four primary clock sources: two crystal oscillators (32K, main), and
@@ -67,21 +59,20 @@ static struct clk clk32k = {
67 .rate_hz = AT91_SLOW_CLOCK, 59 .rate_hz = AT91_SLOW_CLOCK,
68 .users = 1, /* always on */ 60 .users = 1, /* always on */
69 .id = 0, 61 .id = 0,
70 .primary = 1, 62 .type = CLK_TYPE_PRIMARY,
71}; 63};
72static struct clk main_clk = { 64static struct clk main_clk = {
73 .name = "main", 65 .name = "main",
74 .pmc_mask = AT91_PMC_MOSCS, /* in PMC_SR */ 66 .pmc_mask = AT91_PMC_MOSCS, /* in PMC_SR */
75 .id = 1, 67 .id = 1,
76 .primary = 1, 68 .type = CLK_TYPE_PRIMARY,
77}; 69};
78static struct clk plla = { 70static struct clk plla = {
79 .name = "plla", 71 .name = "plla",
80 .parent = &main_clk, 72 .parent = &main_clk,
81 .pmc_mask = AT91_PMC_LOCKA, /* in PMC_SR */ 73 .pmc_mask = AT91_PMC_LOCKA, /* in PMC_SR */
82 .id = 2, 74 .id = 2,
83 .primary = 1, 75 .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL,
84 .pll = 1,
85}; 76};
86 77
87static void pllb_mode(struct clk *clk, int is_on) 78static void pllb_mode(struct clk *clk, int is_on)
@@ -94,6 +85,7 @@ static void pllb_mode(struct clk *clk, int is_on)
94 } else 85 } else
95 value = 0; 86 value = 0;
96 87
88 // REVISIT: Add work-around for AT91RM9200 Errata #26 ?
97 at91_sys_write(AT91_CKGR_PLLBR, value); 89 at91_sys_write(AT91_CKGR_PLLBR, value);
98 90
99 do { 91 do {
@@ -107,8 +99,7 @@ static struct clk pllb = {
107 .pmc_mask = AT91_PMC_LOCKB, /* in PMC_SR */ 99 .pmc_mask = AT91_PMC_LOCKB, /* in PMC_SR */
108 .mode = pllb_mode, 100 .mode = pllb_mode,
109 .id = 3, 101 .id = 3,
110 .primary = 1, 102 .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL,
111 .pll = 1,
112}; 103};
113 104
114static void pmc_sys_mode(struct clk *clk, int is_on) 105static void pmc_sys_mode(struct clk *clk, int is_on)
@@ -133,41 +124,6 @@ static struct clk uhpck = {
133 .mode = pmc_sys_mode, 124 .mode = pmc_sys_mode,
134}; 125};
135 126
136#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
137/*
138 * The four programmable clocks can be parented by any primary clock.
139 * You must configure pin multiplexing to bring these signals out.
140 */
141static struct clk pck0 = {
142 .name = "pck0",
143 .pmc_mask = AT91_PMC_PCK0,
144 .mode = pmc_sys_mode,
145 .programmable = 1,
146 .id = 0,
147};
148static struct clk pck1 = {
149 .name = "pck1",
150 .pmc_mask = AT91_PMC_PCK1,
151 .mode = pmc_sys_mode,
152 .programmable = 1,
153 .id = 1,
154};
155static struct clk pck2 = {
156 .name = "pck2",
157 .pmc_mask = AT91_PMC_PCK2,
158 .mode = pmc_sys_mode,
159 .programmable = 1,
160 .id = 2,
161};
162static struct clk pck3 = {
163 .name = "pck3",
164 .pmc_mask = AT91_PMC_PCK3,
165 .mode = pmc_sys_mode,
166 .programmable = 1,
167 .id = 3,
168};
169#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
170
171 127
172/* 128/*
173 * The master clock is divided from the CPU clock (by 1-4). It's used for 129 * The master clock is divided from the CPU clock (by 1-4). It's used for
@@ -187,131 +143,21 @@ static void pmc_periph_mode(struct clk *clk, int is_on)
187 at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask); 143 at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask);
188} 144}
189 145
190static struct clk udc_clk = { 146static struct clk __init *at91_css_to_clk(unsigned long css)
191 .name = "udc_clk", 147{
192 .parent = &mck, 148 switch (css) {
193 .pmc_mask = 1 << AT91_ID_UDP, 149 case AT91_PMC_CSS_SLOW:
194 .mode = pmc_periph_mode, 150 return &clk32k;
195}; 151 case AT91_PMC_CSS_MAIN:
196static struct clk ohci_clk = { 152 return &main_clk;
197 .name = "ohci_clk", 153 case AT91_PMC_CSS_PLLA:
198 .parent = &mck, 154 return &plla;
199 .pmc_mask = 1 << AT91_ID_UHP, 155 case AT91_PMC_CSS_PLLB:
200 .mode = pmc_periph_mode, 156 return &pllb;
201}; 157 }
202static struct clk ether_clk = {
203 .name = "ether_clk",
204 .parent = &mck,
205 .pmc_mask = 1 << AT91_ID_EMAC,
206 .mode = pmc_periph_mode,
207};
208static struct clk mmc_clk = {
209 .name = "mci_clk",
210 .parent = &mck,
211 .pmc_mask = 1 << AT91_ID_MCI,
212 .mode = pmc_periph_mode,
213};
214static struct clk twi_clk = {
215 .name = "twi_clk",
216 .parent = &mck,
217 .pmc_mask = 1 << AT91_ID_TWI,
218 .mode = pmc_periph_mode,
219};
220static struct clk usart0_clk = {
221 .name = "usart0_clk",
222 .parent = &mck,
223 .pmc_mask = 1 << AT91_ID_US0,
224 .mode = pmc_periph_mode,
225};
226static struct clk usart1_clk = {
227 .name = "usart1_clk",
228 .parent = &mck,
229 .pmc_mask = 1 << AT91_ID_US1,
230 .mode = pmc_periph_mode,
231};
232static struct clk usart2_clk = {
233 .name = "usart2_clk",
234 .parent = &mck,
235 .pmc_mask = 1 << AT91_ID_US2,
236 .mode = pmc_periph_mode,
237};
238static struct clk usart3_clk = {
239 .name = "usart3_clk",
240 .parent = &mck,
241 .pmc_mask = 1 << AT91_ID_US3,
242 .mode = pmc_periph_mode,
243};
244static struct clk spi_clk = {
245 .name = "spi0_clk",
246 .parent = &mck,
247 .pmc_mask = 1 << AT91_ID_SPI,
248 .mode = pmc_periph_mode,
249};
250static struct clk pioA_clk = {
251 .name = "pioA_clk",
252 .parent = &mck,
253 .pmc_mask = 1 << AT91_ID_PIOA,
254 .mode = pmc_periph_mode,
255};
256static struct clk pioB_clk = {
257 .name = "pioB_clk",
258 .parent = &mck,
259 .pmc_mask = 1 << AT91_ID_PIOB,
260 .mode = pmc_periph_mode,
261};
262static struct clk pioC_clk = {
263 .name = "pioC_clk",
264 .parent = &mck,
265 .pmc_mask = 1 << AT91_ID_PIOC,
266 .mode = pmc_periph_mode,
267};
268static struct clk pioD_clk = {
269 .name = "pioD_clk",
270 .parent = &mck,
271 .pmc_mask = 1 << AT91_ID_PIOD,
272 .mode = pmc_periph_mode,
273};
274
275static struct clk *const clock_list[] = {
276 /* four primary clocks -- MUST BE FIRST! */
277 &clk32k,
278 &main_clk,
279 &plla,
280 &pllb,
281
282 /* PLLB children (USB) */
283 &udpck,
284 &uhpck,
285
286#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
287 /* programmable clocks */
288 &pck0,
289 &pck1,
290 &pck2,
291 &pck3,
292#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
293
294 /* MCK and peripherals */
295 &mck,
296 &usart0_clk,
297 &usart1_clk,
298 &usart2_clk,
299 &usart3_clk,
300 &mmc_clk,
301 &udc_clk,
302 &twi_clk,
303 &spi_clk,
304 &pioA_clk,
305 &pioB_clk,
306 &pioC_clk,
307 &pioD_clk,
308 // ssc0..ssc2
309 // tc0..tc5
310 // irq0..irq6
311 &ohci_clk,
312 &ether_clk,
313};
314 158
159 return NULL;
160}
315 161
316/* 162/*
317 * Associate a particular clock with a function (eg, "uart") and device. 163 * Associate a particular clock with a function (eg, "uart") and device.
@@ -329,14 +175,12 @@ void __init at91_clock_associate(const char *id, struct device *dev, const char
329 clk->dev = dev; 175 clk->dev = dev;
330} 176}
331 177
332/* clocks are all static for now; no refcounting necessary */ 178/* clocks cannot be de-registered no refcounting necessary */
333struct clk *clk_get(struct device *dev, const char *id) 179struct clk *clk_get(struct device *dev, const char *id)
334{ 180{
335 int i; 181 struct clk *clk;
336
337 for (i = 0; i < ARRAY_SIZE(clock_list); i++) {
338 struct clk *clk = clock_list[i];
339 182
183 list_for_each_entry(clk, &clocks, node) {
340 if (strcmp(id, clk->name) == 0) 184 if (strcmp(id, clk->name) == 0)
341 return clk; 185 return clk;
342 if (clk->function && (dev == clk->dev) && strcmp(id, clk->function) == 0) 186 if (clk->function && (dev == clk->dev) && strcmp(id, clk->function) == 0)
@@ -424,7 +268,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
424 unsigned prescale; 268 unsigned prescale;
425 unsigned long actual; 269 unsigned long actual;
426 270
427 if (!clk->programmable) 271 if (!clk_is_programmable(clk))
428 return -EINVAL; 272 return -EINVAL;
429 spin_lock_irqsave(&clk_lock, flags); 273 spin_lock_irqsave(&clk_lock, flags);
430 274
@@ -446,7 +290,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
446 unsigned prescale; 290 unsigned prescale;
447 unsigned long actual; 291 unsigned long actual;
448 292
449 if (!clk->programmable) 293 if (!clk_is_programmable(clk))
450 return -EINVAL; 294 return -EINVAL;
451 if (clk->users) 295 if (clk->users)
452 return -EBUSY; 296 return -EBUSY;
@@ -484,7 +328,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
484 328
485 if (clk->users) 329 if (clk->users)
486 return -EBUSY; 330 return -EBUSY;
487 if (!parent->primary || !clk->programmable) 331 if (!clk_is_primary(parent) || !clk_is_programmable(clk))
488 return -EINVAL; 332 return -EINVAL;
489 spin_lock_irqsave(&clk_lock, flags); 333 spin_lock_irqsave(&clk_lock, flags);
490 334
@@ -497,6 +341,18 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
497} 341}
498EXPORT_SYMBOL(clk_set_parent); 342EXPORT_SYMBOL(clk_set_parent);
499 343
344/* establish PCK0..PCK3 parentage and rate */
345static void init_programmable_clock(struct clk *clk)
346{
347 struct clk *parent;
348 u32 pckr;
349
350 pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
351 parent = at91_css_to_clk(pckr & AT91_PMC_CSS);
352 clk->parent = parent;
353 clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3));
354}
355
500#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ 356#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
501 357
502/*------------------------------------------------------------------------*/ 358/*------------------------------------------------------------------------*/
@@ -506,6 +362,7 @@ EXPORT_SYMBOL(clk_set_parent);
506static int at91_clk_show(struct seq_file *s, void *unused) 362static int at91_clk_show(struct seq_file *s, void *unused)
507{ 363{
508 u32 scsr, pcsr, sr; 364 u32 scsr, pcsr, sr;
365 struct clk *clk;
509 unsigned i; 366 unsigned i;
510 367
511 seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); 368 seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR));
@@ -523,9 +380,8 @@ static int at91_clk_show(struct seq_file *s, void *unused)
523 380
524 seq_printf(s, "\n"); 381 seq_printf(s, "\n");
525 382
526 for (i = 0; i < ARRAY_SIZE(clock_list); i++) { 383 list_for_each_entry(clk, &clocks, node) {
527 char *state; 384 char *state;
528 struct clk *clk = clock_list[i];
529 385
530 if (clk->mode == pmc_sys_mode) 386 if (clk->mode == pmc_sys_mode)
531 state = (scsr & clk->pmc_mask) ? "on" : "off"; 387 state = (scsr & clk->pmc_mask) ? "on" : "off";
@@ -570,6 +426,28 @@ postcore_initcall(at91_clk_debugfs_init);
570 426
571/*------------------------------------------------------------------------*/ 427/*------------------------------------------------------------------------*/
572 428
429/* Register a new clock */
430int __init clk_register(struct clk *clk)
431{
432 if (clk_is_peripheral(clk)) {
433 clk->parent = &mck;
434 clk->mode = pmc_periph_mode;
435 list_add_tail(&clk->node, &clocks);
436 }
437#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
438 else if (clk_is_programmable(clk)) {
439 clk->mode = pmc_sys_mode;
440 init_programmable_clock(clk);
441 list_add_tail(&clk->node, &clocks);
442 }
443#endif
444
445 return 0;
446}
447
448
449/*------------------------------------------------------------------------*/
450
573static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) 451static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg)
574{ 452{
575 unsigned mul, div; 453 unsigned mul, div;
@@ -640,20 +518,17 @@ fail:
640 return 0; 518 return 0;
641} 519}
642 520
643
644/* 521/*
645 * Several unused clocks may be active. Turn them off. 522 * Several unused clocks may be active. Turn them off.
646 */ 523 */
647static void at91_periphclk_reset(void) 524static void __init at91_periphclk_reset(void)
648{ 525{
649 unsigned long reg; 526 unsigned long reg;
650 int i; 527 struct clk *clk;
651 528
652 reg = at91_sys_read(AT91_PMC_PCSR); 529 reg = at91_sys_read(AT91_PMC_PCSR);
653 530
654 for (i = 0; i < ARRAY_SIZE(clock_list); i++) { 531 list_for_each_entry(clk, &clocks, node) {
655 struct clk *clk = clock_list[i];
656
657 if (clk->mode != pmc_periph_mode) 532 if (clk->mode != pmc_periph_mode)
658 continue; 533 continue;
659 534
@@ -664,11 +539,25 @@ static void at91_periphclk_reset(void)
664 at91_sys_write(AT91_PMC_PCDR, reg); 539 at91_sys_write(AT91_PMC_PCDR, reg);
665} 540}
666 541
542static struct clk *const standard_pmc_clocks[] __initdata = {
543 /* four primary clocks */
544 &clk32k,
545 &main_clk,
546 &plla,
547 &pllb,
548
549 /* PLLB children (USB) */
550 &udpck,
551 &uhpck,
552
553 /* MCK */
554 &mck
555};
556
667int __init at91_clock_init(unsigned long main_clock) 557int __init at91_clock_init(unsigned long main_clock)
668{ 558{
669 unsigned tmp, freq, mckr; 559 unsigned tmp, freq, mckr;
670 560 int i;
671 spin_lock_init(&clk_lock);
672 561
673 /* 562 /*
674 * When the bootloader initialized the main oscillator correctly, 563 * When the bootloader initialized the main oscillator correctly,
@@ -709,11 +598,15 @@ int __init at91_clock_init(unsigned long main_clock)
709 * For now, assume this parentage won't change. 598 * For now, assume this parentage won't change.
710 */ 599 */
711 mckr = at91_sys_read(AT91_PMC_MCKR); 600 mckr = at91_sys_read(AT91_PMC_MCKR);
712 mck.parent = clock_list[mckr & AT91_PMC_CSS]; 601 mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
713 freq = mck.parent->rate_hz; 602 freq = mck.parent->rate_hz;
714 freq /= (1 << ((mckr >> 2) & 3)); /* prescale */ 603 freq /= (1 << ((mckr >> 2) & 3)); /* prescale */
715 mck.rate_hz = freq / (1 + ((mckr >> 8) & 3)); /* mdiv */ 604 mck.rate_hz = freq / (1 + ((mckr >> 8) & 3)); /* mdiv */
716 605
606 /* Register the PMC's standard clocks */
607 for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
608 list_add_tail(&standard_pmc_clocks[i]->node, &clocks);
609
717 /* MCK and CPU clock are "always on" */ 610 /* MCK and CPU clock are "always on" */
718 clk_enable(&mck); 611 clk_enable(&mck);
719 612
@@ -722,35 +615,8 @@ int __init at91_clock_init(unsigned long main_clock)
722 (unsigned) main_clock / 1000000, 615 (unsigned) main_clock / 1000000,
723 ((unsigned) main_clock % 1000000) / 1000); 616 ((unsigned) main_clock % 1000000) / 1000);
724 617
725#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
726 /* establish PCK0..PCK3 parentage */
727 for (tmp = 0; tmp < ARRAY_SIZE(clock_list); tmp++) {
728 struct clk *clk = clock_list[tmp], *parent;
729 u32 pckr;
730
731 if (!clk->programmable)
732 continue;
733
734 pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
735 parent = clock_list[pckr & AT91_PMC_CSS];
736 clk->parent = parent;
737 clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3));
738
739 if (clk->users == 0) {
740 /* not being used, so switch it off */
741 at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask);
742 }
743 }
744#else
745 /* disable all programmable clocks */ 618 /* disable all programmable clocks */
746 at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK0 | AT91_PMC_PCK1 | AT91_PMC_PCK2 | AT91_PMC_PCK3); 619 at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK0 | AT91_PMC_PCK1 | AT91_PMC_PCK2 | AT91_PMC_PCK3);
747#endif
748
749 /* enable the PIO clocks */
750 clk_enable(&pioA_clk);
751 clk_enable(&pioB_clk);
752 clk_enable(&pioC_clk);
753 clk_enable(&pioD_clk);
754 620
755 /* disable all other unused peripheral clocks */ 621 /* disable all other unused peripheral clocks */
756 at91_periphclk_reset(); 622 at91_periphclk_reset();
diff --git a/arch/arm/mach-at91rm9200/clock.h b/arch/arm/mach-at91rm9200/clock.h
new file mode 100644
index 000000000000..0592e662ab37
--- /dev/null
+++ b/arch/arm/mach-at91rm9200/clock.h
@@ -0,0 +1,30 @@
1/*
2 * linux/arch/arm/mach-at91rm9200/clock.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#define CLK_TYPE_PRIMARY 0x1
10#define CLK_TYPE_PLL 0x2
11#define CLK_TYPE_PROGRAMMABLE 0x4
12#define CLK_TYPE_PERIPHERAL 0x8
13
14
15struct clk {
16 struct list_head node;
17 const char *name; /* unique clock name */
18 const char *function; /* function of the clock */
19 struct device *dev; /* device associated with function */
20 unsigned long rate_hz;
21 struct clk *parent;
22 u32 pmc_mask;
23 void (*mode)(struct clk *, int);
24 unsigned id:2; /* PCK0..3, or 32k/main/a/b */
25 unsigned type; /* clock type */
26 u16 users;
27};
28
29
30extern int __init clk_register(struct clk *clk);
diff --git a/arch/arm/mach-at91rm9200/devices.c b/arch/arm/mach-at91rm9200/devices.c
index 4352acb88178..01525530c287 100644
--- a/arch/arm/mach-at91rm9200/devices.c
+++ b/arch/arm/mach-at91rm9200/devices.c
@@ -35,13 +35,13 @@ static struct at91_usbh_data usbh_data;
35 35
36static struct resource at91_usbh_resources[] = { 36static struct resource at91_usbh_resources[] = {
37 [0] = { 37 [0] = {
38 .start = AT91_UHP_BASE, 38 .start = AT91RM9200_UHP_BASE,
39 .end = AT91_UHP_BASE + SZ_1M - 1, 39 .end = AT91RM9200_UHP_BASE + SZ_1M - 1,
40 .flags = IORESOURCE_MEM, 40 .flags = IORESOURCE_MEM,
41 }, 41 },
42 [1] = { 42 [1] = {
43 .start = AT91_ID_UHP, 43 .start = AT91RM9200_ID_UHP,
44 .end = AT91_ID_UHP, 44 .end = AT91RM9200_ID_UHP,
45 .flags = IORESOURCE_IRQ, 45 .flags = IORESOURCE_IRQ,
46 }, 46 },
47}; 47};
@@ -80,13 +80,13 @@ static struct at91_udc_data udc_data;
80 80
81static struct resource at91_udc_resources[] = { 81static struct resource at91_udc_resources[] = {
82 [0] = { 82 [0] = {
83 .start = AT91_BASE_UDP, 83 .start = AT91RM9200_BASE_UDP,
84 .end = AT91_BASE_UDP + SZ_16K - 1, 84 .end = AT91RM9200_BASE_UDP + SZ_16K - 1,
85 .flags = IORESOURCE_MEM, 85 .flags = IORESOURCE_MEM,
86 }, 86 },
87 [1] = { 87 [1] = {
88 .start = AT91_ID_UDP, 88 .start = AT91RM9200_ID_UDP,
89 .end = AT91_ID_UDP, 89 .end = AT91RM9200_ID_UDP,
90 .flags = IORESOURCE_IRQ, 90 .flags = IORESOURCE_IRQ,
91 }, 91 },
92}; 92};
@@ -131,13 +131,13 @@ static struct at91_eth_data eth_data;
131 131
132static struct resource at91_eth_resources[] = { 132static struct resource at91_eth_resources[] = {
133 [0] = { 133 [0] = {
134 .start = AT91_BASE_EMAC, 134 .start = AT91_VA_BASE_EMAC,
135 .end = AT91_BASE_EMAC + SZ_16K - 1, 135 .end = AT91_VA_BASE_EMAC + SZ_16K - 1,
136 .flags = IORESOURCE_MEM, 136 .flags = IORESOURCE_MEM,
137 }, 137 },
138 [1] = { 138 [1] = {
139 .start = AT91_ID_EMAC, 139 .start = AT91RM9200_ID_EMAC,
140 .end = AT91_ID_EMAC, 140 .end = AT91RM9200_ID_EMAC,
141 .flags = IORESOURCE_IRQ, 141 .flags = IORESOURCE_IRQ,
142 }, 142 },
143}; 143};
@@ -263,13 +263,13 @@ static struct at91_mmc_data mmc_data;
263 263
264static struct resource at91_mmc_resources[] = { 264static struct resource at91_mmc_resources[] = {
265 [0] = { 265 [0] = {
266 .start = AT91_BASE_MCI, 266 .start = AT91RM9200_BASE_MCI,
267 .end = AT91_BASE_MCI + SZ_16K - 1, 267 .end = AT91RM9200_BASE_MCI + SZ_16K - 1,
268 .flags = IORESOURCE_MEM, 268 .flags = IORESOURCE_MEM,
269 }, 269 },
270 [1] = { 270 [1] = {
271 .start = AT91_ID_MCI, 271 .start = AT91RM9200_ID_MCI,
272 .end = AT91_ID_MCI, 272 .end = AT91RM9200_ID_MCI,
273 .flags = IORESOURCE_IRQ, 273 .flags = IORESOURCE_IRQ,
274 }, 274 },
275}; 275};
@@ -423,13 +423,13 @@ static u64 spi_dmamask = 0xffffffffUL;
423 423
424static struct resource at91_spi_resources[] = { 424static struct resource at91_spi_resources[] = {
425 [0] = { 425 [0] = {
426 .start = AT91_BASE_SPI, 426 .start = AT91RM9200_BASE_SPI,
427 .end = AT91_BASE_SPI + SZ_16K - 1, 427 .end = AT91RM9200_BASE_SPI + SZ_16K - 1,
428 .flags = IORESOURCE_MEM, 428 .flags = IORESOURCE_MEM,
429 }, 429 },
430 [1] = { 430 [1] = {
431 .start = AT91_ID_SPI, 431 .start = AT91RM9200_ID_SPI,
432 .end = AT91_ID_SPI, 432 .end = AT91RM9200_ID_SPI,
433 .flags = IORESOURCE_IRQ, 433 .flags = IORESOURCE_IRQ,
434 }, 434 },
435}; 435};
@@ -582,13 +582,13 @@ static inline void configure_dbgu_pins(void)
582 582
583static struct resource uart0_resources[] = { 583static struct resource uart0_resources[] = {
584 [0] = { 584 [0] = {
585 .start = AT91_BASE_US0, 585 .start = AT91RM9200_BASE_US0,
586 .end = AT91_BASE_US0 + SZ_16K - 1, 586 .end = AT91RM9200_BASE_US0 + SZ_16K - 1,
587 .flags = IORESOURCE_MEM, 587 .flags = IORESOURCE_MEM,
588 }, 588 },
589 [1] = { 589 [1] = {
590 .start = AT91_ID_US0, 590 .start = AT91RM9200_ID_US0,
591 .end = AT91_ID_US0, 591 .end = AT91RM9200_ID_US0,
592 .flags = IORESOURCE_IRQ, 592 .flags = IORESOURCE_IRQ,
593 }, 593 },
594}; 594};
@@ -624,13 +624,13 @@ static inline void configure_usart0_pins(void)
624 624
625static struct resource uart1_resources[] = { 625static struct resource uart1_resources[] = {
626 [0] = { 626 [0] = {
627 .start = AT91_BASE_US1, 627 .start = AT91RM9200_BASE_US1,
628 .end = AT91_BASE_US1 + SZ_16K - 1, 628 .end = AT91RM9200_BASE_US1 + SZ_16K - 1,
629 .flags = IORESOURCE_MEM, 629 .flags = IORESOURCE_MEM,
630 }, 630 },
631 [1] = { 631 [1] = {
632 .start = AT91_ID_US1, 632 .start = AT91RM9200_ID_US1,
633 .end = AT91_ID_US1, 633 .end = AT91RM9200_ID_US1,
634 .flags = IORESOURCE_IRQ, 634 .flags = IORESOURCE_IRQ,
635 }, 635 },
636}; 636};
@@ -665,13 +665,13 @@ static inline void configure_usart1_pins(void)
665 665
666static struct resource uart2_resources[] = { 666static struct resource uart2_resources[] = {
667 [0] = { 667 [0] = {
668 .start = AT91_BASE_US2, 668 .start = AT91RM9200_BASE_US2,
669 .end = AT91_BASE_US2 + SZ_16K - 1, 669 .end = AT91RM9200_BASE_US2 + SZ_16K - 1,
670 .flags = IORESOURCE_MEM, 670 .flags = IORESOURCE_MEM,
671 }, 671 },
672 [1] = { 672 [1] = {
673 .start = AT91_ID_US2, 673 .start = AT91RM9200_ID_US2,
674 .end = AT91_ID_US2, 674 .end = AT91RM9200_ID_US2,
675 .flags = IORESOURCE_IRQ, 675 .flags = IORESOURCE_IRQ,
676 }, 676 },
677}; 677};
@@ -700,13 +700,13 @@ static inline void configure_usart2_pins(void)
700 700
701static struct resource uart3_resources[] = { 701static struct resource uart3_resources[] = {
702 [0] = { 702 [0] = {
703 .start = AT91_BASE_US3, 703 .start = AT91RM9200_BASE_US3,
704 .end = AT91_BASE_US3 + SZ_16K - 1, 704 .end = AT91RM9200_BASE_US3 + SZ_16K - 1,
705 .flags = IORESOURCE_MEM, 705 .flags = IORESOURCE_MEM,
706 }, 706 },
707 [1] = { 707 [1] = {
708 .start = AT91_ID_US3, 708 .start = AT91RM9200_ID_US3,
709 .end = AT91_ID_US3, 709 .end = AT91RM9200_ID_US3,
710 .flags = IORESOURCE_IRQ, 710 .flags = IORESOURCE_IRQ,
711 }, 711 },
712}; 712};
diff --git a/arch/arm/mach-at91rm9200/generic.h b/arch/arm/mach-at91rm9200/generic.h
index 7979d8ab7e07..694e411e285f 100644
--- a/arch/arm/mach-at91rm9200/generic.h
+++ b/arch/arm/mach-at91rm9200/generic.h
@@ -8,18 +8,17 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11 /* Processors */
12extern void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks);
13
11 /* Interrupts */ 14 /* Interrupts */
12extern void __init at91rm9200_init_irq(unsigned int priority[]); 15extern void __init at91rm9200_init_interrupts(unsigned int priority[]);
13extern void __init at91_aic_init(unsigned int priority[]); 16extern void __init at91_aic_init(unsigned int priority[]);
14extern void __init at91_gpio_irq_setup(unsigned banks);
15 17
16 /* Timer */ 18 /* Timer */
17struct sys_timer; 19struct sys_timer;
18extern struct sys_timer at91rm9200_timer; 20extern struct sys_timer at91rm9200_timer;
19 21
20 /* Memory Map */
21extern void __init at91rm9200_map_io(void);
22
23 /* Clocks */ 22 /* Clocks */
24extern int __init at91_clock_init(unsigned long main_clock); 23extern int __init at91_clock_init(unsigned long main_clock);
25struct device; 24struct device;
@@ -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 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
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(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/*--------------------------------------------------------------------------*/
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 = 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 */
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 c3a5e777f9f8..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{
@@ -61,12 +59,12 @@ static int at91_aic_set_type(unsigned irq, unsigned type)
61 srctype = AT91_AIC_SRCTYPE_RISING; 59 srctype = AT91_AIC_SRCTYPE_RISING;
62 break; 60 break;
63 case IRQT_LOW: 61 case IRQT_LOW:
64 if ((irq > AT91_ID_FIQ) && (irq < AT91_ID_IRQ0)) /* only supported on external interrupts */ 62 if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0)) /* only supported on external interrupts */
65 return -EINVAL; 63 return -EINVAL;
66 srctype = AT91_AIC_SRCTYPE_LOW; 64 srctype = AT91_AIC_SRCTYPE_LOW;
67 break; 65 break;
68 case IRQT_FALLING: 66 case IRQT_FALLING:
69 if ((irq > AT91_ID_FIQ) && (irq < AT91_ID_IRQ0)) /* only supported on external interrupts */ 67 if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0)) /* only supported on external interrupts */
70 return -EINVAL; 68 return -EINVAL;
71 srctype = AT91_AIC_SRCTYPE_FALLING; 69 srctype = AT91_AIC_SRCTYPE_FALLING;
72 break; 70 break;
diff --git a/arch/arm/mach-at91rm9200/pm.c b/arch/arm/mach-at91rm9200/pm.c
index 47e5480feb7e..32c95d8eaacf 100644
--- a/arch/arm/mach-at91rm9200/pm.c
+++ b/arch/arm/mach-at91rm9200/pm.c
@@ -123,13 +123,13 @@ static int at91_pm_enter(suspend_state_t state)
123 (at91_sys_read(AT91_PMC_PCSR) 123 (at91_sys_read(AT91_PMC_PCSR)
124 | (1 << AT91_ID_FIQ) 124 | (1 << AT91_ID_FIQ)
125 | (1 << AT91_ID_SYS) 125 | (1 << AT91_ID_SYS)
126 | (1 << AT91_ID_IRQ0) 126 | (1 << AT91RM9200_ID_IRQ0)
127 | (1 << AT91_ID_IRQ1) 127 | (1 << AT91RM9200_ID_IRQ1)
128 | (1 << AT91_ID_IRQ2) 128 | (1 << AT91RM9200_ID_IRQ2)
129 | (1 << AT91_ID_IRQ3) 129 | (1 << AT91RM9200_ID_IRQ3)
130 | (1 << AT91_ID_IRQ4) 130 | (1 << AT91RM9200_ID_IRQ4)
131 | (1 << AT91_ID_IRQ5) 131 | (1 << AT91RM9200_ID_IRQ5)
132 | (1 << AT91_ID_IRQ6)) 132 | (1 << AT91RM9200_ID_IRQ6))
133 & at91_sys_read(AT91_AIC_IMR), 133 & at91_sys_read(AT91_AIC_IMR),
134 state); 134 state);
135 135