aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap1
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap1')
-rw-r--r--arch/arm/mach-omap1/Kconfig20
-rw-r--r--arch/arm/mach-omap1/Makefile11
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c116
-rw-r--r--arch/arm/mach-omap1/board-generic.c2
-rw-r--r--arch/arm/mach-omap1/board-h2.c200
-rw-r--r--arch/arm/mach-omap1/board-h3.c277
-rw-r--r--arch/arm/mach-omap1/board-innovator.c56
-rw-r--r--arch/arm/mach-omap1/board-netstar.c160
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c268
-rw-r--r--arch/arm/mach-omap1/board-osk.c95
-rw-r--r--arch/arm/mach-omap1/board-palmte.c12
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c123
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c8
-rw-r--r--arch/arm/mach-omap1/clock.c9
-rw-r--r--arch/arm/mach-omap1/clock.h91
-rw-r--r--arch/arm/mach-omap1/devices.c40
-rw-r--r--arch/arm/mach-omap1/io.c4
-rw-r--r--arch/arm/mach-omap1/irq.c18
-rw-r--r--arch/arm/mach-omap1/mux.c30
-rw-r--r--arch/arm/mach-omap1/pm.c770
-rw-r--r--arch/arm/mach-omap1/serial.c6
-rw-r--r--arch/arm/mach-omap1/sleep.S525
-rw-r--r--arch/arm/mach-omap1/time.c197
23 files changed, 2564 insertions, 474 deletions
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 86a0f0d14345..f8d716ccc1df 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -69,12 +69,6 @@ config MACH_VOICEBLUE
69 Support for Voiceblue GSM/VoIP gateway. Say Y here if you have 69 Support for Voiceblue GSM/VoIP gateway. Say Y here if you have
70 such a board. 70 such a board.
71 71
72config MACH_NETSTAR
73 bool "NetStar"
74 depends on ARCH_OMAP1 && ARCH_OMAP15XX
75 help
76 Support for NetStar PBX. Say Y here if you have such a board.
77
78config MACH_OMAP_PALMTE 72config MACH_OMAP_PALMTE
79 bool "Palm Tungsten E" 73 bool "Palm Tungsten E"
80 depends on ARCH_OMAP1 && ARCH_OMAP15XX 74 depends on ARCH_OMAP1 && ARCH_OMAP15XX
@@ -85,6 +79,20 @@ config MACH_OMAP_PALMTE
85 informations. 79 informations.
86 Say Y here if you have such a PDA, say NO otherwise. 80 Say Y here if you have such a PDA, say NO otherwise.
87 81
82config MACH_NOKIA770
83 bool "Nokia 770"
84 depends on ARCH_OMAP1 && ARCH_OMAP16XX
85 help
86 Support for the Nokia 770 Internet Tablet. Say Y here if you
87 have such a device.
88
89config MACH_AMS_DELTA
90 bool "Amstrad E3 (Delta)"
91 depends on ARCH_OMAP1 && ARCH_OMAP15XX
92 help
93 Support for the Amstrad E3 (codename Delta) videophone. Say Y here
94 if you have such a device.
95
88config MACH_OMAP_GENERIC 96config MACH_OMAP_GENERIC
89 bool "Generic OMAP board" 97 bool "Generic OMAP board"
90 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX) 98 depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index b0b00156faae..9ea719550ad3 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -3,7 +3,13 @@
3# 3#
4 4
5# Common support 5# Common support
6obj-y := io.o id.o clock.o irq.o time.o mux.o serial.o devices.o 6obj-y := io.o id.o clock.o irq.o mux.o serial.o devices.o
7
8obj-$(CONFIG_OMAP_MPU_TIMER) += time.o
9
10# Power Management
11obj-$(CONFIG_PM) += pm.o sleep.o
12
7led-y := leds.o 13led-y := leds.o
8 14
9# Specific board support 15# Specific board support
@@ -14,8 +20,9 @@ obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o
14obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o 20obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o
15obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o 21obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o
16obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o 22obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o
17obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o
18obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o 23obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o
24obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o
25obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o
19 26
20ifeq ($(CONFIG_ARCH_OMAP15XX),y) 27ifeq ($(CONFIG_ARCH_OMAP15XX),y)
21# Innovator-1510 FPGA 28# Innovator-1510 FPGA
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
new file mode 100644
index 000000000000..6178f046f128
--- /dev/null
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -0,0 +1,116 @@
1/*
2 * linux/arch/arm/mach-omap1/board-ams-delta.c
3 *
4 * Modified from board-generic.c
5 *
6 * Board specific inits for the Amstrad E3 (codename Delta) videophone
7 *
8 * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18
19#include <asm/hardware.h>
20#include <asm/mach-types.h>
21#include <asm/mach/arch.h>
22#include <asm/mach/map.h>
23
24#include <asm/arch/board-ams-delta.h>
25#include <asm/arch/gpio.h>
26#include <asm/arch/mux.h>
27#include <asm/arch/usb.h>
28#include <asm/arch/board.h>
29#include <asm/arch/common.h>
30
31static u8 ams_delta_latch1_reg;
32static u16 ams_delta_latch2_reg;
33
34void ams_delta_latch1_write(u8 mask, u8 value)
35{
36 ams_delta_latch1_reg &= ~mask;
37 ams_delta_latch1_reg |= value;
38 *(volatile __u8 *) AMS_DELTA_LATCH1_VIRT = ams_delta_latch1_reg;
39}
40
41void ams_delta_latch2_write(u16 mask, u16 value)
42{
43 ams_delta_latch2_reg &= ~mask;
44 ams_delta_latch2_reg |= value;
45 *(volatile __u16 *) AMS_DELTA_LATCH2_VIRT = ams_delta_latch2_reg;
46}
47
48static void __init ams_delta_init_irq(void)
49{
50 omap1_init_common_hw();
51 omap_init_irq();
52 omap_gpio_init();
53}
54
55static struct map_desc ams_delta_io_desc[] __initdata = {
56 // AMS_DELTA_LATCH1
57 {
58 .virtual = AMS_DELTA_LATCH1_VIRT,
59 .pfn = __phys_to_pfn(AMS_DELTA_LATCH1_PHYS),
60 .length = 0x01000000,
61 .type = MT_DEVICE
62 },
63 // AMS_DELTA_LATCH2
64 {
65 .virtual = AMS_DELTA_LATCH2_VIRT,
66 .pfn = __phys_to_pfn(AMS_DELTA_LATCH2_PHYS),
67 .length = 0x01000000,
68 .type = MT_DEVICE
69 },
70 // AMS_DELTA_MODEM
71 {
72 .virtual = AMS_DELTA_MODEM_VIRT,
73 .pfn = __phys_to_pfn(AMS_DELTA_MODEM_PHYS),
74 .length = 0x01000000,
75 .type = MT_DEVICE
76 }
77};
78
79static struct omap_uart_config ams_delta_uart_config __initdata = {
80 .enabled_uarts = 1,
81};
82
83static struct omap_board_config_kernel ams_delta_config[] = {
84 { OMAP_TAG_UART, &ams_delta_uart_config },
85};
86
87static void __init ams_delta_init(void)
88{
89 iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
90
91 omap_board_config = ams_delta_config;
92 omap_board_config_size = ARRAY_SIZE(ams_delta_config);
93 omap_serial_init();
94
95 /* Clear latch2 (NAND, LCD, modem enable) */
96 ams_delta_latch2_write(~0, 0);
97}
98
99static void __init ams_delta_map_io(void)
100{
101 omap1_map_common_io();
102}
103
104MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
105 /* Maintainer: Jonathan McDowell <noodles@earth.li> */
106 .phys_io = 0xfff00000,
107 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
108 .boot_params = 0x10000100,
109 .map_io = ams_delta_map_io,
110 .init_irq = ams_delta_init_irq,
111 .init_machine = ams_delta_init,
112 .timer = &omap_timer,
113MACHINE_END
114
115EXPORT_SYMBOL(ams_delta_latch1_write);
116EXPORT_SYMBOL(ams_delta_latch2_write);
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index a177e78b2b87..33d01adab1ed 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -88,7 +88,7 @@ static struct omap_board_config_kernel generic_config[] = {
88static void __init omap_generic_init(void) 88static void __init omap_generic_init(void)
89{ 89{
90#ifdef CONFIG_ARCH_OMAP15XX 90#ifdef CONFIG_ARCH_OMAP15XX
91 if (cpu_is_omap1510()) { 91 if (cpu_is_omap15xx()) {
92 generic_config[0].data = &generic1510_usb_config; 92 generic_config[0].data = &generic1510_usb_config;
93 } 93 }
94#endif 94#endif
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 89f0cc74a519..cd3a06dfc0a8 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -24,7 +24,9 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/mtd/mtd.h> 26#include <linux/mtd/mtd.h>
27#include <linux/mtd/nand.h>
27#include <linux/mtd/partitions.h> 28#include <linux/mtd/partitions.h>
29#include <linux/input.h>
28 30
29#include <asm/hardware.h> 31#include <asm/hardware.h>
30#include <asm/mach-types.h> 32#include <asm/mach-types.h>
@@ -35,12 +37,55 @@
35#include <asm/arch/gpio.h> 37#include <asm/arch/gpio.h>
36#include <asm/arch/mux.h> 38#include <asm/arch/mux.h>
37#include <asm/arch/tc.h> 39#include <asm/arch/tc.h>
40#include <asm/arch/irda.h>
38#include <asm/arch/usb.h> 41#include <asm/arch/usb.h>
42#include <asm/arch/keypad.h>
39#include <asm/arch/common.h> 43#include <asm/arch/common.h>
44#include <asm/arch/mcbsp.h>
45#include <asm/arch/omap-alsa.h>
40 46
41extern int omap_gpio_init(void); 47extern int omap_gpio_init(void);
42 48
43static struct mtd_partition h2_partitions[] = { 49static int h2_keymap[] = {
50 KEY(0, 0, KEY_LEFT),
51 KEY(0, 1, KEY_RIGHT),
52 KEY(0, 2, KEY_3),
53 KEY(0, 3, KEY_F10),
54 KEY(0, 4, KEY_F5),
55 KEY(0, 5, KEY_9),
56 KEY(1, 0, KEY_DOWN),
57 KEY(1, 1, KEY_UP),
58 KEY(1, 2, KEY_2),
59 KEY(1, 3, KEY_F9),
60 KEY(1, 4, KEY_F7),
61 KEY(1, 5, KEY_0),
62 KEY(2, 0, KEY_ENTER),
63 KEY(2, 1, KEY_6),
64 KEY(2, 2, KEY_1),
65 KEY(2, 3, KEY_F2),
66 KEY(2, 4, KEY_F6),
67 KEY(2, 5, KEY_HOME),
68 KEY(3, 0, KEY_8),
69 KEY(3, 1, KEY_5),
70 KEY(3, 2, KEY_F12),
71 KEY(3, 3, KEY_F3),
72 KEY(3, 4, KEY_F8),
73 KEY(3, 5, KEY_END),
74 KEY(4, 0, KEY_7),
75 KEY(4, 1, KEY_4),
76 KEY(4, 2, KEY_F11),
77 KEY(4, 3, KEY_F1),
78 KEY(4, 4, KEY_F4),
79 KEY(4, 5, KEY_ESC),
80 KEY(5, 0, KEY_F13),
81 KEY(5, 1, KEY_F14),
82 KEY(5, 2, KEY_F15),
83 KEY(5, 3, KEY_F16),
84 KEY(5, 4, KEY_SLEEP),
85 0
86};
87
88static struct mtd_partition h2_nor_partitions[] = {
44 /* bootloader (U-Boot, etc) in first sector */ 89 /* bootloader (U-Boot, etc) in first sector */
45 { 90 {
46 .name = "bootloader", 91 .name = "bootloader",
@@ -71,26 +116,26 @@ static struct mtd_partition h2_partitions[] = {
71 } 116 }
72}; 117};
73 118
74static struct flash_platform_data h2_flash_data = { 119static struct flash_platform_data h2_nor_data = {
75 .map_name = "cfi_probe", 120 .map_name = "cfi_probe",
76 .width = 2, 121 .width = 2,
77 .parts = h2_partitions, 122 .parts = h2_nor_partitions,
78 .nr_parts = ARRAY_SIZE(h2_partitions), 123 .nr_parts = ARRAY_SIZE(h2_nor_partitions),
79}; 124};
80 125
81static struct resource h2_flash_resource = { 126static struct resource h2_nor_resource = {
82 /* This is on CS3, wherever it's mapped */ 127 /* This is on CS3, wherever it's mapped */
83 .flags = IORESOURCE_MEM, 128 .flags = IORESOURCE_MEM,
84}; 129};
85 130
86static struct platform_device h2_flash_device = { 131static struct platform_device h2_nor_device = {
87 .name = "omapflash", 132 .name = "omapflash",
88 .id = 0, 133 .id = 0,
89 .dev = { 134 .dev = {
90 .platform_data = &h2_flash_data, 135 .platform_data = &h2_nor_data,
91 }, 136 },
92 .num_resources = 1, 137 .num_resources = 1,
93 .resource = &h2_flash_resource, 138 .resource = &h2_nor_resource,
94}; 139};
95 140
96static struct resource h2_smc91x_resources[] = { 141static struct resource h2_smc91x_resources[] = {
@@ -113,9 +158,119 @@ static struct platform_device h2_smc91x_device = {
113 .resource = h2_smc91x_resources, 158 .resource = h2_smc91x_resources,
114}; 159};
115 160
161static struct resource h2_kp_resources[] = {
162 [0] = {
163 .start = INT_KEYBOARD,
164 .end = INT_KEYBOARD,
165 .flags = IORESOURCE_IRQ,
166 },
167};
168
169static struct omap_kp_platform_data h2_kp_data = {
170 .rows = 8,
171 .cols = 8,
172 .keymap = h2_keymap,
173 .rep = 1,
174};
175
176static struct platform_device h2_kp_device = {
177 .name = "omap-keypad",
178 .id = -1,
179 .dev = {
180 .platform_data = &h2_kp_data,
181 },
182 .num_resources = ARRAY_SIZE(h2_kp_resources),
183 .resource = h2_kp_resources,
184};
185
186#define H2_IRDA_FIRSEL_GPIO_PIN 17
187
188#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
189static int h2_transceiver_mode(struct device *dev, int state)
190{
191 if (state & IR_SIRMODE)
192 omap_set_gpio_dataout(H2_IRDA_FIRSEL_GPIO_PIN, 0);
193 else /* MIR/FIR */
194 omap_set_gpio_dataout(H2_IRDA_FIRSEL_GPIO_PIN, 1);
195
196 return 0;
197}
198#endif
199
200static struct omap_irda_config h2_irda_data = {
201 .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
202 .rx_channel = OMAP_DMA_UART3_RX,
203 .tx_channel = OMAP_DMA_UART3_TX,
204 .dest_start = UART3_THR,
205 .src_start = UART3_RHR,
206 .tx_trigger = 0,
207 .rx_trigger = 0,
208};
209
210static struct resource h2_irda_resources[] = {
211 [0] = {
212 .start = INT_UART3,
213 .end = INT_UART3,
214 .flags = IORESOURCE_IRQ,
215 },
216};
217static struct platform_device h2_irda_device = {
218 .name = "omapirda",
219 .id = 0,
220 .dev = {
221 .platform_data = &h2_irda_data,
222 },
223 .num_resources = ARRAY_SIZE(h2_irda_resources),
224 .resource = h2_irda_resources,
225};
226
227static struct platform_device h2_lcd_device = {
228 .name = "lcd_h2",
229 .id = -1,
230};
231
232static struct omap_mcbsp_reg_cfg mcbsp_regs = {
233 .spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
234 .spcr1 = RINTM(3) | RRST,
235 .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
236 RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(1),
237 .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
238 .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
239 XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(1) | XFIG,
240 .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
241 .srgr1 = FWID(15),
242 .srgr2 = GSYNC | CLKSP | FSGM | FPER(31),
243
244 .pcr0 = CLKXM | CLKRM | FSXP | FSRP | CLKXP | CLKRP,
245 //.pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
246};
247
248static struct omap_alsa_codec_config alsa_config = {
249 .name = "H2 TSC2101",
250 .mcbsp_regs_alsa = &mcbsp_regs,
251 .codec_configure_dev = NULL, // tsc2101_configure,
252 .codec_set_samplerate = NULL, // tsc2101_set_samplerate,
253 .codec_clock_setup = NULL, // tsc2101_clock_setup,
254 .codec_clock_on = NULL, // tsc2101_clock_on,
255 .codec_clock_off = NULL, // tsc2101_clock_off,
256 .get_default_samplerate = NULL, // tsc2101_get_default_samplerate,
257};
258
259static struct platform_device h2_mcbsp1_device = {
260 .name = "omap_alsa_mcbsp",
261 .id = 1,
262 .dev = {
263 .platform_data = &alsa_config,
264 },
265};
266
116static struct platform_device *h2_devices[] __initdata = { 267static struct platform_device *h2_devices[] __initdata = {
117 &h2_flash_device, 268 &h2_nor_device,
118 &h2_smc91x_device, 269 &h2_smc91x_device,
270 &h2_irda_device,
271 &h2_kp_device,
272 &h2_lcd_device,
273 &h2_mcbsp1_device,
119}; 274};
120 275
121static void __init h2_init_smc91x(void) 276static void __init h2_init_smc91x(void)
@@ -164,7 +319,6 @@ static struct omap_uart_config h2_uart_config __initdata = {
164}; 319};
165 320
166static struct omap_lcd_config h2_lcd_config __initdata = { 321static struct omap_lcd_config h2_lcd_config __initdata = {
167 .panel_name = "h2",
168 .ctrl_name = "internal", 322 .ctrl_name = "internal",
169}; 323};
170 324
@@ -177,16 +331,34 @@ static struct omap_board_config_kernel h2_config[] = {
177 331
178static void __init h2_init(void) 332static void __init h2_init(void)
179{ 333{
180 /* NOTE: revC boards support NAND-boot, which can put NOR on CS2B 334 /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
181 * and NAND (either 16bit or 8bit) on CS3. 335 * to address 0 by a dip switch), NAND on CS2B. The NAND driver will
336 * notice whether a NAND chip is enabled at probe time.
337 *
338 * FIXME revC boards (and H3) support NAND-boot, with a dip switch to
339 * put NOR on CS2B and NAND (which on H2 may be 16bit) on CS3. Try
340 * detecting that in code here, to avoid probing every possible flash
341 * configuration...
182 */ 342 */
183 h2_flash_resource.end = h2_flash_resource.start = omap_cs3_phys(); 343 h2_nor_resource.end = h2_nor_resource.start = omap_cs3_phys();
184 h2_flash_resource.end += SZ_32M - 1; 344 h2_nor_resource.end += SZ_32M - 1;
345
346 omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
347 omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
185 348
186 /* MMC: card detect and WP */ 349 /* MMC: card detect and WP */
187 // omap_cfg_reg(U19_ARMIO1); /* CD */ 350 // omap_cfg_reg(U19_ARMIO1); /* CD */
188 omap_cfg_reg(BALLOUT_V8_ARMIO3); /* WP */ 351 omap_cfg_reg(BALLOUT_V8_ARMIO3); /* WP */
189 352
353 /* Irda */
354#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
355 omap_writel(omap_readl(FUNC_MUX_CTRL_A) | 7, FUNC_MUX_CTRL_A);
356 if (!(omap_request_gpio(H2_IRDA_FIRSEL_GPIO_PIN))) {
357 omap_set_gpio_direction(H2_IRDA_FIRSEL_GPIO_PIN, 0);
358 h2_irda_data.transceiver_mode = h2_transceiver_mode;
359 }
360#endif
361
190 platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices)); 362 platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
191 omap_board_config = h2_config; 363 omap_board_config = h2_config;
192 omap_board_config_size = ARRAY_SIZE(h2_config); 364 omap_board_config_size = ARRAY_SIZE(h2_config);
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index d9f386265996..4b8d0ec73cb7 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -21,8 +21,11 @@
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/workqueue.h>
24#include <linux/mtd/mtd.h> 25#include <linux/mtd/mtd.h>
26#include <linux/mtd/nand.h>
25#include <linux/mtd/partitions.h> 27#include <linux/mtd/partitions.h>
28#include <linux/input.h>
26 29
27#include <asm/setup.h> 30#include <asm/setup.h>
28#include <asm/page.h> 31#include <asm/page.h>
@@ -33,15 +36,59 @@
33#include <asm/mach/map.h> 36#include <asm/mach/map.h>
34 37
35#include <asm/arch/gpio.h> 38#include <asm/arch/gpio.h>
39#include <asm/arch/gpioexpander.h>
36#include <asm/arch/irqs.h> 40#include <asm/arch/irqs.h>
37#include <asm/arch/mux.h> 41#include <asm/arch/mux.h>
38#include <asm/arch/tc.h> 42#include <asm/arch/tc.h>
43#include <asm/arch/irda.h>
39#include <asm/arch/usb.h> 44#include <asm/arch/usb.h>
45#include <asm/arch/keypad.h>
46#include <asm/arch/dma.h>
40#include <asm/arch/common.h> 47#include <asm/arch/common.h>
41 48
42extern int omap_gpio_init(void); 49extern int omap_gpio_init(void);
43 50
44static struct mtd_partition h3_partitions[] = { 51static int h3_keymap[] = {
52 KEY(0, 0, KEY_LEFT),
53 KEY(0, 1, KEY_RIGHT),
54 KEY(0, 2, KEY_3),
55 KEY(0, 3, KEY_F10),
56 KEY(0, 4, KEY_F5),
57 KEY(0, 5, KEY_9),
58 KEY(1, 0, KEY_DOWN),
59 KEY(1, 1, KEY_UP),
60 KEY(1, 2, KEY_2),
61 KEY(1, 3, KEY_F9),
62 KEY(1, 4, KEY_F7),
63 KEY(1, 5, KEY_0),
64 KEY(2, 0, KEY_ENTER),
65 KEY(2, 1, KEY_6),
66 KEY(2, 2, KEY_1),
67 KEY(2, 3, KEY_F2),
68 KEY(2, 4, KEY_F6),
69 KEY(2, 5, KEY_HOME),
70 KEY(3, 0, KEY_8),
71 KEY(3, 1, KEY_5),
72 KEY(3, 2, KEY_F12),
73 KEY(3, 3, KEY_F3),
74 KEY(3, 4, KEY_F8),
75 KEY(3, 5, KEY_END),
76 KEY(4, 0, KEY_7),
77 KEY(4, 1, KEY_4),
78 KEY(4, 2, KEY_F11),
79 KEY(4, 3, KEY_F1),
80 KEY(4, 4, KEY_F4),
81 KEY(4, 5, KEY_ESC),
82 KEY(5, 0, KEY_F13),
83 KEY(5, 1, KEY_F14),
84 KEY(5, 2, KEY_F15),
85 KEY(5, 3, KEY_F16),
86 KEY(5, 4, KEY_SLEEP),
87 0
88};
89
90
91static struct mtd_partition nor_partitions[] = {
45 /* bootloader (U-Boot, etc) in first sector */ 92 /* bootloader (U-Boot, etc) in first sector */
46 { 93 {
47 .name = "bootloader", 94 .name = "bootloader",
@@ -72,26 +119,80 @@ static struct mtd_partition h3_partitions[] = {
72 } 119 }
73}; 120};
74 121
75static struct flash_platform_data h3_flash_data = { 122static struct flash_platform_data nor_data = {
76 .map_name = "cfi_probe", 123 .map_name = "cfi_probe",
77 .width = 2, 124 .width = 2,
78 .parts = h3_partitions, 125 .parts = nor_partitions,
79 .nr_parts = ARRAY_SIZE(h3_partitions), 126 .nr_parts = ARRAY_SIZE(nor_partitions),
80}; 127};
81 128
82static struct resource h3_flash_resource = { 129static struct resource nor_resource = {
83 /* This is on CS3, wherever it's mapped */ 130 /* This is on CS3, wherever it's mapped */
84 .flags = IORESOURCE_MEM, 131 .flags = IORESOURCE_MEM,
85}; 132};
86 133
87static struct platform_device flash_device = { 134static struct platform_device nor_device = {
88 .name = "omapflash", 135 .name = "omapflash",
89 .id = 0, 136 .id = 0,
90 .dev = { 137 .dev = {
91 .platform_data = &h3_flash_data, 138 .platform_data = &nor_data,
139 },
140 .num_resources = 1,
141 .resource = &nor_resource,
142};
143
144static struct mtd_partition nand_partitions[] = {
145#if 0
146 /* REVISIT: enable these partitions if you make NAND BOOT work */
147 {
148 .name = "xloader",
149 .offset = 0,
150 .size = 64 * 1024,
151 .mask_flags = MTD_WRITEABLE, /* force read-only */
152 },
153 {
154 .name = "bootloader",
155 .offset = MTDPART_OFS_APPEND,
156 .size = 256 * 1024,
157 .mask_flags = MTD_WRITEABLE, /* force read-only */
158 },
159 {
160 .name = "params",
161 .offset = MTDPART_OFS_APPEND,
162 .size = 192 * 1024,
163 },
164 {
165 .name = "kernel",
166 .offset = MTDPART_OFS_APPEND,
167 .size = 2 * SZ_1M,
168 },
169#endif
170 {
171 .name = "filesystem",
172 .size = MTDPART_SIZ_FULL,
173 .offset = MTDPART_OFS_APPEND,
174 },
175};
176
177/* dip switches control NAND chip access: 8 bit, 16 bit, or neither */
178static struct nand_platform_data nand_data = {
179 .options = NAND_SAMSUNG_LP_OPTIONS,
180 .parts = nand_partitions,
181 .nr_parts = ARRAY_SIZE(nand_partitions),
182};
183
184static struct resource nand_resource = {
185 .flags = IORESOURCE_MEM,
186};
187
188static struct platform_device nand_device = {
189 .name = "omapnand",
190 .id = 0,
191 .dev = {
192 .platform_data = &nand_data,
92 }, 193 },
93 .num_resources = 1, 194 .num_resources = 1,
94 .resource = &h3_flash_resource, 195 .resource = &nand_resource,
95}; 196};
96 197
97static struct resource smc91x_resources[] = { 198static struct resource smc91x_resources[] = {
@@ -138,10 +239,136 @@ static struct platform_device intlat_device = {
138 .resource = intlat_resources, 239 .resource = intlat_resources,
139}; 240};
140 241
242static struct resource h3_kp_resources[] = {
243 [0] = {
244 .start = INT_KEYBOARD,
245 .end = INT_KEYBOARD,
246 .flags = IORESOURCE_IRQ,
247 },
248};
249
250static struct omap_kp_platform_data h3_kp_data = {
251 .rows = 8,
252 .cols = 8,
253 .keymap = h3_keymap,
254 .rep = 1,
255};
256
257static struct platform_device h3_kp_device = {
258 .name = "omap-keypad",
259 .id = -1,
260 .dev = {
261 .platform_data = &h3_kp_data,
262 },
263 .num_resources = ARRAY_SIZE(h3_kp_resources),
264 .resource = h3_kp_resources,
265};
266
267
268/* Select between the IrDA and aGPS module
269 */
270static int h3_select_irda(struct device *dev, int state)
271{
272 unsigned char expa;
273 int err = 0;
274
275 if ((err = read_gpio_expa(&expa, 0x26))) {
276 printk(KERN_ERR "Error reading from I/O EXPANDER \n");
277 return err;
278 }
279
280 /* 'P6' enable/disable IRDA_TX and IRDA_RX */
281 if (state & IR_SEL) { /* IrDA */
282 if ((err = write_gpio_expa(expa | 0x40, 0x26))) {
283 printk(KERN_ERR "Error writing to I/O EXPANDER \n");
284 return err;
285 }
286 } else {
287 if ((err = write_gpio_expa(expa & ~0x40, 0x26))) {
288 printk(KERN_ERR "Error writing to I/O EXPANDER \n");
289 return err;
290 }
291 }
292 return err;
293}
294
295static void set_trans_mode(void *data)
296{
297 int *mode = data;
298 unsigned char expa;
299 int err = 0;
300
301 if ((err = read_gpio_expa(&expa, 0x27)) != 0) {
302 printk(KERN_ERR "Error reading from I/O expander\n");
303 }
304
305 expa &= ~0x03;
306
307 if (*mode & IR_SIRMODE) {
308 expa |= 0x01;
309 } else { /* MIR/FIR */
310 expa |= 0x03;
311 }
312
313 if ((err = write_gpio_expa(expa, 0x27)) != 0) {
314 printk(KERN_ERR "Error writing to I/O expander\n");
315 }
316}
317
318static int h3_transceiver_mode(struct device *dev, int mode)
319{
320 struct omap_irda_config *irda_config = dev->platform_data;
321
322 cancel_delayed_work(&irda_config->gpio_expa);
323 PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode);
324 schedule_work(&irda_config->gpio_expa);
325
326 return 0;
327}
328
329static struct omap_irda_config h3_irda_data = {
330 .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
331 .transceiver_mode = h3_transceiver_mode,
332 .select_irda = h3_select_irda,
333 .rx_channel = OMAP_DMA_UART3_RX,
334 .tx_channel = OMAP_DMA_UART3_TX,
335 .dest_start = UART3_THR,
336 .src_start = UART3_RHR,
337 .tx_trigger = 0,
338 .rx_trigger = 0,
339};
340
341static struct resource h3_irda_resources[] = {
342 [0] = {
343 .start = INT_UART3,
344 .end = INT_UART3,
345 .flags = IORESOURCE_IRQ,
346 },
347};
348
349static struct platform_device h3_irda_device = {
350 .name = "omapirda",
351 .id = 0,
352 .dev = {
353 .platform_data = &h3_irda_data,
354 },
355 .num_resources = ARRAY_SIZE(h3_irda_resources),
356 .resource = h3_irda_resources,
357};
358
359static struct platform_device h3_lcd_device = {
360 .name = "lcd_h3",
361 .id = -1,
362};
363
141static struct platform_device *devices[] __initdata = { 364static struct platform_device *devices[] __initdata = {
142 &flash_device, 365 &nor_device,
366 &nand_device,
143 &smc91x_device, 367 &smc91x_device,
144 &intlat_device, 368 &intlat_device,
369 &h3_irda_device,
370 &h3_kp_device,
371 &h3_lcd_device,
145}; 372};
146 373
147static struct omap_usb_config h3_usb_config __initdata = { 374static struct omap_usb_config h3_usb_config __initdata = {
@@ -171,7 +398,6 @@ static struct omap_uart_config h3_uart_config __initdata = {
171}; 398};
172 399
173static struct omap_lcd_config h3_lcd_config __initdata = { 400static struct omap_lcd_config h3_lcd_config __initdata = {
174 .panel_name = "h3",
175 .ctrl_name = "internal", 401 .ctrl_name = "internal",
176}; 402};
177 403
@@ -182,11 +408,36 @@ static struct omap_board_config_kernel h3_config[] = {
182 { OMAP_TAG_LCD, &h3_lcd_config }, 408 { OMAP_TAG_LCD, &h3_lcd_config },
183}; 409};
184 410
411#define H3_NAND_RB_GPIO_PIN 10
412
413static int nand_dev_ready(struct nand_platform_data *data)
414{
415 return omap_get_gpio_datain(H3_NAND_RB_GPIO_PIN);
416}
417
185static void __init h3_init(void) 418static void __init h3_init(void)
186{ 419{
187 h3_flash_resource.end = h3_flash_resource.start = omap_cs3_phys(); 420 /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
188 h3_flash_resource.end += OMAP_CS3_SIZE - 1; 421 * to address 0 by a dip switch), NAND on CS2B. The NAND driver will
189 (void) platform_add_devices(devices, ARRAY_SIZE(devices)); 422 * notice whether a NAND chip is enabled at probe time.
423 *
424 * H3 support NAND-boot, with a dip switch to put NOR on CS2B and NAND
425 * (which on H2 may be 16bit) on CS3. Try detecting that in code here,
426 * to avoid probing every possible flash configuration...
427 */
428 nor_resource.end = nor_resource.start = omap_cs3_phys();
429 nor_resource.end += SZ_32M - 1;
430
431 nand_resource.end = nand_resource.start = OMAP_CS2B_PHYS;
432 nand_resource.end += SZ_4K - 1;
433 if (!(omap_request_gpio(H3_NAND_RB_GPIO_PIN)))
434 nand_data.dev_ready = nand_dev_ready;
435
436 /* GPIO10 Func_MUX_CTRL reg bit 29:27, Configure V2 to mode1 as GPIO */
437 /* GPIO10 pullup/down register, Enable pullup on GPIO10 */
438 omap_cfg_reg(V2_1710_GPIO10);
439
440 platform_add_devices(devices, ARRAY_SIZE(devices));
190 omap_board_config = h3_config; 441 omap_board_config = h3_config;
191 omap_board_config_size = ARRAY_SIZE(h3_config); 442 omap_board_config_size = ARRAY_SIZE(h3_config);
192 omap_serial_init(); 443 omap_serial_init();
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index a04e4332915e..e90c137a4cf3 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -22,6 +22,7 @@
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/mtd/mtd.h> 23#include <linux/mtd/mtd.h>
24#include <linux/mtd/partitions.h> 24#include <linux/mtd/partitions.h>
25#include <linux/input.h>
25 26
26#include <asm/hardware.h> 27#include <asm/hardware.h>
27#include <asm/mach-types.h> 28#include <asm/mach-types.h>
@@ -34,8 +35,22 @@
34#include <asm/arch/gpio.h> 35#include <asm/arch/gpio.h>
35#include <asm/arch/tc.h> 36#include <asm/arch/tc.h>
36#include <asm/arch/usb.h> 37#include <asm/arch/usb.h>
38#include <asm/arch/keypad.h>
37#include <asm/arch/common.h> 39#include <asm/arch/common.h>
38 40
41static int innovator_keymap[] = {
42 KEY(0, 0, KEY_F1),
43 KEY(0, 3, KEY_DOWN),
44 KEY(1, 1, KEY_F2),
45 KEY(1, 2, KEY_RIGHT),
46 KEY(2, 0, KEY_F3),
47 KEY(2, 1, KEY_F4),
48 KEY(2, 2, KEY_UP),
49 KEY(3, 2, KEY_ENTER),
50 KEY(3, 3, KEY_LEFT),
51 0
52};
53
39static struct mtd_partition innovator_partitions[] = { 54static struct mtd_partition innovator_partitions[] = {
40 /* bootloader (U-Boot, etc) in first sector */ 55 /* bootloader (U-Boot, etc) in first sector */
41 { 56 {
@@ -97,6 +112,31 @@ static struct platform_device innovator_flash_device = {
97 .resource = &innovator_flash_resource, 112 .resource = &innovator_flash_resource,
98}; 113};
99 114
115static struct resource innovator_kp_resources[] = {
116 [0] = {
117 .start = INT_KEYBOARD,
118 .end = INT_KEYBOARD,
119 .flags = IORESOURCE_IRQ,
120 },
121};
122
123static struct omap_kp_platform_data innovator_kp_data = {
124 .rows = 8,
125 .cols = 8,
126 .keymap = innovator_keymap,
127};
128
129static struct platform_device innovator_kp_device = {
130 .name = "omap-keypad",
131 .id = -1,
132 .dev = {
133 .platform_data = &innovator_kp_data,
134 },
135 .num_resources = ARRAY_SIZE(innovator_kp_resources),
136 .resource = innovator_kp_resources,
137};
138
139
100#ifdef CONFIG_ARCH_OMAP15XX 140#ifdef CONFIG_ARCH_OMAP15XX
101 141
102/* Only FPGA needs to be mapped here. All others are done with ioremap */ 142/* Only FPGA needs to be mapped here. All others are done with ioremap */
@@ -129,9 +169,16 @@ static struct platform_device innovator1510_smc91x_device = {
129 .resource = innovator1510_smc91x_resources, 169 .resource = innovator1510_smc91x_resources,
130}; 170};
131 171
172static struct platform_device innovator1510_lcd_device = {
173 .name = "lcd_inn1510",
174 .id = -1,
175};
176
132static struct platform_device *innovator1510_devices[] __initdata = { 177static struct platform_device *innovator1510_devices[] __initdata = {
133 &innovator_flash_device, 178 &innovator_flash_device,
134 &innovator1510_smc91x_device, 179 &innovator1510_smc91x_device,
180 &innovator_kp_device,
181 &innovator1510_lcd_device,
135}; 182};
136 183
137#endif /* CONFIG_ARCH_OMAP15XX */ 184#endif /* CONFIG_ARCH_OMAP15XX */
@@ -158,9 +205,16 @@ static struct platform_device innovator1610_smc91x_device = {
158 .resource = innovator1610_smc91x_resources, 205 .resource = innovator1610_smc91x_resources,
159}; 206};
160 207
208static struct platform_device innovator1610_lcd_device = {
209 .name = "inn1610_lcd",
210 .id = -1,
211};
212
161static struct platform_device *innovator1610_devices[] __initdata = { 213static struct platform_device *innovator1610_devices[] __initdata = {
162 &innovator_flash_device, 214 &innovator_flash_device,
163 &innovator1610_smc91x_device, 215 &innovator1610_smc91x_device,
216 &innovator_kp_device,
217 &innovator1610_lcd_device,
164}; 218};
165 219
166#endif /* CONFIG_ARCH_OMAP16XX */ 220#endif /* CONFIG_ARCH_OMAP16XX */
@@ -206,7 +260,6 @@ static struct omap_usb_config innovator1510_usb_config __initdata = {
206}; 260};
207 261
208static struct omap_lcd_config innovator1510_lcd_config __initdata = { 262static struct omap_lcd_config innovator1510_lcd_config __initdata = {
209 .panel_name = "inn1510",
210 .ctrl_name = "internal", 263 .ctrl_name = "internal",
211}; 264};
212#endif 265#endif
@@ -228,7 +281,6 @@ static struct omap_usb_config h2_usb_config __initdata = {
228}; 281};
229 282
230static struct omap_lcd_config innovator1610_lcd_config __initdata = { 283static struct omap_lcd_config innovator1610_lcd_config __initdata = {
231 .panel_name = "inn1610",
232 .ctrl_name = "internal", 284 .ctrl_name = "internal",
233}; 285};
234#endif 286#endif
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c
deleted file mode 100644
index 7520e602d7a2..000000000000
--- a/arch/arm/mach-omap1/board-netstar.c
+++ /dev/null
@@ -1,160 +0,0 @@
1/*
2 * Modified from board-generic.c
3 *
4 * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
5 *
6 * Code for Netstar OMAP board.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/delay.h>
14#include <linux/platform_device.h>
15#include <linux/interrupt.h>
16#include <linux/init.h>
17#include <linux/kernel.h>
18#include <linux/notifier.h>
19#include <linux/reboot.h>
20
21#include <asm/hardware.h>
22#include <asm/mach-types.h>
23#include <asm/mach/arch.h>
24#include <asm/mach/map.h>
25
26#include <asm/arch/gpio.h>
27#include <asm/arch/mux.h>
28#include <asm/arch/usb.h>
29#include <asm/arch/common.h>
30
31extern void __init omap_init_time(void);
32extern int omap_gpio_init(void);
33
34static struct resource netstar_smc91x_resources[] = {
35 [0] = {
36 .start = OMAP_CS1_PHYS + 0x300,
37 .end = OMAP_CS1_PHYS + 0x300 + 16,
38 .flags = IORESOURCE_MEM,
39 },
40 [1] = {
41 .start = OMAP_GPIO_IRQ(8),
42 .end = OMAP_GPIO_IRQ(8),
43 .flags = IORESOURCE_IRQ,
44 },
45};
46
47static struct platform_device netstar_smc91x_device = {
48 .name = "smc91x",
49 .id = 0,
50 .num_resources = ARRAY_SIZE(netstar_smc91x_resources),
51 .resource = netstar_smc91x_resources,
52};
53
54static struct platform_device *netstar_devices[] __initdata = {
55 &netstar_smc91x_device,
56};
57
58static struct omap_uart_config netstar_uart_config __initdata = {
59 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
60};
61
62static struct omap_board_config_kernel netstar_config[] = {
63 { OMAP_TAG_UART, &netstar_uart_config },
64};
65
66static void __init netstar_init_irq(void)
67{
68 omap1_init_common_hw();
69 omap_init_irq();
70 omap_gpio_init();
71}
72
73static void __init netstar_init(void)
74{
75 /* green LED */
76 omap_request_gpio(4);
77 omap_set_gpio_direction(4, 0);
78 /* smc91x reset */
79 omap_request_gpio(7);
80 omap_set_gpio_direction(7, 0);
81 omap_set_gpio_dataout(7, 1);
82 udelay(2); /* wait at least 100ns */
83 omap_set_gpio_dataout(7, 0);
84 mdelay(50); /* 50ms until PHY ready */
85 /* smc91x interrupt pin */
86 omap_request_gpio(8);
87
88 omap_request_gpio(12);
89 omap_request_gpio(13);
90 omap_request_gpio(14);
91 omap_request_gpio(15);
92 set_irq_type(OMAP_GPIO_IRQ(12), IRQT_FALLING);
93 set_irq_type(OMAP_GPIO_IRQ(13), IRQT_FALLING);
94 set_irq_type(OMAP_GPIO_IRQ(14), IRQT_FALLING);
95 set_irq_type(OMAP_GPIO_IRQ(15), IRQT_FALLING);
96
97 platform_add_devices(netstar_devices, ARRAY_SIZE(netstar_devices));
98
99 /* Switch on green LED */
100 omap_set_gpio_dataout(4, 0);
101 /* Switch off red LED */
102 omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */
103 omap_writeb(0x80, OMAP_LPG1_LCR);
104
105 omap_board_config = netstar_config;
106 omap_board_config_size = ARRAY_SIZE(netstar_config);
107 omap_serial_init();
108}
109
110static void __init netstar_map_io(void)
111{
112 omap1_map_common_io();
113}
114
115#define MACHINE_PANICED 1
116#define MACHINE_REBOOTING 2
117#define MACHINE_REBOOT 4
118static unsigned long machine_state;
119
120static int panic_event(struct notifier_block *this, unsigned long event,
121 void *ptr)
122{
123 if (test_and_set_bit(MACHINE_PANICED, &machine_state))
124 return NOTIFY_DONE;
125
126 /* Switch off green LED */
127 omap_set_gpio_dataout(4, 1);
128 /* Flash red LED */
129 omap_writeb(0x78, OMAP_LPG1_LCR);
130 omap_writeb(0x01, OMAP_LPG1_PMR); /* Enable clock */
131
132 return NOTIFY_DONE;
133}
134
135static struct notifier_block panic_block = {
136 .notifier_call = panic_event,
137};
138
139static int __init netstar_late_init(void)
140{
141 /* TODO: Setup front panel switch here */
142
143 /* Setup panic notifier */
144 atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
145
146 return 0;
147}
148
149postcore_initcall(netstar_late_init);
150
151MACHINE_START(NETSTAR, "NetStar OMAP5910")
152 /* Maintainer: Ladislav Michl <michl@2n.cz> */
153 .phys_io = 0xfff00000,
154 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
155 .boot_params = 0x10000100,
156 .map_io = netstar_map_io,
157 .init_irq = netstar_init_irq,
158 .init_machine = netstar_init,
159 .timer = &omap_timer,
160MACHINE_END
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
new file mode 100644
index 000000000000..02b980d77b12
--- /dev/null
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -0,0 +1,268 @@
1/*
2 * linux/arch/arm/mach-omap1/board-nokia770.c
3 *
4 * Modified from board-generic.c
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#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/platform_device.h>
14#include <linux/input.h>
15#include <linux/clk.h>
16
17#include <linux/spi/spi.h>
18#include <linux/spi/ads7846.h>
19
20#include <asm/hardware.h>
21#include <asm/mach-types.h>
22#include <asm/mach/arch.h>
23#include <asm/mach/map.h>
24
25#include <asm/arch/gpio.h>
26#include <asm/arch/mux.h>
27#include <asm/arch/usb.h>
28#include <asm/arch/board.h>
29#include <asm/arch/keypad.h>
30#include <asm/arch/common.h>
31#include <asm/arch/dsp_common.h>
32#include <asm/arch/aic23.h>
33#include <asm/arch/gpio.h>
34
35static void __init omap_nokia770_init_irq(void)
36{
37 /* On Nokia 770, the SleepX signal is masked with an
38 * MPUIO line by default. It has to be unmasked for it
39 * to become functional */
40
41 /* SleepX mask direction */
42 omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008);
43 /* Unmask SleepX signal */
44 omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004);
45
46 omap1_init_common_hw();
47 omap_init_irq();
48}
49
50static int nokia770_keymap[] = {
51 KEY(0, 1, GROUP_0 | KEY_UP),
52 KEY(0, 2, GROUP_1 | KEY_F5),
53 KEY(1, 0, GROUP_0 | KEY_LEFT),
54 KEY(1, 1, GROUP_0 | KEY_ENTER),
55 KEY(1, 2, GROUP_0 | KEY_RIGHT),
56 KEY(2, 0, GROUP_1 | KEY_ESC),
57 KEY(2, 1, GROUP_0 | KEY_DOWN),
58 KEY(2, 2, GROUP_1 | KEY_F4),
59 KEY(3, 0, GROUP_2 | KEY_F7),
60 KEY(3, 1, GROUP_2 | KEY_F8),
61 KEY(3, 2, GROUP_2 | KEY_F6),
62 0
63};
64
65static struct resource nokia770_kp_resources[] = {
66 [0] = {
67 .start = INT_KEYBOARD,
68 .end = INT_KEYBOARD,
69 .flags = IORESOURCE_IRQ,
70 },
71};
72
73static struct omap_kp_platform_data nokia770_kp_data = {
74 .rows = 8,
75 .cols = 8,
76 .keymap = nokia770_keymap
77};
78
79static struct platform_device nokia770_kp_device = {
80 .name = "omap-keypad",
81 .id = -1,
82 .dev = {
83 .platform_data = &nokia770_kp_data,
84 },
85 .num_resources = ARRAY_SIZE(nokia770_kp_resources),
86 .resource = nokia770_kp_resources,
87};
88
89static struct platform_device *nokia770_devices[] __initdata = {
90 &nokia770_kp_device,
91};
92
93static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = {
94 .x_max = 0x0fff,
95 .y_max = 0x0fff,
96 .x_plate_ohms = 180,
97 .pressure_max = 255,
98 .debounce_max = 10,
99 .debounce_tol = 3,
100};
101
102static struct spi_board_info nokia770_spi_board_info[] __initdata = {
103 [0] = {
104 .modalias = "lcd_lph8923",
105 .bus_num = 2,
106 .chip_select = 3,
107 .max_speed_hz = 12000000,
108 },
109 [1] = {
110 .modalias = "ads7846",
111 .bus_num = 2,
112 .chip_select = 0,
113 .max_speed_hz = 2500000,
114 .irq = OMAP_GPIO_IRQ(15),
115 .platform_data = &nokia770_ads7846_platform_data,
116 },
117};
118
119
120/* assume no Mini-AB port */
121
122static struct omap_usb_config nokia770_usb_config __initdata = {
123 .otg = 1,
124 .register_host = 1,
125 .register_dev = 1,
126 .hmc_mode = 16,
127 .pins[0] = 6,
128};
129
130static struct omap_mmc_config nokia770_mmc_config __initdata = {
131 .mmc[0] = {
132 .enabled = 0,
133 .wire4 = 0,
134 .wp_pin = -1,
135 .power_pin = -1,
136 .switch_pin = -1,
137 },
138 .mmc[1] = {
139 .enabled = 0,
140 .wire4 = 0,
141 .wp_pin = -1,
142 .power_pin = -1,
143 .switch_pin = -1,
144 },
145};
146
147static struct omap_board_config_kernel nokia770_config[] = {
148 { OMAP_TAG_USB, NULL },
149 { OMAP_TAG_MMC, &nokia770_mmc_config },
150};
151
152/*
153 * audio power control
154 */
155#define HEADPHONE_GPIO 14
156#define AMPLIFIER_CTRL_GPIO 58
157
158static struct clk *dspxor_ck;
159static DECLARE_MUTEX(audio_pwr_sem);
160/*
161 * audio_pwr_state
162 * +--+-------------------------+---------------------------------------+
163 * |-1|down |power-up request -> 0 |
164 * +--+-------------------------+---------------------------------------+
165 * | 0|up |power-down(1) request -> 1 |
166 * | | |power-down(2) request -> (ignore) |
167 * +--+-------------------------+---------------------------------------+
168 * | 1|up, |power-up request -> 0 |
169 * | |received down(1) request |power-down(2) request -> -1 |
170 * +--+-------------------------+---------------------------------------+
171 */
172static int audio_pwr_state = -1;
173
174/*
175 * audio_pwr_up / down should be called under audio_pwr_sem
176 */
177static void nokia770_audio_pwr_up(void)
178{
179 clk_enable(dspxor_ck);
180
181 /* Turn on codec */
182 tlv320aic23_power_up();
183
184 if (omap_get_gpio_datain(HEADPHONE_GPIO))
185 /* HP not connected, turn on amplifier */
186 omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 1);
187 else
188 /* HP connected, do not turn on amplifier */
189 printk("HP connected\n");
190}
191
192static void codec_delayed_power_down(void *arg)
193{
194 down(&audio_pwr_sem);
195 if (audio_pwr_state == -1)
196 tlv320aic23_power_down();
197 clk_disable(dspxor_ck);
198 up(&audio_pwr_sem);
199}
200
201static DECLARE_WORK(codec_power_down_work, codec_delayed_power_down, NULL);
202
203static void nokia770_audio_pwr_down(void)
204{
205 /* Turn off amplifier */
206 omap_set_gpio_dataout(AMPLIFIER_CTRL_GPIO, 0);
207
208 /* Turn off codec: schedule delayed work */
209 schedule_delayed_work(&codec_power_down_work, HZ / 20); /* 50ms */
210}
211
212void nokia770_audio_pwr_up_request(int stage)
213{
214 down(&audio_pwr_sem);
215 if (audio_pwr_state == -1)
216 nokia770_audio_pwr_up();
217 /* force audio_pwr_state = 0, even if it was 1. */
218 audio_pwr_state = 0;
219 up(&audio_pwr_sem);
220}
221
222void nokia770_audio_pwr_down_request(int stage)
223{
224 down(&audio_pwr_sem);
225 switch (stage) {
226 case 1:
227 if (audio_pwr_state == 0)
228 audio_pwr_state = 1;
229 break;
230 case 2:
231 if (audio_pwr_state == 1) {
232 nokia770_audio_pwr_down();
233 audio_pwr_state = -1;
234 }
235 break;
236 }
237 up(&audio_pwr_sem);
238}
239
240static void __init omap_nokia770_init(void)
241{
242 nokia770_config[0].data = &nokia770_usb_config;
243
244 platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));
245 spi_register_board_info(nokia770_spi_board_info,
246 ARRAY_SIZE(nokia770_spi_board_info));
247 omap_board_config = nokia770_config;
248 omap_board_config_size = ARRAY_SIZE(nokia770_config);
249 omap_serial_init();
250 omap_dsp_audio_pwr_up_request = nokia770_audio_pwr_up_request;
251 omap_dsp_audio_pwr_down_request = nokia770_audio_pwr_down_request;
252 dspxor_ck = clk_get(0, "dspxor_ck");
253}
254
255static void __init omap_nokia770_map_io(void)
256{
257 omap1_map_common_io();
258}
259
260MACHINE_START(NOKIA770, "Nokia 770")
261 .phys_io = 0xfff00000,
262 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
263 .boot_params = 0x10000100,
264 .map_io = omap_nokia770_map_io,
265 .init_irq = omap_nokia770_init_irq,
266 .init_machine = omap_nokia770_init,
267 .timer = &omap_timer,
268MACHINE_END
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 543fa136106d..1160093e8ef6 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -33,6 +33,7 @@
33 33
34#include <linux/mtd/mtd.h> 34#include <linux/mtd/mtd.h>
35#include <linux/mtd/partitions.h> 35#include <linux/mtd/partitions.h>
36#include <linux/input.h>
36 37
37#include <asm/hardware.h> 38#include <asm/hardware.h>
38#include <asm/mach-types.h> 39#include <asm/mach-types.h>
@@ -44,7 +45,24 @@
44#include <asm/arch/usb.h> 45#include <asm/arch/usb.h>
45#include <asm/arch/mux.h> 46#include <asm/arch/mux.h>
46#include <asm/arch/tc.h> 47#include <asm/arch/tc.h>
48#include <asm/arch/keypad.h>
47#include <asm/arch/common.h> 49#include <asm/arch/common.h>
50#include <asm/arch/mcbsp.h>
51#include <asm/arch/omap-alsa.h>
52
53static int osk_keymap[] = {
54 KEY(0, 0, KEY_F1),
55 KEY(0, 3, KEY_UP),
56 KEY(1, 1, KEY_LEFTCTRL),
57 KEY(1, 2, KEY_LEFT),
58 KEY(2, 0, KEY_SPACE),
59 KEY(2, 1, KEY_ESC),
60 KEY(2, 2, KEY_DOWN),
61 KEY(3, 2, KEY_ENTER),
62 KEY(3, 3, KEY_RIGHT),
63 0
64};
65
48 66
49static struct mtd_partition osk_partitions[] = { 67static struct mtd_partition osk_partitions[] = {
50 /* bootloader (U-Boot, etc) in first sector */ 68 /* bootloader (U-Boot, etc) in first sector */
@@ -133,9 +151,69 @@ static struct platform_device osk5912_cf_device = {
133 .resource = osk5912_cf_resources, 151 .resource = osk5912_cf_resources,
134}; 152};
135 153
154#define DEFAULT_BITPERSAMPLE 16
155
156static struct omap_mcbsp_reg_cfg mcbsp_regs = {
157 .spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
158 .spcr1 = RINTM(3) | RRST,
159 .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
160 RWDLEN2(OMAP_MCBSP_WORD_16) | RDATDLY(0),
161 .rcr1 = RFRLEN1(OMAP_MCBSP_WORD_8) | RWDLEN1(OMAP_MCBSP_WORD_16),
162 .xcr2 = XPHASE | XFRLEN2(OMAP_MCBSP_WORD_8) |
163 XWDLEN2(OMAP_MCBSP_WORD_16) | XDATDLY(0) | XFIG,
164 .xcr1 = XFRLEN1(OMAP_MCBSP_WORD_8) | XWDLEN1(OMAP_MCBSP_WORD_16),
165 .srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1),
166 .srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1),
167 /*.pcr0 = FSXM | FSRM | CLKXM | CLKRM | CLKXP | CLKRP,*/ /* mcbsp: master */
168 .pcr0 = CLKXP | CLKRP, /* mcbsp: slave */
169};
170
171static struct omap_alsa_codec_config alsa_config = {
172 .name = "OSK AIC23",
173 .mcbsp_regs_alsa = &mcbsp_regs,
174 .codec_configure_dev = NULL, // aic23_configure,
175 .codec_set_samplerate = NULL, // aic23_set_samplerate,
176 .codec_clock_setup = NULL, // aic23_clock_setup,
177 .codec_clock_on = NULL, // aic23_clock_on,
178 .codec_clock_off = NULL, // aic23_clock_off,
179 .get_default_samplerate = NULL, // aic23_get_default_samplerate,
180};
181
136static struct platform_device osk5912_mcbsp1_device = { 182static struct platform_device osk5912_mcbsp1_device = {
137 .name = "omap_mcbsp", 183 .name = "omap_alsa_mcbsp",
138 .id = 1, 184 .id = 1,
185 .dev = {
186 .platform_data = &alsa_config,
187 },
188};
189
190static struct resource osk5912_kp_resources[] = {
191 [0] = {
192 .start = INT_KEYBOARD,
193 .end = INT_KEYBOARD,
194 .flags = IORESOURCE_IRQ,
195 },
196};
197
198static struct omap_kp_platform_data osk_kp_data = {
199 .rows = 8,
200 .cols = 8,
201 .keymap = osk_keymap,
202};
203
204static struct platform_device osk5912_kp_device = {
205 .name = "omap-keypad",
206 .id = -1,
207 .dev = {
208 .platform_data = &osk_kp_data,
209 },
210 .num_resources = ARRAY_SIZE(osk5912_kp_resources),
211 .resource = osk5912_kp_resources,
212};
213
214static struct platform_device osk5912_lcd_device = {
215 .name = "lcd_osk",
216 .id = -1,
139}; 217};
140 218
141static struct platform_device *osk5912_devices[] __initdata = { 219static struct platform_device *osk5912_devices[] __initdata = {
@@ -143,6 +221,8 @@ static struct platform_device *osk5912_devices[] __initdata = {
143 &osk5912_smc91x_device, 221 &osk5912_smc91x_device,
144 &osk5912_cf_device, 222 &osk5912_cf_device,
145 &osk5912_mcbsp1_device, 223 &osk5912_mcbsp1_device,
224 &osk5912_kp_device,
225 &osk5912_lcd_device,
146}; 226};
147 227
148static void __init osk_init_smc91x(void) 228static void __init osk_init_smc91x(void)
@@ -197,7 +277,6 @@ static struct omap_uart_config osk_uart_config __initdata = {
197}; 277};
198 278
199static struct omap_lcd_config osk_lcd_config __initdata = { 279static struct omap_lcd_config osk_lcd_config __initdata = {
200 .panel_name = "osk",
201 .ctrl_name = "internal", 280 .ctrl_name = "internal",
202}; 281};
203 282
@@ -255,8 +334,18 @@ static void __init osk_mistral_init(void)
255static void __init osk_mistral_init(void) { } 334static void __init osk_mistral_init(void) { }
256#endif 335#endif
257 336
337#define EMIFS_CS3_VAL (0x88013141)
338
258static void __init osk_init(void) 339static void __init osk_init(void)
259{ 340{
341 /* Workaround for wrong CS3 (NOR flash) timing
342 * There are some U-Boot versions out there which configure
343 * wrong CS3 memory timings. This mainly leads to CRC
344 * or similiar errors if you use NOR flash (e.g. with JFFS2)
345 */
346 if (EMIFS_CCS(3) != EMIFS_CS3_VAL)
347 EMIFS_CCS(3) = EMIFS_CS3_VAL;
348
260 osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys(); 349 osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys();
261 osk_flash_resource.end += SZ_32M - 1; 350 osk_flash_resource.end += SZ_32M - 1;
262 platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices)); 351 platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index e488f7236775..4bc8a62909b9 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -38,6 +38,15 @@ static void __init omap_generic_init_irq(void)
38 omap_init_irq(); 38 omap_init_irq();
39} 39}
40 40
41static struct platform_device palmte_lcd_device = {
42 .name = "lcd_palmte",
43 .id = -1,
44};
45
46static struct platform_device *devices[] __initdata = {
47 &palmte_lcd_device,
48};
49
41static struct omap_usb_config palmte_usb_config __initdata = { 50static struct omap_usb_config palmte_usb_config __initdata = {
42 .register_dev = 1, 51 .register_dev = 1,
43 .hmc_mode = 0, 52 .hmc_mode = 0,
@@ -55,7 +64,6 @@ static struct omap_mmc_config palmte_mmc_config __initdata = {
55}; 64};
56 65
57static struct omap_lcd_config palmte_lcd_config __initdata = { 66static struct omap_lcd_config palmte_lcd_config __initdata = {
58 .panel_name = "palmte",
59 .ctrl_name = "internal", 67 .ctrl_name = "internal",
60}; 68};
61 69
@@ -69,6 +77,8 @@ static void __init omap_generic_init(void)
69{ 77{
70 omap_board_config = palmte_config; 78 omap_board_config = palmte_config;
71 omap_board_config_size = ARRAY_SIZE(palmte_config); 79 omap_board_config_size = ARRAY_SIZE(palmte_config);
80
81 platform_add_devices(devices, ARRAY_SIZE(devices));
72} 82}
73 83
74static void __init omap_generic_map_io(void) 84static void __init omap_generic_map_io(void)
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index 3913a3cc0ce6..64b45d8ae357 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -16,7 +16,9 @@
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/mtd/mtd.h> 18#include <linux/mtd/mtd.h>
19#include <linux/mtd/nand.h>
19#include <linux/mtd/partitions.h> 20#include <linux/mtd/partitions.h>
21#include <linux/input.h>
20 22
21#include <asm/hardware.h> 23#include <asm/hardware.h>
22#include <asm/mach-types.h> 24#include <asm/mach-types.h>
@@ -28,9 +30,44 @@
28#include <asm/arch/gpio.h> 30#include <asm/arch/gpio.h>
29#include <asm/arch/mux.h> 31#include <asm/arch/mux.h>
30#include <asm/arch/fpga.h> 32#include <asm/arch/fpga.h>
33#include <asm/arch/keypad.h>
31#include <asm/arch/common.h> 34#include <asm/arch/common.h>
32#include <asm/arch/board.h> 35#include <asm/arch/board.h>
33 36
37static int p2_keymap[] = {
38 KEY(0,0,KEY_UP),
39 KEY(0,1,KEY_RIGHT),
40 KEY(0,2,KEY_LEFT),
41 KEY(0,3,KEY_DOWN),
42 KEY(0,4,KEY_CENTER),
43 KEY(0,5,KEY_0_5),
44 KEY(1,0,KEY_SOFT2),
45 KEY(1,1,KEY_SEND),
46 KEY(1,2,KEY_END),
47 KEY(1,3,KEY_VOLUMEDOWN),
48 KEY(1,4,KEY_VOLUMEUP),
49 KEY(1,5,KEY_RECORD),
50 KEY(2,0,KEY_SOFT1),
51 KEY(2,1,KEY_3),
52 KEY(2,2,KEY_6),
53 KEY(2,3,KEY_9),
54 KEY(2,4,KEY_SHARP),
55 KEY(2,5,KEY_2_5),
56 KEY(3,0,KEY_BACK),
57 KEY(3,1,KEY_2),
58 KEY(3,2,KEY_5),
59 KEY(3,3,KEY_8),
60 KEY(3,4,KEY_0),
61 KEY(3,5,KEY_HEADSETHOOK),
62 KEY(4,0,KEY_HOME),
63 KEY(4,1,KEY_1),
64 KEY(4,2,KEY_4),
65 KEY(4,3,KEY_7),
66 KEY(4,4,KEY_STAR),
67 KEY(4,5,KEY_POWER),
68 0
69};
70
34static struct resource smc91x_resources[] = { 71static struct resource smc91x_resources[] = {
35 [0] = { 72 [0] = {
36 .start = H2P2_DBG_FPGA_ETHR_START, /* Physical */ 73 .start = H2P2_DBG_FPGA_ETHR_START, /* Physical */
@@ -44,7 +81,7 @@ static struct resource smc91x_resources[] = {
44 }, 81 },
45}; 82};
46 83
47static struct mtd_partition p2_partitions[] = { 84static struct mtd_partition nor_partitions[] = {
48 /* bootloader (U-Boot, etc) in first sector */ 85 /* bootloader (U-Boot, etc) in first sector */
49 { 86 {
50 .name = "bootloader", 87 .name = "bootloader",
@@ -75,27 +112,47 @@ static struct mtd_partition p2_partitions[] = {
75 }, 112 },
76}; 113};
77 114
78static struct flash_platform_data p2_flash_data = { 115static struct flash_platform_data nor_data = {
79 .map_name = "cfi_probe", 116 .map_name = "cfi_probe",
80 .width = 2, 117 .width = 2,
81 .parts = p2_partitions, 118 .parts = nor_partitions,
82 .nr_parts = ARRAY_SIZE(p2_partitions), 119 .nr_parts = ARRAY_SIZE(nor_partitions),
83}; 120};
84 121
85static struct resource p2_flash_resource = { 122static struct resource nor_resource = {
86 .start = OMAP_CS0_PHYS, 123 .start = OMAP_CS0_PHYS,
87 .end = OMAP_CS0_PHYS + SZ_32M - 1, 124 .end = OMAP_CS0_PHYS + SZ_32M - 1,
88 .flags = IORESOURCE_MEM, 125 .flags = IORESOURCE_MEM,
89}; 126};
90 127
91static struct platform_device p2_flash_device = { 128static struct platform_device nor_device = {
92 .name = "omapflash", 129 .name = "omapflash",
93 .id = 0, 130 .id = 0,
94 .dev = { 131 .dev = {
95 .platform_data = &p2_flash_data, 132 .platform_data = &nor_data,
133 },
134 .num_resources = 1,
135 .resource = &nor_resource,
136};
137
138static struct nand_platform_data nand_data = {
139 .options = NAND_SAMSUNG_LP_OPTIONS,
140};
141
142static struct resource nand_resource = {
143 .start = OMAP_CS3_PHYS,
144 .end = OMAP_CS3_PHYS + SZ_4K - 1,
145 .flags = IORESOURCE_MEM,
146};
147
148static struct platform_device nand_device = {
149 .name = "omapnand",
150 .id = 0,
151 .dev = {
152 .platform_data = &nand_data,
96 }, 153 },
97 .num_resources = 1, 154 .num_resources = 1,
98 .resource = &p2_flash_resource, 155 .resource = &nand_resource,
99}; 156};
100 157
101static struct platform_device smc91x_device = { 158static struct platform_device smc91x_device = {
@@ -105,17 +162,55 @@ static struct platform_device smc91x_device = {
105 .resource = smc91x_resources, 162 .resource = smc91x_resources,
106}; 163};
107 164
165static struct resource kp_resources[] = {
166 [0] = {
167 .start = INT_730_MPUIO_KEYPAD,
168 .end = INT_730_MPUIO_KEYPAD,
169 .flags = IORESOURCE_IRQ,
170 },
171};
172
173static struct omap_kp_platform_data kp_data = {
174 .rows = 8,
175 .cols = 8,
176 .keymap = p2_keymap,
177};
178
179static struct platform_device kp_device = {
180 .name = "omap-keypad",
181 .id = -1,
182 .dev = {
183 .platform_data = &kp_data,
184 },
185 .num_resources = ARRAY_SIZE(kp_resources),
186 .resource = kp_resources,
187};
188
189static struct platform_device lcd_device = {
190 .name = "lcd_p2",
191 .id = -1,
192};
193
108static struct platform_device *devices[] __initdata = { 194static struct platform_device *devices[] __initdata = {
109 &p2_flash_device, 195 &nor_device,
196 &nand_device,
110 &smc91x_device, 197 &smc91x_device,
198 &kp_device,
199 &lcd_device,
111}; 200};
112 201
202#define P2_NAND_RB_GPIO_PIN 62
203
204static int nand_dev_ready(struct nand_platform_data *data)
205{
206 return omap_get_gpio_datain(P2_NAND_RB_GPIO_PIN);
207}
208
113static struct omap_uart_config perseus2_uart_config __initdata = { 209static struct omap_uart_config perseus2_uart_config __initdata = {
114 .enabled_uarts = ((1 << 0) | (1 << 1)), 210 .enabled_uarts = ((1 << 0) | (1 << 1)),
115}; 211};
116 212
117static struct omap_lcd_config perseus2_lcd_config __initdata = { 213static struct omap_lcd_config perseus2_lcd_config __initdata = {
118 .panel_name = "p2",
119 .ctrl_name = "internal", 214 .ctrl_name = "internal",
120}; 215};
121 216
@@ -126,7 +221,13 @@ static struct omap_board_config_kernel perseus2_config[] = {
126 221
127static void __init omap_perseus2_init(void) 222static void __init omap_perseus2_init(void)
128{ 223{
129 (void) platform_add_devices(devices, ARRAY_SIZE(devices)); 224 if (!(omap_request_gpio(P2_NAND_RB_GPIO_PIN)))
225 nand_data.dev_ready = nand_dev_ready;
226
227 omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
228 omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
229
230 platform_add_devices(devices, ARRAY_SIZE(devices));
130 231
131 omap_board_config = perseus2_config; 232 omap_board_config = perseus2_config;
132 omap_board_config_size = ARRAY_SIZE(perseus2_config); 233 omap_board_config_size = ARRAY_SIZE(perseus2_config);
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 52e4a9d69642..447a586eb334 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -155,9 +155,9 @@ static struct omap_uart_config voiceblue_uart_config __initdata = {
155}; 155};
156 156
157static struct omap_board_config_kernel voiceblue_config[] = { 157static struct omap_board_config_kernel voiceblue_config[] = {
158 { OMAP_TAG_USB, &voiceblue_usb_config }, 158 { OMAP_TAG_USB, &voiceblue_usb_config },
159 { OMAP_TAG_MMC, &voiceblue_mmc_config }, 159 { OMAP_TAG_MMC, &voiceblue_mmc_config },
160 { OMAP_TAG_UART, &voiceblue_uart_config }, 160 { OMAP_TAG_UART, &voiceblue_uart_config },
161}; 161};
162 162
163static void __init voiceblue_init_irq(void) 163static void __init voiceblue_init_irq(void)
@@ -235,7 +235,7 @@ static struct notifier_block panic_block = {
235static int __init voiceblue_setup(void) 235static int __init voiceblue_setup(void)
236{ 236{
237 /* Setup panic notifier */ 237 /* Setup panic notifier */
238 atomic_notifier_chain_register(&panic_notifier_list, &panic_block); 238 notifier_chain_register(&panic_notifier_list, &panic_block);
239 239
240 return 0; 240 return 0;
241} 241}
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index 75110ba10424..619db18144ea 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -345,7 +345,7 @@ static unsigned calc_ext_dsor(unsigned long rate)
345 */ 345 */
346 for (dsor = 2; dsor < 96; ++dsor) { 346 for (dsor = 2; dsor < 96; ++dsor) {
347 if ((dsor & 1) && dsor > 8) 347 if ((dsor & 1) && dsor > 8)
348 continue; 348 continue;
349 if (rate >= 96000000 / dsor) 349 if (rate >= 96000000 / dsor)
350 break; 350 break;
351 } 351 }
@@ -687,6 +687,11 @@ int __init omap1_clk_init(void)
687 clk_register(*clkp); 687 clk_register(*clkp);
688 continue; 688 continue;
689 } 689 }
690
691 if (((*clkp)->flags &CLOCK_IN_OMAP310) && cpu_is_omap310()) {
692 clk_register(*clkp);
693 continue;
694 }
690 } 695 }
691 696
692 info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); 697 info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
@@ -784,7 +789,7 @@ int __init omap1_clk_init(void)
784 clk_enable(&armxor_ck.clk); 789 clk_enable(&armxor_ck.clk);
785 clk_enable(&armtim_ck.clk); /* This should be done by timer code */ 790 clk_enable(&armtim_ck.clk); /* This should be done by timer code */
786 791
787 if (cpu_is_omap1510()) 792 if (cpu_is_omap15xx())
788 clk_enable(&arm_gpio_ck); 793 clk_enable(&arm_gpio_ck);
789 794
790 return 0; 795 return 0;
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index 4f18d1b94449..b7c68819c4e7 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -151,7 +151,7 @@ static struct clk ck_ref = {
151 .name = "ck_ref", 151 .name = "ck_ref",
152 .rate = 12000000, 152 .rate = 12000000,
153 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 153 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
154 ALWAYS_ENABLED, 154 CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
155 .enable = &omap1_clk_enable_generic, 155 .enable = &omap1_clk_enable_generic,
156 .disable = &omap1_clk_disable_generic, 156 .disable = &omap1_clk_disable_generic,
157}; 157};
@@ -160,7 +160,7 @@ static struct clk ck_dpll1 = {
160 .name = "ck_dpll1", 160 .name = "ck_dpll1",
161 .parent = &ck_ref, 161 .parent = &ck_ref,
162 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 162 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
163 RATE_PROPAGATES | ALWAYS_ENABLED, 163 CLOCK_IN_OMAP310 | RATE_PROPAGATES | ALWAYS_ENABLED,
164 .enable = &omap1_clk_enable_generic, 164 .enable = &omap1_clk_enable_generic,
165 .disable = &omap1_clk_disable_generic, 165 .disable = &omap1_clk_disable_generic,
166}; 166};
@@ -183,7 +183,8 @@ static struct clk arm_ck = {
183 .name = "arm_ck", 183 .name = "arm_ck",
184 .parent = &ck_dpll1, 184 .parent = &ck_dpll1,
185 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 185 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
186 RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED, 186 CLOCK_IN_OMAP310 | RATE_CKCTL | RATE_PROPAGATES |
187 ALWAYS_ENABLED,
187 .rate_offset = CKCTL_ARMDIV_OFFSET, 188 .rate_offset = CKCTL_ARMDIV_OFFSET,
188 .recalc = &omap1_ckctl_recalc, 189 .recalc = &omap1_ckctl_recalc,
189 .enable = &omap1_clk_enable_generic, 190 .enable = &omap1_clk_enable_generic,
@@ -195,7 +196,8 @@ static struct arm_idlect1_clk armper_ck = {
195 .name = "armper_ck", 196 .name = "armper_ck",
196 .parent = &ck_dpll1, 197 .parent = &ck_dpll1,
197 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 198 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
198 RATE_CKCTL | CLOCK_IDLE_CONTROL, 199 CLOCK_IN_OMAP310 | RATE_CKCTL |
200 CLOCK_IDLE_CONTROL,
199 .enable_reg = (void __iomem *)ARM_IDLECT2, 201 .enable_reg = (void __iomem *)ARM_IDLECT2,
200 .enable_bit = EN_PERCK, 202 .enable_bit = EN_PERCK,
201 .rate_offset = CKCTL_PERDIV_OFFSET, 203 .rate_offset = CKCTL_PERDIV_OFFSET,
@@ -209,7 +211,7 @@ static struct arm_idlect1_clk armper_ck = {
209static struct clk arm_gpio_ck = { 211static struct clk arm_gpio_ck = {
210 .name = "arm_gpio_ck", 212 .name = "arm_gpio_ck",
211 .parent = &ck_dpll1, 213 .parent = &ck_dpll1,
212 .flags = CLOCK_IN_OMAP1510, 214 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
213 .enable_reg = (void __iomem *)ARM_IDLECT2, 215 .enable_reg = (void __iomem *)ARM_IDLECT2,
214 .enable_bit = EN_GPIOCK, 216 .enable_bit = EN_GPIOCK,
215 .recalc = &followparent_recalc, 217 .recalc = &followparent_recalc,
@@ -222,7 +224,7 @@ static struct arm_idlect1_clk armxor_ck = {
222 .name = "armxor_ck", 224 .name = "armxor_ck",
223 .parent = &ck_ref, 225 .parent = &ck_ref,
224 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 226 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
225 CLOCK_IDLE_CONTROL, 227 CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
226 .enable_reg = (void __iomem *)ARM_IDLECT2, 228 .enable_reg = (void __iomem *)ARM_IDLECT2,
227 .enable_bit = EN_XORPCK, 229 .enable_bit = EN_XORPCK,
228 .recalc = &followparent_recalc, 230 .recalc = &followparent_recalc,
@@ -237,7 +239,7 @@ static struct arm_idlect1_clk armtim_ck = {
237 .name = "armtim_ck", 239 .name = "armtim_ck",
238 .parent = &ck_ref, 240 .parent = &ck_ref,
239 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 241 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
240 CLOCK_IDLE_CONTROL, 242 CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
241 .enable_reg = (void __iomem *)ARM_IDLECT2, 243 .enable_reg = (void __iomem *)ARM_IDLECT2,
242 .enable_bit = EN_TIMCK, 244 .enable_bit = EN_TIMCK,
243 .recalc = &followparent_recalc, 245 .recalc = &followparent_recalc,
@@ -252,7 +254,7 @@ static struct arm_idlect1_clk armwdt_ck = {
252 .name = "armwdt_ck", 254 .name = "armwdt_ck",
253 .parent = &ck_ref, 255 .parent = &ck_ref,
254 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 256 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
255 CLOCK_IDLE_CONTROL, 257 CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
256 .enable_reg = (void __iomem *)ARM_IDLECT2, 258 .enable_reg = (void __iomem *)ARM_IDLECT2,
257 .enable_bit = EN_WDTCK, 259 .enable_bit = EN_WDTCK,
258 .recalc = &omap1_watchdog_recalc, 260 .recalc = &omap1_watchdog_recalc,
@@ -344,9 +346,9 @@ static struct arm_idlect1_clk tc_ck = {
344 .name = "tc_ck", 346 .name = "tc_ck",
345 .parent = &ck_dpll1, 347 .parent = &ck_dpll1,
346 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 348 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
347 CLOCK_IN_OMAP730 | RATE_CKCTL | 349 CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
348 RATE_PROPAGATES | ALWAYS_ENABLED | 350 RATE_CKCTL | RATE_PROPAGATES |
349 CLOCK_IDLE_CONTROL, 351 ALWAYS_ENABLED | CLOCK_IDLE_CONTROL,
350 .rate_offset = CKCTL_TCDIV_OFFSET, 352 .rate_offset = CKCTL_TCDIV_OFFSET,
351 .recalc = &omap1_ckctl_recalc, 353 .recalc = &omap1_ckctl_recalc,
352 .enable = &omap1_clk_enable_generic, 354 .enable = &omap1_clk_enable_generic,
@@ -358,7 +360,8 @@ static struct arm_idlect1_clk tc_ck = {
358static struct clk arminth_ck1510 = { 360static struct clk arminth_ck1510 = {
359 .name = "arminth_ck", 361 .name = "arminth_ck",
360 .parent = &tc_ck.clk, 362 .parent = &tc_ck.clk,
361 .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED, 363 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
364 ALWAYS_ENABLED,
362 .recalc = &followparent_recalc, 365 .recalc = &followparent_recalc,
363 /* Note: On 1510 the frequency follows TC_CK 366 /* Note: On 1510 the frequency follows TC_CK
364 * 367 *
@@ -372,7 +375,8 @@ static struct clk tipb_ck = {
372 /* No-idle controlled by "tc_ck" */ 375 /* No-idle controlled by "tc_ck" */
373 .name = "tibp_ck", 376 .name = "tibp_ck",
374 .parent = &tc_ck.clk, 377 .parent = &tc_ck.clk,
375 .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED, 378 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
379 ALWAYS_ENABLED,
376 .recalc = &followparent_recalc, 380 .recalc = &followparent_recalc,
377 .enable = &omap1_clk_enable_generic, 381 .enable = &omap1_clk_enable_generic,
378 .disable = &omap1_clk_disable_generic, 382 .disable = &omap1_clk_disable_generic,
@@ -417,7 +421,7 @@ static struct clk dma_ck = {
417 .name = "dma_ck", 421 .name = "dma_ck",
418 .parent = &tc_ck.clk, 422 .parent = &tc_ck.clk,
419 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 423 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
420 ALWAYS_ENABLED, 424 CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
421 .recalc = &followparent_recalc, 425 .recalc = &followparent_recalc,
422 .enable = &omap1_clk_enable_generic, 426 .enable = &omap1_clk_enable_generic,
423 .disable = &omap1_clk_disable_generic, 427 .disable = &omap1_clk_disable_generic,
@@ -437,7 +441,7 @@ static struct arm_idlect1_clk api_ck = {
437 .name = "api_ck", 441 .name = "api_ck",
438 .parent = &tc_ck.clk, 442 .parent = &tc_ck.clk,
439 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 443 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
440 CLOCK_IDLE_CONTROL, 444 CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
441 .enable_reg = (void __iomem *)ARM_IDLECT2, 445 .enable_reg = (void __iomem *)ARM_IDLECT2,
442 .enable_bit = EN_APICK, 446 .enable_bit = EN_APICK,
443 .recalc = &followparent_recalc, 447 .recalc = &followparent_recalc,
@@ -451,7 +455,8 @@ static struct arm_idlect1_clk lb_ck = {
451 .clk = { 455 .clk = {
452 .name = "lb_ck", 456 .name = "lb_ck",
453 .parent = &tc_ck.clk, 457 .parent = &tc_ck.clk,
454 .flags = CLOCK_IN_OMAP1510 | CLOCK_IDLE_CONTROL, 458 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
459 CLOCK_IDLE_CONTROL,
455 .enable_reg = (void __iomem *)ARM_IDLECT2, 460 .enable_reg = (void __iomem *)ARM_IDLECT2,
456 .enable_bit = EN_LBCK, 461 .enable_bit = EN_LBCK,
457 .recalc = &followparent_recalc, 462 .recalc = &followparent_recalc,
@@ -495,8 +500,8 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
495 .clk = { 500 .clk = {
496 .name = "lcd_ck", 501 .name = "lcd_ck",
497 .parent = &ck_dpll1, 502 .parent = &ck_dpll1,
498 .flags = CLOCK_IN_OMAP1510 | RATE_CKCTL | 503 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
499 CLOCK_IDLE_CONTROL, 504 RATE_CKCTL | CLOCK_IDLE_CONTROL,
500 .enable_reg = (void __iomem *)ARM_IDLECT2, 505 .enable_reg = (void __iomem *)ARM_IDLECT2,
501 .enable_bit = EN_LCDCK, 506 .enable_bit = EN_LCDCK,
502 .rate_offset = CKCTL_LCDDIV_OFFSET, 507 .rate_offset = CKCTL_LCDDIV_OFFSET,
@@ -512,8 +517,9 @@ static struct clk uart1_1510 = {
512 /* Direct from ULPD, no real parent */ 517 /* Direct from ULPD, no real parent */
513 .parent = &armper_ck.clk, 518 .parent = &armper_ck.clk,
514 .rate = 12000000, 519 .rate = 12000000,
515 .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | 520 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
516 ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT, 521 ENABLE_REG_32BIT | ALWAYS_ENABLED |
522 CLOCK_NO_IDLE_PARENT,
517 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, 523 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
518 .enable_bit = 29, /* Chooses between 12MHz and 48MHz */ 524 .enable_bit = 29, /* Chooses between 12MHz and 48MHz */
519 .set_rate = &omap1_set_uart_rate, 525 .set_rate = &omap1_set_uart_rate,
@@ -544,8 +550,8 @@ static struct clk uart2_ck = {
544 .parent = &armper_ck.clk, 550 .parent = &armper_ck.clk,
545 .rate = 12000000, 551 .rate = 12000000,
546 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 552 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
547 ENABLE_REG_32BIT | ALWAYS_ENABLED | 553 CLOCK_IN_OMAP310 | ENABLE_REG_32BIT |
548 CLOCK_NO_IDLE_PARENT, 554 ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
549 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, 555 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
550 .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ 556 .enable_bit = 30, /* Chooses between 12MHz and 48MHz */
551 .set_rate = &omap1_set_uart_rate, 557 .set_rate = &omap1_set_uart_rate,
@@ -559,8 +565,9 @@ static struct clk uart3_1510 = {
559 /* Direct from ULPD, no real parent */ 565 /* Direct from ULPD, no real parent */
560 .parent = &armper_ck.clk, 566 .parent = &armper_ck.clk,
561 .rate = 12000000, 567 .rate = 12000000,
562 .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | 568 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
563 ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT, 569 ENABLE_REG_32BIT | ALWAYS_ENABLED |
570 CLOCK_NO_IDLE_PARENT,
564 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, 571 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
565 .enable_bit = 31, /* Chooses between 12MHz and 48MHz */ 572 .enable_bit = 31, /* Chooses between 12MHz and 48MHz */
566 .set_rate = &omap1_set_uart_rate, 573 .set_rate = &omap1_set_uart_rate,
@@ -590,7 +597,7 @@ static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
590 /* Direct from ULPD, no parent */ 597 /* Direct from ULPD, no parent */
591 .rate = 6000000, 598 .rate = 6000000,
592 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 599 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
593 RATE_FIXED | ENABLE_REG_32BIT, 600 CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT,
594 .enable_reg = (void __iomem *)ULPD_CLOCK_CTRL, 601 .enable_reg = (void __iomem *)ULPD_CLOCK_CTRL,
595 .enable_bit = USB_MCLK_EN_BIT, 602 .enable_bit = USB_MCLK_EN_BIT,
596 .enable = &omap1_clk_enable_generic, 603 .enable = &omap1_clk_enable_generic,
@@ -601,7 +608,7 @@ static struct clk usb_hhc_ck1510 = {
601 .name = "usb_hhc_ck", 608 .name = "usb_hhc_ck",
602 /* Direct from ULPD, no parent */ 609 /* Direct from ULPD, no parent */
603 .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */ 610 .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
604 .flags = CLOCK_IN_OMAP1510 | 611 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
605 RATE_FIXED | ENABLE_REG_32BIT, 612 RATE_FIXED | ENABLE_REG_32BIT,
606 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, 613 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
607 .enable_bit = USB_HOST_HHC_UHOST_EN, 614 .enable_bit = USB_HOST_HHC_UHOST_EN,
@@ -637,7 +644,9 @@ static struct clk mclk_1510 = {
637 .name = "mclk", 644 .name = "mclk",
638 /* Direct from ULPD, no parent. May be enabled by ext hardware. */ 645 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
639 .rate = 12000000, 646 .rate = 12000000,
640 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, 647 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
648 .enable_reg = (void __iomem *)SOFT_REQ_REG,
649 .enable_bit = 6,
641 .enable = &omap1_clk_enable_generic, 650 .enable = &omap1_clk_enable_generic,
642 .disable = &omap1_clk_disable_generic, 651 .disable = &omap1_clk_disable_generic,
643}; 652};
@@ -659,7 +668,7 @@ static struct clk bclk_1510 = {
659 .name = "bclk", 668 .name = "bclk",
660 /* Direct from ULPD, no parent. May be enabled by ext hardware. */ 669 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
661 .rate = 12000000, 670 .rate = 12000000,
662 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, 671 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
663 .enable = &omap1_clk_enable_generic, 672 .enable = &omap1_clk_enable_generic,
664 .disable = &omap1_clk_disable_generic, 673 .disable = &omap1_clk_disable_generic,
665}; 674};
@@ -678,12 +687,14 @@ static struct clk bclk_16xx = {
678}; 687};
679 688
680static struct clk mmc1_ck = { 689static struct clk mmc1_ck = {
681 .name = "mmc1_ck", 690 .name = "mmc_ck",
691 .id = 1,
682 /* Functional clock is direct from ULPD, interface clock is ARMPER */ 692 /* Functional clock is direct from ULPD, interface clock is ARMPER */
683 .parent = &armper_ck.clk, 693 .parent = &armper_ck.clk,
684 .rate = 48000000, 694 .rate = 48000000,
685 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 695 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
686 RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, 696 CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT |
697 CLOCK_NO_IDLE_PARENT,
687 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0, 698 .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
688 .enable_bit = 23, 699 .enable_bit = 23,
689 .enable = &omap1_clk_enable_generic, 700 .enable = &omap1_clk_enable_generic,
@@ -691,7 +702,8 @@ static struct clk mmc1_ck = {
691}; 702};
692 703
693static struct clk mmc2_ck = { 704static struct clk mmc2_ck = {
694 .name = "mmc2_ck", 705 .name = "mmc_ck",
706 .id = 2,
695 /* Functional clock is direct from ULPD, interface clock is ARMPER */ 707 /* Functional clock is direct from ULPD, interface clock is ARMPER */
696 .parent = &armper_ck.clk, 708 .parent = &armper_ck.clk,
697 .rate = 48000000, 709 .rate = 48000000,
@@ -706,7 +718,7 @@ static struct clk mmc2_ck = {
706static struct clk virtual_ck_mpu = { 718static struct clk virtual_ck_mpu = {
707 .name = "mpu", 719 .name = "mpu",
708 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 720 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
709 VIRTUAL_CLOCK | ALWAYS_ENABLED, 721 CLOCK_IN_OMAP310 | VIRTUAL_CLOCK | ALWAYS_ENABLED,
710 .parent = &arm_ck, /* Is smarter alias for */ 722 .parent = &arm_ck, /* Is smarter alias for */
711 .recalc = &followparent_recalc, 723 .recalc = &followparent_recalc,
712 .set_rate = &omap1_select_table_rate, 724 .set_rate = &omap1_select_table_rate,
@@ -715,6 +727,20 @@ static struct clk virtual_ck_mpu = {
715 .disable = &omap1_clk_disable_generic, 727 .disable = &omap1_clk_disable_generic,
716}; 728};
717 729
730/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
731remains active during MPU idle whenever this is enabled */
732static struct clk i2c_fck = {
733 .name = "i2c_fck",
734 .id = 1,
735 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
736 VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT |
737 ALWAYS_ENABLED,
738 .parent = &armxor_ck.clk,
739 .recalc = &followparent_recalc,
740 .enable = &omap1_clk_enable_generic,
741 .disable = &omap1_clk_disable_generic,
742};
743
718static struct clk * onchip_clks[] = { 744static struct clk * onchip_clks[] = {
719 /* non-ULPD clocks */ 745 /* non-ULPD clocks */
720 &ck_ref, 746 &ck_ref,
@@ -763,6 +789,7 @@ static struct clk * onchip_clks[] = {
763 &mmc2_ck, 789 &mmc2_ck,
764 /* Virtual clocks */ 790 /* Virtual clocks */
765 &virtual_ck_mpu, 791 &virtual_ck_mpu,
792 &i2c_fck,
766}; 793};
767 794
768#endif 795#endif
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index ecbc47514adc..876c38da14f7 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -99,6 +99,45 @@ static void omap_init_rtc(void)
99static inline void omap_init_rtc(void) {} 99static inline void omap_init_rtc(void) {}
100#endif 100#endif
101 101
102#if defined(CONFIG_OMAP_STI)
103
104#define OMAP1_STI_BASE IO_ADDRESS(0xfffea000)
105#define OMAP1_STI_CHANNEL_BASE (OMAP1_STI_BASE + 0x400)
106
107static struct resource sti_resources[] = {
108 {
109 .start = OMAP1_STI_BASE,
110 .end = OMAP1_STI_BASE + SZ_1K - 1,
111 .flags = IORESOURCE_MEM,
112 },
113 {
114 .start = OMAP1_STI_CHANNEL_BASE,
115 .end = OMAP1_STI_CHANNEL_BASE + SZ_1K - 1,
116 .flags = IORESOURCE_MEM,
117 },
118 {
119 .start = INT_1610_STI,
120 .flags = IORESOURCE_IRQ,
121 }
122};
123
124static struct platform_device sti_device = {
125 .name = "sti",
126 .id = -1,
127 .dev = {
128 .release = omap_nop_release,
129 },
130 .num_resources = ARRAY_SIZE(sti_resources),
131 .resource = sti_resources,
132};
133
134static inline void omap_init_sti(void)
135{
136 platform_device_register(&sti_device);
137}
138#else
139static inline void omap_init_sti(void) {}
140#endif
102 141
103/*-------------------------------------------------------------------------*/ 142/*-------------------------------------------------------------------------*/
104 143
@@ -129,6 +168,7 @@ static int __init omap1_init_devices(void)
129 */ 168 */
130 omap_init_irda(); 169 omap_init_irda();
131 omap_init_rtc(); 170 omap_init_rtc();
171 omap_init_sti();
132 172
133 return 0; 173 return 0;
134} 174}
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index 82d556be79c5..be3a2a4ee2b8 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -18,6 +18,7 @@
18#include <asm/io.h> 18#include <asm/io.h>
19#include <asm/arch/mux.h> 19#include <asm/arch/mux.h>
20#include <asm/arch/tc.h> 20#include <asm/arch/tc.h>
21#include <asm/arch/omapfb.h>
21 22
22extern int omap1_clk_init(void); 23extern int omap1_clk_init(void);
23extern void omap_check_revision(void); 24extern void omap_check_revision(void);
@@ -110,7 +111,7 @@ void __init omap1_map_common_io(void)
110 } 111 }
111#endif 112#endif
112#ifdef CONFIG_ARCH_OMAP15XX 113#ifdef CONFIG_ARCH_OMAP15XX
113 if (cpu_is_omap1510()) { 114 if (cpu_is_omap15xx()) {
114 iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); 115 iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
115 } 116 }
116#endif 117#endif
@@ -121,6 +122,7 @@ void __init omap1_map_common_io(void)
121#endif 122#endif
122 123
123 omap_sram_init(); 124 omap_sram_init();
125 omapfb_reserve_mem();
124} 126}
125 127
126/* 128/*
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index ed65a7d2e941..a0431c00fa81 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -60,7 +60,7 @@ struct omap_irq_bank {
60 unsigned long wake_enable; 60 unsigned long wake_enable;
61}; 61};
62 62
63static unsigned int irq_bank_count = 0; 63static unsigned int irq_bank_count;
64static struct omap_irq_bank *irq_banks; 64static struct omap_irq_bank *irq_banks;
65 65
66static inline unsigned int irq_bank_readl(int bank, int offset) 66static inline unsigned int irq_bank_readl(int bank, int offset)
@@ -142,28 +142,28 @@ static void omap_irq_set_cfg(int irq, int fiq, int priority, int trigger)
142 142
143#ifdef CONFIG_ARCH_OMAP730 143#ifdef CONFIG_ARCH_OMAP730
144static struct omap_irq_bank omap730_irq_banks[] = { 144static struct omap_irq_bank omap730_irq_banks[] = {
145 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f }, 145 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f },
146 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 }, 146 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 },
147 { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0x800040f3 }, 147 { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0x800040f3 },
148}; 148};
149#endif 149#endif
150 150
151#ifdef CONFIG_ARCH_OMAP15XX 151#ifdef CONFIG_ARCH_OMAP15XX
152static struct omap_irq_bank omap1510_irq_banks[] = { 152static struct omap_irq_bank omap1510_irq_banks[] = {
153 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff }, 153 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff },
154 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed }, 154 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed },
155}; 155};
156static struct omap_irq_bank omap310_irq_banks[] = { 156static struct omap_irq_bank omap310_irq_banks[] = {
157 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 }, 157 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 },
158 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 }, 158 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 },
159}; 159};
160#endif 160#endif
161 161
162#if defined(CONFIG_ARCH_OMAP16XX) 162#if defined(CONFIG_ARCH_OMAP16XX)
163 163
164static struct omap_irq_bank omap1610_irq_banks[] = { 164static struct omap_irq_bank omap1610_irq_banks[] = {
165 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f }, 165 { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f },
166 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd }, 166 { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd },
167 { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0xffffb7ff }, 167 { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0xffffb7ff },
168 { .base_reg = OMAP_IH2_BASE + 0x200, .trigger_map = 0xffffffff }, 168 { .base_reg = OMAP_IH2_BASE + 0x200, .trigger_map = 0xffffffff },
169}; 169};
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c
index d4b8d624e742..10fe0b3efcac 100644
--- a/arch/arm/mach-omap1/mux.c
+++ b/arch/arm/mach-omap1/mux.c
@@ -35,16 +35,20 @@
35 35
36#ifdef CONFIG_ARCH_OMAP730 36#ifdef CONFIG_ARCH_OMAP730
37struct pin_config __initdata_or_module omap730_pins[] = { 37struct pin_config __initdata_or_module omap730_pins[] = {
38MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 0, 20, 1, NA, 0, 0) 38MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 20, 1, 0)
39MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 0, 24, 1, NA, 0, 0) 39MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 24, 1, 0)
40MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 0, 28, 1, NA, 0, 0) 40MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 28, 1, 0)
41MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 0, 1, NA, 0, 0) 41MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 1, 0)
42MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 0, 4, 1, NA, 0, 0) 42MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 4, 1, 0)
43MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 0, 8, 1, NA, 0, 0) 43MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 8, 1, 0)
44MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 0, 12, 1, NA, 0, 0) 44MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 12, 1, 0)
45MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 0, 16, 1, NA, 0, 0) 45MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 16, 1, 0)
46MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 0, 20, 1, NA, 0, 0) 46MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 20, 1, 0)
47MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 0, 24, 1, NA, 0, 0) 47MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 24, 1, 0)
48
49MUX_CFG_730("AA17_730_USB_DM", 2, 21, 0, 20, 0, 0)
50MUX_CFG_730("W16_730_USB_PU_EN", 2, 25, 0, 24, 0, 0)
51MUX_CFG_730("W17_730_USB_VBUSI", 2, 29, 0, 28, 0, 0)
48}; 52};
49#endif 53#endif
50 54
@@ -73,8 +77,8 @@ MUX_CFG("UART3_BCLK", A, 0, 0, 2, 6, 0, NA, 0, 0)
73MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0) 77MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0)
74 78
75/* PWT & PWL, conflicts with UART3 */ 79/* PWT & PWL, conflicts with UART3 */
76MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0) 80MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0)
77MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0) 81MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0)
78 82
79/* USB internal master generic */ 83/* USB internal master generic */
80MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1) 84MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1)
@@ -151,7 +155,7 @@ MUX_CFG("MCBSP3_CLKX", 9, 3, 1, 1, 29, 0, NA, 0, 1)
151 155
152/* Misc ballouts */ 156/* Misc ballouts */
153MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1) 157MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1)
154MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0) 158MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0)
155 159
156/* OMAP-1610 MMC2 */ 160/* OMAP-1610 MMC2 */
157MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1) 161MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1)
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
new file mode 100644
index 000000000000..ddf6b07dc9c7
--- /dev/null
+++ b/arch/arm/mach-omap1/pm.c
@@ -0,0 +1,770 @@
1/*
2 * linux/arch/arm/mach-omap1/pm.c
3 *
4 * OMAP Power Management Routines
5 *
6 * Original code for the SA11x0:
7 * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
8 *
9 * Modified for the PXA250 by Nicolas Pitre:
10 * Copyright (c) 2002 Monta Vista Software, Inc.
11 *
12 * Modified for the OMAP1510 by David Singleton:
13 * Copyright (c) 2002 Monta Vista Software, Inc.
14 *
15 * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com>
16 *
17 * This program is free software; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License as published by the
19 * Free Software Foundation; either version 2 of the License, or (at your
20 * option) any later version.
21 *
22 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * You should have received a copy of the GNU General Public License along
34 * with this program; if not, write to the Free Software Foundation, Inc.,
35 * 675 Mass Ave, Cambridge, MA 02139, USA.
36 */
37
38#include <linux/pm.h>
39#include <linux/sched.h>
40#include <linux/proc_fs.h>
41#include <linux/pm.h>
42#include <linux/interrupt.h>
43#include <linux/sysfs.h>
44#include <linux/module.h>
45
46#include <asm/io.h>
47#include <asm/irq.h>
48#include <asm/atomic.h>
49#include <asm/mach/time.h>
50#include <asm/mach/irq.h>
51#include <asm/mach-types.h>
52
53#include <asm/arch/irqs.h>
54#include <asm/arch/clock.h>
55#include <asm/arch/sram.h>
56#include <asm/arch/tc.h>
57#include <asm/arch/pm.h>
58#include <asm/arch/mux.h>
59#include <asm/arch/tps65010.h>
60#include <asm/arch/dma.h>
61#include <asm/arch/dsp_common.h>
62#include <asm/arch/dmtimer.h>
63
64static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
65static unsigned short dsp_sleep_save[DSP_SLEEP_SAVE_SIZE];
66static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
67static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE];
68static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
69static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
70
71static unsigned short enable_dyn_sleep = 1;
72
73static ssize_t omap_pm_sleep_while_idle_show(struct subsystem * subsys, char *buf)
74{
75 return sprintf(buf, "%hu\n", enable_dyn_sleep);
76}
77
78static ssize_t omap_pm_sleep_while_idle_store(struct subsystem * subsys,
79 const char * buf,
80 size_t n)
81{
82 unsigned short value;
83 if (sscanf(buf, "%hu", &value) != 1 ||
84 (value != 0 && value != 1)) {
85 printk(KERN_ERR "idle_sleep_store: Invalid value\n");
86 return -EINVAL;
87 }
88 enable_dyn_sleep = value;
89 return n;
90}
91
92static struct subsys_attribute sleep_while_idle_attr = {
93 .attr = {
94 .name = __stringify(sleep_while_idle),
95 .mode = 0644,
96 },
97 .show = omap_pm_sleep_while_idle_show,
98 .store = omap_pm_sleep_while_idle_store,
99};
100
101extern struct subsystem power_subsys;
102static void (*omap_sram_idle)(void) = NULL;
103static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
104
105/*
106 * Let's power down on idle, but only if we are really
107 * idle, because once we start down the path of
108 * going idle we continue to do idle even if we get
109 * a clock tick interrupt . .
110 */
111void omap_pm_idle(void)
112{
113 extern __u32 arm_idlect1_mask;
114 __u32 use_idlect1 = arm_idlect1_mask;
115#ifndef CONFIG_OMAP_MPU_TIMER
116 int do_sleep;
117#endif
118
119 local_irq_disable();
120 local_fiq_disable();
121 if (need_resched()) {
122 local_fiq_enable();
123 local_irq_enable();
124 return;
125 }
126
127 /*
128 * Since an interrupt may set up a timer, we don't want to
129 * reprogram the hardware timer with interrupts enabled.
130 * Re-enable interrupts only after returning from idle.
131 */
132 timer_dyn_reprogram();
133
134#ifdef CONFIG_OMAP_MPU_TIMER
135#warning Enable 32kHz OS timer in order to allow sleep states in idle
136 use_idlect1 = use_idlect1 & ~(1 << 9);
137#else
138
139 do_sleep = 0;
140 while (enable_dyn_sleep) {
141
142#ifdef CONFIG_CBUS_TAHVO_USB
143 extern int vbus_active;
144 /* Clock requirements? */
145 if (vbus_active)
146 break;
147#endif
148 do_sleep = 1;
149 break;
150 }
151
152#ifdef CONFIG_OMAP_DM_TIMER
153 use_idlect1 = omap_dm_timer_modify_idlect_mask(use_idlect1);
154#endif
155
156 if (omap_dma_running()) {
157 use_idlect1 &= ~(1 << 6);
158 if (omap_lcd_dma_ext_running())
159 use_idlect1 &= ~(1 << 12);
160 }
161
162 /* We should be able to remove the do_sleep variable and multiple
163 * tests above as soon as drivers, timer and DMA code have been fixed.
164 * Even the sleep block count should become obsolete. */
165 if ((use_idlect1 != ~0) || !do_sleep) {
166
167 __u32 saved_idlect1 = omap_readl(ARM_IDLECT1);
168 if (cpu_is_omap15xx())
169 use_idlect1 &= OMAP1510_BIG_SLEEP_REQUEST;
170 else
171 use_idlect1 &= OMAP1610_IDLECT1_SLEEP_VAL;
172 omap_writel(use_idlect1, ARM_IDLECT1);
173 __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4");
174 omap_writel(saved_idlect1, ARM_IDLECT1);
175
176 local_fiq_enable();
177 local_irq_enable();
178 return;
179 }
180 omap_sram_suspend(omap_readl(ARM_IDLECT1),
181 omap_readl(ARM_IDLECT2));
182#endif
183
184 local_fiq_enable();
185 local_irq_enable();
186}
187
188/*
189 * Configuration of the wakeup event is board specific. For the
190 * moment we put it into this helper function. Later it may move
191 * to board specific files.
192 */
193static void omap_pm_wakeup_setup(void)
194{
195 u32 level1_wake = 0;
196 u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
197
198 /*
199 * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
200 * and the L2 wakeup interrupts: keypad and UART2. Note that the
201 * drivers must still separately call omap_set_gpio_wakeup() to
202 * wake up to a GPIO interrupt.
203 */
204 if (cpu_is_omap730())
205 level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) |
206 OMAP_IRQ_BIT(INT_730_IH2_IRQ);
207 else if (cpu_is_omap15xx())
208 level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
209 OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
210 else if (cpu_is_omap16xx())
211 level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
212 OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
213
214 omap_writel(~level1_wake, OMAP_IH1_MIR);
215
216 if (cpu_is_omap730()) {
217 omap_writel(~level2_wake, OMAP_IH2_0_MIR);
218 omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) |
219 OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)),
220 OMAP_IH2_1_MIR);
221 } else if (cpu_is_omap15xx()) {
222 level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
223 omap_writel(~level2_wake, OMAP_IH2_MIR);
224 } else if (cpu_is_omap16xx()) {
225 level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
226 omap_writel(~level2_wake, OMAP_IH2_0_MIR);
227
228 /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
229 omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ),
230 OMAP_IH2_1_MIR);
231 omap_writel(~0x0, OMAP_IH2_2_MIR);
232 omap_writel(~0x0, OMAP_IH2_3_MIR);
233 }
234
235 /* New IRQ agreement, recalculate in cascade order */
236 omap_writel(1, OMAP_IH2_CONTROL);
237 omap_writel(1, OMAP_IH1_CONTROL);
238}
239
240#define EN_DSPCK 13 /* ARM_CKCTL */
241#define EN_APICK 6 /* ARM_IDLECT2 */
242#define DSP_EN 1 /* ARM_RSTCT1 */
243
244void omap_pm_suspend(void)
245{
246 unsigned long arg0 = 0, arg1 = 0;
247
248 printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev);
249
250 omap_serial_wake_trigger(1);
251
252 if (machine_is_omap_osk()) {
253 /* Stop LED1 (D9) blink */
254 tps65010_set_led(LED1, OFF);
255 }
256
257 omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG);
258
259 /*
260 * Step 1: turn off interrupts (FIXME: NOTE: already disabled)
261 */
262
263 local_irq_disable();
264 local_fiq_disable();
265
266 /*
267 * Step 2: save registers
268 *
269 * The omap is a strange/beautiful device. The caches, memory
270 * and register state are preserved across power saves.
271 * We have to save and restore very little register state to
272 * idle the omap.
273 *
274 * Save interrupt, MPUI, ARM and UPLD control registers.
275 */
276
277 if (cpu_is_omap730()) {
278 MPUI730_SAVE(OMAP_IH1_MIR);
279 MPUI730_SAVE(OMAP_IH2_0_MIR);
280 MPUI730_SAVE(OMAP_IH2_1_MIR);
281 MPUI730_SAVE(MPUI_CTRL);
282 MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
283 MPUI730_SAVE(MPUI_DSP_API_CONFIG);
284 MPUI730_SAVE(EMIFS_CONFIG);
285 MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
286
287 } else if (cpu_is_omap15xx()) {
288 MPUI1510_SAVE(OMAP_IH1_MIR);
289 MPUI1510_SAVE(OMAP_IH2_MIR);
290 MPUI1510_SAVE(MPUI_CTRL);
291 MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
292 MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
293 MPUI1510_SAVE(EMIFS_CONFIG);
294 MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
295 } else if (cpu_is_omap16xx()) {
296 MPUI1610_SAVE(OMAP_IH1_MIR);
297 MPUI1610_SAVE(OMAP_IH2_0_MIR);
298 MPUI1610_SAVE(OMAP_IH2_1_MIR);
299 MPUI1610_SAVE(OMAP_IH2_2_MIR);
300 MPUI1610_SAVE(OMAP_IH2_3_MIR);
301 MPUI1610_SAVE(MPUI_CTRL);
302 MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
303 MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
304 MPUI1610_SAVE(EMIFS_CONFIG);
305 MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
306 }
307
308 ARM_SAVE(ARM_CKCTL);
309 ARM_SAVE(ARM_IDLECT1);
310 ARM_SAVE(ARM_IDLECT2);
311 if (!(cpu_is_omap15xx()))
312 ARM_SAVE(ARM_IDLECT3);
313 ARM_SAVE(ARM_EWUPCT);
314 ARM_SAVE(ARM_RSTCT1);
315 ARM_SAVE(ARM_RSTCT2);
316 ARM_SAVE(ARM_SYSST);
317 ULPD_SAVE(ULPD_CLOCK_CTRL);
318 ULPD_SAVE(ULPD_STATUS_REQ);
319
320 /* (Step 3 removed - we now allow deep sleep by default) */
321
322 /*
323 * Step 4: OMAP DSP Shutdown
324 */
325
326 /* stop DSP */
327 omap_writew(omap_readw(ARM_RSTCT1) & ~(1 << DSP_EN), ARM_RSTCT1);
328
329 /* shut down dsp_ck */
330 omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL);
331
332 /* temporarily enabling api_ck to access DSP registers */
333 omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
334
335 /* save DSP registers */
336 DSP_SAVE(DSP_IDLECT2);
337
338 /* Stop all DSP domain clocks */
339 __raw_writew(0, DSP_IDLECT2);
340
341 /*
342 * Step 5: Wakeup Event Setup
343 */
344
345 omap_pm_wakeup_setup();
346
347 /*
348 * Step 6: ARM and Traffic controller shutdown
349 */
350
351 /* disable ARM watchdog */
352 omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
353 omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
354
355 /*
356 * Step 6b: ARM and Traffic controller shutdown
357 *
358 * Step 6 continues here. Prepare jump to power management
359 * assembly code in internal SRAM.
360 *
361 * Since the omap_cpu_suspend routine has been copied to
362 * SRAM, we'll do an indirect procedure call to it and pass the
363 * contents of arm_idlect1 and arm_idlect2 so it can restore
364 * them when it wakes up and it will return.
365 */
366
367 arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
368 arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
369
370 /*
371 * Step 6c: ARM and Traffic controller shutdown
372 *
373 * Jump to assembly code. The processor will stay there
374 * until wake up.
375 */
376 omap_sram_suspend(arg0, arg1);
377
378 /*
379 * If we are here, processor is woken up!
380 */
381
382 /*
383 * Restore DSP clocks
384 */
385
386 /* again temporarily enabling api_ck to access DSP registers */
387 omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
388
389 /* Restore DSP domain clocks */
390 DSP_RESTORE(DSP_IDLECT2);
391
392 /*
393 * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
394 */
395
396 if (!(cpu_is_omap15xx()))
397 ARM_RESTORE(ARM_IDLECT3);
398 ARM_RESTORE(ARM_CKCTL);
399 ARM_RESTORE(ARM_EWUPCT);
400 ARM_RESTORE(ARM_RSTCT1);
401 ARM_RESTORE(ARM_RSTCT2);
402 ARM_RESTORE(ARM_SYSST);
403 ULPD_RESTORE(ULPD_CLOCK_CTRL);
404 ULPD_RESTORE(ULPD_STATUS_REQ);
405
406 if (cpu_is_omap730()) {
407 MPUI730_RESTORE(EMIFS_CONFIG);
408 MPUI730_RESTORE(EMIFF_SDRAM_CONFIG);
409 MPUI730_RESTORE(OMAP_IH1_MIR);
410 MPUI730_RESTORE(OMAP_IH2_0_MIR);
411 MPUI730_RESTORE(OMAP_IH2_1_MIR);
412 } else if (cpu_is_omap15xx()) {
413 MPUI1510_RESTORE(MPUI_CTRL);
414 MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
415 MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
416 MPUI1510_RESTORE(EMIFS_CONFIG);
417 MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG);
418 MPUI1510_RESTORE(OMAP_IH1_MIR);
419 MPUI1510_RESTORE(OMAP_IH2_MIR);
420 } else if (cpu_is_omap16xx()) {
421 MPUI1610_RESTORE(MPUI_CTRL);
422 MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG);
423 MPUI1610_RESTORE(MPUI_DSP_API_CONFIG);
424 MPUI1610_RESTORE(EMIFS_CONFIG);
425 MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG);
426
427 MPUI1610_RESTORE(OMAP_IH1_MIR);
428 MPUI1610_RESTORE(OMAP_IH2_0_MIR);
429 MPUI1610_RESTORE(OMAP_IH2_1_MIR);
430 MPUI1610_RESTORE(OMAP_IH2_2_MIR);
431 MPUI1610_RESTORE(OMAP_IH2_3_MIR);
432 }
433
434 omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG);
435
436 /*
437 * Reenable interrupts
438 */
439
440 local_irq_enable();
441 local_fiq_enable();
442
443 omap_serial_wake_trigger(0);
444
445 printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev);
446
447 if (machine_is_omap_osk()) {
448 /* Let LED1 (D9) blink again */
449 tps65010_set_led(LED1, BLINK);
450 }
451}
452
453#if defined(DEBUG) && defined(CONFIG_PROC_FS)
454static int g_read_completed;
455
456/*
457 * Read system PM registers for debugging
458 */
459static int omap_pm_read_proc(
460 char *page_buffer,
461 char **my_first_byte,
462 off_t virtual_start,
463 int length,
464 int *eof,
465 void *data)
466{
467 int my_buffer_offset = 0;
468 char * const my_base = page_buffer;
469
470 ARM_SAVE(ARM_CKCTL);
471 ARM_SAVE(ARM_IDLECT1);
472 ARM_SAVE(ARM_IDLECT2);
473 if (!(cpu_is_omap15xx()))
474 ARM_SAVE(ARM_IDLECT3);
475 ARM_SAVE(ARM_EWUPCT);
476 ARM_SAVE(ARM_RSTCT1);
477 ARM_SAVE(ARM_RSTCT2);
478 ARM_SAVE(ARM_SYSST);
479
480 ULPD_SAVE(ULPD_IT_STATUS);
481 ULPD_SAVE(ULPD_CLOCK_CTRL);
482 ULPD_SAVE(ULPD_SOFT_REQ);
483 ULPD_SAVE(ULPD_STATUS_REQ);
484 ULPD_SAVE(ULPD_DPLL_CTRL);
485 ULPD_SAVE(ULPD_POWER_CTRL);
486
487 if (cpu_is_omap730()) {
488 MPUI730_SAVE(MPUI_CTRL);
489 MPUI730_SAVE(MPUI_DSP_STATUS);
490 MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG);
491 MPUI730_SAVE(MPUI_DSP_API_CONFIG);
492 MPUI730_SAVE(EMIFF_SDRAM_CONFIG);
493 MPUI730_SAVE(EMIFS_CONFIG);
494 } else if (cpu_is_omap15xx()) {
495 MPUI1510_SAVE(MPUI_CTRL);
496 MPUI1510_SAVE(MPUI_DSP_STATUS);
497 MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
498 MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
499 MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
500 MPUI1510_SAVE(EMIFS_CONFIG);
501 } else if (cpu_is_omap16xx()) {
502 MPUI1610_SAVE(MPUI_CTRL);
503 MPUI1610_SAVE(MPUI_DSP_STATUS);
504 MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
505 MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
506 MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
507 MPUI1610_SAVE(EMIFS_CONFIG);
508 }
509
510 if (virtual_start == 0) {
511 g_read_completed = 0;
512
513 my_buffer_offset += sprintf(my_base + my_buffer_offset,
514 "ARM_CKCTL_REG: 0x%-8x \n"
515 "ARM_IDLECT1_REG: 0x%-8x \n"
516 "ARM_IDLECT2_REG: 0x%-8x \n"
517 "ARM_IDLECT3_REG: 0x%-8x \n"
518 "ARM_EWUPCT_REG: 0x%-8x \n"
519 "ARM_RSTCT1_REG: 0x%-8x \n"
520 "ARM_RSTCT2_REG: 0x%-8x \n"
521 "ARM_SYSST_REG: 0x%-8x \n"
522 "ULPD_IT_STATUS_REG: 0x%-4x \n"
523 "ULPD_CLOCK_CTRL_REG: 0x%-4x \n"
524 "ULPD_SOFT_REQ_REG: 0x%-4x \n"
525 "ULPD_DPLL_CTRL_REG: 0x%-4x \n"
526 "ULPD_STATUS_REQ_REG: 0x%-4x \n"
527 "ULPD_POWER_CTRL_REG: 0x%-4x \n",
528 ARM_SHOW(ARM_CKCTL),
529 ARM_SHOW(ARM_IDLECT1),
530 ARM_SHOW(ARM_IDLECT2),
531 ARM_SHOW(ARM_IDLECT3),
532 ARM_SHOW(ARM_EWUPCT),
533 ARM_SHOW(ARM_RSTCT1),
534 ARM_SHOW(ARM_RSTCT2),
535 ARM_SHOW(ARM_SYSST),
536 ULPD_SHOW(ULPD_IT_STATUS),
537 ULPD_SHOW(ULPD_CLOCK_CTRL),
538 ULPD_SHOW(ULPD_SOFT_REQ),
539 ULPD_SHOW(ULPD_DPLL_CTRL),
540 ULPD_SHOW(ULPD_STATUS_REQ),
541 ULPD_SHOW(ULPD_POWER_CTRL));
542
543 if (cpu_is_omap730()) {
544 my_buffer_offset += sprintf(my_base + my_buffer_offset,
545 "MPUI730_CTRL_REG 0x%-8x \n"
546 "MPUI730_DSP_STATUS_REG: 0x%-8x \n"
547 "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
548 "MPUI730_DSP_API_CONFIG_REG: 0x%-8x \n"
549 "MPUI730_SDRAM_CONFIG_REG: 0x%-8x \n"
550 "MPUI730_EMIFS_CONFIG_REG: 0x%-8x \n",
551 MPUI730_SHOW(MPUI_CTRL),
552 MPUI730_SHOW(MPUI_DSP_STATUS),
553 MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG),
554 MPUI730_SHOW(MPUI_DSP_API_CONFIG),
555 MPUI730_SHOW(EMIFF_SDRAM_CONFIG),
556 MPUI730_SHOW(EMIFS_CONFIG));
557 } else if (cpu_is_omap15xx()) {
558 my_buffer_offset += sprintf(my_base + my_buffer_offset,
559 "MPUI1510_CTRL_REG 0x%-8x \n"
560 "MPUI1510_DSP_STATUS_REG: 0x%-8x \n"
561 "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
562 "MPUI1510_DSP_API_CONFIG_REG: 0x%-8x \n"
563 "MPUI1510_SDRAM_CONFIG_REG: 0x%-8x \n"
564 "MPUI1510_EMIFS_CONFIG_REG: 0x%-8x \n",
565 MPUI1510_SHOW(MPUI_CTRL),
566 MPUI1510_SHOW(MPUI_DSP_STATUS),
567 MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG),
568 MPUI1510_SHOW(MPUI_DSP_API_CONFIG),
569 MPUI1510_SHOW(EMIFF_SDRAM_CONFIG),
570 MPUI1510_SHOW(EMIFS_CONFIG));
571 } else if (cpu_is_omap16xx()) {
572 my_buffer_offset += sprintf(my_base + my_buffer_offset,
573 "MPUI1610_CTRL_REG 0x%-8x \n"
574 "MPUI1610_DSP_STATUS_REG: 0x%-8x \n"
575 "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
576 "MPUI1610_DSP_API_CONFIG_REG: 0x%-8x \n"
577 "MPUI1610_SDRAM_CONFIG_REG: 0x%-8x \n"
578 "MPUI1610_EMIFS_CONFIG_REG: 0x%-8x \n",
579 MPUI1610_SHOW(MPUI_CTRL),
580 MPUI1610_SHOW(MPUI_DSP_STATUS),
581 MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG),
582 MPUI1610_SHOW(MPUI_DSP_API_CONFIG),
583 MPUI1610_SHOW(EMIFF_SDRAM_CONFIG),
584 MPUI1610_SHOW(EMIFS_CONFIG));
585 }
586
587 g_read_completed++;
588 } else if (g_read_completed >= 1) {
589 *eof = 1;
590 return 0;
591 }
592 g_read_completed++;
593
594 *my_first_byte = page_buffer;
595 return my_buffer_offset;
596}
597
598static void omap_pm_init_proc(void)
599{
600 struct proc_dir_entry *entry;
601
602 entry = create_proc_read_entry("driver/omap_pm",
603 S_IWUSR | S_IRUGO, NULL,
604 omap_pm_read_proc, NULL);
605}
606
607#endif /* DEBUG && CONFIG_PROC_FS */
608
609static void (*saved_idle)(void) = NULL;
610
611/*
612 * omap_pm_prepare - Do preliminary suspend work.
613 * @state: suspend state we're entering.
614 *
615 */
616static int omap_pm_prepare(suspend_state_t state)
617{
618 int error = 0;
619
620 /* We cannot sleep in idle until we have resumed */
621 saved_idle = pm_idle;
622 pm_idle = NULL;
623
624 switch (state)
625 {
626 case PM_SUSPEND_STANDBY:
627 case PM_SUSPEND_MEM:
628 break;
629
630 case PM_SUSPEND_DISK:
631 return -ENOTSUPP;
632
633 default:
634 return -EINVAL;
635 }
636
637 return error;
638}
639
640
641/*
642 * omap_pm_enter - Actually enter a sleep state.
643 * @state: State we're entering.
644 *
645 */
646
647static int omap_pm_enter(suspend_state_t state)
648{
649 switch (state)
650 {
651 case PM_SUSPEND_STANDBY:
652 case PM_SUSPEND_MEM:
653 omap_pm_suspend();
654 break;
655
656 case PM_SUSPEND_DISK:
657 return -ENOTSUPP;
658
659 default:
660 return -EINVAL;
661 }
662
663 return 0;
664}
665
666
667/**
668 * omap_pm_finish - Finish up suspend sequence.
669 * @state: State we're coming out of.
670 *
671 * This is called after we wake back up (or if entering the sleep state
672 * failed).
673 */
674
675static int omap_pm_finish(suspend_state_t state)
676{
677 pm_idle = saved_idle;
678 return 0;
679}
680
681
682static irqreturn_t omap_wakeup_interrupt(int irq, void * dev,
683 struct pt_regs * regs)
684{
685 return IRQ_HANDLED;
686}
687
688static struct irqaction omap_wakeup_irq = {
689 .name = "peripheral wakeup",
690 .flags = SA_INTERRUPT,
691 .handler = omap_wakeup_interrupt
692};
693
694
695
696static struct pm_ops omap_pm_ops ={
697 .pm_disk_mode = 0,
698 .prepare = omap_pm_prepare,
699 .enter = omap_pm_enter,
700 .finish = omap_pm_finish,
701};
702
703static int __init omap_pm_init(void)
704{
705 printk("Power Management for TI OMAP.\n");
706
707 /*
708 * We copy the assembler sleep/wakeup routines to SRAM.
709 * These routines need to be in SRAM as that's the only
710 * memory the MPU can see when it wakes up.
711 */
712 if (cpu_is_omap730()) {
713 omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend,
714 omap730_idle_loop_suspend_sz);
715 omap_sram_suspend = omap_sram_push(omap730_cpu_suspend,
716 omap730_cpu_suspend_sz);
717 } else if (cpu_is_omap15xx()) {
718 omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend,
719 omap1510_idle_loop_suspend_sz);
720 omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
721 omap1510_cpu_suspend_sz);
722 } else if (cpu_is_omap16xx()) {
723 omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend,
724 omap1610_idle_loop_suspend_sz);
725 omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend,
726 omap1610_cpu_suspend_sz);
727 }
728
729 if (omap_sram_idle == NULL || omap_sram_suspend == NULL) {
730 printk(KERN_ERR "PM not initialized: Missing SRAM support\n");
731 return -ENODEV;
732 }
733
734 pm_idle = omap_pm_idle;
735
736 if (cpu_is_omap730())
737 setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq);
738 else if (cpu_is_omap16xx())
739 setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
740
741 /* Program new power ramp-up time
742 * (0 for most boards since we don't lower voltage when in deep sleep)
743 */
744 omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3);
745
746 /* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */
747 omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
748
749 /* Configure IDLECT3 */
750 if (cpu_is_omap730())
751 omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3);
752 else if (cpu_is_omap16xx())
753 omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
754
755 pm_set_ops(&omap_pm_ops);
756
757#if defined(DEBUG) && defined(CONFIG_PROC_FS)
758 omap_pm_init_proc();
759#endif
760
761 subsys_create_file(&power_subsys, &sleep_while_idle_attr);
762
763 if (cpu_is_omap16xx()) {
764 /* configure LOW_PWR pin */
765 omap_cfg_reg(T20_1610_LOW_PWR);
766 }
767
768 return 0;
769}
770__initcall(omap_pm_init);
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index e924e0c6a4ce..9b4cd698bec8 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -30,9 +30,9 @@
30#include <asm/arch/pm.h> 30#include <asm/arch/pm.h>
31#endif 31#endif
32 32
33static struct clk * uart1_ck = NULL; 33static struct clk * uart1_ck;
34static struct clk * uart2_ck = NULL; 34static struct clk * uart2_ck;
35static struct clk * uart3_ck = NULL; 35static struct clk * uart3_ck;
36 36
37static inline unsigned int omap_serial_in(struct plat_serial8250_port *up, 37static inline unsigned int omap_serial_in(struct plat_serial8250_port *up,
38 int offset) 38 int offset)
diff --git a/arch/arm/mach-omap1/sleep.S b/arch/arm/mach-omap1/sleep.S
new file mode 100644
index 000000000000..e58295e2d3b2
--- /dev/null
+++ b/arch/arm/mach-omap1/sleep.S
@@ -0,0 +1,525 @@
1/*
2 * linux/arch/arm/mach-omap1/sleep.S
3 *
4 * Low-level OMAP730/1510/1610 sleep/wakeUp support
5 *
6 * Initial SA1110 code:
7 * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
8 *
9 * Adapted for PXA by Nicolas Pitre:
10 * Copyright (c) 2002 Monta Vista Software, Inc.
11 *
12 * Support for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com>
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version.
18 *
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
22 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 */
34
35#include <linux/config.h>
36#include <linux/linkage.h>
37#include <asm/assembler.h>
38#include <asm/arch/io.h>
39#include <asm/arch/pm.h>
40
41 .text
42
43/*
44 * Forces OMAP into idle state
45 *
46 * omapXXXX_idle_loop_suspend()
47 *
48 * Note: This code get's copied to internal SRAM at boot. When the OMAP
49 * wakes up it continues execution at the point it went to sleep.
50 *
51 * Note: Because of slightly different configuration values we have
52 * processor specific functions here.
53 */
54
55#if defined(CONFIG_ARCH_OMAP730)
56ENTRY(omap730_idle_loop_suspend)
57
58 stmfd sp!, {r0 - r12, lr} @ save registers on stack
59
60 @ load base address of ARM_IDLECT1 and ARM_IDLECT2
61 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
62 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
63 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
64
65 @ turn off clock domains
66 @ get ARM_IDLECT2 into r2
67 ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
68 mov r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff
69 orr r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00
70 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
71
72 @ request ARM idle
73 @ get ARM_IDLECT1 into r1
74 ldrh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
75 orr r3, r1, #OMAP730_IDLE_LOOP_REQUEST & 0xffff
76 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
77
78 mov r5, #IDLE_WAIT_CYCLES & 0xff
79 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
80l_730: subs r5, r5, #1
81 bne l_730
82/*
83 * Let's wait for the next clock tick to wake us up.
84 */
85 mov r0, #0
86 mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
87/*
88 * omap730_idle_loop_suspend()'s resume point.
89 *
90 * It will just start executing here, so we'll restore stuff from the
91 * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
92 */
93
94 @ restore ARM_IDLECT1 and ARM_IDLECT2 and return
95 @ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
96 strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
97 strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
98
99 ldmfd sp!, {r0 - r12, pc} @ restore regs and return
100
101ENTRY(omap730_idle_loop_suspend_sz)
102 .word . - omap730_idle_loop_suspend
103#endif /* CONFIG_ARCH_OMAP730 */
104
105#ifdef CONFIG_ARCH_OMAP15XX
106ENTRY(omap1510_idle_loop_suspend)
107
108 stmfd sp!, {r0 - r12, lr} @ save registers on stack
109
110 @ load base address of ARM_IDLECT1 and ARM_IDLECT2
111 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
112 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
113 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
114
115 @ turn off clock domains
116 @ get ARM_IDLECT2 into r2
117 ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
118 mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
119 orr r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
120 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
121
122 @ request ARM idle
123 @ get ARM_IDLECT1 into r1
124 ldrh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
125 orr r3, r1, #OMAP1510_IDLE_LOOP_REQUEST & 0xffff
126 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
127
128 mov r5, #IDLE_WAIT_CYCLES & 0xff
129 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
130l_1510: subs r5, r5, #1
131 bne l_1510
132/*
133 * Let's wait for the next clock tick to wake us up.
134 */
135 mov r0, #0
136 mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
137/*
138 * omap1510_idle_loop_suspend()'s resume point.
139 *
140 * It will just start executing here, so we'll restore stuff from the
141 * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
142 */
143
144 @ restore ARM_IDLECT1 and ARM_IDLECT2 and return
145 @ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
146 strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
147 strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
148
149 ldmfd sp!, {r0 - r12, pc} @ restore regs and return
150
151ENTRY(omap1510_idle_loop_suspend_sz)
152 .word . - omap1510_idle_loop_suspend
153#endif /* CONFIG_ARCH_OMAP15XX */
154
155#if defined(CONFIG_ARCH_OMAP16XX)
156ENTRY(omap1610_idle_loop_suspend)
157
158 stmfd sp!, {r0 - r12, lr} @ save registers on stack
159
160 @ load base address of ARM_IDLECT1 and ARM_IDLECT2
161 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
162 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
163 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
164
165 @ turn off clock domains
166 @ get ARM_IDLECT2 into r2
167 ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
168 mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
169 orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
170 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
171
172 @ request ARM idle
173 @ get ARM_IDLECT1 into r1
174 ldrh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
175 orr r3, r1, #OMAP1610_IDLE_LOOP_REQUEST & 0xffff
176 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
177
178 mov r5, #IDLE_WAIT_CYCLES & 0xff
179 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
180l_1610: subs r5, r5, #1
181 bne l_1610
182/*
183 * Let's wait for the next clock tick to wake us up.
184 */
185 mov r0, #0
186 mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
187/*
188 * omap1610_idle_loop_suspend()'s resume point.
189 *
190 * It will just start executing here, so we'll restore stuff from the
191 * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
192 */
193
194 @ restore ARM_IDLECT1 and ARM_IDLECT2 and return
195 @ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
196 strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
197 strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
198
199 ldmfd sp!, {r0 - r12, pc} @ restore regs and return
200
201ENTRY(omap1610_idle_loop_suspend_sz)
202 .word . - omap1610_idle_loop_suspend
203#endif /* CONFIG_ARCH_OMAP16XX */
204
205/*
206 * Forces OMAP into deep sleep state
207 *
208 * omapXXXX_cpu_suspend()
209 *
210 * The values of the registers ARM_IDLECT1 and ARM_IDLECT2 are passed
211 * as arg0 and arg1 from caller. arg0 is stored in register r0 and arg1
212 * in register r1.
213 *
214 * Note: This code get's copied to internal SRAM at boot. When the OMAP
215 * wakes up it continues execution at the point it went to sleep.
216 *
217 * Note: Because of errata work arounds we have processor specific functions
218 * here. They are mostly the same, but slightly different.
219 *
220 */
221
222#if defined(CONFIG_ARCH_OMAP730)
223ENTRY(omap730_cpu_suspend)
224
225 @ save registers on stack
226 stmfd sp!, {r0 - r12, lr}
227
228 @ Drain write cache
229 mov r4, #0
230 mcr p15, 0, r0, c7, c10, 4
231 nop
232
233 @ load base address of Traffic Controller
234 mov r6, #TCMIF_ASM_BASE & 0xff000000
235 orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
236 orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
237
238 @ prepare to put SDRAM into self-refresh manually
239 ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
240 orr r9, r7, #SELF_REFRESH_MODE & 0xff000000
241 orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff
242 str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
243
244 @ prepare to put EMIFS to Sleep
245 ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
246 orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff
247 str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
248
249 @ load base address of ARM_IDLECT1 and ARM_IDLECT2
250 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
251 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
252 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
253
254 @ turn off clock domains
255 @ do not disable PERCK (0x04)
256 mov r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff
257 orr r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00
258 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
259
260 @ request ARM idle
261 mov r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff
262 orr r3, r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff00
263 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
264
265 @ disable instruction cache
266 mrc p15, 0, r9, c1, c0, 0
267 bic r2, r9, #0x1000
268 mcr p15, 0, r2, c1, c0, 0
269 nop
270
271/*
272 * Let's wait for the next wake up event to wake us up. r0 can't be
273 * used here because r0 holds ARM_IDLECT1
274 */
275 mov r2, #0
276 mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
277/*
278 * omap730_cpu_suspend()'s resume point.
279 *
280 * It will just start executing here, so we'll restore stuff from the
281 * stack.
282 */
283 @ re-enable Icache
284 mcr p15, 0, r9, c1, c0, 0
285
286 @ reset the ARM_IDLECT1 and ARM_IDLECT2.
287 strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
288 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
289
290 @ Restore EMIFF controls
291 str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
292 str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
293
294 @ restore regs and return
295 ldmfd sp!, {r0 - r12, pc}
296
297ENTRY(omap730_cpu_suspend_sz)
298 .word . - omap730_cpu_suspend
299#endif /* CONFIG_ARCH_OMAP730 */
300
301#ifdef CONFIG_ARCH_OMAP15XX
302ENTRY(omap1510_cpu_suspend)
303
304 @ save registers on stack
305 stmfd sp!, {r0 - r12, lr}
306
307 @ load base address of Traffic Controller
308 mov r4, #TCMIF_ASM_BASE & 0xff000000
309 orr r4, r4, #TCMIF_ASM_BASE & 0x00ff0000
310 orr r4, r4, #TCMIF_ASM_BASE & 0x0000ff00
311
312 @ work around errata of OMAP1510 PDE bit for TC shut down
313 @ clear PDE bit
314 ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
315 bic r5, r5, #PDE_BIT & 0xff
316 str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
317
318 @ set PWD_EN bit
319 and r5, r5, #PWD_EN_BIT & 0xff
320 str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
321
322 @ prepare to put SDRAM into self-refresh manually
323 ldr r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
324 orr r5, r5, #SELF_REFRESH_MODE & 0xff000000
325 orr r5, r5, #SELF_REFRESH_MODE & 0x000000ff
326 str r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
327
328 @ prepare to put EMIFS to Sleep
329 ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
330 orr r5, r5, #IDLE_EMIFS_REQUEST & 0xff
331 str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
332
333 @ load base address of ARM_IDLECT1 and ARM_IDLECT2
334 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
335 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
336 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
337
338 @ turn off clock domains
339 mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
340 orr r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
341 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
342
343 @ request ARM idle
344 mov r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff
345 orr r3, r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff00
346 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
347
348 mov r5, #IDLE_WAIT_CYCLES & 0xff
349 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
350l_1510_2:
351 subs r5, r5, #1
352 bne l_1510_2
353/*
354 * Let's wait for the next wake up event to wake us up. r0 can't be
355 * used here because r0 holds ARM_IDLECT1
356 */
357 mov r2, #0
358 mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
359/*
360 * omap1510_cpu_suspend()'s resume point.
361 *
362 * It will just start executing here, so we'll restore stuff from the
363 * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
364 */
365 strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
366 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
367
368 @ restore regs and return
369 ldmfd sp!, {r0 - r12, pc}
370
371ENTRY(omap1510_cpu_suspend_sz)
372 .word . - omap1510_cpu_suspend
373#endif /* CONFIG_ARCH_OMAP15XX */
374
375#if defined(CONFIG_ARCH_OMAP16XX)
376ENTRY(omap1610_cpu_suspend)
377
378 @ save registers on stack
379 stmfd sp!, {r0 - r12, lr}
380
381 @ Drain write cache
382 mov r4, #0
383 mcr p15, 0, r0, c7, c10, 4
384 nop
385
386 @ Load base address of Traffic Controller
387 mov r6, #TCMIF_ASM_BASE & 0xff000000
388 orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
389 orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
390
391 @ Prepare to put SDRAM into self-refresh manually
392 ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
393 orr r9, r7, #SELF_REFRESH_MODE & 0xff000000
394 orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff
395 str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
396
397 @ Prepare to put EMIFS to Sleep
398 ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
399 orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff
400 str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
401
402 @ Load base address of ARM_IDLECT1 and ARM_IDLECT2
403 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
404 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
405 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
406
407 @ Turn off clock domains
408 @ Do not disable PERCK (0x04)
409 mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
410 orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
411 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
412
413 @ Request ARM idle
414 mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff
415 orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00
416 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
417
418/*
419 * Let's wait for the next wake up event to wake us up. r0 can't be
420 * used here because r0 holds ARM_IDLECT1
421 */
422 mov r2, #0
423 mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
424
425 @ Errata (HEL3SU467, section 1.4.4) specifies nop-instructions
426 @ according to this formula:
427 @ 2 + (4*DPLL_MULT)/DPLL_DIV/ARMDIV
428 @ Max DPLL_MULT = 18
429 @ DPLL_DIV = 1
430 @ ARMDIV = 1
431 @ => 74 nop-instructions
432 nop
433 nop
434 nop
435 nop
436 nop
437 nop
438 nop
439 nop
440 nop
441 nop @10
442 nop
443 nop
444 nop
445 nop
446 nop
447 nop
448 nop
449 nop
450 nop
451 nop @20
452 nop
453 nop
454 nop
455 nop
456 nop
457 nop
458 nop
459 nop
460 nop
461 nop @30
462 nop
463 nop
464 nop
465 nop
466 nop
467 nop
468 nop
469 nop
470 nop
471 nop @40
472 nop
473 nop
474 nop
475 nop
476 nop
477 nop
478 nop
479 nop
480 nop
481 nop @50
482 nop
483 nop
484 nop
485 nop
486 nop
487 nop
488 nop
489 nop
490 nop
491 nop @60
492 nop
493 nop
494 nop
495 nop
496 nop
497 nop
498 nop
499 nop
500 nop
501 nop @70
502 nop
503 nop
504 nop
505 nop @74
506/*
507 * omap1610_cpu_suspend()'s resume point.
508 *
509 * It will just start executing here, so we'll restore stuff from the
510 * stack.
511 */
512 @ Restore the ARM_IDLECT1 and ARM_IDLECT2.
513 strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
514 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
515
516 @ Restore EMIFF controls
517 str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
518 str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
519
520 @ Restore regs and return
521 ldmfd sp!, {r0 - r12, pc}
522
523ENTRY(omap1610_cpu_suspend_sz)
524 .word . - omap1610_cpu_suspend
525#endif /* CONFIG_ARCH_OMAP16XX */
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index cdbf4d7620c6..a85fe6066bc4 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -51,8 +51,6 @@
51 51
52struct sys_timer omap_timer; 52struct sys_timer omap_timer;
53 53
54#ifdef CONFIG_OMAP_MPU_TIMER
55
56/* 54/*
57 * --------------------------------------------------------------------------- 55 * ---------------------------------------------------------------------------
58 * MPU timer 56 * MPU timer
@@ -222,195 +220,6 @@ unsigned long long sched_clock(void)
222 220
223 return cycles_2_ns(ticks64); 221 return cycles_2_ns(ticks64);
224} 222}
225#endif /* CONFIG_OMAP_MPU_TIMER */
226
227#ifdef CONFIG_OMAP_32K_TIMER
228
229#ifdef CONFIG_ARCH_OMAP15XX
230#error OMAP 32KHz timer does not currently work on 15XX!
231#endif
232
233/*
234 * ---------------------------------------------------------------------------
235 * 32KHz OS timer
236 *
237 * This currently works only on 16xx, as 1510 does not have the continuous
238 * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track
239 * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer
240 * on 1510 would be possible, but the timer would not be as accurate as
241 * with the 32KHz synchronized timer.
242 * ---------------------------------------------------------------------------
243 */
244#define OMAP_32K_TIMER_BASE 0xfffb9000
245#define OMAP_32K_TIMER_CR 0x08
246#define OMAP_32K_TIMER_TVR 0x00
247#define OMAP_32K_TIMER_TCR 0x04
248
249#define OMAP_32K_TICKS_PER_HZ (32768 / HZ)
250
251/*
252 * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
253 * so with HZ = 100, TVR = 327.68.
254 */
255#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1)
256#define TIMER_32K_SYNCHRONIZED 0xfffbc410
257
258#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \
259 (((nr_jiffies) * (clock_rate)) / HZ)
260
261static inline void omap_32k_timer_write(int val, int reg)
262{
263 omap_writew(val, reg + OMAP_32K_TIMER_BASE);
264}
265
266static inline unsigned long omap_32k_timer_read(int reg)
267{
268 return omap_readl(reg + OMAP_32K_TIMER_BASE) & 0xffffff;
269}
270
271/*
272 * The 32KHz synchronized timer is an additional timer on 16xx.
273 * It is always running.
274 */
275static inline unsigned long omap_32k_sync_timer_read(void)
276{
277 return omap_readl(TIMER_32K_SYNCHRONIZED);
278}
279
280static inline void omap_32k_timer_start(unsigned long load_val)
281{
282 omap_32k_timer_write(load_val, OMAP_32K_TIMER_TVR);
283 omap_32k_timer_write(0x0f, OMAP_32K_TIMER_CR);
284}
285
286static inline void omap_32k_timer_stop(void)
287{
288 omap_32k_timer_write(0x0, OMAP_32K_TIMER_CR);
289}
290
291/*
292 * Rounds down to nearest usec. Note that this will overflow for larger values.
293 */
294static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k)
295{
296 return (ticks_32k * 5*5*5*5*5*5) >> 9;
297}
298
299/*
300 * Rounds down to nearest nsec.
301 */
302static inline unsigned long long
303omap_32k_ticks_to_nsecs(unsigned long ticks_32k)
304{
305 return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9;
306}
307
308static unsigned long omap_32k_last_tick = 0;
309
310/*
311 * Returns elapsed usecs since last 32k timer interrupt
312 */
313static unsigned long omap_32k_timer_gettimeoffset(void)
314{
315 unsigned long now = omap_32k_sync_timer_read();
316 return omap_32k_ticks_to_usecs(now - omap_32k_last_tick);
317}
318
319/*
320 * Returns current time from boot in nsecs. It's OK for this to wrap
321 * around for now, as it's just a relative time stamp.
322 */
323unsigned long long sched_clock(void)
324{
325 return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
326}
327
328/*
329 * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
330 * function is also called from other interrupts to remove latency
331 * issues with dynamic tick. In the dynamic tick case, we need to lock
332 * with irqsave.
333 */
334static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
335 struct pt_regs *regs)
336{
337 unsigned long flags;
338 unsigned long now;
339
340 write_seqlock_irqsave(&xtime_lock, flags);
341 now = omap_32k_sync_timer_read();
342
343 while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
344 omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
345 timer_tick(regs);
346 }
347
348 /* Restart timer so we don't drift off due to modulo or dynamic tick.
349 * By default we program the next timer to be continuous to avoid
350 * latencies during high system load. During dynamic tick operation the
351 * continuous timer can be overridden from pm_idle to be longer.
352 */
353 omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
354 write_sequnlock_irqrestore(&xtime_lock, flags);
355
356 return IRQ_HANDLED;
357}
358
359#ifdef CONFIG_NO_IDLE_HZ
360/*
361 * Programs the next timer interrupt needed. Called when dynamic tick is
362 * enabled, and to reprogram the ticks to skip from pm_idle. Note that
363 * we can keep the timer continuous, and don't need to set it to run in
364 * one-shot mode. This is because the timer will get reprogrammed again
365 * after next interrupt.
366 */
367void omap_32k_timer_reprogram(unsigned long next_tick)
368{
369 omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1);
370}
371
372static struct irqaction omap_32k_timer_irq;
373extern struct timer_update_handler timer_update;
374
375static int omap_32k_timer_enable_dyn_tick(void)
376{
377 /* No need to reprogram timer, just use the next interrupt */
378 return 0;
379}
380
381static int omap_32k_timer_disable_dyn_tick(void)
382{
383 omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
384 return 0;
385}
386
387static struct dyn_tick_timer omap_dyn_tick_timer = {
388 .enable = omap_32k_timer_enable_dyn_tick,
389 .disable = omap_32k_timer_disable_dyn_tick,
390 .reprogram = omap_32k_timer_reprogram,
391 .handler = omap_32k_timer_interrupt,
392};
393#endif /* CONFIG_NO_IDLE_HZ */
394
395static struct irqaction omap_32k_timer_irq = {
396 .name = "32KHz timer",
397 .flags = SA_INTERRUPT | SA_TIMER,
398 .handler = omap_32k_timer_interrupt,
399};
400
401static __init void omap_init_32k_timer(void)
402{
403
404#ifdef CONFIG_NO_IDLE_HZ
405 omap_timer.dyn_tick = &omap_dyn_tick_timer;
406#endif
407
408 setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
409 omap_timer.offset = omap_32k_timer_gettimeoffset;
410 omap_32k_last_tick = omap_32k_sync_timer_read();
411 omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
412}
413#endif /* CONFIG_OMAP_32K_TIMER */
414 223
415/* 224/*
416 * --------------------------------------------------------------------------- 225 * ---------------------------------------------------------------------------
@@ -419,13 +228,7 @@ static __init void omap_init_32k_timer(void)
419 */ 228 */
420static void __init omap_timer_init(void) 229static void __init omap_timer_init(void)
421{ 230{
422#if defined(CONFIG_OMAP_MPU_TIMER)
423 omap_init_mpu_timer(); 231 omap_init_mpu_timer();
424#elif defined(CONFIG_OMAP_32K_TIMER)
425 omap_init_32k_timer();
426#else
427#error No system timer selected in Kconfig!
428#endif
429} 232}
430 233
431struct sys_timer omap_timer = { 234struct sys_timer omap_timer = {