diff options
Diffstat (limited to 'arch/arm/mach-omap1')
-rw-r--r-- | arch/arm/mach-omap1/Kconfig | 20 | ||||
-rw-r--r-- | arch/arm/mach-omap1/Makefile | 11 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-ams-delta.c | 116 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-generic.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-h2.c | 200 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-h3.c | 277 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-innovator.c | 56 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-netstar.c | 160 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-nokia770.c | 268 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-osk.c | 95 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-palmte.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-perseus2.c | 123 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-voiceblue.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-omap1/clock.c | 9 | ||||
-rw-r--r-- | arch/arm/mach-omap1/clock.h | 91 | ||||
-rw-r--r-- | arch/arm/mach-omap1/devices.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-omap1/io.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-omap1/irq.c | 18 | ||||
-rw-r--r-- | arch/arm/mach-omap1/mux.c | 30 | ||||
-rw-r--r-- | arch/arm/mach-omap1/pm.c | 770 | ||||
-rw-r--r-- | arch/arm/mach-omap1/serial.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-omap1/sleep.S | 525 | ||||
-rw-r--r-- | arch/arm/mach-omap1/time.c | 197 |
23 files changed, 2561 insertions, 482 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 | ||
72 | config 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 | |||
78 | config MACH_OMAP_PALMTE | 72 | config 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 | ||
82 | config 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 | |||
89 | config 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 | |||
88 | config MACH_OMAP_GENERIC | 96 | config 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 |
6 | obj-y := io.o id.o clock.o irq.o time.o mux.o serial.o devices.o | 6 | obj-y := io.o id.o clock.o irq.o mux.o serial.o devices.o |
7 | |||
8 | obj-$(CONFIG_OMAP_MPU_TIMER) += time.o | ||
9 | |||
10 | # Power Management | ||
11 | obj-$(CONFIG_PM) += pm.o sleep.o | ||
12 | |||
7 | led-y := leds.o | 13 | led-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 | |||
14 | obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o | 20 | obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o |
15 | obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o | 21 | obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o |
16 | obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o | 22 | obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o |
17 | obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o | ||
18 | obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o | 23 | obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o |
24 | obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o | ||
25 | obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o | ||
19 | 26 | ||
20 | ifeq ($(CONFIG_ARCH_OMAP15XX),y) | 27 | ifeq ($(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 | |||
31 | static u8 ams_delta_latch1_reg; | ||
32 | static u16 ams_delta_latch2_reg; | ||
33 | |||
34 | void 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 | |||
41 | void 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 | |||
48 | static void __init ams_delta_init_irq(void) | ||
49 | { | ||
50 | omap1_init_common_hw(); | ||
51 | omap_init_irq(); | ||
52 | omap_gpio_init(); | ||
53 | } | ||
54 | |||
55 | static 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 | |||
79 | static struct omap_uart_config ams_delta_uart_config __initdata = { | ||
80 | .enabled_uarts = 1, | ||
81 | }; | ||
82 | |||
83 | static struct omap_board_config_kernel ams_delta_config[] = { | ||
84 | { OMAP_TAG_UART, &ams_delta_uart_config }, | ||
85 | }; | ||
86 | |||
87 | static 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 | |||
99 | static void __init ams_delta_map_io(void) | ||
100 | { | ||
101 | omap1_map_common_io(); | ||
102 | } | ||
103 | |||
104 | MACHINE_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, | ||
113 | MACHINE_END | ||
114 | |||
115 | EXPORT_SYMBOL(ams_delta_latch1_write); | ||
116 | EXPORT_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[] = { | |||
88 | static void __init omap_generic_init(void) | 88 | static 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 | ||
41 | extern int omap_gpio_init(void); | 47 | extern int omap_gpio_init(void); |
42 | 48 | ||
43 | static struct mtd_partition h2_partitions[] = { | 49 | static 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 | |||
88 | static 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 | ||
74 | static struct flash_platform_data h2_flash_data = { | 119 | static 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 | ||
81 | static struct resource h2_flash_resource = { | 126 | static 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 | ||
86 | static struct platform_device h2_flash_device = { | 131 | static 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 | ||
96 | static struct resource h2_smc91x_resources[] = { | 141 | static 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 | ||
161 | static struct resource h2_kp_resources[] = { | ||
162 | [0] = { | ||
163 | .start = INT_KEYBOARD, | ||
164 | .end = INT_KEYBOARD, | ||
165 | .flags = IORESOURCE_IRQ, | ||
166 | }, | ||
167 | }; | ||
168 | |||
169 | static struct omap_kp_platform_data h2_kp_data = { | ||
170 | .rows = 8, | ||
171 | .cols = 8, | ||
172 | .keymap = h2_keymap, | ||
173 | .rep = 1, | ||
174 | }; | ||
175 | |||
176 | static 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) | ||
189 | static 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 | |||
200 | static 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 | |||
210 | static struct resource h2_irda_resources[] = { | ||
211 | [0] = { | ||
212 | .start = INT_UART3, | ||
213 | .end = INT_UART3, | ||
214 | .flags = IORESOURCE_IRQ, | ||
215 | }, | ||
216 | }; | ||
217 | static 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 | |||
227 | static struct platform_device h2_lcd_device = { | ||
228 | .name = "lcd_h2", | ||
229 | .id = -1, | ||
230 | }; | ||
231 | |||
232 | static 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 | |||
248 | static 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 | |||
259 | static struct platform_device h2_mcbsp1_device = { | ||
260 | .name = "omap_alsa_mcbsp", | ||
261 | .id = 1, | ||
262 | .dev = { | ||
263 | .platform_data = &alsa_config, | ||
264 | }, | ||
265 | }; | ||
266 | |||
116 | static struct platform_device *h2_devices[] __initdata = { | 267 | static 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 | ||
121 | static void __init h2_init_smc91x(void) | 276 | static void __init h2_init_smc91x(void) |
@@ -164,7 +319,6 @@ static struct omap_uart_config h2_uart_config __initdata = { | |||
164 | }; | 319 | }; |
165 | 320 | ||
166 | static struct omap_lcd_config h2_lcd_config __initdata = { | 321 | static 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 | ||
178 | static void __init h2_init(void) | 332 | static 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 | ||
42 | extern int omap_gpio_init(void); | 49 | extern int omap_gpio_init(void); |
43 | 50 | ||
44 | static struct mtd_partition h3_partitions[] = { | 51 | static 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 | |||
91 | static 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 | ||
75 | static struct flash_platform_data h3_flash_data = { | 122 | static 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 | ||
82 | static struct resource h3_flash_resource = { | 129 | static 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 | ||
87 | static struct platform_device flash_device = { | 134 | static 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 | |||
144 | static 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 */ | ||
178 | static 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 | |||
184 | static struct resource nand_resource = { | ||
185 | .flags = IORESOURCE_MEM, | ||
186 | }; | ||
187 | |||
188 | static 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 | ||
97 | static struct resource smc91x_resources[] = { | 198 | static 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 | ||
242 | static struct resource h3_kp_resources[] = { | ||
243 | [0] = { | ||
244 | .start = INT_KEYBOARD, | ||
245 | .end = INT_KEYBOARD, | ||
246 | .flags = IORESOURCE_IRQ, | ||
247 | }, | ||
248 | }; | ||
249 | |||
250 | static struct omap_kp_platform_data h3_kp_data = { | ||
251 | .rows = 8, | ||
252 | .cols = 8, | ||
253 | .keymap = h3_keymap, | ||
254 | .rep = 1, | ||
255 | }; | ||
256 | |||
257 | static 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 | */ | ||
270 | static 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 | |||
295 | static 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 | |||
318 | static 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 | |||
329 | static 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 | |||
341 | static struct resource h3_irda_resources[] = { | ||
342 | [0] = { | ||
343 | .start = INT_UART3, | ||
344 | .end = INT_UART3, | ||
345 | .flags = IORESOURCE_IRQ, | ||
346 | }, | ||
347 | }; | ||
348 | |||
349 | static 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 | |||
359 | static struct platform_device h3_lcd_device = { | ||
360 | .name = "lcd_h3", | ||
361 | .id = -1, | ||
362 | }; | ||
363 | |||
141 | static struct platform_device *devices[] __initdata = { | 364 | static 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 | ||
147 | static struct omap_usb_config h3_usb_config __initdata = { | 374 | static 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 | ||
173 | static struct omap_lcd_config h3_lcd_config __initdata = { | 400 | static 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 | |||
413 | static int nand_dev_ready(struct nand_platform_data *data) | ||
414 | { | ||
415 | return omap_get_gpio_datain(H3_NAND_RB_GPIO_PIN); | ||
416 | } | ||
417 | |||
185 | static void __init h3_init(void) | 418 | static 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 | ||
41 | static 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 | |||
39 | static struct mtd_partition innovator_partitions[] = { | 54 | static 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 | ||
115 | static struct resource innovator_kp_resources[] = { | ||
116 | [0] = { | ||
117 | .start = INT_KEYBOARD, | ||
118 | .end = INT_KEYBOARD, | ||
119 | .flags = IORESOURCE_IRQ, | ||
120 | }, | ||
121 | }; | ||
122 | |||
123 | static struct omap_kp_platform_data innovator_kp_data = { | ||
124 | .rows = 8, | ||
125 | .cols = 8, | ||
126 | .keymap = innovator_keymap, | ||
127 | }; | ||
128 | |||
129 | static 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 | ||
172 | static struct platform_device innovator1510_lcd_device = { | ||
173 | .name = "lcd_inn1510", | ||
174 | .id = -1, | ||
175 | }; | ||
176 | |||
132 | static struct platform_device *innovator1510_devices[] __initdata = { | 177 | static 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 | ||
208 | static struct platform_device innovator1610_lcd_device = { | ||
209 | .name = "inn1610_lcd", | ||
210 | .id = -1, | ||
211 | }; | ||
212 | |||
161 | static struct platform_device *innovator1610_devices[] __initdata = { | 213 | static 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 | ||
208 | static struct omap_lcd_config innovator1510_lcd_config __initdata = { | 262 | static 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 | ||
230 | static struct omap_lcd_config innovator1610_lcd_config __initdata = { | 283 | static 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 | |||
31 | extern void __init omap_init_time(void); | ||
32 | extern int omap_gpio_init(void); | ||
33 | |||
34 | static 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 | |||
47 | static 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 | |||
54 | static struct platform_device *netstar_devices[] __initdata = { | ||
55 | &netstar_smc91x_device, | ||
56 | }; | ||
57 | |||
58 | static struct omap_uart_config netstar_uart_config __initdata = { | ||
59 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
60 | }; | ||
61 | |||
62 | static struct omap_board_config_kernel netstar_config[] = { | ||
63 | { OMAP_TAG_UART, &netstar_uart_config }, | ||
64 | }; | ||
65 | |||
66 | static void __init netstar_init_irq(void) | ||
67 | { | ||
68 | omap1_init_common_hw(); | ||
69 | omap_init_irq(); | ||
70 | omap_gpio_init(); | ||
71 | } | ||
72 | |||
73 | static 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 | |||
110 | static 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 | ||
118 | static unsigned long machine_state; | ||
119 | |||
120 | static 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 | |||
135 | static struct notifier_block panic_block = { | ||
136 | .notifier_call = panic_event, | ||
137 | }; | ||
138 | |||
139 | static 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 | |||
149 | postcore_initcall(netstar_late_init); | ||
150 | |||
151 | MACHINE_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, | ||
160 | MACHINE_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 | |||
35 | static 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 | |||
50 | static 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 | |||
65 | static struct resource nokia770_kp_resources[] = { | ||
66 | [0] = { | ||
67 | .start = INT_KEYBOARD, | ||
68 | .end = INT_KEYBOARD, | ||
69 | .flags = IORESOURCE_IRQ, | ||
70 | }, | ||
71 | }; | ||
72 | |||
73 | static struct omap_kp_platform_data nokia770_kp_data = { | ||
74 | .rows = 8, | ||
75 | .cols = 8, | ||
76 | .keymap = nokia770_keymap | ||
77 | }; | ||
78 | |||
79 | static 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 | |||
89 | static struct platform_device *nokia770_devices[] __initdata = { | ||
90 | &nokia770_kp_device, | ||
91 | }; | ||
92 | |||
93 | static 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 | |||
102 | static 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 | |||
122 | static 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 | |||
130 | static 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 | |||
147 | static 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 | |||
158 | static struct clk *dspxor_ck; | ||
159 | static 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 | */ | ||
172 | static int audio_pwr_state = -1; | ||
173 | |||
174 | /* | ||
175 | * audio_pwr_up / down should be called under audio_pwr_sem | ||
176 | */ | ||
177 | static 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 | |||
192 | static 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 | |||
201 | static DECLARE_WORK(codec_power_down_work, codec_delayed_power_down, NULL); | ||
202 | |||
203 | static 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 | |||
212 | void 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 | |||
222 | void 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 | |||
240 | static 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 | |||
255 | static void __init omap_nokia770_map_io(void) | ||
256 | { | ||
257 | omap1_map_common_io(); | ||
258 | } | ||
259 | |||
260 | MACHINE_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, | ||
268 | MACHINE_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 | |||
53 | static 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 | ||
49 | static struct mtd_partition osk_partitions[] = { | 67 | static 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 | |||
156 | static 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 | |||
171 | static 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 | |||
136 | static struct platform_device osk5912_mcbsp1_device = { | 182 | static 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 | |||
190 | static struct resource osk5912_kp_resources[] = { | ||
191 | [0] = { | ||
192 | .start = INT_KEYBOARD, | ||
193 | .end = INT_KEYBOARD, | ||
194 | .flags = IORESOURCE_IRQ, | ||
195 | }, | ||
196 | }; | ||
197 | |||
198 | static struct omap_kp_platform_data osk_kp_data = { | ||
199 | .rows = 8, | ||
200 | .cols = 8, | ||
201 | .keymap = osk_keymap, | ||
202 | }; | ||
203 | |||
204 | static 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 | |||
214 | static struct platform_device osk5912_lcd_device = { | ||
215 | .name = "lcd_osk", | ||
216 | .id = -1, | ||
139 | }; | 217 | }; |
140 | 218 | ||
141 | static struct platform_device *osk5912_devices[] __initdata = { | 219 | static 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 | ||
148 | static void __init osk_init_smc91x(void) | 228 | static void __init osk_init_smc91x(void) |
@@ -197,7 +277,6 @@ static struct omap_uart_config osk_uart_config __initdata = { | |||
197 | }; | 277 | }; |
198 | 278 | ||
199 | static struct omap_lcd_config osk_lcd_config __initdata = { | 279 | static 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) | |||
255 | static void __init osk_mistral_init(void) { } | 334 | static void __init osk_mistral_init(void) { } |
256 | #endif | 335 | #endif |
257 | 336 | ||
337 | #define EMIFS_CS3_VAL (0x88013141) | ||
338 | |||
258 | static void __init osk_init(void) | 339 | static 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 | ||
41 | static struct platform_device palmte_lcd_device = { | ||
42 | .name = "lcd_palmte", | ||
43 | .id = -1, | ||
44 | }; | ||
45 | |||
46 | static struct platform_device *devices[] __initdata = { | ||
47 | &palmte_lcd_device, | ||
48 | }; | ||
49 | |||
41 | static struct omap_usb_config palmte_usb_config __initdata = { | 50 | static 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 | ||
57 | static struct omap_lcd_config palmte_lcd_config __initdata = { | 66 | static 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 | ||
74 | static void __init omap_generic_map_io(void) | 84 | static 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 | ||
37 | static 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 | |||
34 | static struct resource smc91x_resources[] = { | 71 | static 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 | ||
47 | static struct mtd_partition p2_partitions[] = { | 84 | static 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 | ||
78 | static struct flash_platform_data p2_flash_data = { | 115 | static 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 | ||
85 | static struct resource p2_flash_resource = { | 122 | static 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 | ||
91 | static struct platform_device p2_flash_device = { | 128 | static 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 | |||
138 | static struct nand_platform_data nand_data = { | ||
139 | .options = NAND_SAMSUNG_LP_OPTIONS, | ||
140 | }; | ||
141 | |||
142 | static struct resource nand_resource = { | ||
143 | .start = OMAP_CS3_PHYS, | ||
144 | .end = OMAP_CS3_PHYS + SZ_4K - 1, | ||
145 | .flags = IORESOURCE_MEM, | ||
146 | }; | ||
147 | |||
148 | static 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 | ||
101 | static struct platform_device smc91x_device = { | 158 | static 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 | ||
165 | static 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 | |||
173 | static struct omap_kp_platform_data kp_data = { | ||
174 | .rows = 8, | ||
175 | .cols = 8, | ||
176 | .keymap = p2_keymap, | ||
177 | }; | ||
178 | |||
179 | static 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 | |||
189 | static struct platform_device lcd_device = { | ||
190 | .name = "lcd_p2", | ||
191 | .id = -1, | ||
192 | }; | ||
193 | |||
108 | static struct platform_device *devices[] __initdata = { | 194 | static 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 | |||
204 | static int nand_dev_ready(struct nand_platform_data *data) | ||
205 | { | ||
206 | return omap_get_gpio_datain(P2_NAND_RB_GPIO_PIN); | ||
207 | } | ||
208 | |||
113 | static struct omap_uart_config perseus2_uart_config __initdata = { | 209 | static 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 | ||
117 | static struct omap_lcd_config perseus2_lcd_config __initdata = { | 213 | static 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 | ||
127 | static void __init omap_perseus2_init(void) | 222 | static 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 | ||
157 | static struct omap_board_config_kernel voiceblue_config[] = { | 157 | static 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 | ||
163 | static void __init voiceblue_init_irq(void) | 163 | static void __init voiceblue_init_irq(void) |
@@ -235,7 +235,7 @@ static struct notifier_block panic_block = { | |||
235 | static int __init voiceblue_setup(void) | 235 | static 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 = { | |||
209 | static struct clk arm_gpio_ck = { | 211 | static 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 = { | |||
358 | static struct clk arminth_ck1510 = { | 360 | static 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 | ||
680 | static struct clk mmc1_ck = { | 689 | static 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 | ||
693 | static struct clk mmc2_ck = { | 704 | static 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 = { | |||
706 | static struct clk virtual_ck_mpu = { | 718 | static 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 | ||
731 | remains active during MPU idle whenever this is enabled */ | ||
732 | static 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 | |||
718 | static struct clk * onchip_clks[] = { | 744 | static 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..847329cafc5c 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c | |||
@@ -25,10 +25,6 @@ | |||
25 | #include <asm/arch/mux.h> | 25 | #include <asm/arch/mux.h> |
26 | #include <asm/arch/gpio.h> | 26 | #include <asm/arch/gpio.h> |
27 | 27 | ||
28 | extern void omap_nop_release(struct device *dev); | ||
29 | |||
30 | /*-------------------------------------------------------------------------*/ | ||
31 | |||
32 | #if defined(CONFIG_OMAP1610_IR) || defined(CONFIG_OMAP161O_IR_MODULE) | 28 | #if defined(CONFIG_OMAP1610_IR) || defined(CONFIG_OMAP161O_IR_MODULE) |
33 | 29 | ||
34 | static u64 irda_dmamask = 0xffffffff; | 30 | static u64 irda_dmamask = 0xffffffff; |
@@ -37,7 +33,6 @@ static struct platform_device omap1610ir_device = { | |||
37 | .name = "omap1610-ir", | 33 | .name = "omap1610-ir", |
38 | .id = -1, | 34 | .id = -1, |
39 | .dev = { | 35 | .dev = { |
40 | .release = omap_nop_release, | ||
41 | .dma_mask = &irda_dmamask, | 36 | .dma_mask = &irda_dmamask, |
42 | }, | 37 | }, |
43 | }; | 38 | }; |
@@ -84,9 +79,6 @@ static struct resource rtc_resources[] = { | |||
84 | static struct platform_device omap_rtc_device = { | 79 | static struct platform_device omap_rtc_device = { |
85 | .name = "omap_rtc", | 80 | .name = "omap_rtc", |
86 | .id = -1, | 81 | .id = -1, |
87 | .dev = { | ||
88 | .release = omap_nop_release, | ||
89 | }, | ||
90 | .num_resources = ARRAY_SIZE(rtc_resources), | 82 | .num_resources = ARRAY_SIZE(rtc_resources), |
91 | .resource = rtc_resources, | 83 | .resource = rtc_resources, |
92 | }; | 84 | }; |
@@ -99,6 +91,42 @@ static void omap_init_rtc(void) | |||
99 | static inline void omap_init_rtc(void) {} | 91 | static inline void omap_init_rtc(void) {} |
100 | #endif | 92 | #endif |
101 | 93 | ||
94 | #if defined(CONFIG_OMAP_STI) | ||
95 | |||
96 | #define OMAP1_STI_BASE IO_ADDRESS(0xfffea000) | ||
97 | #define OMAP1_STI_CHANNEL_BASE (OMAP1_STI_BASE + 0x400) | ||
98 | |||
99 | static struct resource sti_resources[] = { | ||
100 | { | ||
101 | .start = OMAP1_STI_BASE, | ||
102 | .end = OMAP1_STI_BASE + SZ_1K - 1, | ||
103 | .flags = IORESOURCE_MEM, | ||
104 | }, | ||
105 | { | ||
106 | .start = OMAP1_STI_CHANNEL_BASE, | ||
107 | .end = OMAP1_STI_CHANNEL_BASE + SZ_1K - 1, | ||
108 | .flags = IORESOURCE_MEM, | ||
109 | }, | ||
110 | { | ||
111 | .start = INT_1610_STI, | ||
112 | .flags = IORESOURCE_IRQ, | ||
113 | } | ||
114 | }; | ||
115 | |||
116 | static struct platform_device sti_device = { | ||
117 | .name = "sti", | ||
118 | .id = -1, | ||
119 | .num_resources = ARRAY_SIZE(sti_resources), | ||
120 | .resource = sti_resources, | ||
121 | }; | ||
122 | |||
123 | static inline void omap_init_sti(void) | ||
124 | { | ||
125 | platform_device_register(&sti_device); | ||
126 | } | ||
127 | #else | ||
128 | static inline void omap_init_sti(void) {} | ||
129 | #endif | ||
102 | 130 | ||
103 | /*-------------------------------------------------------------------------*/ | 131 | /*-------------------------------------------------------------------------*/ |
104 | 132 | ||
@@ -129,6 +157,7 @@ static int __init omap1_init_devices(void) | |||
129 | */ | 157 | */ |
130 | omap_init_irda(); | 158 | omap_init_irda(); |
131 | omap_init_rtc(); | 159 | omap_init_rtc(); |
160 | omap_init_sti(); | ||
132 | 161 | ||
133 | return 0; | 162 | return 0; |
134 | } | 163 | } |
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 | ||
22 | extern int omap1_clk_init(void); | 23 | extern int omap1_clk_init(void); |
23 | extern void omap_check_revision(void); | 24 | extern 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 | ||
63 | static unsigned int irq_bank_count = 0; | 63 | static unsigned int irq_bank_count; |
64 | static struct omap_irq_bank *irq_banks; | 64 | static struct omap_irq_bank *irq_banks; |
65 | 65 | ||
66 | static inline unsigned int irq_bank_readl(int bank, int offset) | 66 | static 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 |
144 | static struct omap_irq_bank omap730_irq_banks[] = { | 144 | static 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 |
152 | static struct omap_irq_bank omap1510_irq_banks[] = { | 152 | static 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 | }; |
156 | static struct omap_irq_bank omap310_irq_banks[] = { | 156 | static 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 | ||
164 | static struct omap_irq_bank omap1610_irq_banks[] = { | 164 | static 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 |
37 | struct pin_config __initdata_or_module omap730_pins[] = { | 37 | struct pin_config __initdata_or_module omap730_pins[] = { |
38 | MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 0, 20, 1, NA, 0, 0) | 38 | MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 20, 1, 0) |
39 | MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 0, 24, 1, NA, 0, 0) | 39 | MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 24, 1, 0) |
40 | MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 0, 28, 1, NA, 0, 0) | 40 | MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 28, 1, 0) |
41 | MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 0, 1, NA, 0, 0) | 41 | MUX_CFG_730("F3_730_KBR3", 13, 1, 0, 0, 1, 0) |
42 | MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 0, 4, 1, NA, 0, 0) | 42 | MUX_CFG_730("D2_730_KBR4", 13, 5, 0, 4, 1, 0) |
43 | MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 0, 8, 1, NA, 0, 0) | 43 | MUX_CFG_730("C2_730_KBC0", 13, 9, 0, 8, 1, 0) |
44 | MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 0, 12, 1, NA, 0, 0) | 44 | MUX_CFG_730("D3_730_KBC1", 13, 13, 0, 12, 1, 0) |
45 | MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 0, 16, 1, NA, 0, 0) | 45 | MUX_CFG_730("E4_730_KBC2", 13, 17, 0, 16, 1, 0) |
46 | MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 0, 20, 1, NA, 0, 0) | 46 | MUX_CFG_730("F4_730_KBC3", 13, 21, 0, 20, 1, 0) |
47 | MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 0, 24, 1, NA, 0, 0) | 47 | MUX_CFG_730("E3_730_KBC4", 13, 25, 0, 24, 1, 0) |
48 | |||
49 | MUX_CFG_730("AA17_730_USB_DM", 2, 21, 0, 20, 0, 0) | ||
50 | MUX_CFG_730("W16_730_USB_PU_EN", 2, 25, 0, 24, 0, 0) | ||
51 | MUX_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) | |||
73 | MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0) | 77 | MUX_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 */ |
76 | MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0) | 80 | MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0) |
77 | MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0) | 81 | MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0) |
78 | 82 | ||
79 | /* USB internal master generic */ | 83 | /* USB internal master generic */ |
80 | MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1) | 84 | MUX_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 */ |
153 | MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1) | 157 | MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1) |
154 | MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0) | 158 | MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0) |
155 | 159 | ||
156 | /* OMAP-1610 MMC2 */ | 160 | /* OMAP-1610 MMC2 */ |
157 | MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1) | 161 | MUX_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 | |||
64 | static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; | ||
65 | static unsigned short dsp_sleep_save[DSP_SLEEP_SAVE_SIZE]; | ||
66 | static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE]; | ||
67 | static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE]; | ||
68 | static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE]; | ||
69 | static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; | ||
70 | |||
71 | static unsigned short enable_dyn_sleep = 1; | ||
72 | |||
73 | static 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 | |||
78 | static 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 | |||
92 | static 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 | |||
101 | extern struct subsystem power_subsys; | ||
102 | static void (*omap_sram_idle)(void) = NULL; | ||
103 | static 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 | */ | ||
111 | void 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 | */ | ||
193 | static 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 | |||
244 | void 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) | ||
454 | static int g_read_completed; | ||
455 | |||
456 | /* | ||
457 | * Read system PM registers for debugging | ||
458 | */ | ||
459 | static 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 | |||
598 | static 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 | |||
609 | static void (*saved_idle)(void) = NULL; | ||
610 | |||
611 | /* | ||
612 | * omap_pm_prepare - Do preliminary suspend work. | ||
613 | * @state: suspend state we're entering. | ||
614 | * | ||
615 | */ | ||
616 | static 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 | |||
647 | static 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 | |||
675 | static int omap_pm_finish(suspend_state_t state) | ||
676 | { | ||
677 | pm_idle = saved_idle; | ||
678 | return 0; | ||
679 | } | ||
680 | |||
681 | |||
682 | static irqreturn_t omap_wakeup_interrupt(int irq, void * dev, | ||
683 | struct pt_regs * regs) | ||
684 | { | ||
685 | return IRQ_HANDLED; | ||
686 | } | ||
687 | |||
688 | static struct irqaction omap_wakeup_irq = { | ||
689 | .name = "peripheral wakeup", | ||
690 | .flags = SA_INTERRUPT, | ||
691 | .handler = omap_wakeup_interrupt | ||
692 | }; | ||
693 | |||
694 | |||
695 | |||
696 | static 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 | |||
703 | static 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 | ||
33 | static struct clk * uart1_ck = NULL; | 33 | static struct clk * uart1_ck; |
34 | static struct clk * uart2_ck = NULL; | 34 | static struct clk * uart2_ck; |
35 | static struct clk * uart3_ck = NULL; | 35 | static struct clk * uart3_ck; |
36 | 36 | ||
37 | static inline unsigned int omap_serial_in(struct plat_serial8250_port *up, | 37 | static 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) | ||
56 | ENTRY(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 | ||
80 | l_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 | |||
101 | ENTRY(omap730_idle_loop_suspend_sz) | ||
102 | .word . - omap730_idle_loop_suspend | ||
103 | #endif /* CONFIG_ARCH_OMAP730 */ | ||
104 | |||
105 | #ifdef CONFIG_ARCH_OMAP15XX | ||
106 | ENTRY(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 | ||
130 | l_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 | |||
151 | ENTRY(omap1510_idle_loop_suspend_sz) | ||
152 | .word . - omap1510_idle_loop_suspend | ||
153 | #endif /* CONFIG_ARCH_OMAP15XX */ | ||
154 | |||
155 | #if defined(CONFIG_ARCH_OMAP16XX) | ||
156 | ENTRY(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 | ||
180 | l_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 | |||
201 | ENTRY(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) | ||
223 | ENTRY(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 | |||
297 | ENTRY(omap730_cpu_suspend_sz) | ||
298 | .word . - omap730_cpu_suspend | ||
299 | #endif /* CONFIG_ARCH_OMAP730 */ | ||
300 | |||
301 | #ifdef CONFIG_ARCH_OMAP15XX | ||
302 | ENTRY(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 | ||
350 | l_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 | |||
371 | ENTRY(omap1510_cpu_suspend_sz) | ||
372 | .word . - omap1510_cpu_suspend | ||
373 | #endif /* CONFIG_ARCH_OMAP15XX */ | ||
374 | |||
375 | #if defined(CONFIG_ARCH_OMAP16XX) | ||
376 | ENTRY(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 | |||
523 | ENTRY(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 | ||
52 | struct sys_timer omap_timer; | 52 | struct 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 | |||
261 | static inline void omap_32k_timer_write(int val, int reg) | ||
262 | { | ||
263 | omap_writew(val, reg + OMAP_32K_TIMER_BASE); | ||
264 | } | ||
265 | |||
266 | static 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 | */ | ||
275 | static inline unsigned long omap_32k_sync_timer_read(void) | ||
276 | { | ||
277 | return omap_readl(TIMER_32K_SYNCHRONIZED); | ||
278 | } | ||
279 | |||
280 | static 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 | |||
286 | static 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 | */ | ||
294 | static 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 | */ | ||
302 | static inline unsigned long long | ||
303 | omap_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 | |||
308 | static unsigned long omap_32k_last_tick = 0; | ||
309 | |||
310 | /* | ||
311 | * Returns elapsed usecs since last 32k timer interrupt | ||
312 | */ | ||
313 | static 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 | */ | ||
323 | unsigned 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 | */ | ||
334 | static 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 | */ | ||
367 | void omap_32k_timer_reprogram(unsigned long next_tick) | ||
368 | { | ||
369 | omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); | ||
370 | } | ||
371 | |||
372 | static struct irqaction omap_32k_timer_irq; | ||
373 | extern struct timer_update_handler timer_update; | ||
374 | |||
375 | static 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 | |||
381 | static int omap_32k_timer_disable_dyn_tick(void) | ||
382 | { | ||
383 | omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); | ||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | static 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 | |||
395 | static struct irqaction omap_32k_timer_irq = { | ||
396 | .name = "32KHz timer", | ||
397 | .flags = SA_INTERRUPT | SA_TIMER, | ||
398 | .handler = omap_32k_timer_interrupt, | ||
399 | }; | ||
400 | |||
401 | static __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 | */ |
420 | static void __init omap_timer_init(void) | 229 | static 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 | ||
431 | struct sys_timer omap_timer = { | 234 | struct sys_timer omap_timer = { |