aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig5
-rw-r--r--arch/arm/boot/compressed/head-xscale.S5
-rw-r--r--arch/arm/common/sharpsl_pm.c2
-rw-r--r--arch/arm/mach-at91/board-sam9261ek.c130
-rw-r--r--arch/arm/mach-at91/board-sam9263ek.c64
-rw-r--r--arch/arm/mach-davinci/Makefile3
-rw-r--r--arch/arm/mach-davinci/board-evm.c2
-rw-r--r--arch/arm/mach-davinci/clock.c323
-rw-r--r--arch/arm/mach-davinci/clock.h33
-rw-r--r--arch/arm/mach-davinci/gpio.c286
-rw-r--r--arch/arm/mach-davinci/io.c6
-rw-r--r--arch/arm/mach-davinci/mux.c41
-rw-r--r--arch/arm/mach-davinci/psc.c87
-rw-r--r--arch/arm/mach-imx/generic.c118
-rw-r--r--arch/arm/mach-imx/time.c121
-rw-r--r--arch/arm/mach-iop13xx/tpmi.c32
-rw-r--r--arch/arm/mach-ixp4xx/Kconfig16
-rw-r--r--arch/arm/mach-ixp4xx/Makefile4
-rw-r--r--arch/arm/mach-ixp4xx/gateway7001-pci.c63
-rw-r--r--arch/arm/mach-ixp4xx/gateway7001-setup.c108
-rw-r--r--arch/arm/mach-ixp4xx/gtwx5715-pci.c8
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-setup.c96
-rw-r--r--arch/arm/mach-ixp4xx/wg302v2-pci.c63
-rw-r--r--arch/arm/mach-ixp4xx/wg302v2-setup.c109
-rw-r--r--arch/arm/mach-ks8695/Makefile2
-rw-r--r--arch/arm/mach-ks8695/gpio.c218
-rw-r--r--arch/arm/mach-pxa/clock.c15
-rw-r--r--arch/arm/mach-pxa/corgi.c7
-rw-r--r--arch/arm/mach-pxa/devices.h11
-rw-r--r--arch/arm/mach-pxa/dma.c44
-rw-r--r--arch/arm/mach-pxa/generic.c93
-rw-r--r--arch/arm/mach-pxa/generic.h6
-rw-r--r--arch/arm/mach-pxa/idp.c3
-rw-r--r--arch/arm/mach-pxa/irq.c106
-rw-r--r--arch/arm/mach-pxa/lpd270.c3
-rw-r--r--arch/arm/mach-pxa/lubbock.c3
-rw-r--r--arch/arm/mach-pxa/mainstone.c3
-rw-r--r--arch/arm/mach-pxa/pm.c47
-rw-r--r--arch/arm/mach-pxa/poodle.c3
-rw-r--r--arch/arm/mach-pxa/pxa25x.c62
-rw-r--r--arch/arm/mach-pxa/pxa27x.c78
-rw-r--r--arch/arm/mach-pxa/spitz.c7
-rw-r--r--arch/arm/mach-pxa/time.c9
-rw-r--r--arch/arm/mach-pxa/tosa.c4
-rw-r--r--arch/arm/mach-pxa/trizeps4.c3
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c59
-rw-r--r--arch/arm/mach-s3c2440/mach-anubis.c141
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c38
48 files changed, 2372 insertions, 318 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 50d9f3e4e0f..a0fa1ce9ad6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -241,6 +241,9 @@ config ARCH_H720X
241 241
242config ARCH_IMX 242config ARCH_IMX
243 bool "IMX" 243 bool "IMX"
244 select GENERIC_GPIO
245 select GENERIC_TIME
246 select GENERIC_CLOCKEVENTS
244 help 247 help
245 Support for Motorola's i.MX family of processors (MX1, MXL). 248 Support for Motorola's i.MX family of processors (MX1, MXL).
246 249
@@ -308,6 +311,7 @@ config ARCH_L7200
308 311
309config ARCH_KS8695 312config ARCH_KS8695
310 bool "Micrel/Kendin KS8695" 313 bool "Micrel/Kendin KS8695"
314 select GENERIC_GPIO
311 help 315 help
312 Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based 316 Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
313 System-on-Chip devices. 317 System-on-Chip devices.
@@ -384,6 +388,7 @@ config ARCH_DAVINCI
384 bool "TI DaVinci" 388 bool "TI DaVinci"
385 select GENERIC_TIME 389 select GENERIC_TIME
386 select GENERIC_CLOCKEVENTS 390 select GENERIC_CLOCKEVENTS
391 select GENERIC_GPIO
387 help 392 help
388 Support for TI's DaVinci platform. 393 Support for TI's DaVinci platform.
389 394
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S
index 73c5d9e0201..236bbe57831 100644
--- a/arch/arm/boot/compressed/head-xscale.S
+++ b/arch/arm/boot/compressed/head-xscale.S
@@ -41,11 +41,6 @@ __XScale_start:
41 mov r7, #MACH_TYPE_COTULLA_IDP 41 mov r7, #MACH_TYPE_COTULLA_IDP
42#endif 42#endif
43 43
44#ifdef CONFIG_MACH_GTWX5715
45 mov r7, #(MACH_TYPE_GTWX5715 & 0xff)
46 orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00)
47#endif
48
49#ifdef CONFIG_ARCH_IXP2000 44#ifdef CONFIG_ARCH_IXP2000
50 mov r1, #-1 45 mov r1, #-1
51 mov r0, #0xd6000000 46 mov r0, #0xd6000000
diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c
index 3bf3a927ae2..111a7fa5deb 100644
--- a/arch/arm/common/sharpsl_pm.c
+++ b/arch/arm/common/sharpsl_pm.c
@@ -766,9 +766,7 @@ static void sharpsl_apm_get_power_status(struct apm_power_info *info)
766} 766}
767 767
768static struct pm_ops sharpsl_pm_ops = { 768static struct pm_ops sharpsl_pm_ops = {
769 .prepare = pxa_pm_prepare,
770 .enter = corgi_pxa_pm_enter, 769 .enter = corgi_pxa_pm_enter,
771 .finish = pxa_pm_finish,
772 .valid = pm_valid_only_mem, 770 .valid = pm_valid_only_mem,
773}; 771};
774 772
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 26ca8ab3f62..42e172cb0f4 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -27,6 +27,11 @@
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/spi/ads7846.h> 28#include <linux/spi/ads7846.h>
29#include <linux/dm9000.h> 29#include <linux/dm9000.h>
30#include <linux/fb.h>
31#include <linux/gpio_keys.h>
32#include <linux/input.h>
33
34#include <video/atmel_lcdc.h>
30 35
31#include <asm/hardware.h> 36#include <asm/hardware.h>
32#include <asm/setup.h> 37#include <asm/setup.h>
@@ -271,6 +276,127 @@ static struct spi_board_info ek_spi_devices[] = {
271}; 276};
272 277
273 278
279/*
280 * LCD Controller
281 */
282#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
283static struct fb_videomode at91_tft_vga_modes[] = {
284 {
285 .name = "TX09D50VM1CCA @ 60",
286 .refresh = 60,
287 .xres = 240, .yres = 320,
288 .pixclock = KHZ2PICOS(4965),
289
290 .left_margin = 1, .right_margin = 33,
291 .upper_margin = 1, .lower_margin = 0,
292 .hsync_len = 5, .vsync_len = 1,
293
294 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
295 .vmode = FB_VMODE_NONINTERLACED,
296 },
297};
298
299static struct fb_monspecs at91fb_default_monspecs = {
300 .manufacturer = "HIT",
301 .monitor = "TX09D50VM1CCA",
302
303 .modedb = at91_tft_vga_modes,
304 .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
305 .hfmin = 15000,
306 .hfmax = 64000,
307 .vfmin = 50,
308 .vfmax = 150,
309};
310
311#define AT91SAM9261_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
312 | ATMEL_LCDC_DISTYPE_TFT \
313 | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
314
315static void at91_lcdc_power_control(int on)
316{
317 if (on)
318 at91_set_gpio_value(AT91_PIN_PA12, 0); /* power up */
319 else
320 at91_set_gpio_value(AT91_PIN_PA12, 1); /* power down */
321}
322
323/* Driver datas */
324static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
325 .default_bpp = 16,
326 .default_dmacon = ATMEL_LCDC_DMAEN,
327 .default_lcdcon2 = AT91SAM9261_DEFAULT_LCDCON2,
328 .default_monspecs = &at91fb_default_monspecs,
329 .atmel_lcdfb_power_control = at91_lcdc_power_control,
330 .guard_time = 1,
331};
332
333#else
334static struct atmel_lcdfb_info __initdata ek_lcdc_data;
335#endif
336
337
338/*
339 * GPIO Buttons
340 */
341#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
342static struct gpio_keys_button ek_buttons[] = {
343 {
344 .gpio = AT91_PIN_PA27,
345 .keycode = BTN_0,
346 .desc = "Button 0",
347 .active_low = 1,
348 },
349 {
350 .gpio = AT91_PIN_PA26,
351 .keycode = BTN_1,
352 .desc = "Button 1",
353 .active_low = 1,
354 },
355 {
356 .gpio = AT91_PIN_PA25,
357 .keycode = BTN_2,
358 .desc = "Button 2",
359 .active_low = 1,
360 },
361 {
362 .gpio = AT91_PIN_PA24,
363 .keycode = BTN_3,
364 .desc = "Button 3",
365 .active_low = 1,
366 }
367};
368
369static struct gpio_keys_platform_data ek_button_data = {
370 .buttons = ek_buttons,
371 .nbuttons = ARRAY_SIZE(ek_buttons),
372};
373
374static struct platform_device ek_button_device = {
375 .name = "gpio-keys",
376 .id = -1,
377 .num_resources = 0,
378 .dev = {
379 .platform_data = &ek_button_data,
380 }
381};
382
383static void __init ek_add_device_buttons(void)
384{
385 at91_set_gpio_input(AT91_PIN_PB27, 0); /* btn0 */
386 at91_set_deglitch(AT91_PIN_PB27, 1);
387 at91_set_gpio_input(AT91_PIN_PB26, 0); /* btn1 */
388 at91_set_deglitch(AT91_PIN_PB26, 1);
389 at91_set_gpio_input(AT91_PIN_PB25, 0); /* btn2 */
390 at91_set_deglitch(AT91_PIN_PB25, 1);
391 at91_set_gpio_input(AT91_PIN_PB24, 0); /* btn3 */
392 at91_set_deglitch(AT91_PIN_PB24, 1);
393
394 platform_device_register(&ek_button_device);
395}
396#else
397static void __init ek_add_device_buttons(void) {}
398#endif
399
274static void __init ek_board_init(void) 400static void __init ek_board_init(void)
275{ 401{
276 /* Serial */ 402 /* Serial */
@@ -296,6 +422,10 @@ static void __init ek_board_init(void)
296 /* MMC */ 422 /* MMC */
297 at91_add_device_mmc(0, &ek_mmc_data); 423 at91_add_device_mmc(0, &ek_mmc_data);
298#endif 424#endif
425 /* LCD Controller */
426 at91_add_device_lcdc(&ek_lcdc_data);
427 /* Push Buttons */
428 ek_add_device_buttons();
299} 429}
300 430
301MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK") 431MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK")
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index c164c8e58ae..2a1cc73390b 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -26,6 +26,9 @@
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/spi/ads7846.h> 28#include <linux/spi/ads7846.h>
29#include <linux/fb.h>
30
31#include <video/atmel_lcdc.h>
29 32
30#include <asm/hardware.h> 33#include <asm/hardware.h>
31#include <asm/setup.h> 34#include <asm/setup.h>
@@ -202,6 +205,65 @@ static struct at91_nand_data __initdata ek_nand_data = {
202 205
203 206
204/* 207/*
208 * LCD Controller
209 */
210#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
211static struct fb_videomode at91_tft_vga_modes[] = {
212 {
213 .name = "TX09D50VM1CCA @ 60",
214 .refresh = 60,
215 .xres = 240, .yres = 320,
216 .pixclock = KHZ2PICOS(4965),
217
218 .left_margin = 1, .right_margin = 33,
219 .upper_margin = 1, .lower_margin = 0,
220 .hsync_len = 5, .vsync_len = 1,
221
222 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
223 .vmode = FB_VMODE_NONINTERLACED,
224 },
225};
226
227static struct fb_monspecs at91fb_default_monspecs = {
228 .manufacturer = "HIT",
229 .monitor = "TX09D70VM1CCA",
230
231 .modedb = at91_tft_vga_modes,
232 .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
233 .hfmin = 15000,
234 .hfmax = 64000,
235 .vfmin = 50,
236 .vfmax = 150,
237};
238
239#define AT91SAM9263_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
240 | ATMEL_LCDC_DISTYPE_TFT \
241 | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
242
243static void at91_lcdc_power_control(int on)
244{
245 if (on)
246 at91_set_gpio_value(AT91_PIN_PD12, 0); /* power up */
247 else
248 at91_set_gpio_value(AT91_PIN_PD12, 1); /* power down */
249}
250
251/* Driver datas */
252static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
253 .default_bpp = 16,
254 .default_dmacon = ATMEL_LCDC_DMAEN,
255 .default_lcdcon2 = AT91SAM9263_DEFAULT_LCDCON2,
256 .default_monspecs = &at91fb_default_monspecs,
257 .atmel_lcdfb_power_control = at91_lcdc_power_control,
258 .guard_time = 1,
259};
260
261#else
262static struct atmel_lcdfb_info __initdata ek_lcdc_data;
263#endif
264
265
266/*
205 * AC97 267 * AC97
206 */ 268 */
207static struct atmel_ac97_data ek_ac97_data = { 269static struct atmel_ac97_data ek_ac97_data = {
@@ -230,6 +292,8 @@ static void __init ek_board_init(void)
230 at91_add_device_nand(&ek_nand_data); 292 at91_add_device_nand(&ek_nand_data);
231 /* I2C */ 293 /* I2C */
232 at91_add_device_i2c(); 294 at91_add_device_i2c();
295 /* LCD Controller */
296 at91_add_device_lcdc(&ek_lcdc_data);
233 /* AC97 */ 297 /* AC97 */
234 at91_add_device_ac97(&ek_ac97_data); 298 at91_add_device_ac97(&ek_ac97_data);
235} 299}
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index a8f88cd2990..99ac2e55774 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -4,7 +4,8 @@
4# 4#
5 5
6# Common objects 6# Common objects
7obj-y := time.o irq.o serial.o io.o id.o psc.o 7obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o \
8 gpio.o mux.o
8 9
9# Board specific 10# Board specific
10obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o 11obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o
diff --git a/arch/arm/mach-davinci/board-evm.c b/arch/arm/mach-davinci/board-evm.c
index 633c12e4304..9e4024c4965 100644
--- a/arch/arm/mach-davinci/board-evm.c
+++ b/arch/arm/mach-davinci/board-evm.c
@@ -32,6 +32,7 @@
32void __init davinci_psc_init(void); 32void __init davinci_psc_init(void);
33void __init davinci_irq_init(void); 33void __init davinci_irq_init(void);
34void __init davinci_map_common_io(void); 34void __init davinci_map_common_io(void);
35void __init davinci_init_common_hw(void);
35 36
36/* NOR Flash base address set to CS0 by default */ 37/* NOR Flash base address set to CS0 by default */
37#define NOR_FLASH_PHYS 0x02000000 38#define NOR_FLASH_PHYS 0x02000000
@@ -116,6 +117,7 @@ static __init void davinci_evm_init(void)
116 117
117static __init void davinci_evm_irq_init(void) 118static __init void davinci_evm_irq_init(void)
118{ 119{
120 davinci_init_common_hw();
119 davinci_irq_init(); 121 davinci_irq_init();
120} 122}
121 123
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
new file mode 100644
index 00000000000..139ceaa35e2
--- /dev/null
+++ b/arch/arm/mach-davinci/clock.c
@@ -0,0 +1,323 @@
1/*
2 * TI DaVinci clock config file
3 *
4 * Copyright (C) 2006 Texas Instruments.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/errno.h>
16#include <linux/err.h>
17#include <linux/mutex.h>
18#include <linux/platform_device.h>
19
20#include <asm/hardware.h>
21#include <asm/io.h>
22
23#include <asm/arch/psc.h>
24#include "clock.h"
25
26/* PLL/Reset register offsets */
27#define PLLM 0x110
28
29static LIST_HEAD(clocks);
30static DEFINE_MUTEX(clocks_mutex);
31static DEFINE_SPINLOCK(clockfw_lock);
32
33static unsigned int commonrate;
34static unsigned int armrate;
35static unsigned int fixedrate = 27000000; /* 27 MHZ */
36
37extern void davinci_psc_config(unsigned int domain, unsigned int id, char enable);
38
39/*
40 * Returns a clock. Note that we first try to use device id on the bus
41 * and clock name. If this fails, we try to use clock name only.
42 */
43struct clk *clk_get(struct device *dev, const char *id)
44{
45 struct clk *p, *clk = ERR_PTR(-ENOENT);
46 int idno;
47
48 if (dev == NULL || dev->bus != &platform_bus_type)
49 idno = -1;
50 else
51 idno = to_platform_device(dev)->id;
52
53 mutex_lock(&clocks_mutex);
54
55 list_for_each_entry(p, &clocks, node) {
56 if (p->id == idno &&
57 strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
58 clk = p;
59 goto found;
60 }
61 }
62
63 list_for_each_entry(p, &clocks, node) {
64 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
65 clk = p;
66 break;
67 }
68 }
69
70found:
71 mutex_unlock(&clocks_mutex);
72
73 return clk;
74}
75EXPORT_SYMBOL(clk_get);
76
77void clk_put(struct clk *clk)
78{
79 if (clk && !IS_ERR(clk))
80 module_put(clk->owner);
81}
82EXPORT_SYMBOL(clk_put);
83
84static int __clk_enable(struct clk *clk)
85{
86 if (clk->flags & ALWAYS_ENABLED)
87 return 0;
88
89 davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 1);
90 return 0;
91}
92
93static void __clk_disable(struct clk *clk)
94{
95 if (clk->usecount)
96 return;
97
98 davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, clk->lpsc, 0);
99}
100
101int clk_enable(struct clk *clk)
102{
103 unsigned long flags;
104 int ret = 0;
105
106 if (clk == NULL || IS_ERR(clk))
107 return -EINVAL;
108
109 if (clk->usecount++ == 0) {
110 spin_lock_irqsave(&clockfw_lock, flags);
111 ret = __clk_enable(clk);
112 spin_unlock_irqrestore(&clockfw_lock, flags);
113 }
114
115 return ret;
116}
117EXPORT_SYMBOL(clk_enable);
118
119void clk_disable(struct clk *clk)
120{
121 unsigned long flags;
122
123 if (clk == NULL || IS_ERR(clk))
124 return;
125
126 if (clk->usecount > 0 && !(--clk->usecount)) {
127 spin_lock_irqsave(&clockfw_lock, flags);
128 __clk_disable(clk);
129 spin_unlock_irqrestore(&clockfw_lock, flags);
130 }
131}
132EXPORT_SYMBOL(clk_disable);
133
134unsigned long clk_get_rate(struct clk *clk)
135{
136 if (clk == NULL || IS_ERR(clk))
137 return -EINVAL;
138
139 return *(clk->rate);
140}
141EXPORT_SYMBOL(clk_get_rate);
142
143long clk_round_rate(struct clk *clk, unsigned long rate)
144{
145 if (clk == NULL || IS_ERR(clk))
146 return -EINVAL;
147
148 return *(clk->rate);
149}
150EXPORT_SYMBOL(clk_round_rate);
151
152int clk_set_rate(struct clk *clk, unsigned long rate)
153{
154 if (clk == NULL || IS_ERR(clk))
155 return -EINVAL;
156
157 /* changing the clk rate is not supported */
158 return -EINVAL;
159}
160EXPORT_SYMBOL(clk_set_rate);
161
162int clk_register(struct clk *clk)
163{
164 if (clk == NULL || IS_ERR(clk))
165 return -EINVAL;
166
167 mutex_lock(&clocks_mutex);
168 list_add(&clk->node, &clocks);
169 mutex_unlock(&clocks_mutex);
170
171 return 0;
172}
173EXPORT_SYMBOL(clk_register);
174
175void clk_unregister(struct clk *clk)
176{
177 if (clk == NULL || IS_ERR(clk))
178 return;
179
180 mutex_lock(&clocks_mutex);
181 list_del(&clk->node);
182 mutex_unlock(&clocks_mutex);
183}
184EXPORT_SYMBOL(clk_unregister);
185
186static struct clk davinci_clks[] = {
187 {
188 .name = "ARMCLK",
189 .rate = &armrate,
190 .lpsc = -1,
191 .flags = ALWAYS_ENABLED,
192 },
193 {
194 .name = "UART",
195 .rate = &fixedrate,
196 .lpsc = DAVINCI_LPSC_UART0,
197 },
198 {
199 .name = "EMACCLK",
200 .rate = &commonrate,
201 .lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
202 },
203 {
204 .name = "I2CCLK",
205 .rate = &fixedrate,
206 .lpsc = DAVINCI_LPSC_I2C,
207 },
208 {
209 .name = "IDECLK",
210 .rate = &commonrate,
211 .lpsc = DAVINCI_LPSC_ATA,
212 },
213 {
214 .name = "McBSPCLK",
215 .rate = &commonrate,
216 .lpsc = DAVINCI_LPSC_McBSP,
217 },
218 {
219 .name = "MMCSDCLK",
220 .rate = &commonrate,
221 .lpsc = DAVINCI_LPSC_MMC_SD,
222 },
223 {
224 .name = "SPICLK",
225 .rate = &commonrate,
226 .lpsc = DAVINCI_LPSC_SPI,
227 },
228 {
229 .name = "gpio",
230 .rate = &commonrate,
231 .lpsc = DAVINCI_LPSC_GPIO,
232 },
233 {
234 .name = "AEMIFCLK",
235 .rate = &commonrate,
236 .lpsc = DAVINCI_LPSC_AEMIF,
237 .usecount = 1,
238 }
239};
240
241int __init davinci_clk_init(void)
242{
243 struct clk *clkp;
244 int count = 0;
245 u32 pll_mult;
246
247 pll_mult = davinci_readl(DAVINCI_PLL_CNTRL0_BASE + PLLM);
248 commonrate = ((pll_mult + 1) * 27000000) / 6;
249 armrate = ((pll_mult + 1) * 27000000) / 2;
250
251 for (clkp = davinci_clks; count < ARRAY_SIZE(davinci_clks);
252 count++, clkp++) {
253 clk_register(clkp);
254
255 /* Turn on clocks that have been enabled in the
256 * table above */
257 if (clkp->usecount)
258 clk_enable(clkp);
259 }
260
261 return 0;
262}
263
264#ifdef CONFIG_PROC_FS
265#include <linux/proc_fs.h>
266#include <linux/seq_file.h>
267
268static void *davinci_ck_start(struct seq_file *m, loff_t *pos)
269{
270 return *pos < 1 ? (void *)1 : NULL;
271}
272
273static void *davinci_ck_next(struct seq_file *m, void *v, loff_t *pos)
274{
275 ++*pos;
276 return NULL;
277}
278
279static void davinci_ck_stop(struct seq_file *m, void *v)
280{
281}
282
283static int davinci_ck_show(struct seq_file *m, void *v)
284{
285 struct clk *cp;
286
287 list_for_each_entry(cp, &clocks, node)
288 seq_printf(m,"%s %d %d\n", cp->name, *(cp->rate), cp->usecount);
289
290 return 0;
291}
292
293static struct seq_operations davinci_ck_op = {
294 .start = davinci_ck_start,
295 .next = davinci_ck_next,
296 .stop = davinci_ck_stop,
297 .show = davinci_ck_show
298};
299
300static int davinci_ck_open(struct inode *inode, struct file *file)
301{
302 return seq_open(file, &davinci_ck_op);
303}
304
305static struct file_operations proc_davinci_ck_operations = {
306 .open = davinci_ck_open,
307 .read = seq_read,
308 .llseek = seq_lseek,
309 .release = seq_release,
310};
311
312static int __init davinci_ck_proc_init(void)
313{
314 struct proc_dir_entry *entry;
315
316 entry = create_proc_entry("davinci_clocks", 0, NULL);
317 if (entry)
318 entry->proc_fops = &proc_davinci_ck_operations;
319 return 0;
320
321}
322__initcall(davinci_ck_proc_init);
323#endif /* CONFIG_DEBUG_PROC_FS */
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
new file mode 100644
index 00000000000..ed47079a52e
--- /dev/null
+++ b/arch/arm/mach-davinci/clock.h
@@ -0,0 +1,33 @@
1/*
2 * TI DaVinci clock definitions
3 *
4 * Copyright (C) 2006 Texas Instruments.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __ARCH_ARM_DAVINCI_CLOCK_H
12#define __ARCH_ARM_DAVINCI_CLOCK_H
13
14struct clk {
15 struct list_head node;
16 struct module *owner;
17 const char *name;
18 unsigned int *rate;
19 int id;
20 __s8 usecount;
21 __u8 flags;
22 __u8 lpsc;
23};
24
25/* Clock flags */
26#define RATE_CKCTL 1
27#define RATE_FIXED 2
28#define RATE_PROPAGATES 4
29#define VIRTUAL_CLOCK 8
30#define ALWAYS_ENABLED 16
31#define ENABLE_REG_32BIT 32
32
33#endif
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
new file mode 100644
index 00000000000..9c67886e718
--- /dev/null
+++ b/arch/arm/mach-davinci/gpio.c
@@ -0,0 +1,286 @@
1/*
2 * TI DaVinci GPIO Support
3 *
4 * Copyright (c) 2006 David Brownell
5 * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/errno.h>
14#include <linux/kernel.h>
15#include <linux/list.h>
16#include <linux/module.h>
17#include <linux/clk.h>
18#include <linux/err.h>
19#include <linux/io.h>
20#include <linux/irq.h>
21#include <linux/bitops.h>
22
23#include <asm/arch/irqs.h>
24#include <asm/arch/hardware.h>
25#include <asm/arch/gpio.h>
26
27#include <asm/mach/irq.h>
28
29static DEFINE_SPINLOCK(gpio_lock);
30static DECLARE_BITMAP(gpio_in_use, DAVINCI_N_GPIO);
31
32int gpio_request(unsigned gpio, const char *tag)
33{
34 if (gpio >= DAVINCI_N_GPIO)
35 return -EINVAL;
36
37 if (test_and_set_bit(gpio, gpio_in_use))
38 return -EBUSY;
39
40 return 0;
41}
42EXPORT_SYMBOL(gpio_request);
43
44void gpio_free(unsigned gpio)
45{
46 if (gpio >= DAVINCI_N_GPIO)
47 return;
48
49 clear_bit(gpio, gpio_in_use);
50}
51EXPORT_SYMBOL(gpio_free);
52
53/* create a non-inlined version */
54static struct gpio_controller *__iomem gpio2controller(unsigned gpio)
55{
56 return __gpio_to_controller(gpio);
57}
58
59/*
60 * Assuming the pin is muxed as a gpio output, set its output value.
61 */
62void __gpio_set(unsigned gpio, int value)
63{
64 struct gpio_controller *__iomem g = gpio2controller(gpio);
65
66 __raw_writel(__gpio_mask(gpio), value ? &g->set_data : &g->clr_data);
67}
68EXPORT_SYMBOL(__gpio_set);
69
70
71/*
72 * Read the pin's value (works even if it's set up as output);
73 * returns zero/nonzero.
74 *
75 * Note that changes are synched to the GPIO clock, so reading values back
76 * right after you've set them may give old values.
77 */
78int __gpio_get(unsigned gpio)
79{
80 struct gpio_controller *__iomem g = gpio2controller(gpio);
81
82 return !!(__gpio_mask(gpio) & __raw_readl(&g->in_data));
83}
84EXPORT_SYMBOL(__gpio_get);
85
86
87/*--------------------------------------------------------------------------*/
88
89/*
90 * board setup code *MUST* set PINMUX0 and PINMUX1 as
91 * needed, and enable the GPIO clock.
92 */
93
94int gpio_direction_input(unsigned gpio)
95{
96 struct gpio_controller *__iomem g = gpio2controller(gpio);
97 u32 temp;
98 u32 mask;
99
100 if (!g)
101 return -EINVAL;
102
103 spin_lock(&gpio_lock);
104 mask = __gpio_mask(gpio);
105 temp = __raw_readl(&g->dir);
106 temp |= mask;
107 __raw_writel(temp, &g->dir);
108 spin_unlock(&gpio_lock);
109 return 0;
110}
111EXPORT_SYMBOL(gpio_direction_input);
112
113int gpio_direction_output(unsigned gpio, int value)
114{
115 struct gpio_controller *__iomem g = gpio2controller(gpio);
116 u32 temp;
117 u32 mask;
118
119 if (!g)
120 return -EINVAL;
121
122 spin_lock(&gpio_lock);
123 mask = __gpio_mask(gpio);
124 temp = __raw_readl(&g->dir);
125 temp &= ~mask;
126 __raw_writel(mask, value ? &g->set_data : &g->clr_data);
127 __raw_writel(temp, &g->dir);
128 spin_unlock(&gpio_lock);
129 return 0;
130}
131EXPORT_SYMBOL(gpio_direction_output);
132
133/*
134 * We expect irqs will normally be set up as input pins, but they can also be
135 * used as output pins ... which is convenient for testing.
136 *
137 * NOTE: GPIO0..GPIO7 also have direct INTC hookups, which work in addition
138 * to their GPIOBNK0 irq (but with a bit less overhead). But we don't have
139 * a good way to hook those up ...
140 *
141 * All those INTC hookups (GPIO0..GPIO7 plus five IRQ banks) can also
142 * serve as EDMA event triggers.
143 */
144
145static void gpio_irq_disable(unsigned irq)
146{
147 struct gpio_controller *__iomem g = get_irq_chip_data(irq);
148 u32 mask = __gpio_mask(irq_to_gpio(irq));
149
150 __raw_writel(mask, &g->clr_falling);
151 __raw_writel(mask, &g->clr_rising);
152}
153
154static void gpio_irq_enable(unsigned irq)
155{
156 struct gpio_controller *__iomem g = get_irq_chip_data(irq);
157 u32 mask = __gpio_mask(irq_to_gpio(irq));
158
159 if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING)
160 __raw_writel(mask, &g->set_falling);
161 if (irq_desc[irq].status & IRQ_TYPE_EDGE_RISING)
162 __raw_writel(mask, &g->set_rising);
163}
164
165static int gpio_irq_type(unsigned irq, unsigned trigger)
166{
167 struct gpio_controller *__iomem g = get_irq_chip_data(irq);
168 u32 mask = __gpio_mask(irq_to_gpio(irq));
169
170 if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
171 return -EINVAL;
172
173 irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
174 irq_desc[irq].status |= trigger;
175
176 __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
177 ? &g->set_falling : &g->clr_falling);
178 __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
179 ? &g->set_rising : &g->clr_rising);
180 return 0;
181}
182
183static struct irq_chip gpio_irqchip = {
184 .name = "GPIO",
185 .enable = gpio_irq_enable,
186 .disable = gpio_irq_disable,
187 .set_type = gpio_irq_type,
188};
189
190static void
191gpio_irq_handler(unsigned irq, struct irq_desc *desc)
192{
193 struct gpio_controller *__iomem g = get_irq_chip_data(irq);
194 u32 mask = 0xffff;
195
196 /* we only care about one bank */
197 if (irq & 1)
198 mask <<= 16;
199
200 /* temporarily mask (level sensitive) parent IRQ */
201 desc->chip->ack(irq);
202 while (1) {
203 u32 status;
204 struct irq_desc *gpio;
205 int n;
206 int res;
207
208 /* ack any irqs */
209 status = __raw_readl(&g->intstat) & mask;
210 if (!status)
211 break;
212 __raw_writel(status, &g->intstat);
213 if (irq & 1)
214 status >>= 16;
215
216 /* now demux them to the right lowlevel handler */
217 n = (int)get_irq_data(irq);
218 gpio = &irq_desc[n];
219 while (status) {
220 res = ffs(status);
221 n += res;
222 gpio += res;
223 desc_handle_irq(n - 1, gpio - 1);
224 status >>= res;
225 }
226 }
227 desc->chip->unmask(irq);
228 /* now it may re-trigger */
229}
230
231/*
232 * NOTE: for suspend/resume, probably best to make a sysdev (and class)
233 * with its suspend/resume calls hooking into the results of the set_wake()
234 * calls ... so if no gpios are wakeup events the clock can be disabled,
235 * with outputs left at previously set levels, and so that VDD3P3V.IOPWDN0
236 * can be set appropriately for GPIOV33 pins.
237 */
238
239static int __init davinci_gpio_irq_setup(void)
240{
241 unsigned gpio, irq, bank;
242 struct clk *clk;
243
244 clk = clk_get(NULL, "gpio");
245 if (IS_ERR(clk)) {
246 printk(KERN_ERR "Error %ld getting gpio clock?\n",
247 PTR_ERR(clk));
248 return 0;
249 }
250
251 clk_enable(clk);
252
253 for (gpio = 0, irq = gpio_to_irq(0), bank = IRQ_GPIOBNK0;
254 gpio < DAVINCI_N_GPIO; bank++) {
255 struct gpio_controller *__iomem g = gpio2controller(gpio);
256 unsigned i;
257
258 __raw_writel(~0, &g->clr_falling);
259 __raw_writel(~0, &g->clr_rising);
260
261 /* set up all irqs in this bank */
262 set_irq_chained_handler(bank, gpio_irq_handler);
263 set_irq_chip_data(bank, g);
264 set_irq_data(bank, (void *)irq);
265
266 for (i = 0; i < 16 && gpio < DAVINCI_N_GPIO;
267 i++, irq++, gpio++) {
268 set_irq_chip(irq, &gpio_irqchip);
269 set_irq_chip_data(irq, g);
270 set_irq_handler(irq, handle_simple_irq);
271 set_irq_flags(irq, IRQF_VALID);
272 }
273 }
274
275 /* BINTEN -- per-bank interrupt enable. genirq would also let these
276 * bits be set/cleared dynamically.
277 */
278 __raw_writel(0x1f, (void *__iomem)
279 IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08));
280
281 printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
282
283 return 0;
284}
285
286arch_initcall(davinci_gpio_irq_setup);
diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c
index 87fae6fb6ec..47787ff84a6 100644
--- a/arch/arm/mach-davinci/io.c
+++ b/arch/arm/mach-davinci/io.c
@@ -17,6 +17,7 @@
17#include <asm/memory.h> 17#include <asm/memory.h>
18 18
19#include <asm/mach/map.h> 19#include <asm/mach/map.h>
20#include <asm/arch/clock.h>
20 21
21extern void davinci_check_revision(void); 22extern void davinci_check_revision(void);
22 23
@@ -49,3 +50,8 @@ void __init davinci_map_common_io(void)
49 */ 50 */
50 davinci_check_revision(); 51 davinci_check_revision();
51} 52}
53
54void __init davinci_init_common_hw(void)
55{
56 davinci_clk_init();
57}
diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c
new file mode 100644
index 00000000000..92d26bd305b
--- /dev/null
+++ b/arch/arm/mach-davinci/mux.c
@@ -0,0 +1,41 @@
1/*
2 * DaVinci pin multiplexing configurations
3 *
4 * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
5 *
6 * 2007 (c) MontaVista Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 */
11#include <linux/io.h>
12#include <linux/spinlock.h>
13
14#include <asm/hardware.h>
15
16#include <asm/arch/mux.h>
17
18/* System control register offsets */
19#define PINMUX0 0x00
20#define PINMUX1 0x04
21
22static DEFINE_SPINLOCK(mux_lock);
23
24void davinci_mux_peripheral(unsigned int mux, unsigned int enable)
25{
26 u32 pinmux, muxreg = PINMUX0;
27
28 if (mux >= DAVINCI_MUX_LEVEL2) {
29 muxreg = PINMUX1;
30 mux -= DAVINCI_MUX_LEVEL2;
31 }
32
33 spin_lock(&mux_lock);
34 pinmux = davinci_readl(DAVINCI_SYSTEM_MODULE_BASE + muxreg);
35 if (enable)
36 pinmux |= (1 << mux);
37 else
38 pinmux &= ~(1 << mux);
39 davinci_writel(pinmux, DAVINCI_SYSTEM_MODULE_BASE + muxreg);
40 spin_unlock(&mux_lock);
41}
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
index e1b0050283a..1334416559a 100644
--- a/arch/arm/mach-davinci/psc.c
+++ b/arch/arm/mach-davinci/psc.c
@@ -25,39 +25,40 @@
25#include <asm/io.h> 25#include <asm/io.h>
26#include <asm/hardware.h> 26#include <asm/hardware.h>
27#include <asm/arch/psc.h> 27#include <asm/arch/psc.h>
28#include <asm/arch/mux.h>
28 29
29#define PTCMD __REG(0x01C41120) 30/* PSC register offsets */
30#define PDSTAT __REG(0x01C41200) 31#define EPCPR 0x070
31#define PDCTL1 __REG(0x01C41304) 32#define PTCMD 0x120
32#define EPCPR __REG(0x01C41070) 33#define PTSTAT 0x128
33#define PTSTAT __REG(0x01C41128) 34#define PDSTAT 0x200
35#define PDCTL1 0x304
36#define MDSTAT 0x800
37#define MDCTL 0xA00
34 38
35#define MDSTAT IO_ADDRESS(0x01C41800) 39/* System control register offsets */
36#define MDCTL IO_ADDRESS(0x01C41A00) 40#define VDD3P3V_PWDN 0x48
37
38#define PINMUX0 __REG(0x01c40000)
39#define PINMUX1 __REG(0x01c40004)
40#define VDD3P3V_PWDN __REG(0x01C40048)
41 41
42static void davinci_psc_mux(unsigned int id) 42static void davinci_psc_mux(unsigned int id)
43{ 43{
44 switch (id) { 44 switch (id) {
45 case DAVINCI_LPSC_ATA: 45 case DAVINCI_LPSC_ATA:
46 PINMUX0 |= (1 << 17) | (1 << 16); 46 davinci_mux_peripheral(DAVINCI_MUX_HDIREN, 1);
47 davinci_mux_peripheral(DAVINCI_MUX_ATAEN, 1);
47 break; 48 break;
48 case DAVINCI_LPSC_MMC_SD: 49 case DAVINCI_LPSC_MMC_SD:
49 /* VDD power manupulations are done in U-Boot for CPMAC 50 /* VDD power manupulations are done in U-Boot for CPMAC
50 * so applies to MMC as well 51 * so applies to MMC as well
51 */ 52 */
52 /*Set up the pull regiter for MMC */ 53 /*Set up the pull regiter for MMC */
53 VDD3P3V_PWDN = 0x0; 54 davinci_writel(0, DAVINCI_SYSTEM_MODULE_BASE + VDD3P3V_PWDN);
54 PINMUX1 &= (~(1 << 9)); 55 davinci_mux_peripheral(DAVINCI_MUX_MSTK, 0);
55 break; 56 break;
56 case DAVINCI_LPSC_I2C: 57 case DAVINCI_LPSC_I2C:
57 PINMUX1 |= (1 << 7); 58 davinci_mux_peripheral(DAVINCI_MUX_I2C, 1);
58 break; 59 break;
59 case DAVINCI_LPSC_McBSP: 60 case DAVINCI_LPSC_McBSP:
60 PINMUX1 |= (1 << 10); 61 davinci_mux_peripheral(DAVINCI_MUX_ASP, 1);
61 break; 62 break;
62 default: 63 default:
63 break; 64 break;
@@ -67,33 +68,59 @@ static void davinci_psc_mux(unsigned int id)
67/* Enable or disable a PSC domain */ 68/* Enable or disable a PSC domain */
68void davinci_psc_config(unsigned int domain, unsigned int id, char enable) 69void davinci_psc_config(unsigned int domain, unsigned int id, char enable)
69{ 70{
70 volatile unsigned int *mdstat = (unsigned int *)((int)MDSTAT + 4 * id); 71 u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl, mdstat_mask;
71 volatile unsigned int *mdctl = (unsigned int *)((int)MDCTL + 4 * id);
72 72
73 if (id < 0) 73 if (id < 0)
74 return; 74 return;
75 75
76 mdctl = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
76 if (enable) 77 if (enable)
77 *mdctl |= 0x00000003; /* Enable Module */ 78 mdctl |= 0x00000003; /* Enable Module */
78 else 79 else
79 *mdctl &= 0xFFFFFFF2; /* Disable Module */ 80 mdctl &= 0xFFFFFFF2; /* Disable Module */
81 davinci_writel(mdctl, DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
82
83 pdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDSTAT);
84 if ((pdstat & 0x00000001) == 0) {
85 pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
86 pdctl1 |= 0x1;
87 davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
88
89 ptcmd = 1 << domain;
90 davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
80 91
81 if ((PDSTAT & 0x00000001) == 0) { 92 do {
82 PDCTL1 |= 0x1; 93 epcpr = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
83 PTCMD = (1 << domain); 94 EPCPR);
84 while ((((EPCPR >> domain) & 1) == 0)); 95 } while ((((epcpr >> domain) & 1) == 0));
85 96
86 PDCTL1 |= 0x100; 97 pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
87 while (!(((PTSTAT >> domain) & 1) == 0)); 98 pdctl1 |= 0x100;
99 davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
100
101 do {
102 ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
103 PTSTAT);
104 } while (!(((ptstat >> domain) & 1) == 0));
88 } else { 105 } else {
89 PTCMD = (1 << domain); 106 ptcmd = 1 << domain;
90 while (!(((PTSTAT >> domain) & 1) == 0)); 107 davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
108
109 do {
110 ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
111 PTSTAT);
112 } while (!(((ptstat >> domain) & 1) == 0));
91 } 113 }
92 114
93 if (enable) 115 if (enable)
94 while (!((*mdstat & 0x0000001F) == 0x3)); 116 mdstat_mask = 0x3;
95 else 117 else
96 while (!((*mdstat & 0x0000001F) == 0x2)); 118 mdstat_mask = 0x2;
119
120 do {
121 mdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
122 MDSTAT + 4 * id);
123 } while (!((mdstat & 0x0000001F) == mdstat_mask));
97 124
98 if (enable) 125 if (enable)
99 davinci_psc_mux(id); 126 davinci_psc_mux(id);
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c
index 1c474cf709c..a58b678006d 100644
--- a/arch/arm/mach-imx/generic.c
+++ b/arch/arm/mach-imx/generic.c
@@ -28,12 +28,16 @@
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/string.h> 29#include <linux/string.h>
30 30
31#include <asm/errno.h>
31#include <asm/arch/imxfb.h> 32#include <asm/arch/imxfb.h>
32#include <asm/hardware.h> 33#include <asm/hardware.h>
33#include <asm/arch/imx-regs.h> 34#include <asm/arch/imx-regs.h>
34 35
35#include <asm/mach/map.h> 36#include <asm/mach/map.h>
36#include <asm/arch/mmc.h> 37#include <asm/arch/mmc.h>
38#include <asm/arch/gpio.h>
39
40unsigned long imx_gpio_alloc_map[(GPIO_PORT_MAX + 1) * 32 / BITS_PER_LONG];
37 41
38void imx_gpio_mode(int gpio_mode) 42void imx_gpio_mode(int gpio_mode)
39{ 43{
@@ -95,6 +99,120 @@ void imx_gpio_mode(int gpio_mode)
95 99
96EXPORT_SYMBOL(imx_gpio_mode); 100EXPORT_SYMBOL(imx_gpio_mode);
97 101
102int imx_gpio_request(unsigned gpio, const char *label)
103{
104 if(gpio >= (GPIO_PORT_MAX + 1) * 32)
105 printk(KERN_ERR "imx_gpio: Attempt to request nonexistent GPIO %d for \"%s\"\n",
106 gpio, label ? label : "?");
107 return -EINVAL;
108
109 if(test_and_set_bit(gpio, imx_gpio_alloc_map)) {
110 printk(KERN_ERR "imx_gpio: GPIO %d already used. Allocation for \"%s\" failed\n",
111 gpio, label ? label : "?");
112 return -EBUSY;
113 }
114
115 return 0;
116}
117
118EXPORT_SYMBOL(imx_gpio_request);
119
120void imx_gpio_free(unsigned gpio)
121{
122 if(gpio >= (GPIO_PORT_MAX + 1) * 32)
123 return;
124
125 clear_bit(gpio, imx_gpio_alloc_map);
126}
127
128EXPORT_SYMBOL(imx_gpio_free);
129
130int imx_gpio_direction_input(unsigned gpio)
131{
132 imx_gpio_mode(gpio| GPIO_IN);
133 return 0;
134}
135
136EXPORT_SYMBOL(imx_gpio_direction_input);
137
138int imx_gpio_direction_output(unsigned gpio, int value)
139{
140 imx_gpio_set_value(gpio, value);
141 imx_gpio_mode(gpio| GPIO_OUT);
142 return 0;
143}
144
145EXPORT_SYMBOL(imx_gpio_direction_output);
146
147int imx_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
148 int alloc_mode, const char *label)
149{
150 const int *p = pin_list;
151 int i;
152 unsigned gpio;
153 unsigned mode;
154
155 for (i = 0; i < count; i++) {
156 gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK);
157 mode = *p & ~(GPIO_PIN_MASK | GPIO_PORT_MASK);
158
159 if (gpio >= (GPIO_PORT_MAX + 1) * 32)
160 goto setup_error;
161
162 if (alloc_mode & IMX_GPIO_ALLOC_MODE_RELEASE)
163 imx_gpio_free(gpio);
164 else if (!(alloc_mode & IMX_GPIO_ALLOC_MODE_NO_ALLOC))
165 if (imx_gpio_request(gpio, label))
166 if (!(alloc_mode & IMX_GPIO_ALLOC_MODE_TRY_ALLOC))
167 goto setup_error;
168
169 if (!(alloc_mode & (IMX_GPIO_ALLOC_MODE_ALLOC_ONLY |
170 IMX_GPIO_ALLOC_MODE_RELEASE)))
171 imx_gpio_mode(gpio | mode);
172
173 p++;
174 }
175 return 0;
176
177setup_error:
178 if(alloc_mode & (IMX_GPIO_ALLOC_MODE_NO_ALLOC |
179 IMX_GPIO_ALLOC_MODE_TRY_ALLOC))
180 return -EINVAL;
181
182 while (p != pin_list) {
183 p--;
184 gpio = *p & (GPIO_PIN_MASK | GPIO_PORT_MASK);
185 imx_gpio_free(gpio);
186 }
187
188 return -EINVAL;
189}
190
191EXPORT_SYMBOL(imx_gpio_setup_multiple_pins);
192
193void __imx_gpio_set_value(unsigned gpio, int value)
194{
195 imx_gpio_set_value_inline(gpio, value);
196}
197
198EXPORT_SYMBOL(__imx_gpio_set_value);
199
200int imx_gpio_to_irq(unsigned gpio)
201{
202 return IRQ_GPIOA(0) + gpio;
203}
204
205EXPORT_SYMBOL(imx_gpio_to_irq);
206
207int imx_irq_to_gpio(unsigned irq)
208{
209 if (irq < IRQ_GPIOA(0))
210 return -EINVAL;
211 return irq - IRQ_GPIOA(0);
212}
213
214EXPORT_SYMBOL(imx_irq_to_gpio);
215
98/* 216/*
99 * get the system pll clock in Hz 217 * get the system pll clock in Hz
100 * 218 *
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 6960a9d0421..010f6fa984a 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (C) 2000-2001 Deep Blue Solutions 4 * Copyright (C) 2000-2001 Deep Blue Solutions
5 * Copyright (C) 2002 Shane Nay (shane@minirl.com) 5 * Copyright (C) 2002 Shane Nay (shane@minirl.com)
6 * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -15,6 +16,7 @@
15#include <linux/irq.h> 16#include <linux/irq.h>
16#include <linux/time.h> 17#include <linux/time.h>
17#include <linux/clocksource.h> 18#include <linux/clocksource.h>
19#include <linux/clockchips.h>
18 20
19#include <asm/hardware.h> 21#include <asm/hardware.h>
20#include <asm/io.h> 22#include <asm/io.h>
@@ -25,7 +27,8 @@
25/* Use timer 1 as system timer */ 27/* Use timer 1 as system timer */
26#define TIMER_BASE IMX_TIM1_BASE 28#define TIMER_BASE IMX_TIM1_BASE
27 29
28static unsigned long evt_diff; 30static struct clock_event_device clockevent_imx;
31static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
29 32
30/* 33/*
31 * IRQ handler for the timer 34 * IRQ handler for the timer
@@ -33,25 +36,20 @@ static unsigned long evt_diff;
33static irqreturn_t 36static irqreturn_t
34imx_timer_interrupt(int irq, void *dev_id) 37imx_timer_interrupt(int irq, void *dev_id)
35{ 38{
39 struct clock_event_device *evt = &clockevent_imx;
36 uint32_t tstat; 40 uint32_t tstat;
41 irqreturn_t ret = IRQ_NONE;
37 42
38 /* clear the interrupt */ 43 /* clear the interrupt */
39 tstat = IMX_TSTAT(TIMER_BASE); 44 tstat = IMX_TSTAT(TIMER_BASE);
40 IMX_TSTAT(TIMER_BASE) = 0; 45 IMX_TSTAT(TIMER_BASE) = 0;
41 46
42 if (tstat & TSTAT_COMP) { 47 if (tstat & TSTAT_COMP) {
43 do { 48 evt->event_handler(evt);
44 49 ret = IRQ_HANDLED;
45 write_seqlock(&xtime_lock);
46 timer_tick();
47 write_sequnlock(&xtime_lock);
48 IMX_TCMP(TIMER_BASE) += evt_diff;
49
50 } while (unlikely((int32_t)(IMX_TCMP(TIMER_BASE)
51 - IMX_TCN(TIMER_BASE)) < 0));
52 } 50 }
53 51
54 return IRQ_HANDLED; 52 return ret;
55} 53}
56 54
57static struct irqaction imx_timer_irq = { 55static struct irqaction imx_timer_irq = {
@@ -70,10 +68,8 @@ static void __init imx_timer_hardware_init(void)
70 */ 68 */
71 IMX_TCTL(TIMER_BASE) = 0; 69 IMX_TCTL(TIMER_BASE) = 0;
72 IMX_TPRER(TIMER_BASE) = 0; 70 IMX_TPRER(TIMER_BASE) = 0;
73 IMX_TCMP(TIMER_BASE) = LATCH - 1;
74 71
75 IMX_TCTL(TIMER_BASE) = TCTL_FRR | TCTL_CLK_PCLK1 | TCTL_IRQEN | TCTL_TEN; 72 IMX_TCTL(TIMER_BASE) = TCTL_FRR | TCTL_CLK_PCLK1 | TCTL_TEN;
76 evt_diff = LATCH;
77} 73}
78 74
79cycle_t imx_get_cycles(void) 75cycle_t imx_get_cycles(void)
@@ -99,11 +95,108 @@ static int __init imx_clocksource_init(void)
99 return 0; 95 return 0;
100} 96}
101 97
98static int imx_set_next_event(unsigned long evt,
99 struct clock_event_device *unused)
100{
101 unsigned long tcmp;
102
103 tcmp = IMX_TCN(TIMER_BASE) + evt;
104 IMX_TCMP(TIMER_BASE) = tcmp;
105
106 return (int32_t)(tcmp - IMX_TCN(TIMER_BASE)) < 0 ? -ETIME : 0;
107}
108
109#ifdef DEBUG
110static const char *clock_event_mode_label[]={
111 [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
112 [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
113 [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
114 [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
115};
116#endif /*DEBUG*/
117
118static void imx_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
119{
120 unsigned long flags;
121
122 /*
123 * The timer interrupt generation is disabled at least
124 * for enough time to call imx_set_next_event()
125 */
126 local_irq_save(flags);
127 /* Disable interrupt in GPT module */
128 IMX_TCTL(TIMER_BASE) &= ~TCTL_IRQEN;
129 if (mode != clockevent_mode) {
130 /* Set event time into far-far future */
131 IMX_TCMP(TIMER_BASE) = IMX_TCN(TIMER_BASE) - 3;
132 /* Clear pending interrupt */
133 IMX_TSTAT(TIMER_BASE) &= ~TSTAT_COMP;
134 }
135
136#ifdef DEBUG
137 printk(KERN_INFO "imx_set_mode: changing mode from %s to %s\n",
138 clock_event_mode_label[clockevent_mode], clock_event_mode_label[mode]);
139#endif /*DEBUG*/
140
141 /* Remember timer mode */
142 clockevent_mode = mode;
143 local_irq_restore(flags);
144
145 switch (mode) {
146 case CLOCK_EVT_MODE_PERIODIC:
147 printk(KERN_ERR "imx_set_mode: Periodic mode is not supported for i.MX\n");
148 break;
149 case CLOCK_EVT_MODE_ONESHOT:
150 /*
151 * Do not put overhead of interrupt enable/disable into
152 * imx_set_next_event(), the core has about 4 minutes
153 * to call imx_set_next_event() or shutdown clock after
154 * mode switching
155 */
156 local_irq_save(flags);
157 IMX_TCTL(TIMER_BASE) |= TCTL_IRQEN;
158 local_irq_restore(flags);
159 break;
160 case CLOCK_EVT_MODE_SHUTDOWN:
161 case CLOCK_EVT_MODE_UNUSED:
162 /* Left event sources disabled, no more interrupts appears */
163 break;
164 }
165}
166
167static struct clock_event_device clockevent_imx = {
168 .name = "imx_timer1",
169 .features = CLOCK_EVT_FEAT_ONESHOT,
170 .shift = 32,
171 .set_mode = imx_set_mode,
172 .set_next_event = imx_set_next_event,
173 .rating = 200,
174};
175
176static int __init imx_clockevent_init(void)
177{
178 clockevent_imx.mult = div_sc(imx_get_perclk1(), NSEC_PER_SEC,
179 clockevent_imx.shift);
180 clockevent_imx.max_delta_ns =
181 clockevent_delta2ns(0xfffffffe, &clockevent_imx);
182 clockevent_imx.min_delta_ns =
183 clockevent_delta2ns(0xf, &clockevent_imx);
184
185 clockevent_imx.cpumask = cpumask_of_cpu(0);
186
187 clockevents_register_device(&clockevent_imx);
188
189 return 0;
190}
191
192
102static void __init imx_timer_init(void) 193static void __init imx_timer_init(void)
103{ 194{
104 imx_timer_hardware_init(); 195 imx_timer_hardware_init();
105 imx_clocksource_init(); 196 imx_clocksource_init();
106 197
198 imx_clockevent_init();
199
107 /* 200 /*
108 * Make irqs happen for the system timer 201 * Make irqs happen for the system timer
109 */ 202 */
diff --git a/arch/arm/mach-iop13xx/tpmi.c b/arch/arm/mach-iop13xx/tpmi.c
index d3dc278213d..2476347ea62 100644
--- a/arch/arm/mach-iop13xx/tpmi.c
+++ b/arch/arm/mach-iop13xx/tpmi.c
@@ -29,13 +29,15 @@
29#define IOP13XX_TPMI_MMR(dev) IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12)) 29#define IOP13XX_TPMI_MMR(dev) IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12))
30#define IOP13XX_TPMI_MEM(dev) IOP13XX_REG_ADDR32_PHYS(0x60000 + (dev << 13)) 30#define IOP13XX_TPMI_MEM(dev) IOP13XX_REG_ADDR32_PHYS(0x60000 + (dev << 13))
31#define IOP13XX_TPMI_CTRL(dev) IOP13XX_REG_ADDR32_PHYS(0x50000 + (dev << 10)) 31#define IOP13XX_TPMI_CTRL(dev) IOP13XX_REG_ADDR32_PHYS(0x50000 + (dev << 10))
32#define IOP13XX_TPMI_IOP_CTRL(dev) (IOP13XX_TPMI_CTRL(dev) + 0x2000)
32#define IOP13XX_TPMI_MMR_SIZE (SZ_4K - 1) 33#define IOP13XX_TPMI_MMR_SIZE (SZ_4K - 1)
33#define IOP13XX_TPMI_MEM_SIZE (255) 34#define IOP13XX_TPMI_MEM_SIZE (255)
34#define IOP13XX_TPMI_MEM_CTRL (SZ_1K - 1) 35#define IOP13XX_TPMI_MEM_CTRL (SZ_1K - 1)
35#define IOP13XX_TPMI_RESOURCE_MMR 0 36#define IOP13XX_TPMI_RESOURCE_MMR 0
36#define IOP13XX_TPMI_RESOURCE_MEM 1 37#define IOP13XX_TPMI_RESOURCE_MEM 1
37#define IOP13XX_TPMI_RESOURCE_CTRL 2 38#define IOP13XX_TPMI_RESOURCE_CTRL 2
38#define IOP13XX_TPMI_RESOURCE_IRQ 3 39#define IOP13XX_TPMI_RESOURCE_IOP_CTRL 3
40#define IOP13XX_TPMI_RESOURCE_IRQ 4
39 41
40static struct resource iop13xx_tpmi_0_resources[] = { 42static struct resource iop13xx_tpmi_0_resources[] = {
41 [IOP13XX_TPMI_RESOURCE_MMR] = { 43 [IOP13XX_TPMI_RESOURCE_MMR] = {
@@ -53,6 +55,11 @@ static struct resource iop13xx_tpmi_0_resources[] = {
53 .end = IOP13XX_TPMI_CTRL(0) + IOP13XX_TPMI_MEM_CTRL, 55 .end = IOP13XX_TPMI_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
54 .flags = IORESOURCE_MEM, 56 .flags = IORESOURCE_MEM,
55 }, 57 },
58 [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
59 .start = IOP13XX_TPMI_IOP_CTRL(0),
60 .end = IOP13XX_TPMI_IOP_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
61 .flags = IORESOURCE_MEM,
62 },
56 [IOP13XX_TPMI_RESOURCE_IRQ] = { 63 [IOP13XX_TPMI_RESOURCE_IRQ] = {
57 .start = IRQ_IOP13XX_TPMI0_OUT, 64 .start = IRQ_IOP13XX_TPMI0_OUT,
58 .end = IRQ_IOP13XX_TPMI0_OUT, 65 .end = IRQ_IOP13XX_TPMI0_OUT,
@@ -76,6 +83,11 @@ static struct resource iop13xx_tpmi_1_resources[] = {
76 .end = IOP13XX_TPMI_CTRL(1) + IOP13XX_TPMI_MEM_CTRL, 83 .end = IOP13XX_TPMI_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
77 .flags = IORESOURCE_MEM, 84 .flags = IORESOURCE_MEM,
78 }, 85 },
86 [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
87 .start = IOP13XX_TPMI_IOP_CTRL(1),
88 .end = IOP13XX_TPMI_IOP_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
89 .flags = IORESOURCE_MEM,
90 },
79 [IOP13XX_TPMI_RESOURCE_IRQ] = { 91 [IOP13XX_TPMI_RESOURCE_IRQ] = {
80 .start = IRQ_IOP13XX_TPMI1_OUT, 92 .start = IRQ_IOP13XX_TPMI1_OUT,
81 .end = IRQ_IOP13XX_TPMI1_OUT, 93 .end = IRQ_IOP13XX_TPMI1_OUT,
@@ -99,6 +111,11 @@ static struct resource iop13xx_tpmi_2_resources[] = {
99 .end = IOP13XX_TPMI_CTRL(2) + IOP13XX_TPMI_MEM_CTRL, 111 .end = IOP13XX_TPMI_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
100 .flags = IORESOURCE_MEM, 112 .flags = IORESOURCE_MEM,
101 }, 113 },
114 [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
115 .start = IOP13XX_TPMI_IOP_CTRL(2),
116 .end = IOP13XX_TPMI_IOP_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
117 .flags = IORESOURCE_MEM,
118 },
102 [IOP13XX_TPMI_RESOURCE_IRQ] = { 119 [IOP13XX_TPMI_RESOURCE_IRQ] = {
103 .start = IRQ_IOP13XX_TPMI2_OUT, 120 .start = IRQ_IOP13XX_TPMI2_OUT,
104 .end = IRQ_IOP13XX_TPMI2_OUT, 121 .end = IRQ_IOP13XX_TPMI2_OUT,
@@ -122,6 +139,11 @@ static struct resource iop13xx_tpmi_3_resources[] = {
122 .end = IOP13XX_TPMI_CTRL(3) + IOP13XX_TPMI_MEM_CTRL, 139 .end = IOP13XX_TPMI_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
123 .flags = IORESOURCE_MEM, 140 .flags = IORESOURCE_MEM,
124 }, 141 },
142 [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
143 .start = IOP13XX_TPMI_IOP_CTRL(3),
144 .end = IOP13XX_TPMI_IOP_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
145 .flags = IORESOURCE_MEM,
146 },
125 [IOP13XX_TPMI_RESOURCE_IRQ] = { 147 [IOP13XX_TPMI_RESOURCE_IRQ] = {
126 .start = IRQ_IOP13XX_TPMI3_OUT, 148 .start = IRQ_IOP13XX_TPMI3_OUT,
127 .end = IRQ_IOP13XX_TPMI3_OUT, 149 .end = IRQ_IOP13XX_TPMI3_OUT,
@@ -133,7 +155,7 @@ u64 iop13xx_tpmi_mask = DMA_64BIT_MASK;
133static struct platform_device iop13xx_tpmi_0_device = { 155static struct platform_device iop13xx_tpmi_0_device = {
134 .name = "iop-tpmi", 156 .name = "iop-tpmi",
135 .id = 0, 157 .id = 0,
136 .num_resources = 4, 158 .num_resources = ARRAY_SIZE(iop13xx_tpmi_0_resources),
137 .resource = iop13xx_tpmi_0_resources, 159 .resource = iop13xx_tpmi_0_resources,
138 .dev = { 160 .dev = {
139 .dma_mask = &iop13xx_tpmi_mask, 161 .dma_mask = &iop13xx_tpmi_mask,
@@ -144,7 +166,7 @@ static struct platform_device iop13xx_tpmi_0_device = {
144static struct platform_device iop13xx_tpmi_1_device = { 166static struct platform_device iop13xx_tpmi_1_device = {
145 .name = "iop-tpmi", 167 .name = "iop-tpmi",
146 .id = 1, 168 .id = 1,
147 .num_resources = 4, 169 .num_resources = ARRAY_SIZE(iop13xx_tpmi_1_resources),
148 .resource = iop13xx_tpmi_1_resources, 170 .resource = iop13xx_tpmi_1_resources,
149 .dev = { 171 .dev = {
150 .dma_mask = &iop13xx_tpmi_mask, 172 .dma_mask = &iop13xx_tpmi_mask,
@@ -155,7 +177,7 @@ static struct platform_device iop13xx_tpmi_1_device = {
155static struct platform_device iop13xx_tpmi_2_device = { 177static struct platform_device iop13xx_tpmi_2_device = {
156 .name = "iop-tpmi", 178 .name = "iop-tpmi",
157 .id = 2, 179 .id = 2,
158 .num_resources = 4, 180 .num_resources = ARRAY_SIZE(iop13xx_tpmi_2_resources),
159 .resource = iop13xx_tpmi_2_resources, 181 .resource = iop13xx_tpmi_2_resources,
160 .dev = { 182 .dev = {
161 .dma_mask = &iop13xx_tpmi_mask, 183 .dma_mask = &iop13xx_tpmi_mask,
@@ -166,7 +188,7 @@ static struct platform_device iop13xx_tpmi_2_device = {
166static struct platform_device iop13xx_tpmi_3_device = { 188static struct platform_device iop13xx_tpmi_3_device = {
167 .name = "iop-tpmi", 189 .name = "iop-tpmi",
168 .id = 3, 190 .id = 3,
169 .num_resources = 4, 191 .num_resources = ARRAY_SIZE(iop13xx_tpmi_3_resources),
170 .resource = iop13xx_tpmi_3_resources, 192 .resource = iop13xx_tpmi_3_resources,
171 .dev = { 193 .dev = {
172 .dma_mask = &iop13xx_tpmi_mask, 194 .dma_mask = &iop13xx_tpmi_mask,
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 060909870b5..61b2dfcb89d 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -41,6 +41,22 @@ config ARCH_ADI_COYOTE
41 Engineering Coyote Gateway Reference Platform. For more 41 Engineering Coyote Gateway Reference Platform. For more
42 information on this platform, see <file:Documentation/arm/IXP4xx>. 42 information on this platform, see <file:Documentation/arm/IXP4xx>.
43 43
44config MACH_GATEWAY7001
45 bool "Gateway 7001"
46 select PCI
47 help
48 Say 'Y' here if you want your kernel to support Gateway's
49 7001 Access Point. For more information on this platform,
50 see http://openwrt.org
51
52config MACH_WG302V2
53 bool "Netgear WG302 v2 / WAG302 v2"
54 select PCI
55 help
56 Say 'Y' here if you want your kernel to support Netgear's
57 WG302 v2 or WAG302 v2 Access Points. For more information
58 on this platform, see http://openwrt.org
59
44config ARCH_IXDP425 60config ARCH_IXDP425
45 bool "IXDP425" 61 bool "IXDP425"
46 help 62 help
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index 3b87c47e06c..77e00ade558 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -13,6 +13,8 @@ obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o
13obj-pci-$(CONFIG_MACH_NSLU2) += nslu2-pci.o 13obj-pci-$(CONFIG_MACH_NSLU2) += nslu2-pci.o
14obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o 14obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o
15obj-pci-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o 15obj-pci-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o
16obj-pci-$(CONFIG_MACH_GATEWAY7001) += gateway7001-pci.o
17obj-pci-$(CONFIG_MACH_WG302V2) += wg302v2-pci.o
16 18
17obj-y += common.o 19obj-y += common.o
18 20
@@ -24,5 +26,7 @@ obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o
24obj-$(CONFIG_MACH_NSLU2) += nslu2-setup.o nslu2-power.o 26obj-$(CONFIG_MACH_NSLU2) += nslu2-setup.o nslu2-power.o
25obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o nas100d-power.o 27obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o nas100d-power.o
26obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o dsmg600-power.o 28obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o dsmg600-power.o
29obj-$(CONFIG_MACH_GATEWAY7001) += gateway7001-setup.o
30obj-$(CONFIG_MACH_WG302V2) += wg302v2-setup.o
27 31
28obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o 32obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o
diff --git a/arch/arm/mach-ixp4xx/gateway7001-pci.c b/arch/arm/mach-ixp4xx/gateway7001-pci.c
new file mode 100644
index 00000000000..6abf568322d
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/gateway7001-pci.c
@@ -0,0 +1,63 @@
1/*
2 * arch/arch/mach-ixp4xx/gateway7001-pci.c
3 *
4 * PCI setup routines for Gateway 7001
5 *
6 * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * based on coyote-pci.c:
9 * Copyright (C) 2002 Jungo Software Technologies.
10 * Copyright (C) 2003 MontaVista Softwrae, Inc.
11 *
12 * Maintainer: Imre Kaloz <kaloz@openwrt.org>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/pci.h>
22#include <linux/init.h>
23#include <linux/irq.h>
24
25#include <asm/mach-types.h>
26#include <asm/hardware.h>
27
28#include <asm/mach/pci.h>
29
30void __init gateway7001_pci_preinit(void)
31{
32 set_irq_type(IRQ_IXP4XX_GPIO10, IRQT_LOW);
33 set_irq_type(IRQ_IXP4XX_GPIO11, IRQT_LOW);
34
35 ixp4xx_pci_preinit();
36}
37
38static int __init gateway7001_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
39{
40 if (slot == 1)
41 return IRQ_IXP4XX_GPIO11;
42 else if (slot == 2)
43 return IRQ_IXP4XX_GPIO10;
44 else return -1;
45}
46
47struct hw_pci gateway7001_pci __initdata = {
48 .nr_controllers = 1,
49 .preinit = gateway7001_pci_preinit,
50 .swizzle = pci_std_swizzle,
51 .setup = ixp4xx_setup,
52 .scan = ixp4xx_scan_bus,
53 .map_irq = gateway7001_map_irq,
54};
55
56int __init gateway7001_pci_init(void)
57{
58 if (machine_is_gateway7001())
59 pci_common_init(&gateway7001_pci);
60 return 0;
61}
62
63subsys_initcall(gateway7001_pci_init);
diff --git a/arch/arm/mach-ixp4xx/gateway7001-setup.c b/arch/arm/mach-ixp4xx/gateway7001-setup.c
new file mode 100644
index 00000000000..37876832e14
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/gateway7001-setup.c
@@ -0,0 +1,108 @@
1/*
2 * arch/arm/mach-ixp4xx/gateway7001-setup.c
3 *
4 * Board setup for the Gateway 7001 board
5 *
6 * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * based on coyote-setup.c:
9 * Copyright (C) 2003-2005 MontaVista Software, Inc.
10 *
11 * Author: Imre Kaloz <Kaloz@openwrt.org>
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/device.h>
17#include <linux/serial.h>
18#include <linux/tty.h>
19#include <linux/serial_8250.h>
20#include <linux/slab.h>
21
22#include <asm/types.h>
23#include <asm/setup.h>
24#include <asm/memory.h>
25#include <asm/hardware.h>
26#include <asm/irq.h>
27#include <asm/mach-types.h>
28#include <asm/mach/arch.h>
29#include <asm/mach/flash.h>
30
31static struct flash_platform_data gateway7001_flash_data = {
32 .map_name = "cfi_probe",
33 .width = 2,
34};
35
36static struct resource gateway7001_flash_resource = {
37 .flags = IORESOURCE_MEM,
38};
39
40static struct platform_device gateway7001_flash = {
41 .name = "IXP4XX-Flash",
42 .id = 0,
43 .dev = {
44 .platform_data = &gateway7001_flash_data,
45 },
46 .num_resources = 1,
47 .resource = &gateway7001_flash_resource,
48};
49
50static struct resource gateway7001_uart_resource = {
51 .start = IXP4XX_UART2_BASE_PHYS,
52 .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
53 .flags = IORESOURCE_MEM,
54};
55
56static struct plat_serial8250_port gateway7001_uart_data[] = {
57 {
58 .mapbase = IXP4XX_UART2_BASE_PHYS,
59 .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
60 .irq = IRQ_IXP4XX_UART2,
61 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
62 .iotype = UPIO_MEM,
63 .regshift = 2,
64 .uartclk = IXP4XX_UART_XTAL,
65 },
66 { },
67};
68
69static struct platform_device gateway7001_uart = {
70 .name = "serial8250",
71 .id = PLAT8250_DEV_PLATFORM,
72 .dev = {
73 .platform_data = gateway7001_uart_data,
74 },
75 .num_resources = 1,
76 .resource = &gateway7001_uart_resource,
77};
78
79static struct platform_device *gateway7001_devices[] __initdata = {
80 &gateway7001_flash,
81 &gateway7001_uart
82};
83
84static void __init gateway7001_init(void)
85{
86 ixp4xx_sys_init();
87
88 gateway7001_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
89 gateway7001_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
90
91 *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
92 *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
93
94 platform_add_devices(gateway7001_devices, ARRAY_SIZE(gateway7001_devices));
95}
96
97#ifdef CONFIG_MACH_GATEWAY7001
98MACHINE_START(GATEWAY7001, "Gateway 7001 AP")
99 /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
100 .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
101 .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
102 .map_io = ixp4xx_map_io,
103 .init_irq = ixp4xx_init_irq,
104 .timer = &ixp4xx_timer,
105 .boot_params = 0x0100,
106 .init_machine = gateway7001_init,
107MACHINE_END
108#endif
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-pci.c b/arch/arm/mach-ixp4xx/gtwx5715-pci.c
index a66484b63d3..0d5a4245582 100644
--- a/arch/arm/mach-ixp4xx/gtwx5715-pci.c
+++ b/arch/arm/mach-ixp4xx/gtwx5715-pci.c
@@ -25,17 +25,13 @@
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/irq.h>
29
28#include <asm/mach-types.h> 30#include <asm/mach-types.h>
29#include <asm/hardware.h> 31#include <asm/hardware.h>
30#include <asm/irq.h>
31#include <asm/arch/gtwx5715.h> 32#include <asm/arch/gtwx5715.h>
32#include <asm/mach/pci.h> 33#include <asm/mach/pci.h>
33 34
34extern void ixp4xx_pci_preinit(void);
35extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
36extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
37
38
39/* 35/*
40 * The exact GPIO pins and IRQs are defined in arch-ixp4xx/gtwx5715.h 36 * The exact GPIO pins and IRQs are defined in arch-ixp4xx/gtwx5715.h
41 * Slot 0 isn't actually populated with a card connector but 37 * Slot 0 isn't actually populated with a card connector but
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index ec4f07950ec..d5008d8fc9a 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -15,6 +15,10 @@
15#include <linux/tty.h> 15#include <linux/tty.h>
16#include <linux/serial_8250.h> 16#include <linux/serial_8250.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/io.h>
19#include <linux/mtd/mtd.h>
20#include <linux/mtd/nand.h>
21#include <linux/mtd/partitions.h>
18 22
19#include <asm/types.h> 23#include <asm/types.h>
20#include <asm/setup.h> 24#include <asm/setup.h>
@@ -24,6 +28,7 @@
24#include <asm/irq.h> 28#include <asm/irq.h>
25#include <asm/mach/arch.h> 29#include <asm/mach/arch.h>
26#include <asm/mach/flash.h> 30#include <asm/mach/flash.h>
31#include <asm/delay.h>
27 32
28static struct flash_platform_data ixdp425_flash_data = { 33static struct flash_platform_data ixdp425_flash_data = {
29 .map_name = "cfi_probe", 34 .map_name = "cfi_probe",
@@ -44,6 +49,77 @@ static struct platform_device ixdp425_flash = {
44 .resource = &ixdp425_flash_resource, 49 .resource = &ixdp425_flash_resource,
45}; 50};
46 51
52#if defined(CONFIG_MTD_NAND_PLATFORM) || \
53 defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
54
55#ifdef CONFIG_MTD_PARTITIONS
56const char *part_probes[] = { "cmdlinepart", NULL };
57
58static struct mtd_partition ixdp425_partitions[] = {
59 {
60 .name = "ixp400 NAND FS 0",
61 .offset = 0,
62 .size = SZ_8M
63 }, {
64 .name = "ixp400 NAND FS 1",
65 .offset = MTDPART_OFS_APPEND,
66 .size = MTDPART_SIZ_FULL
67 },
68};
69#endif
70
71static void
72ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
73{
74 struct nand_chip *this = mtd->priv;
75 int offset = (int)this->priv;
76
77 if (ctrl & NAND_CTRL_CHANGE) {
78 if (ctrl & NAND_NCE) {
79 gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_LOW);
80 udelay(5);
81 } else
82 gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_HIGH);
83
84 offset = (ctrl & NAND_CLE) ? IXDP425_NAND_CMD_BYTE : 0;
85 offset |= (ctrl & NAND_ALE) ? IXDP425_NAND_ADDR_BYTE : 0;
86 this->priv = (void *)offset;
87 }
88
89 if (cmd != NAND_CMD_NONE)
90 writeb(cmd, this->IO_ADDR_W + offset);
91}
92
93static struct platform_nand_data ixdp425_flash_nand_data = {
94 .chip = {
95 .chip_delay = 30,
96 .options = NAND_NO_AUTOINCR,
97#ifdef CONFIG_MTD_PARTITIONS
98 .part_probe_types = part_probes,
99 .partitions = ixdp425_partitions,
100 .nr_partitions = ARRAY_SIZE(ixdp425_partitions),
101#endif
102 },
103 .ctrl = {
104 .cmd_ctrl = ixdp425_flash_nand_cmd_ctrl
105 }
106};
107
108static struct resource ixdp425_flash_nand_resource = {
109 .flags = IORESOURCE_MEM,
110};
111
112static struct platform_device ixdp425_flash_nand = {
113 .name = "gen_nand",
114 .id = -1,
115 .dev = {
116 .platform_data = &ixdp425_flash_nand_data,
117 },
118 .num_resources = 1,
119 .resource = &ixdp425_flash_nand_resource,
120};
121#endif /* CONFIG_MTD_NAND_PLATFORM */
122
47static struct ixp4xx_i2c_pins ixdp425_i2c_gpio_pins = { 123static struct ixp4xx_i2c_pins ixdp425_i2c_gpio_pins = {
48 .sda_pin = IXDP425_SDA_PIN, 124 .sda_pin = IXDP425_SDA_PIN,
49 .scl_pin = IXDP425_SCL_PIN, 125 .scl_pin = IXDP425_SCL_PIN,
@@ -104,6 +180,10 @@ static struct platform_device ixdp425_uart = {
104static struct platform_device *ixdp425_devices[] __initdata = { 180static struct platform_device *ixdp425_devices[] __initdata = {
105 &ixdp425_i2c_controller, 181 &ixdp425_i2c_controller,
106 &ixdp425_flash, 182 &ixdp425_flash,
183#if defined(CONFIG_MTD_NAND_PLATFORM) || \
184 defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
185 &ixdp425_flash_nand,
186#endif
107 &ixdp425_uart 187 &ixdp425_uart
108}; 188};
109 189
@@ -115,6 +195,22 @@ static void __init ixdp425_init(void)
115 ixdp425_flash_resource.end = 195 ixdp425_flash_resource.end =
116 IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; 196 IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
117 197
198#if defined(CONFIG_MTD_NAND_PLATFORM) || \
199 defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
200 ixdp425_flash_nand_resource.start = IXP4XX_EXP_BUS_BASE(3),
201 ixdp425_flash_nand_resource.end = IXP4XX_EXP_BUS_BASE(3) + 0x10 - 1;
202
203 gpio_line_config(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_OUT);
204
205 /* Configure expansion bus for NAND Flash */
206 *IXP4XX_EXP_CS3 = IXP4XX_EXP_BUS_CS_EN |
207 IXP4XX_EXP_BUS_STROBE_T(1) | /* extend by 1 clock */
208 IXP4XX_EXP_BUS_CYCLES(0) | /* Intel cycles */
209 IXP4XX_EXP_BUS_SIZE(0) | /* 512bytes addr space*/
210 IXP4XX_EXP_BUS_WR_EN |
211 IXP4XX_EXP_BUS_BYTE_EN; /* 8 bit data bus */
212#endif
213
118 if (cpu_is_ixp43x()) { 214 if (cpu_is_ixp43x()) {
119 ixdp425_uart.num_resources = 1; 215 ixdp425_uart.num_resources = 1;
120 ixdp425_uart_data[1].flags = 0; 216 ixdp425_uart_data[1].flags = 0;
diff --git a/arch/arm/mach-ixp4xx/wg302v2-pci.c b/arch/arm/mach-ixp4xx/wg302v2-pci.c
new file mode 100644
index 00000000000..6588f2c758e
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/wg302v2-pci.c
@@ -0,0 +1,63 @@
1/*
2 * arch/arch/mach-ixp4xx/wg302v2-pci.c
3 *
4 * PCI setup routines for the Netgear WG302 v2 and WAG302 v2
5 *
6 * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
7 *
8 * based on coyote-pci.c:
9 * Copyright (C) 2002 Jungo Software Technologies.
10 * Copyright (C) 2003 MontaVista Software, Inc.
11 *
12 * Maintainer: Imre Kaloz <kaloz@openwrt.org>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/pci.h>
22#include <linux/init.h>
23#include <linux/irq.h>
24
25#include <asm/mach-types.h>
26#include <asm/hardware.h>
27
28#include <asm/mach/pci.h>
29
30void __init wg302v2_pci_preinit(void)
31{
32 set_irq_type(IRQ_IXP4XX_GPIO8, IRQT_LOW);
33 set_irq_type(IRQ_IXP4XX_GPIO9, IRQT_LOW);
34
35 ixp4xx_pci_preinit();
36}
37
38static int __init wg302v2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
39{
40 if (slot == 1)
41 return IRQ_IXP4XX_GPIO8;
42 else if (slot == 2)
43 return IRQ_IXP4XX_GPIO9;
44 else return -1;
45}
46
47struct hw_pci wg302v2_pci __initdata = {
48 .nr_controllers = 1,
49 .preinit = wg302v2_pci_preinit,
50 .swizzle = pci_std_swizzle,
51 .setup = ixp4xx_setup,
52 .scan = ixp4xx_scan_bus,
53 .map_irq = wg302v2_map_irq,
54};
55
56int __init wg302v2_pci_init(void)
57{
58 if (machine_is_wg302v2())
59 pci_common_init(&wg302v2_pci);
60 return 0;
61}
62
63subsys_initcall(wg302v2_pci_init);
diff --git a/arch/arm/mach-ixp4xx/wg302v2-setup.c b/arch/arm/mach-ixp4xx/wg302v2-setup.c
new file mode 100644
index 00000000000..f7e09ad804e
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/wg302v2-setup.c
@@ -0,0 +1,109 @@
1/*
2 * arch/arm/mach-ixp4xx/wg302-setup.c
3 *
4 * Board setup for the Netgear WG302 v2 and WAG302 v2
5 *
6 * Copyright (C) 2007 Imre Kaloz <Kaloz@openwrt.org>
7 *
8 * based on coyote-setup.c:
9 * Copyright (C) 2003-2005 MontaVista Software, Inc.
10 *
11 * Author: Imre Kaloz <kaloz@openwrt.org>
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/device.h>
18#include <linux/serial.h>
19#include <linux/tty.h>
20#include <linux/serial_8250.h>
21#include <linux/slab.h>
22
23#include <asm/types.h>
24#include <asm/setup.h>
25#include <asm/memory.h>
26#include <asm/hardware.h>
27#include <asm/irq.h>
28#include <asm/mach-types.h>
29#include <asm/mach/arch.h>
30#include <asm/mach/flash.h>
31
32static struct flash_platform_data wg302v2_flash_data = {
33 .map_name = "cfi_probe",
34 .width = 2,
35};
36
37static struct resource wg302v2_flash_resource = {
38 .flags = IORESOURCE_MEM,
39};
40
41static struct platform_device wg302v2_flash = {
42 .name = "IXP4XX-Flash",
43 .id = 0,
44 .dev = {
45 .platform_data = &wg302v2_flash_data,
46 },
47 .num_resources = 1,
48 .resource = &wg302v2_flash_resource,
49};
50
51static struct resource wg302v2_uart_resource = {
52 .start = IXP4XX_UART2_BASE_PHYS,
53 .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
54 .flags = IORESOURCE_MEM,
55};
56
57static struct plat_serial8250_port wg302v2_uart_data[] = {
58 {
59 .mapbase = IXP4XX_UART2_BASE_PHYS,
60 .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
61 .irq = IRQ_IXP4XX_UART2,
62 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
63 .iotype = UPIO_MEM,
64 .regshift = 2,
65 .uartclk = IXP4XX_UART_XTAL,
66 },
67 { },
68};
69
70static struct platform_device wg302v2_uart = {
71 .name = "serial8250",
72 .id = PLAT8250_DEV_PLATFORM,
73 .dev = {
74 .platform_data = wg302v2_uart_data,
75 },
76 .num_resources = 1,
77 .resource = &wg302v2_uart_resource,
78};
79
80static struct platform_device *wg302v2_devices[] __initdata = {
81 &wg302v2_flash,
82 &wg302v2_uart,
83};
84
85static void __init wg302v2_init(void)
86{
87 ixp4xx_sys_init();
88
89 wg302v2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
90 wg302v2_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
91
92 *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
93 *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
94
95 platform_add_devices(wg302v2_devices, ARRAY_SIZE(wg302v2_devices));
96}
97
98#ifdef CONFIG_MACH_WG302V2
99MACHINE_START(WG302V2, "Netgear WG302 v2 / WAG302 v2")
100 /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
101 .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
102 .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
103 .map_io = ixp4xx_map_io,
104 .init_irq = ixp4xx_init_irq,
105 .timer = &ixp4xx_timer,
106 .boot_params = 0x0100,
107 .init_machine = wg302v2_init,
108MACHINE_END
109#endif
diff --git a/arch/arm/mach-ks8695/Makefile b/arch/arm/mach-ks8695/Makefile
index 56b7d337333..2a07a281fa8 100644
--- a/arch/arm/mach-ks8695/Makefile
+++ b/arch/arm/mach-ks8695/Makefile
@@ -3,7 +3,7 @@
3# Makefile for KS8695 architecture support 3# Makefile for KS8695 architecture support
4# 4#
5 5
6obj-y := cpu.o irq.o time.o devices.o 6obj-y := cpu.o irq.o time.o gpio.o devices.o
7obj-m := 7obj-m :=
8obj-n := 8obj-n :=
9obj- := 9obj- :=
diff --git a/arch/arm/mach-ks8695/gpio.c b/arch/arm/mach-ks8695/gpio.c
new file mode 100644
index 00000000000..b1aa3cb3d4a
--- /dev/null
+++ b/arch/arm/mach-ks8695/gpio.c
@@ -0,0 +1,218 @@
1/*
2 * arch/arm/mach-ks8695/gpio.c
3 *
4 * Copyright (C) 2006 Andrew Victor
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/kernel.h>
21#include <linux/mm.h>
22#include <linux/init.h>
23#include <linux/module.h>
24
25#include <asm/io.h>
26#include <asm/hardware.h>
27#include <asm/mach/irq.h>
28
29#include <asm/arch/regs-gpio.h>
30#include <asm/arch/gpio.h>
31
32/*
33 * Configure a GPIO line for either GPIO function, or its internal
34 * function (Interrupt, Timer, etc).
35 */
36static void __init_or_module ks8695_gpio_mode(unsigned int pin, short gpio)
37{
38 unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN };
39 unsigned long x, flags;
40
41 if (pin > KS8695_GPIO_5) /* only GPIO 0..5 have internal functions */
42 return;
43
44 local_irq_save(flags);
45
46 x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
47 if (gpio) /* GPIO: set bit to 0 */
48 x &= ~enable[pin];
49 else /* Internal function: set bit to 1 */
50 x |= enable[pin];
51 __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPC);
52
53 local_irq_restore(flags);
54}
55
56
57static unsigned short gpio_irq[] = { KS8695_IRQ_EXTERN0, KS8695_IRQ_EXTERN1, KS8695_IRQ_EXTERN2, KS8695_IRQ_EXTERN3 };
58
59/*
60 * Configure GPIO pin as external interrupt source.
61 */
62int __init_or_module ks8695_gpio_interrupt(unsigned int pin, unsigned int type)
63{
64 unsigned long x, flags;
65
66 if (pin > KS8695_GPIO_3) /* only GPIO 0..3 can generate IRQ */
67 return -EINVAL;
68
69 local_irq_save(flags);
70
71 /* set pin as input */
72 x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
73 x &= ~IOPM_(pin);
74 __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
75
76 local_irq_restore(flags);
77
78 /* Set IRQ triggering type */
79 set_irq_type(gpio_irq[pin], type);
80
81 /* enable interrupt mode */
82 ks8695_gpio_mode(pin, 0);
83
84 return 0;
85}
86EXPORT_SYMBOL(ks8695_gpio_interrupt);
87
88
89
90/* .... Generic GPIO interface .............................................. */
91
92/*
93 * Configure the GPIO line as an input.
94 */
95int __init_or_module gpio_direction_input(unsigned int pin)
96{
97 unsigned long x, flags;
98
99 if (pin > KS8695_GPIO_15)
100 return -EINVAL;
101
102 /* set pin to GPIO mode */
103 ks8695_gpio_mode(pin, 1);
104
105 local_irq_save(flags);
106
107 /* set pin as input */
108 x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
109 x &= ~IOPM_(pin);
110 __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
111
112 local_irq_restore(flags);
113
114 return 0;
115}
116EXPORT_SYMBOL(gpio_direction_input);
117
118
119/*
120 * Configure the GPIO line as an output, with default state.
121 */
122int __init_or_module gpio_direction_output(unsigned int pin, unsigned int state)
123{
124 unsigned long x, flags;
125
126 if (pin > KS8695_GPIO_15)
127 return -EINVAL;
128
129 /* set pin to GPIO mode */
130 ks8695_gpio_mode(pin, 1);
131
132 local_irq_save(flags);
133
134 /* set line state */
135 x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
136 if (state)
137 x |= (1 << pin);
138 else
139 x &= ~(1 << pin);
140 __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD);
141
142 /* set pin as output */
143 x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
144 x |= IOPM_(pin);
145 __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
146
147 local_irq_restore(flags);
148
149 return 0;
150}
151EXPORT_SYMBOL(gpio_direction_output);
152
153
154/*
155 * Set the state of an output GPIO line.
156 */
157void gpio_set_value(unsigned int pin, unsigned int state)
158{
159 unsigned long x, flags;
160
161 if (pin > KS8695_GPIO_15)
162 return;
163
164 local_irq_save(flags);
165
166 /* set output line state */
167 x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
168 if (state)
169 x |= (1 << pin);
170 else
171 x &= ~(1 << pin);
172 __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD);
173
174 local_irq_restore(flags);
175}
176EXPORT_SYMBOL(gpio_set_value);
177
178
179/*
180 * Read the state of a GPIO line.
181 */
182int gpio_get_value(unsigned int pin)
183{
184 unsigned long x;
185
186 if (pin > KS8695_GPIO_15)
187 return -EINVAL;
188
189 x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
190 return (x & (1 << pin)) != 0;
191}
192EXPORT_SYMBOL(gpio_get_value);
193
194
195/*
196 * Map GPIO line to IRQ number.
197 */
198int gpio_to_irq(unsigned int pin)
199{
200 if (pin > KS8695_GPIO_3) /* only GPIO 0..3 can generate IRQ */
201 return -EINVAL;
202
203 return gpio_irq[pin];
204}
205EXPORT_SYMBOL(gpio_to_irq);
206
207
208/*
209 * Map IRQ number to GPIO line.
210 */
211int irq_to_gpio(unsigned int irq)
212{
213 if ((irq < KS8695_IRQ_EXTERN0) || (irq > KS8695_IRQ_EXTERN3))
214 return -EINVAL;
215
216 return (irq - KS8695_IRQ_EXTERN0);
217}
218EXPORT_SYMBOL(irq_to_gpio);
diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c
index 8f7c90a0593..34a31caa6f9 100644
--- a/arch/arm/mach-pxa/clock.c
+++ b/arch/arm/mach-pxa/clock.c
@@ -12,7 +12,6 @@
12 12
13#include <asm/arch/pxa-regs.h> 13#include <asm/arch/pxa-regs.h>
14#include <asm/hardware.h> 14#include <asm/hardware.h>
15#include <asm/semaphore.h>
16 15
17struct clk { 16struct clk {
18 struct list_head node; 17 struct list_head node;
@@ -25,21 +24,21 @@ struct clk {
25}; 24};
26 25
27static LIST_HEAD(clocks); 26static LIST_HEAD(clocks);
28static DECLARE_MUTEX(clocks_sem); 27static DEFINE_MUTEX(clocks_mutex);
29static DEFINE_SPINLOCK(clocks_lock); 28static DEFINE_SPINLOCK(clocks_lock);
30 29
31struct clk *clk_get(struct device *dev, const char *id) 30struct clk *clk_get(struct device *dev, const char *id)
32{ 31{
33 struct clk *p, *clk = ERR_PTR(-ENOENT); 32 struct clk *p, *clk = ERR_PTR(-ENOENT);
34 33
35 down(&clocks_sem); 34 mutex_lock(&clocks_mutex);
36 list_for_each_entry(p, &clocks, node) { 35 list_for_each_entry(p, &clocks, node) {
37 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { 36 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
38 clk = p; 37 clk = p;
39 break; 38 break;
40 } 39 }
41 } 40 }
42 up(&clocks_sem); 41 mutex_unlock(&clocks_mutex);
43 42
44 return clk; 43 return clk;
45} 44}
@@ -101,18 +100,18 @@ static struct clk clk_gpio27 = {
101 100
102int clk_register(struct clk *clk) 101int clk_register(struct clk *clk)
103{ 102{
104 down(&clocks_sem); 103 mutex_lock(&clocks_mutex);
105 list_add(&clk->node, &clocks); 104 list_add(&clk->node, &clocks);
106 up(&clocks_sem); 105 mutex_unlock(&clocks_mutex);
107 return 0; 106 return 0;
108} 107}
109EXPORT_SYMBOL(clk_register); 108EXPORT_SYMBOL(clk_register);
110 109
111void clk_unregister(struct clk *clk) 110void clk_unregister(struct clk *clk)
112{ 111{
113 down(&clocks_sem); 112 mutex_lock(&clocks_mutex);
114 list_del(&clk->node); 113 list_del(&clk->node);
115 up(&clocks_sem); 114 mutex_unlock(&clocks_mutex);
116} 115}
117EXPORT_SYMBOL(clk_unregister); 116EXPORT_SYMBOL(clk_unregister);
118 117
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index a1a900d1666..aab27297b3c 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -44,6 +44,7 @@
44#include <asm/hardware/scoop.h> 44#include <asm/hardware/scoop.h>
45 45
46#include "generic.h" 46#include "generic.h"
47#include "devices.h"
47#include "sharpsl.h" 48#include "sharpsl.h"
48 49
49 50
@@ -368,7 +369,7 @@ MACHINE_START(CORGI, "SHARP Corgi")
368 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 369 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
369 .fixup = fixup_corgi, 370 .fixup = fixup_corgi,
370 .map_io = pxa_map_io, 371 .map_io = pxa_map_io,
371 .init_irq = pxa_init_irq, 372 .init_irq = pxa25x_init_irq,
372 .init_machine = corgi_init, 373 .init_machine = corgi_init,
373 .timer = &pxa_timer, 374 .timer = &pxa_timer,
374MACHINE_END 375MACHINE_END
@@ -380,7 +381,7 @@ MACHINE_START(SHEPHERD, "SHARP Shepherd")
380 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 381 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
381 .fixup = fixup_corgi, 382 .fixup = fixup_corgi,
382 .map_io = pxa_map_io, 383 .map_io = pxa_map_io,
383 .init_irq = pxa_init_irq, 384 .init_irq = pxa25x_init_irq,
384 .init_machine = corgi_init, 385 .init_machine = corgi_init,
385 .timer = &pxa_timer, 386 .timer = &pxa_timer,
386MACHINE_END 387MACHINE_END
@@ -392,7 +393,7 @@ MACHINE_START(HUSKY, "SHARP Husky")
392 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 393 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
393 .fixup = fixup_corgi, 394 .fixup = fixup_corgi,
394 .map_io = pxa_map_io, 395 .map_io = pxa_map_io,
395 .init_irq = pxa_init_irq, 396 .init_irq = pxa25x_init_irq,
396 .init_machine = corgi_init, 397 .init_machine = corgi_init,
397 .timer = &pxa_timer, 398 .timer = &pxa_timer,
398MACHINE_END 399MACHINE_END
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
new file mode 100644
index 00000000000..9a6faff8e5a
--- /dev/null
+++ b/arch/arm/mach-pxa/devices.h
@@ -0,0 +1,11 @@
1extern struct platform_device pxamci_device;
2extern struct platform_device pxaudc_device;
3extern struct platform_device pxafb_device;
4extern struct platform_device ffuart_device;
5extern struct platform_device btuart_device;
6extern struct platform_device stuart_device;
7extern struct platform_device hwuart_device;
8extern struct platform_device pxai2c_device;
9extern struct platform_device pxai2s_device;
10extern struct platform_device pxaficp_device;
11extern struct platform_device pxartc_device;
diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/mach-pxa/dma.c
index 4440babe7b9..93c4f31f127 100644
--- a/arch/arm/mach-pxa/dma.c
+++ b/arch/arm/mach-pxa/dma.c
@@ -25,12 +25,15 @@
25 25
26#include <asm/arch/pxa-regs.h> 26#include <asm/arch/pxa-regs.h>
27 27
28static struct dma_channel { 28struct dma_channel {
29 char *name; 29 char *name;
30 pxa_dma_prio prio;
30 void (*irq_handler)(int, void *); 31 void (*irq_handler)(int, void *);
31 void *data; 32 void *data;
32} dma_channels[PXA_DMA_CHANNELS]; 33};
33 34
35static struct dma_channel *dma_channels;
36static int num_dma_channels;
34 37
35int pxa_request_dma (char *name, pxa_dma_prio prio, 38int pxa_request_dma (char *name, pxa_dma_prio prio,
36 void (*irq_handler)(int, void *), 39 void (*irq_handler)(int, void *),
@@ -47,8 +50,9 @@ int pxa_request_dma (char *name, pxa_dma_prio prio,
47 50
48 do { 51 do {
49 /* try grabbing a DMA channel with the requested priority */ 52 /* try grabbing a DMA channel with the requested priority */
50 pxa_for_each_dma_prio (i, prio) { 53 for (i = 0; i < num_dma_channels; i++) {
51 if (!dma_channels[i].name) { 54 if ((dma_channels[i].prio == prio) &&
55 !dma_channels[i].name) {
52 found = 1; 56 found = 1;
53 break; 57 break;
54 } 58 }
@@ -91,7 +95,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
91{ 95{
92 int i, dint = DINT; 96 int i, dint = DINT;
93 97
94 for (i = 0; i < PXA_DMA_CHANNELS; i++) { 98 for (i = 0; i < num_dma_channels; i++) {
95 if (dint & (1 << i)) { 99 if (dint & (1 << i)) {
96 struct dma_channel *channel = &dma_channels[i]; 100 struct dma_channel *channel = &dma_channels[i];
97 if (channel->name && channel->irq_handler) { 101 if (channel->name && channel->irq_handler) {
@@ -109,18 +113,32 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
109 return IRQ_HANDLED; 113 return IRQ_HANDLED;
110} 114}
111 115
112static int __init pxa_dma_init (void) 116int __init pxa_init_dma(int num_ch)
113{ 117{
114 int ret; 118 int i, ret;
115 119
116 ret = request_irq (IRQ_DMA, dma_irq_handler, 0, "DMA", NULL); 120 dma_channels = kzalloc(sizeof(struct dma_channel) * num_ch, GFP_KERNEL);
117 if (ret) 121 if (dma_channels == NULL)
122 return -ENOMEM;
123
124 ret = request_irq(IRQ_DMA, dma_irq_handler, IRQF_DISABLED, "DMA", NULL);
125 if (ret) {
118 printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n"); 126 printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n");
119 return ret; 127 kfree(dma_channels);
120} 128 return ret;
129 }
121 130
122arch_initcall(pxa_dma_init); 131 /* dma channel priorities on pxa2xx processors:
132 * ch 0 - 3, 16 - 19 <--> (0) DMA_PRIO_HIGH
133 * ch 4 - 7, 20 - 23 <--> (1) DMA_PRIO_MEDIUM
134 * ch 8 - 15, 24 - 31 <--> (2) DMA_PRIO_LOW
135 */
136 for (i = 0; i < num_ch; i++)
137 dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW);
138
139 num_dma_channels = num_ch;
140 return 0;
141}
123 142
124EXPORT_SYMBOL(pxa_request_dma); 143EXPORT_SYMBOL(pxa_request_dma);
125EXPORT_SYMBOL(pxa_free_dma); 144EXPORT_SYMBOL(pxa_free_dma);
126
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 64b08b744f9..296539b6359 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -43,6 +43,7 @@
43#include <asm/arch/irda.h> 43#include <asm/arch/irda.h>
44#include <asm/arch/i2c.h> 44#include <asm/arch/i2c.h>
45 45
46#include "devices.h"
46#include "generic.h" 47#include "generic.h"
47 48
48/* 49/*
@@ -242,7 +243,7 @@ static struct resource pxamci_resources[] = {
242 243
243static u64 pxamci_dmamask = 0xffffffffUL; 244static u64 pxamci_dmamask = 0xffffffffUL;
244 245
245static struct platform_device pxamci_device = { 246struct platform_device pxamci_device = {
246 .name = "pxa2xx-mci", 247 .name = "pxa2xx-mci",
247 .id = -1, 248 .id = -1,
248 .dev = { 249 .dev = {
@@ -281,7 +282,7 @@ static struct resource pxa2xx_udc_resources[] = {
281 282
282static u64 udc_dma_mask = ~(u32)0; 283static u64 udc_dma_mask = ~(u32)0;
283 284
284static struct platform_device udc_device = { 285struct platform_device pxaudc_device = {
285 .name = "pxa2xx-udc", 286 .name = "pxa2xx-udc",
286 .id = -1, 287 .id = -1,
287 .resource = pxa2xx_udc_resources, 288 .resource = pxa2xx_udc_resources,
@@ -307,7 +308,7 @@ static struct resource pxafb_resources[] = {
307 308
308static u64 fb_dma_mask = ~(u64)0; 309static u64 fb_dma_mask = ~(u64)0;
309 310
310static struct platform_device pxafb_device = { 311struct platform_device pxafb_device = {
311 .name = "pxa2xx-fb", 312 .name = "pxa2xx-fb",
312 .id = -1, 313 .id = -1,
313 .dev = { 314 .dev = {
@@ -328,24 +329,24 @@ void __init set_pxa_fb_parent(struct device *parent_dev)
328 pxafb_device.dev.parent = parent_dev; 329 pxafb_device.dev.parent = parent_dev;
329} 330}
330 331
331static struct platform_device ffuart_device = { 332struct platform_device ffuart_device = {
332 .name = "pxa2xx-uart", 333 .name = "pxa2xx-uart",
333 .id = 0, 334 .id = 0,
334}; 335};
335static struct platform_device btuart_device = { 336struct platform_device btuart_device = {
336 .name = "pxa2xx-uart", 337 .name = "pxa2xx-uart",
337 .id = 1, 338 .id = 1,
338}; 339};
339static struct platform_device stuart_device = { 340struct platform_device stuart_device = {
340 .name = "pxa2xx-uart", 341 .name = "pxa2xx-uart",
341 .id = 2, 342 .id = 2,
342}; 343};
343static struct platform_device hwuart_device = { 344struct platform_device hwuart_device = {
344 .name = "pxa2xx-uart", 345 .name = "pxa2xx-uart",
345 .id = 3, 346 .id = 3,
346}; 347};
347 348
348static struct resource i2c_resources[] = { 349static struct resource pxai2c_resources[] = {
349 { 350 {
350 .start = 0x40301680, 351 .start = 0x40301680,
351 .end = 0x403016a3, 352 .end = 0x403016a3,
@@ -357,40 +358,19 @@ static struct resource i2c_resources[] = {
357 }, 358 },
358}; 359};
359 360
360static struct platform_device i2c_device = { 361struct platform_device pxai2c_device = {
361 .name = "pxa2xx-i2c", 362 .name = "pxa2xx-i2c",
362 .id = 0, 363 .id = 0,
363 .resource = i2c_resources, 364 .resource = pxai2c_resources,
364 .num_resources = ARRAY_SIZE(i2c_resources), 365 .num_resources = ARRAY_SIZE(pxai2c_resources),
365}; 366};
366 367
367#ifdef CONFIG_PXA27x
368static struct resource i2c_power_resources[] = {
369 {
370 .start = 0x40f00180,
371 .end = 0x40f001a3,
372 .flags = IORESOURCE_MEM,
373 }, {
374 .start = IRQ_PWRI2C,
375 .end = IRQ_PWRI2C,
376 .flags = IORESOURCE_IRQ,
377 },
378};
379
380static struct platform_device i2c_power_device = {
381 .name = "pxa2xx-i2c",
382 .id = 1,
383 .resource = i2c_power_resources,
384 .num_resources = ARRAY_SIZE(i2c_resources),
385};
386#endif
387
388void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info) 368void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
389{ 369{
390 i2c_device.dev.platform_data = info; 370 pxai2c_device.dev.platform_data = info;
391} 371}
392 372
393static struct resource i2s_resources[] = { 373static struct resource pxai2s_resources[] = {
394 { 374 {
395 .start = 0x40400000, 375 .start = 0x40400000,
396 .end = 0x40400083, 376 .end = 0x40400083,
@@ -402,16 +382,16 @@ static struct resource i2s_resources[] = {
402 }, 382 },
403}; 383};
404 384
405static struct platform_device i2s_device = { 385struct platform_device pxai2s_device = {
406 .name = "pxa2xx-i2s", 386 .name = "pxa2xx-i2s",
407 .id = -1, 387 .id = -1,
408 .resource = i2s_resources, 388 .resource = pxai2s_resources,
409 .num_resources = ARRAY_SIZE(i2s_resources), 389 .num_resources = ARRAY_SIZE(pxai2s_resources),
410}; 390};
411 391
412static u64 pxaficp_dmamask = ~(u32)0; 392static u64 pxaficp_dmamask = ~(u32)0;
413 393
414static struct platform_device pxaficp_device = { 394struct platform_device pxaficp_device = {
415 .name = "pxa2xx-ir", 395 .name = "pxa2xx-ir",
416 .id = -1, 396 .id = -1,
417 .dev = { 397 .dev = {
@@ -425,42 +405,7 @@ void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
425 pxaficp_device.dev.platform_data = info; 405 pxaficp_device.dev.platform_data = info;
426} 406}
427 407
428static struct platform_device pxartc_device = { 408struct platform_device pxartc_device = {
429 .name = "sa1100-rtc", 409 .name = "sa1100-rtc",
430 .id = -1, 410 .id = -1,
431}; 411};
432
433static struct platform_device *devices[] __initdata = {
434 &pxamci_device,
435 &udc_device,
436 &pxafb_device,
437 &ffuart_device,
438 &btuart_device,
439 &stuart_device,
440 &pxaficp_device,
441 &i2c_device,
442#ifdef CONFIG_PXA27x
443 &i2c_power_device,
444#endif
445 &i2s_device,
446 &pxartc_device,
447};
448
449static int __init pxa_init(void)
450{
451 int cpuid, ret;
452
453 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
454 if (ret)
455 return ret;
456
457 /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
458 cpuid = read_cpuid(CPUID_ID);
459 if (((cpuid >> 4) & 0xfff) == 0x2d0 ||
460 ((cpuid >> 4) & 0xfff) == 0x290)
461 ret = platform_device_register(&hwuart_device);
462
463 return ret;
464}
465
466subsys_initcall(pxa_init);
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index e54a8dd63c1..91ab2ad8b34 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -12,8 +12,12 @@
12struct sys_timer; 12struct sys_timer;
13 13
14extern struct sys_timer pxa_timer; 14extern struct sys_timer pxa_timer;
15extern void __init pxa_init_irq_low(void);
16extern void __init pxa_init_irq_high(void);
17extern void __init pxa_init_irq_gpio(int gpio_nr);
18extern void __init pxa25x_init_irq(void);
19extern void __init pxa27x_init_irq(void);
15extern void __init pxa_map_io(void); 20extern void __init pxa_map_io(void);
16extern void __init pxa_init_irq(void);
17 21
18extern unsigned int get_clk_frequency_khz(int info); 22extern unsigned int get_clk_frequency_khz(int info);
19 23
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 64df44043a6..465108da285 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -38,6 +38,7 @@
38#include <asm/arch/mmc.h> 38#include <asm/arch/mmc.h>
39 39
40#include "generic.h" 40#include "generic.h"
41#include "devices.h"
41 42
42/* TODO: 43/* TODO:
43 * - add pxa2xx_audio_ops_t device structure 44 * - add pxa2xx_audio_ops_t device structure
@@ -152,7 +153,7 @@ static void __init idp_init(void)
152static void __init idp_init_irq(void) 153static void __init idp_init_irq(void)
153{ 154{
154 155
155 pxa_init_irq(); 156 pxa25x_init_irq();
156 157
157 set_irq_type(TOUCH_PANEL_IRQ, TOUCH_PANEL_IRQ_EDGE); 158 set_irq_type(TOUCH_PANEL_IRQ, TOUCH_PANEL_IRQ_EDGE);
158} 159}
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 4619d5fe606..4b867b0789d 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -30,12 +30,12 @@
30 30
31static void pxa_mask_low_irq(unsigned int irq) 31static void pxa_mask_low_irq(unsigned int irq)
32{ 32{
33 ICMR &= ~(1 << (irq + PXA_IRQ_SKIP)); 33 ICMR &= ~(1 << irq);
34} 34}
35 35
36static void pxa_unmask_low_irq(unsigned int irq) 36static void pxa_unmask_low_irq(unsigned int irq)
37{ 37{
38 ICMR |= (1 << (irq + PXA_IRQ_SKIP)); 38 ICMR |= (1 << irq);
39} 39}
40 40
41static int pxa_set_wake(unsigned int irq, unsigned int on) 41static int pxa_set_wake(unsigned int irq, unsigned int on)
@@ -67,7 +67,27 @@ static struct irq_chip pxa_internal_chip_low = {
67 .set_wake = pxa_set_wake, 67 .set_wake = pxa_set_wake,
68}; 68};
69 69
70#if PXA_INTERNAL_IRQS > 32 70void __init pxa_init_irq_low(void)
71{
72 int irq;
73
74 /* disable all IRQs */
75 ICMR = 0;
76
77 /* all IRQs are IRQ, not FIQ */
78 ICLR = 0;
79
80 /* only unmasked interrupts kick us out of idle */
81 ICCR = 1;
82
83 for (irq = PXA_IRQ(0); irq <= PXA_IRQ(31); irq++) {
84 set_irq_chip(irq, &pxa_internal_chip_low);
85 set_irq_handler(irq, handle_level_irq);
86 set_irq_flags(irq, IRQF_VALID);
87 }
88}
89
90#ifdef CONFIG_PXA27x
71 91
72/* 92/*
73 * This is for the second set of internal IRQs as found on the PXA27x. 93 * This is for the second set of internal IRQs as found on the PXA27x.
@@ -75,12 +95,12 @@ static struct irq_chip pxa_internal_chip_low = {
75 95
76static void pxa_mask_high_irq(unsigned int irq) 96static void pxa_mask_high_irq(unsigned int irq)
77{ 97{
78 ICMR2 &= ~(1 << (irq - 32 + PXA_IRQ_SKIP)); 98 ICMR2 &= ~(1 << (irq - 32));
79} 99}
80 100
81static void pxa_unmask_high_irq(unsigned int irq) 101static void pxa_unmask_high_irq(unsigned int irq)
82{ 102{
83 ICMR2 |= (1 << (irq - 32 + PXA_IRQ_SKIP)); 103 ICMR2 |= (1 << (irq - 32));
84} 104}
85 105
86static struct irq_chip pxa_internal_chip_high = { 106static struct irq_chip pxa_internal_chip_high = {
@@ -90,6 +110,19 @@ static struct irq_chip pxa_internal_chip_high = {
90 .unmask = pxa_unmask_high_irq, 110 .unmask = pxa_unmask_high_irq,
91}; 111};
92 112
113void __init pxa_init_irq_high(void)
114{
115 int irq;
116
117 ICMR2 = 0;
118 ICLR2 = 0;
119
120 for (irq = PXA_IRQ(32); irq < PXA_IRQ(64); irq++) {
121 set_irq_chip(irq, &pxa_internal_chip_high);
122 set_irq_handler(irq, handle_level_irq);
123 set_irq_flags(irq, IRQF_VALID);
124 }
125}
93#endif 126#endif
94 127
95/* Note that if an input/irq line ever gets changed to an output during 128/* Note that if an input/irq line ever gets changed to an output during
@@ -217,7 +250,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
217 do { 250 do {
218 loop = 0; 251 loop = 0;
219 252
220 mask = GEDR0 & ~3; 253 mask = GEDR0 & GPIO_IRQ_mask[0] & ~3;
221 if (mask) { 254 if (mask) {
222 GEDR0 = mask; 255 GEDR0 = mask;
223 irq = IRQ_GPIO(2); 256 irq = IRQ_GPIO(2);
@@ -233,7 +266,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
233 loop = 1; 266 loop = 1;
234 } 267 }
235 268
236 mask = GEDR1; 269 mask = GEDR1 & GPIO_IRQ_mask[1];
237 if (mask) { 270 if (mask) {
238 GEDR1 = mask; 271 GEDR1 = mask;
239 irq = IRQ_GPIO(32); 272 irq = IRQ_GPIO(32);
@@ -248,7 +281,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
248 loop = 1; 281 loop = 1;
249 } 282 }
250 283
251 mask = GEDR2; 284 mask = GEDR2 & GPIO_IRQ_mask[2];
252 if (mask) { 285 if (mask) {
253 GEDR2 = mask; 286 GEDR2 = mask;
254 irq = IRQ_GPIO(64); 287 irq = IRQ_GPIO(64);
@@ -263,8 +296,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
263 loop = 1; 296 loop = 1;
264 } 297 }
265 298
266#if PXA_LAST_GPIO >= 96 299 mask = GEDR3 & GPIO_IRQ_mask[3];
267 mask = GEDR3;
268 if (mask) { 300 if (mask) {
269 GEDR3 = mask; 301 GEDR3 = mask;
270 irq = IRQ_GPIO(96); 302 irq = IRQ_GPIO(96);
@@ -278,7 +310,6 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
278 } while (mask); 310 } while (mask);
279 loop = 1; 311 loop = 1;
280 } 312 }
281#endif
282 } while (loop); 313 } while (loop);
283} 314}
284 315
@@ -314,64 +345,27 @@ static struct irq_chip pxa_muxed_gpio_chip = {
314 .set_wake = pxa_set_gpio_wake, 345 .set_wake = pxa_set_gpio_wake,
315}; 346};
316 347
317 348void __init pxa_init_irq_gpio(int gpio_nr)
318void __init pxa_init_irq(void)
319{ 349{
320 int irq; 350 int irq, i;
321
322 /* disable all IRQs */
323 ICMR = 0;
324
325 /* all IRQs are IRQ, not FIQ */
326 ICLR = 0;
327 351
328 /* clear all GPIO edge detects */ 352 /* clear all GPIO edge detects */
329 GFER0 = 0; 353 for (i = 0; i < gpio_nr; i += 32) {
330 GFER1 = 0; 354 GFER(i) = 0;
331 GFER2 = 0; 355 GRER(i) = 0;
332 GRER0 = 0; 356 GEDR(i) = GEDR(i);
333 GRER1 = 0; 357 }
334 GRER2 = 0;
335 GEDR0 = GEDR0;
336 GEDR1 = GEDR1;
337 GEDR2 = GEDR2;
338
339#ifdef CONFIG_PXA27x
340 /* And similarly for the extra regs on the PXA27x */
341 ICMR2 = 0;
342 ICLR2 = 0;
343 GFER3 = 0;
344 GRER3 = 0;
345 GEDR3 = GEDR3;
346#endif
347
348 /* only unmasked interrupts kick us out of idle */
349 ICCR = 1;
350 358
351 /* GPIO 0 and 1 must have their mask bit always set */ 359 /* GPIO 0 and 1 must have their mask bit always set */
352 GPIO_IRQ_mask[0] = 3; 360 GPIO_IRQ_mask[0] = 3;
353 361
354 for (irq = PXA_IRQ(PXA_IRQ_SKIP); irq <= PXA_IRQ(31); irq++) {
355 set_irq_chip(irq, &pxa_internal_chip_low);
356 set_irq_handler(irq, handle_level_irq);
357 set_irq_flags(irq, IRQF_VALID);
358 }
359
360#if PXA_INTERNAL_IRQS > 32
361 for (irq = PXA_IRQ(32); irq < PXA_IRQ(PXA_INTERNAL_IRQS); irq++) {
362 set_irq_chip(irq, &pxa_internal_chip_high);
363 set_irq_handler(irq, handle_level_irq);
364 set_irq_flags(irq, IRQF_VALID);
365 }
366#endif
367
368 for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) { 362 for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
369 set_irq_chip(irq, &pxa_low_gpio_chip); 363 set_irq_chip(irq, &pxa_low_gpio_chip);
370 set_irq_handler(irq, handle_edge_irq); 364 set_irq_handler(irq, handle_edge_irq);
371 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 365 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
372 } 366 }
373 367
374 for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(PXA_LAST_GPIO); irq++) { 368 for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(gpio_nr); irq++) {
375 set_irq_chip(irq, &pxa_muxed_gpio_chip); 369 set_irq_chip(irq, &pxa_muxed_gpio_chip);
376 set_irq_handler(irq, handle_edge_irq); 370 set_irq_handler(irq, handle_edge_irq);
377 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); 371 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index e3097664ffe..26116440a7c 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -46,6 +46,7 @@
46#include <asm/arch/ohci.h> 46#include <asm/arch/ohci.h>
47 47
48#include "generic.h" 48#include "generic.h"
49#include "devices.h"
49 50
50 51
51static unsigned int lpd270_irq_enabled; 52static unsigned int lpd270_irq_enabled;
@@ -97,7 +98,7 @@ static void __init lpd270_init_irq(void)
97{ 98{
98 int irq; 99 int irq;
99 100
100 pxa_init_irq(); 101 pxa27x_init_irq();
101 102
102 __raw_writew(0, LPD270_INT_MASK); 103 __raw_writew(0, LPD270_INT_MASK);
103 __raw_writew(0, LPD270_INT_STATUS); 104 __raw_writew(0, LPD270_INT_STATUS);
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 6377b2e29ff..e70048fd00a 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -48,6 +48,7 @@
48#include <asm/arch/mmc.h> 48#include <asm/arch/mmc.h>
49 49
50#include "generic.h" 50#include "generic.h"
51#include "devices.h"
51 52
52 53
53#define LUB_MISC_WR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080) 54#define LUB_MISC_WR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
@@ -103,7 +104,7 @@ static void __init lubbock_init_irq(void)
103{ 104{
104 int irq; 105 int irq;
105 106
106 pxa_init_irq(); 107 pxa25x_init_irq();
107 108
108 /* setup extra lubbock irqs */ 109 /* setup extra lubbock irqs */
109 for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) { 110 for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) {
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index ed99a81b98f..b02c79c7e6a 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -46,6 +46,7 @@
46#include <asm/arch/ohci.h> 46#include <asm/arch/ohci.h>
47 47
48#include "generic.h" 48#include "generic.h"
49#include "devices.h"
49 50
50 51
51static unsigned long mainstone_irq_enabled; 52static unsigned long mainstone_irq_enabled;
@@ -89,7 +90,7 @@ static void __init mainstone_init_irq(void)
89{ 90{
90 int irq; 91 int irq;
91 92
92 pxa_init_irq(); 93 pxa27x_init_irq();
93 94
94 /* setup extra Mainstone irqs */ 95 /* setup extra Mainstone irqs */
95 for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) { 96 for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) {
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index 6bf15ae7384..e66dbc26add 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -77,7 +77,6 @@ int pxa_pm_enter(suspend_state_t state)
77{ 77{
78 unsigned long sleep_save[SLEEP_SAVE_SIZE]; 78 unsigned long sleep_save[SLEEP_SAVE_SIZE];
79 unsigned long checksum = 0; 79 unsigned long checksum = 0;
80 struct timespec delta, rtc;
81 int i; 80 int i;
82 extern void pxa_cpu_pm_enter(suspend_state_t state); 81 extern void pxa_cpu_pm_enter(suspend_state_t state);
83 82
@@ -87,11 +86,6 @@ int pxa_pm_enter(suspend_state_t state)
87 iwmmxt_task_disable(NULL); 86 iwmmxt_task_disable(NULL);
88#endif 87#endif
89 88
90 /* preserve current time */
91 rtc.tv_sec = RCNR;
92 rtc.tv_nsec = 0;
93 save_time_delta(&delta, &rtc);
94
95 SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); 89 SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2);
96 SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); 90 SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2);
97 SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); 91 SAVE(GRER0); SAVE(GRER1); SAVE(GRER2);
@@ -183,10 +177,6 @@ int pxa_pm_enter(suspend_state_t state)
183 177
184 RESTORE(PSTR); 178 RESTORE(PSTR);
185 179
186 /* restore current time */
187 rtc.tv_sec = RCNR;
188 restore_time_delta(&delta, &rtc);
189
190#ifdef DEBUG 180#ifdef DEBUG
191 printk(KERN_DEBUG "*** made it back from resume\n"); 181 printk(KERN_DEBUG "*** made it back from resume\n");
192#endif 182#endif
@@ -200,40 +190,3 @@ unsigned long sleep_phys_sp(void *sp)
200{ 190{
201 return virt_to_phys(sp); 191 return virt_to_phys(sp);
202} 192}
203
204/*
205 * Called after processes are frozen, but before we shut down devices.
206 */
207int pxa_pm_prepare(suspend_state_t state)
208{
209 extern int pxa_cpu_pm_prepare(suspend_state_t state);
210
211 return pxa_cpu_pm_prepare(state);
212}
213
214EXPORT_SYMBOL_GPL(pxa_pm_prepare);
215
216/*
217 * Called after devices are re-setup, but before processes are thawed.
218 */
219int pxa_pm_finish(suspend_state_t state)
220{
221 return 0;
222}
223
224EXPORT_SYMBOL_GPL(pxa_pm_finish);
225
226static struct pm_ops pxa_pm_ops = {
227 .prepare = pxa_pm_prepare,
228 .enter = pxa_pm_enter,
229 .finish = pxa_pm_finish,
230 .valid = pm_valid_only_mem,
231};
232
233static int __init pxa_pm_init(void)
234{
235 pm_set_ops(&pxa_pm_ops);
236 return 0;
237}
238
239device_initcall(pxa_pm_init);
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 34fb80b3702..655668d4d0e 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -45,6 +45,7 @@
45#include <asm/mach/sharpsl_param.h> 45#include <asm/mach/sharpsl_param.h>
46 46
47#include "generic.h" 47#include "generic.h"
48#include "devices.h"
48#include "sharpsl.h" 49#include "sharpsl.h"
49 50
50static struct resource poodle_scoop_resources[] = { 51static struct resource poodle_scoop_resources[] = {
@@ -412,7 +413,7 @@ MACHINE_START(POODLE, "SHARP Poodle")
412 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 413 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
413 .fixup = fixup_poodle, 414 .fixup = fixup_poodle,
414 .map_io = pxa_map_io, 415 .map_io = pxa_map_io,
415 .init_irq = pxa_init_irq, 416 .init_irq = pxa25x_init_irq,
416 .timer = &pxa_timer, 417 .timer = &pxa_timer,
417 .init_machine = poodle_init, 418 .init_machine = poodle_init,
418MACHINE_END 419MACHINE_END
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index c1f21739bf7..f36ca448338 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -19,12 +19,17 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/platform_device.h>
22#include <linux/pm.h> 23#include <linux/pm.h>
23 24
24#include <asm/hardware.h> 25#include <asm/hardware.h>
26#include <asm/arch/irqs.h>
25#include <asm/arch/pxa-regs.h> 27#include <asm/arch/pxa-regs.h>
28#include <asm/arch/pm.h>
29#include <asm/arch/dma.h>
26 30
27#include "generic.h" 31#include "generic.h"
32#include "devices.h"
28 33
29/* 34/*
30 * Various clock factors driven by the CCCR register. 35 * Various clock factors driven by the CCCR register.
@@ -105,18 +110,6 @@ EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
105 110
106#ifdef CONFIG_PM 111#ifdef CONFIG_PM
107 112
108int pxa_cpu_pm_prepare(suspend_state_t state)
109{
110 switch (state) {
111 case PM_SUSPEND_MEM:
112 break;
113 default:
114 return -EINVAL;
115 }
116
117 return 0;
118}
119
120void pxa_cpu_pm_enter(suspend_state_t state) 113void pxa_cpu_pm_enter(suspend_state_t state)
121{ 114{
122 extern void pxa_cpu_suspend(unsigned int); 115 extern void pxa_cpu_suspend(unsigned int);
@@ -133,4 +126,49 @@ void pxa_cpu_pm_enter(suspend_state_t state)
133 } 126 }
134} 127}
135 128
129static struct pm_ops pxa25x_pm_ops = {
130 .enter = pxa_pm_enter,
131 .valid = pm_valid_only_mem,
132};
133#endif
134
135void __init pxa25x_init_irq(void)
136{
137 pxa_init_irq_low();
138 pxa_init_irq_gpio(85);
139}
140
141static struct platform_device *pxa25x_devices[] __initdata = {
142 &pxamci_device,
143 &pxaudc_device,
144 &pxafb_device,
145 &ffuart_device,
146 &btuart_device,
147 &stuart_device,
148 &pxai2c_device,
149 &pxai2s_device,
150 &pxaficp_device,
151 &pxartc_device,
152};
153
154static int __init pxa25x_init(void)
155{
156 int ret = 0;
157
158 if (cpu_is_pxa21x() || cpu_is_pxa25x()) {
159 if ((ret = pxa_init_dma(16)))
160 return ret;
161#ifdef CONFIG_PM
162 pm_set_ops(&pxa25x_pm_ops);
136#endif 163#endif
164 ret = platform_add_devices(pxa25x_devices,
165 ARRAY_SIZE(pxa25x_devices));
166 }
167 /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
168 if (cpu_is_pxa25x())
169 ret = platform_device_register(&hwuart_device);
170
171 return ret;
172}
173
174subsys_initcall(pxa25x_init);
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 1939acc3f9f..aa5bb02c897 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -19,10 +19,14 @@
19 19
20#include <asm/hardware.h> 20#include <asm/hardware.h>
21#include <asm/irq.h> 21#include <asm/irq.h>
22#include <asm/arch/irqs.h>
22#include <asm/arch/pxa-regs.h> 23#include <asm/arch/pxa-regs.h>
23#include <asm/arch/ohci.h> 24#include <asm/arch/ohci.h>
25#include <asm/arch/pm.h>
26#include <asm/arch/dma.h>
24 27
25#include "generic.h" 28#include "generic.h"
29#include "devices.h"
26 30
27/* Crystal clock: 13MHz */ 31/* Crystal clock: 13MHz */
28#define BASE_CLK 13000000 32#define BASE_CLK 13000000
@@ -122,17 +126,6 @@ EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
122 126
123#ifdef CONFIG_PM 127#ifdef CONFIG_PM
124 128
125int pxa_cpu_pm_prepare(suspend_state_t state)
126{
127 switch (state) {
128 case PM_SUSPEND_MEM:
129 case PM_SUSPEND_STANDBY:
130 return 0;
131 default:
132 return -EINVAL;
133 }
134}
135
136void pxa_cpu_pm_enter(suspend_state_t state) 129void pxa_cpu_pm_enter(suspend_state_t state)
137{ 130{
138 extern void pxa_cpu_standby(void); 131 extern void pxa_cpu_standby(void);
@@ -162,6 +155,15 @@ void pxa_cpu_pm_enter(suspend_state_t state)
162 } 155 }
163} 156}
164 157
158static int pxa27x_pm_valid(suspend_state_t state)
159{
160 return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
161}
162
163static struct pm_ops pxa27x_pm_ops = {
164 .enter = pxa_pm_enter,
165 .valid = pxa27x_pm_valid,
166};
165#endif 167#endif
166 168
167/* 169/*
@@ -183,7 +185,7 @@ static struct resource pxa27x_ohci_resources[] = {
183 }, 185 },
184}; 186};
185 187
186static struct platform_device ohci_device = { 188static struct platform_device pxaohci_device = {
187 .name = "pxa27x-ohci", 189 .name = "pxa27x-ohci",
188 .id = -1, 190 .id = -1,
189 .dev = { 191 .dev = {
@@ -196,16 +198,62 @@ static struct platform_device ohci_device = {
196 198
197void __init pxa_set_ohci_info(struct pxaohci_platform_data *info) 199void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
198{ 200{
199 ohci_device.dev.platform_data = info; 201 pxaohci_device.dev.platform_data = info;
200} 202}
201 203
204static struct resource i2c_power_resources[] = {
205 {
206 .start = 0x40f00180,
207 .end = 0x40f001a3,
208 .flags = IORESOURCE_MEM,
209 }, {
210 .start = IRQ_PWRI2C,
211 .end = IRQ_PWRI2C,
212 .flags = IORESOURCE_IRQ,
213 },
214};
215
216static struct platform_device pxai2c_power_device = {
217 .name = "pxa2xx-i2c",
218 .id = 1,
219 .resource = i2c_power_resources,
220 .num_resources = ARRAY_SIZE(i2c_power_resources),
221};
222
202static struct platform_device *devices[] __initdata = { 223static struct platform_device *devices[] __initdata = {
203 &ohci_device, 224 &pxamci_device,
225 &pxaudc_device,
226 &pxafb_device,
227 &ffuart_device,
228 &btuart_device,
229 &stuart_device,
230 &pxai2c_device,
231 &pxai2c_power_device,
232 &pxai2s_device,
233 &pxaficp_device,
234 &pxartc_device,
235 &pxaohci_device,
204}; 236};
205 237
238void __init pxa27x_init_irq(void)
239{
240 pxa_init_irq_low();
241 pxa_init_irq_high();
242 pxa_init_irq_gpio(128);
243}
244
206static int __init pxa27x_init(void) 245static int __init pxa27x_init(void)
207{ 246{
208 return platform_add_devices(devices, ARRAY_SIZE(devices)); 247 int ret = 0;
248 if (cpu_is_pxa27x()) {
249 if ((ret = pxa_init_dma(32)))
250 return ret;
251#ifdef CONFIG_PM
252 pm_set_ops(&pxa27x_pm_ops);
253#endif
254 ret = platform_add_devices(devices, ARRAY_SIZE(devices));
255 }
256 return ret;
209} 257}
210 258
211subsys_initcall(pxa27x_init); 259subsys_initcall(pxa27x_init);
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 3cbac63bed3..bae47e145de 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -48,6 +48,7 @@
48#include <asm/hardware/scoop.h> 48#include <asm/hardware/scoop.h>
49 49
50#include "generic.h" 50#include "generic.h"
51#include "devices.h"
51#include "sharpsl.h" 52#include "sharpsl.h"
52 53
53/* 54/*
@@ -560,7 +561,7 @@ MACHINE_START(SPITZ, "SHARP Spitz")
560 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 561 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
561 .fixup = fixup_spitz, 562 .fixup = fixup_spitz,
562 .map_io = pxa_map_io, 563 .map_io = pxa_map_io,
563 .init_irq = pxa_init_irq, 564 .init_irq = pxa27x_init_irq,
564 .init_machine = spitz_init, 565 .init_machine = spitz_init,
565 .timer = &pxa_timer, 566 .timer = &pxa_timer,
566MACHINE_END 567MACHINE_END
@@ -572,7 +573,7 @@ MACHINE_START(BORZOI, "SHARP Borzoi")
572 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 573 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
573 .fixup = fixup_spitz, 574 .fixup = fixup_spitz,
574 .map_io = pxa_map_io, 575 .map_io = pxa_map_io,
575 .init_irq = pxa_init_irq, 576 .init_irq = pxa27x_init_irq,
576 .init_machine = spitz_init, 577 .init_machine = spitz_init,
577 .timer = &pxa_timer, 578 .timer = &pxa_timer,
578MACHINE_END 579MACHINE_END
@@ -584,7 +585,7 @@ MACHINE_START(AKITA, "SHARP Akita")
584 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 585 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
585 .fixup = fixup_spitz, 586 .fixup = fixup_spitz,
586 .map_io = pxa_map_io, 587 .map_io = pxa_map_io,
587 .init_irq = pxa_init_irq, 588 .init_irq = pxa27x_init_irq,
588 .init_machine = akita_init, 589 .init_machine = akita_init,
589 .timer = &pxa_timer, 590 .timer = &pxa_timer,
590MACHINE_END 591MACHINE_END
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 5248abe334d..6f91fd2d061 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -30,11 +30,6 @@
30#include <asm/arch/pxa-regs.h> 30#include <asm/arch/pxa-regs.h>
31 31
32 32
33static inline unsigned long pxa_get_rtc_time(void)
34{
35 return RCNR;
36}
37
38static int pxa_set_rtc(void) 33static int pxa_set_rtc(void)
39{ 34{
40 unsigned long current_time = xtime.tv_sec; 35 unsigned long current_time = xtime.tv_sec;
@@ -122,10 +117,6 @@ static void __init pxa_timer_init(void)
122 117
123 set_rtc = pxa_set_rtc; 118 set_rtc = pxa_set_rtc;
124 119
125 tv.tv_nsec = 0;
126 tv.tv_sec = pxa_get_rtc_time();
127 do_settimeofday(&tv);
128
129 OIER = 0; /* disable any timer interrupts */ 120 OIER = 0; /* disable any timer interrupts */
130 OSSR = 0xf; /* clear status on all timers */ 121 OSSR = 0xf; /* clear status on all timers */
131 setup_irq(IRQ_OST0, &pxa_timer_irq); 122 setup_irq(IRQ_OST0, &pxa_timer_irq);
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 72738771fb5..240fd042083 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -42,7 +42,7 @@
42#include <asm/mach/sharpsl_param.h> 42#include <asm/mach/sharpsl_param.h>
43 43
44#include "generic.h" 44#include "generic.h"
45 45#include "devices.h"
46 46
47/* 47/*
48 * SCOOP Device 48 * SCOOP Device
@@ -332,7 +332,7 @@ MACHINE_START(TOSA, "SHARP Tosa")
332 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 332 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
333 .fixup = fixup_tosa, 333 .fixup = fixup_tosa,
334 .map_io = pxa_map_io, 334 .map_io = pxa_map_io,
335 .init_irq = pxa_init_irq, 335 .init_irq = pxa25x_init_irq,
336 .init_machine = tosa_init, 336 .init_machine = tosa_init,
337 .timer = &pxa_timer, 337 .timer = &pxa_timer,
338MACHINE_END 338MACHINE_END
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 28c79bd0a3a..e4ba43bdf85 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -49,6 +49,7 @@
49#include <asm/arch/ohci.h> 49#include <asm/arch/ohci.h>
50 50
51#include "generic.h" 51#include "generic.h"
52#include "devices.h"
52 53
53/******************************************************************************************** 54/********************************************************************************************
54 * ONBOARD FLASH 55 * ONBOARD FLASH
@@ -503,7 +504,7 @@ MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")
503 .boot_params = TRIZEPS4_SDRAM_BASE + 0x100, 504 .boot_params = TRIZEPS4_SDRAM_BASE + 0x100,
504 .init_machine = trizeps4_init, 505 .init_machine = trizeps4_init,
505 .map_io = trizeps4_map_io, 506 .map_io = trizeps4_map_io,
506 .init_irq = pxa_init_irq, 507 .init_irq = pxa27x_init_irq,
507 .timer = &pxa_timer, 508 .timer = &pxa_timer,
508MACHINE_END 509MACHINE_END
509 510
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index f01de807b72..8b52ea95d4f 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -20,6 +20,8 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/dm9000.h> 21#include <linux/dm9000.h>
22 22
23#include <net/ax88796.h>
24
23#include <asm/mach/arch.h> 25#include <asm/mach/arch.h>
24#include <asm/mach/map.h> 26#include <asm/mach/map.h>
25#include <asm/mach/irq.h> 27#include <asm/mach/irq.h>
@@ -409,6 +411,61 @@ static struct s3c2410_platform_i2c bast_i2c_info = {
409 .max_freq = 130*1000, 411 .max_freq = 130*1000,
410}; 412};
411 413
414/* Asix AX88796 10/100 ethernet controller */
415
416static struct ax_plat_data bast_asix_platdata = {
417 .flags = AXFLG_MAC_FROMDEV,
418 .wordlength = 2,
419 .dcr_val = 0x48,
420 .rcr_val = 0x40,
421};
422
423static struct resource bast_asix_resource[] = {
424 [0] = {
425 .start = S3C2410_CS5 + BAST_PA_ASIXNET,
426 .end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20) - 1,
427 .flags = IORESOURCE_MEM,
428 },
429 [1] = {
430 .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20),
431 .end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20),
432 .flags = IORESOURCE_MEM,
433 },
434 [2] = {
435 .start = IRQ_ASIX,
436 .end = IRQ_ASIX,
437 .flags = IORESOURCE_IRQ
438 }
439};
440
441static struct platform_device bast_device_asix = {
442 .name = "ax88796",
443 .id = 0,
444 .num_resources = ARRAY_SIZE(bast_asix_resource),
445 .resource = bast_asix_resource,
446 .dev = {
447 .platform_data = &bast_asix_platdata
448 }
449};
450
451/* Asix AX88796 10/100 ethernet controller parallel port */
452
453static struct resource bast_asixpp_resource[] = {
454 [0] = {
455 .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20),
456 .end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1b * 0x20) - 1,
457 .flags = IORESOURCE_MEM,
458 }
459};
460
461static struct platform_device bast_device_axpp = {
462 .name = "ax88796-pp",
463 .id = 0,
464 .num_resources = ARRAY_SIZE(bast_asixpp_resource),
465 .resource = bast_asixpp_resource,
466};
467
468/* LCD/VGA controller */
412 469
413static struct s3c2410fb_mach_info __initdata bast_lcd_info = { 470static struct s3c2410fb_mach_info __initdata bast_lcd_info = {
414 .width = 640, 471 .width = 640,
@@ -453,6 +510,8 @@ static struct platform_device *bast_devices[] __initdata = {
453 &s3c_device_nand, 510 &s3c_device_nand,
454 &bast_device_nor, 511 &bast_device_nor,
455 &bast_device_dm9k, 512 &bast_device_dm9k,
513 &bast_device_asix,
514 &bast_device_axpp,
456 &bast_sio, 515 &bast_sio,
457}; 516};
458 517
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
index bff7ddd06a5..29c163d300d 100644
--- a/arch/arm/mach-s3c2440/mach-anubis.c
+++ b/arch/arm/mach-s3c2440/mach-anubis.c
@@ -18,6 +18,9 @@
18#include <linux/serial_core.h> 18#include <linux/serial_core.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20 20
21#include <linux/sm501.h>
22#include <linux/sm501-regs.h>
23
21#include <asm/mach/arch.h> 24#include <asm/mach/arch.h>
22#include <asm/mach/map.h> 25#include <asm/mach/map.h>
23#include <asm/mach/irq.h> 26#include <asm/mach/irq.h>
@@ -42,6 +45,8 @@
42#include <linux/mtd/nand_ecc.h> 45#include <linux/mtd/nand_ecc.h>
43#include <linux/mtd/partitions.h> 46#include <linux/mtd/partitions.h>
44 47
48#include <net/ax88796.h>
49
45#include <asm/plat-s3c24xx/clock.h> 50#include <asm/plat-s3c24xx/clock.h>
46#include <asm/plat-s3c24xx/devs.h> 51#include <asm/plat-s3c24xx/devs.h>
47#include <asm/plat-s3c24xx/cpu.h> 52#include <asm/plat-s3c24xx/cpu.h>
@@ -153,6 +158,29 @@ static struct mtd_partition anubis_default_nand_part[] = {
153 } 158 }
154}; 159};
155 160
161static struct mtd_partition anubis_default_nand_part_large[] = {
162 [0] = {
163 .name = "Boot Agent",
164 .size = SZ_128K,
165 .offset = 0,
166 },
167 [1] = {
168 .name = "/boot",
169 .size = SZ_4M - SZ_128K,
170 .offset = SZ_128K,
171 },
172 [2] = {
173 .name = "user1",
174 .offset = SZ_4M,
175 .size = SZ_32M - SZ_4M,
176 },
177 [3] = {
178 .name = "user2",
179 .offset = SZ_32M,
180 .size = MTDPART_SIZ_FULL,
181 }
182};
183
156/* the Anubis has 3 selectable slots for nand-flash, the two 184/* the Anubis has 3 selectable slots for nand-flash, the two
157 * on-board chip areas, as well as the external slot. 185 * on-board chip areas, as well as the external slot.
158 * 186 *
@@ -260,6 +288,104 @@ static struct platform_device anubis_device_ide1 = {
260 .resource = anubis_ide1_resource, 288 .resource = anubis_ide1_resource,
261}; 289};
262 290
291/* Asix AX88796 10/100 ethernet controller */
292
293static struct ax_plat_data anubis_asix_platdata = {
294 .flags = AXFLG_MAC_FROMDEV,
295 .wordlength = 2,
296 .dcr_val = 0x48,
297 .rcr_val = 0x40,
298};
299
300static struct resource anubis_asix_resource[] = {
301 [0] = {
302 .start = S3C2410_CS5,
303 .end = S3C2410_CS5 + (0x20 * 0x20) -1,
304 .flags = IORESOURCE_MEM
305 },
306 [1] = {
307 .start = IRQ_ASIX,
308 .end = IRQ_ASIX,
309 .flags = IORESOURCE_IRQ
310 }
311};
312
313static struct platform_device anubis_device_asix = {
314 .name = "ax88796",
315 .id = 0,
316 .num_resources = ARRAY_SIZE(anubis_asix_resource),
317 .resource = anubis_asix_resource,
318 .dev = {
319 .platform_data = &anubis_asix_platdata,
320 }
321};
322
323/* SM501 */
324
325static struct resource anubis_sm501_resource[] = {
326 [0] = {
327 .start = S3C2410_CS2,
328 .end = S3C2410_CS2 + SZ_8M,
329 .flags = IORESOURCE_MEM,
330 },
331 [1] = {
332 .start = S3C2410_CS2 + SZ_64M - SZ_2M,
333 .end = S3C2410_CS2 + SZ_64M - 1,
334 .flags = IORESOURCE_MEM,
335 },
336 [2] = {
337 .start = IRQ_EINT0,
338 .end = IRQ_EINT0,
339 .flags = IORESOURCE_IRQ,
340 },
341};
342
343static struct sm501_initdata anubis_sm501_initdata = {
344 .gpio_high = {
345 .set = 0x3F000000, /* 24bit panel */
346 .mask = 0x0,
347 },
348 .misc_timing = {
349 .set = 0x010100, /* SDRAM timing */
350 .mask = 0x1F1F00,
351 },
352 .misc_control = {
353 .set = SM501_MISC_PNL_24BIT,
354 .mask = 0,
355 },
356
357 /* set the SDRAM and bus clocks */
358 .mclk = 72 * MHZ,
359 .m1xclk = 144 * MHZ,
360};
361
362static struct sm501_platdata_gpio_i2c anubis_sm501_gpio_i2c[] = {
363 [0] = {
364 .pin_scl = 44,
365 .pin_sda = 45,
366 },
367 [1] = {
368 .pin_scl = 40,
369 .pin_sda = 41,
370 },
371};
372
373static struct sm501_platdata anubis_sm501_platdata = {
374 .init = &anubis_sm501_initdata,
375 .gpio_i2c = anubis_sm501_gpio_i2c,
376 .gpio_i2c_nr = ARRAY_SIZE(anubis_sm501_gpio_i2c),
377};
378
379static struct platform_device anubis_device_sm501 = {
380 .name = "sm501",
381 .id = 0,
382 .num_resources = ARRAY_SIZE(anubis_sm501_resource),
383 .resource = anubis_sm501_resource,
384 .dev = {
385 .platform_data = &anubis_sm501_platdata,
386 },
387};
388
263/* Standard Anubis devices */ 389/* Standard Anubis devices */
264 390
265static struct platform_device *anubis_devices[] __initdata = { 391static struct platform_device *anubis_devices[] __initdata = {
@@ -271,6 +397,8 @@ static struct platform_device *anubis_devices[] __initdata = {
271 &s3c_device_nand, 397 &s3c_device_nand,
272 &anubis_device_ide0, 398 &anubis_device_ide0,
273 &anubis_device_ide1, 399 &anubis_device_ide1,
400 &anubis_device_asix,
401 &anubis_device_sm501,
274}; 402};
275 403
276static struct clk *anubis_clocks[] = { 404static struct clk *anubis_clocks[] = {
@@ -304,8 +432,17 @@ static void __init anubis_map_io(void)
304 s3c24xx_init_clocks(0); 432 s3c24xx_init_clocks(0);
305 s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs)); 433 s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
306 434
307 /* ensure that the GPIO is setup */ 435 /* check for the newer revision boards with large page nand */
308 s3c2410_gpio_setpin(S3C2410_GPA0, 1); 436
437 if ((__raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK) >= 4) {
438 printk(KERN_INFO "ANUBIS-B detected (revision %d)\n",
439 __raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK);
440 anubis_nand_sets[0].partitions = anubis_default_nand_part_large;
441 anubis_nand_sets[0].nr_partitions = ARRAY_SIZE(anubis_default_nand_part_large);
442 } else {
443 /* ensure that the GPIO is setup */
444 s3c2410_gpio_setpin(S3C2410_GPA0, 1);
445 }
309} 446}
310 447
311static void __init anubis_init(void) 448static void __init anubis_init(void)
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index 15811601f03..89f4c9c5777 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -166,6 +166,29 @@ static struct mtd_partition osiris_default_nand_part[] = {
166 } 166 }
167}; 167};
168 168
169static struct mtd_partition osiris_default_nand_part_large[] = {
170 [0] = {
171 .name = "Boot Agent",
172 .size = SZ_128K,
173 .offset = 0,
174 },
175 [1] = {
176 .name = "/boot",
177 .size = SZ_4M - SZ_128K,
178 .offset = SZ_128K,
179 },
180 [2] = {
181 .name = "user1",
182 .offset = SZ_4M,
183 .size = SZ_32M - SZ_4M,
184 },
185 [3] = {
186 .name = "user2",
187 .offset = SZ_32M,
188 .size = MTDPART_SIZ_FULL,
189 }
190};
191
169/* the Osiris has 3 selectable slots for nand-flash, the two 192/* the Osiris has 3 selectable slots for nand-flash, the two
170 * on-board chip areas, as well as the external slot. 193 * on-board chip areas, as well as the external slot.
171 * 194 *
@@ -322,14 +345,23 @@ static void __init osiris_map_io(void)
322 s3c24xx_init_clocks(0); 345 s3c24xx_init_clocks(0);
323 s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs)); 346 s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
324 347
348 /* check for the newer revision boards with large page nand */
349
350 if ((__raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK) >= 4) {
351 printk(KERN_INFO "OSIRIS-B detected (revision %d)\n",
352 __raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK);
353 osiris_nand_sets[0].partitions = osiris_default_nand_part_large;
354 osiris_nand_sets[0].nr_partitions = ARRAY_SIZE(osiris_default_nand_part_large);
355 } else {
356 /* write-protect line to the NAND */
357 s3c2410_gpio_setpin(S3C2410_GPA0, 1);
358 }
359
325 /* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */ 360 /* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */
326 361
327 local_irq_save(flags); 362 local_irq_save(flags);
328 __raw_writel(__raw_readl(S3C2410_BWSCON) | S3C2410_BWSCON_ST1 | S3C2410_BWSCON_ST2 | S3C2410_BWSCON_ST3 | S3C2410_BWSCON_ST4 | S3C2410_BWSCON_ST5, S3C2410_BWSCON); 363 __raw_writel(__raw_readl(S3C2410_BWSCON) | S3C2410_BWSCON_ST1 | S3C2410_BWSCON_ST2 | S3C2410_BWSCON_ST3 | S3C2410_BWSCON_ST4 | S3C2410_BWSCON_ST5, S3C2410_BWSCON);
329 local_irq_restore(flags); 364 local_irq_restore(flags);
330
331 /* write-protect line to the NAND */
332 s3c2410_gpio_setpin(S3C2410_GPA0, 1);
333} 365}
334 366
335static void __init osiris_init(void) 367static void __init osiris_init(void)