diff options
Diffstat (limited to 'arch/arm/mach-omap2')
49 files changed, 3751 insertions, 289 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index a755eb5e2361..75b1c7efae7e 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -31,6 +31,11 @@ config MACH_OMAP_GENERIC | |||
31 | bool "Generic OMAP board" | 31 | bool "Generic OMAP board" |
32 | depends on ARCH_OMAP2 && ARCH_OMAP24XX | 32 | depends on ARCH_OMAP2 && ARCH_OMAP24XX |
33 | 33 | ||
34 | config MACH_OMAP2_TUSB6010 | ||
35 | bool | ||
36 | depends on ARCH_OMAP2 && ARCH_OMAP2420 | ||
37 | default y if MACH_NOKIA_N8X0 | ||
38 | |||
34 | config MACH_OMAP_H4 | 39 | config MACH_OMAP_H4 |
35 | bool "OMAP 2420 H4 board" | 40 | bool "OMAP 2420 H4 board" |
36 | depends on ARCH_OMAP2 && ARCH_OMAP24XX | 41 | depends on ARCH_OMAP2 && ARCH_OMAP24XX |
@@ -68,6 +73,10 @@ config MACH_OMAP_3430SDP | |||
68 | bool "OMAP 3430 SDP board" | 73 | bool "OMAP 3430 SDP board" |
69 | depends on ARCH_OMAP3 && ARCH_OMAP34XX | 74 | depends on ARCH_OMAP3 && ARCH_OMAP34XX |
70 | 75 | ||
76 | config MACH_NOKIA_N8X0 | ||
77 | bool "Nokia N800/N810" | ||
78 | depends on ARCH_OMAP2420 | ||
79 | |||
71 | config MACH_NOKIA_RX51 | 80 | config MACH_NOKIA_RX51 |
72 | bool "Nokia RX-51 board" | 81 | bool "Nokia RX-51 board" |
73 | depends on ARCH_OMAP3 && ARCH_OMAP34XX | 82 | depends on ARCH_OMAP3 && ARCH_OMAP34XX |
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 735bae5b0dec..8cb16777661a 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | # Common support | 5 | # Common support |
6 | obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o | 6 | obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o |
7 | 7 | ||
8 | omap-2-3-common = irq.o sdrc.o | 8 | omap-2-3-common = irq.o sdrc.o omap_hwmod.o |
9 | prcm-common = prcm.o powerdomain.o | 9 | prcm-common = prcm.o powerdomain.o |
10 | clock-common = clock.o clockdomain.o | 10 | clock-common = clock.o clockdomain.o |
11 | 11 | ||
@@ -35,6 +35,11 @@ obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o | |||
35 | obj-$(CONFIG_PM_DEBUG) += pm-debug.o | 35 | obj-$(CONFIG_PM_DEBUG) += pm-debug.o |
36 | endif | 36 | endif |
37 | 37 | ||
38 | # PRCM | ||
39 | obj-$(CONFIG_ARCH_OMAP2) += cm.o | ||
40 | obj-$(CONFIG_ARCH_OMAP3) += cm.o | ||
41 | obj-$(CONFIG_ARCH_OMAP4) += cm4xxx.o | ||
42 | |||
38 | # Clock framework | 43 | # Clock framework |
39 | obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o | 44 | obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o |
40 | obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o | 45 | obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o |
@@ -62,7 +67,7 @@ obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \ | |||
62 | mmc-twl4030.o | 67 | mmc-twl4030.o |
63 | obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \ | 68 | obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \ |
64 | mmc-twl4030.o | 69 | mmc-twl4030.o |
65 | 70 | obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o | |
66 | obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \ | 71 | obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \ |
67 | board-rx51-peripherals.o \ | 72 | board-rx51-peripherals.o \ |
68 | mmc-twl4030.o | 73 | mmc-twl4030.o |
@@ -74,6 +79,7 @@ obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o | |||
74 | 79 | ||
75 | # Platform specific device init code | 80 | # Platform specific device init code |
76 | obj-y += usb-musb.o | 81 | obj-y += usb-musb.o |
82 | obj-$(CONFIG_MACH_OMAP2_TUSB6010) += usb-tusb6010.o | ||
77 | 83 | ||
78 | onenand-$(CONFIG_MTD_ONENAND_OMAP2) := gpmc-onenand.o | 84 | onenand-$(CONFIG_MTD_ONENAND_OMAP2) := gpmc-onenand.o |
79 | obj-y += $(onenand-m) $(onenand-y) | 85 | obj-y += $(onenand-m) $(onenand-y) |
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index 8ec2a132904d..42217b32f835 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c | |||
@@ -139,23 +139,19 @@ static inline void board_smc91x_init(void) | |||
139 | 139 | ||
140 | #endif | 140 | #endif |
141 | 141 | ||
142 | static struct omap_board_config_kernel sdp2430_config[] = { | ||
143 | {OMAP_TAG_LCD, &sdp2430_lcd_config}, | ||
144 | }; | ||
145 | |||
142 | static void __init omap_2430sdp_init_irq(void) | 146 | static void __init omap_2430sdp_init_irq(void) |
143 | { | 147 | { |
148 | omap_board_config = sdp2430_config; | ||
149 | omap_board_config_size = ARRAY_SIZE(sdp2430_config); | ||
144 | omap2_init_common_hw(NULL, NULL); | 150 | omap2_init_common_hw(NULL, NULL); |
145 | omap_init_irq(); | 151 | omap_init_irq(); |
146 | omap_gpio_init(); | 152 | omap_gpio_init(); |
147 | } | 153 | } |
148 | 154 | ||
149 | static struct omap_uart_config sdp2430_uart_config __initdata = { | ||
150 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
151 | }; | ||
152 | |||
153 | static struct omap_board_config_kernel sdp2430_config[] = { | ||
154 | {OMAP_TAG_UART, &sdp2430_uart_config}, | ||
155 | {OMAP_TAG_LCD, &sdp2430_lcd_config}, | ||
156 | }; | ||
157 | |||
158 | |||
159 | static struct twl4030_gpio_platform_data sdp2430_gpio_data = { | 155 | static struct twl4030_gpio_platform_data sdp2430_gpio_data = { |
160 | .gpio_base = OMAP_MAX_GPIO_LINES, | 156 | .gpio_base = OMAP_MAX_GPIO_LINES, |
161 | .irq_base = TWL4030_GPIO_IRQ_BASE, | 157 | .irq_base = TWL4030_GPIO_IRQ_BASE, |
@@ -205,8 +201,6 @@ static void __init omap_2430sdp_init(void) | |||
205 | omap2430_i2c_init(); | 201 | omap2430_i2c_init(); |
206 | 202 | ||
207 | platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices)); | 203 | platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices)); |
208 | omap_board_config = sdp2430_config; | ||
209 | omap_board_config_size = ARRAY_SIZE(sdp2430_config); | ||
210 | omap_serial_init(); | 204 | omap_serial_init(); |
211 | twl4030_mmc_init(mmc); | 205 | twl4030_mmc_init(mmc); |
212 | usb_musb_init(); | 206 | usb_musb_init(); |
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index ac262cd74503..bd57ec76dc5e 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c | |||
@@ -167,26 +167,23 @@ static struct platform_device *sdp3430_devices[] __initdata = { | |||
167 | &sdp3430_lcd_device, | 167 | &sdp3430_lcd_device, |
168 | }; | 168 | }; |
169 | 169 | ||
170 | static void __init omap_3430sdp_init_irq(void) | ||
171 | { | ||
172 | omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL); | ||
173 | omap_init_irq(); | ||
174 | omap_gpio_init(); | ||
175 | } | ||
176 | |||
177 | static struct omap_uart_config sdp3430_uart_config __initdata = { | ||
178 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
179 | }; | ||
180 | |||
181 | static struct omap_lcd_config sdp3430_lcd_config __initdata = { | 170 | static struct omap_lcd_config sdp3430_lcd_config __initdata = { |
182 | .ctrl_name = "internal", | 171 | .ctrl_name = "internal", |
183 | }; | 172 | }; |
184 | 173 | ||
185 | static struct omap_board_config_kernel sdp3430_config[] __initdata = { | 174 | static struct omap_board_config_kernel sdp3430_config[] __initdata = { |
186 | { OMAP_TAG_UART, &sdp3430_uart_config }, | ||
187 | { OMAP_TAG_LCD, &sdp3430_lcd_config }, | 175 | { OMAP_TAG_LCD, &sdp3430_lcd_config }, |
188 | }; | 176 | }; |
189 | 177 | ||
178 | static void __init omap_3430sdp_init_irq(void) | ||
179 | { | ||
180 | omap_board_config = sdp3430_config; | ||
181 | omap_board_config_size = ARRAY_SIZE(sdp3430_config); | ||
182 | omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL); | ||
183 | omap_init_irq(); | ||
184 | omap_gpio_init(); | ||
185 | } | ||
186 | |||
190 | static int sdp3430_batt_table[] = { | 187 | static int sdp3430_batt_table[] = { |
191 | /* 0 C*/ | 188 | /* 0 C*/ |
192 | 30800, 29500, 28300, 27100, | 189 | 30800, 29500, 28300, 27100, |
@@ -478,12 +475,15 @@ static inline void board_smc91x_init(void) | |||
478 | 475 | ||
479 | #endif | 476 | #endif |
480 | 477 | ||
478 | static void enable_board_wakeup_source(void) | ||
479 | { | ||
480 | omap_cfg_reg(AF26_34XX_SYS_NIRQ); /* T2 interrupt line (keypad) */ | ||
481 | } | ||
482 | |||
481 | static void __init omap_3430sdp_init(void) | 483 | static void __init omap_3430sdp_init(void) |
482 | { | 484 | { |
483 | omap3430_i2c_init(); | 485 | omap3430_i2c_init(); |
484 | platform_add_devices(sdp3430_devices, ARRAY_SIZE(sdp3430_devices)); | 486 | platform_add_devices(sdp3430_devices, ARRAY_SIZE(sdp3430_devices)); |
485 | omap_board_config = sdp3430_config; | ||
486 | omap_board_config_size = ARRAY_SIZE(sdp3430_config); | ||
487 | if (omap_rev() > OMAP3430_REV_ES1_0) | 487 | if (omap_rev() > OMAP3430_REV_ES1_0) |
488 | ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV2; | 488 | ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV2; |
489 | else | 489 | else |
@@ -495,6 +495,7 @@ static void __init omap_3430sdp_init(void) | |||
495 | omap_serial_init(); | 495 | omap_serial_init(); |
496 | usb_musb_init(); | 496 | usb_musb_init(); |
497 | board_smc91x_init(); | 497 | board_smc91x_init(); |
498 | enable_board_wakeup_source(); | ||
498 | } | 499 | } |
499 | 500 | ||
500 | static void __init omap_3430sdp_map_io(void) | 501 | static void __init omap_3430sdp_map_io(void) |
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 1b223076ceb7..eb37c40ea83a 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c | |||
@@ -47,14 +47,13 @@ static struct omap_lcd_config sdp4430_lcd_config __initdata = { | |||
47 | }; | 47 | }; |
48 | 48 | ||
49 | static struct omap_board_config_kernel sdp4430_config[] __initdata = { | 49 | static struct omap_board_config_kernel sdp4430_config[] __initdata = { |
50 | { OMAP_TAG_UART, &sdp4430_uart_config }, | ||
51 | { OMAP_TAG_LCD, &sdp4430_lcd_config }, | 50 | { OMAP_TAG_LCD, &sdp4430_lcd_config }, |
52 | }; | 51 | }; |
53 | 52 | ||
54 | static void __init gic_init_irq(void) | 53 | static void __init gic_init_irq(void) |
55 | { | 54 | { |
56 | gic_dist_init(0, IO_ADDRESS(OMAP44XX_GIC_DIST_BASE), 29); | 55 | gic_dist_init(0, OMAP2_IO_ADDRESS(OMAP44XX_GIC_DIST_BASE), 29); |
57 | gic_cpu_init(0, IO_ADDRESS(OMAP44XX_GIC_CPU_BASE)); | 56 | gic_cpu_init(0, OMAP2_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE)); |
58 | } | 57 | } |
59 | 58 | ||
60 | static void __init omap_4430sdp_init_irq(void) | 59 | static void __init omap_4430sdp_init_irq(void) |
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index dcfc20d03894..a1132288c701 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c | |||
@@ -87,7 +87,7 @@ static struct mtd_partition apollon_partitions[] = { | |||
87 | }, | 87 | }, |
88 | }; | 88 | }; |
89 | 89 | ||
90 | static struct flash_platform_data apollon_flash_data = { | 90 | static struct onenand_platform_data apollon_flash_data = { |
91 | .parts = apollon_partitions, | 91 | .parts = apollon_partitions, |
92 | .nr_parts = ARRAY_SIZE(apollon_partitions), | 92 | .nr_parts = ARRAY_SIZE(apollon_partitions), |
93 | }; | 93 | }; |
@@ -99,7 +99,7 @@ static struct resource apollon_flash_resource[] = { | |||
99 | }; | 99 | }; |
100 | 100 | ||
101 | static struct platform_device apollon_onenand_device = { | 101 | static struct platform_device apollon_onenand_device = { |
102 | .name = "onenand", | 102 | .name = "onenand-flash", |
103 | .id = -1, | 103 | .id = -1, |
104 | .dev = { | 104 | .dev = { |
105 | .platform_data = &apollon_flash_data, | 105 | .platform_data = &apollon_flash_data, |
@@ -248,18 +248,6 @@ out: | |||
248 | clk_put(gpmc_fck); | 248 | clk_put(gpmc_fck); |
249 | } | 249 | } |
250 | 250 | ||
251 | static void __init omap_apollon_init_irq(void) | ||
252 | { | ||
253 | omap2_init_common_hw(NULL, NULL); | ||
254 | omap_init_irq(); | ||
255 | omap_gpio_init(); | ||
256 | apollon_init_smc91x(); | ||
257 | } | ||
258 | |||
259 | static struct omap_uart_config apollon_uart_config __initdata = { | ||
260 | .enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2), | ||
261 | }; | ||
262 | |||
263 | static struct omap_usb_config apollon_usb_config __initdata = { | 251 | static struct omap_usb_config apollon_usb_config __initdata = { |
264 | .register_dev = 1, | 252 | .register_dev = 1, |
265 | .hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */ | 253 | .hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */ |
@@ -272,10 +260,19 @@ static struct omap_lcd_config apollon_lcd_config __initdata = { | |||
272 | }; | 260 | }; |
273 | 261 | ||
274 | static struct omap_board_config_kernel apollon_config[] = { | 262 | static struct omap_board_config_kernel apollon_config[] = { |
275 | { OMAP_TAG_UART, &apollon_uart_config }, | ||
276 | { OMAP_TAG_LCD, &apollon_lcd_config }, | 263 | { OMAP_TAG_LCD, &apollon_lcd_config }, |
277 | }; | 264 | }; |
278 | 265 | ||
266 | static void __init omap_apollon_init_irq(void) | ||
267 | { | ||
268 | omap_board_config = apollon_config; | ||
269 | omap_board_config_size = ARRAY_SIZE(apollon_config); | ||
270 | omap2_init_common_hw(NULL, NULL); | ||
271 | omap_init_irq(); | ||
272 | omap_gpio_init(); | ||
273 | apollon_init_smc91x(); | ||
274 | } | ||
275 | |||
279 | static void __init apollon_led_init(void) | 276 | static void __init apollon_led_init(void) |
280 | { | 277 | { |
281 | /* LED0 - AA10 */ | 278 | /* LED0 - AA10 */ |
@@ -324,8 +321,6 @@ static void __init omap_apollon_init(void) | |||
324 | * if not needed. | 321 | * if not needed. |
325 | */ | 322 | */ |
326 | platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices)); | 323 | platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices)); |
327 | omap_board_config = apollon_config; | ||
328 | omap_board_config_size = ARRAY_SIZE(apollon_config); | ||
329 | omap_serial_init(); | 324 | omap_serial_init(); |
330 | } | 325 | } |
331 | 326 | ||
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index fd00aa03690c..2e09a1c444cb 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c | |||
@@ -31,24 +31,19 @@ | |||
31 | #include <mach/board.h> | 31 | #include <mach/board.h> |
32 | #include <mach/common.h> | 32 | #include <mach/common.h> |
33 | 33 | ||
34 | static struct omap_board_config_kernel generic_config[] = { | ||
35 | }; | ||
36 | |||
34 | static void __init omap_generic_init_irq(void) | 37 | static void __init omap_generic_init_irq(void) |
35 | { | 38 | { |
39 | omap_board_config = generic_config; | ||
40 | omap_board_config_size = ARRAY_SIZE(generic_config); | ||
36 | omap2_init_common_hw(NULL, NULL); | 41 | omap2_init_common_hw(NULL, NULL); |
37 | omap_init_irq(); | 42 | omap_init_irq(); |
38 | } | 43 | } |
39 | 44 | ||
40 | static struct omap_uart_config generic_uart_config __initdata = { | ||
41 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
42 | }; | ||
43 | |||
44 | static struct omap_board_config_kernel generic_config[] = { | ||
45 | { OMAP_TAG_UART, &generic_uart_config }, | ||
46 | }; | ||
47 | |||
48 | static void __init omap_generic_init(void) | 45 | static void __init omap_generic_init(void) |
49 | { | 46 | { |
50 | omap_board_config = generic_config; | ||
51 | omap_board_config_size = ARRAY_SIZE(generic_config); | ||
52 | omap_serial_init(); | 47 | omap_serial_init(); |
53 | } | 48 | } |
54 | 49 | ||
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 7b1d61d5bb2c..eaa02d012c5c 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c | |||
@@ -268,18 +268,6 @@ static void __init h4_init_flash(void) | |||
268 | h4_flash_resource.end = base + SZ_64M - 1; | 268 | h4_flash_resource.end = base + SZ_64M - 1; |
269 | } | 269 | } |
270 | 270 | ||
271 | static void __init omap_h4_init_irq(void) | ||
272 | { | ||
273 | omap2_init_common_hw(NULL, NULL); | ||
274 | omap_init_irq(); | ||
275 | omap_gpio_init(); | ||
276 | h4_init_flash(); | ||
277 | } | ||
278 | |||
279 | static struct omap_uart_config h4_uart_config __initdata = { | ||
280 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
281 | }; | ||
282 | |||
283 | static struct omap_lcd_config h4_lcd_config __initdata = { | 271 | static struct omap_lcd_config h4_lcd_config __initdata = { |
284 | .ctrl_name = "internal", | 272 | .ctrl_name = "internal", |
285 | }; | 273 | }; |
@@ -318,10 +306,19 @@ static struct omap_usb_config h4_usb_config __initdata = { | |||
318 | }; | 306 | }; |
319 | 307 | ||
320 | static struct omap_board_config_kernel h4_config[] = { | 308 | static struct omap_board_config_kernel h4_config[] = { |
321 | { OMAP_TAG_UART, &h4_uart_config }, | ||
322 | { OMAP_TAG_LCD, &h4_lcd_config }, | 309 | { OMAP_TAG_LCD, &h4_lcd_config }, |
323 | }; | 310 | }; |
324 | 311 | ||
312 | static void __init omap_h4_init_irq(void) | ||
313 | { | ||
314 | omap_board_config = h4_config; | ||
315 | omap_board_config_size = ARRAY_SIZE(h4_config); | ||
316 | omap2_init_common_hw(NULL, NULL); | ||
317 | omap_init_irq(); | ||
318 | omap_gpio_init(); | ||
319 | h4_init_flash(); | ||
320 | } | ||
321 | |||
325 | static struct at24_platform_data m24c01 = { | 322 | static struct at24_platform_data m24c01 = { |
326 | .byte_len = SZ_1K / 8, | 323 | .byte_len = SZ_1K / 8, |
327 | .page_size = 16, | 324 | .page_size = 16, |
@@ -366,8 +363,6 @@ static void __init omap_h4_init(void) | |||
366 | ARRAY_SIZE(h4_i2c_board_info)); | 363 | ARRAY_SIZE(h4_i2c_board_info)); |
367 | 364 | ||
368 | platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); | 365 | platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); |
369 | omap_board_config = h4_config; | ||
370 | omap_board_config_size = ARRAY_SIZE(h4_config); | ||
371 | omap_usb_init(&h4_usb_config); | 366 | omap_usb_init(&h4_usb_config); |
372 | omap_serial_init(); | 367 | omap_serial_init(); |
373 | } | 368 | } |
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index ea383f88cb1b..ec6854cbdd9f 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c | |||
@@ -268,18 +268,6 @@ static inline void __init ldp_init_smsc911x(void) | |||
268 | gpio_direction_input(eth_gpio); | 268 | gpio_direction_input(eth_gpio); |
269 | } | 269 | } |
270 | 270 | ||
271 | static void __init omap_ldp_init_irq(void) | ||
272 | { | ||
273 | omap2_init_common_hw(NULL, NULL); | ||
274 | omap_init_irq(); | ||
275 | omap_gpio_init(); | ||
276 | ldp_init_smsc911x(); | ||
277 | } | ||
278 | |||
279 | static struct omap_uart_config ldp_uart_config __initdata = { | ||
280 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
281 | }; | ||
282 | |||
283 | static struct platform_device ldp_lcd_device = { | 271 | static struct platform_device ldp_lcd_device = { |
284 | .name = "ldp_lcd", | 272 | .name = "ldp_lcd", |
285 | .id = -1, | 273 | .id = -1, |
@@ -290,10 +278,19 @@ static struct omap_lcd_config ldp_lcd_config __initdata = { | |||
290 | }; | 278 | }; |
291 | 279 | ||
292 | static struct omap_board_config_kernel ldp_config[] __initdata = { | 280 | static struct omap_board_config_kernel ldp_config[] __initdata = { |
293 | { OMAP_TAG_UART, &ldp_uart_config }, | ||
294 | { OMAP_TAG_LCD, &ldp_lcd_config }, | 281 | { OMAP_TAG_LCD, &ldp_lcd_config }, |
295 | }; | 282 | }; |
296 | 283 | ||
284 | static void __init omap_ldp_init_irq(void) | ||
285 | { | ||
286 | omap_board_config = ldp_config; | ||
287 | omap_board_config_size = ARRAY_SIZE(ldp_config); | ||
288 | omap2_init_common_hw(NULL, NULL); | ||
289 | omap_init_irq(); | ||
290 | omap_gpio_init(); | ||
291 | ldp_init_smsc911x(); | ||
292 | } | ||
293 | |||
297 | static struct twl4030_usb_data ldp_usb_data = { | 294 | static struct twl4030_usb_data ldp_usb_data = { |
298 | .usb_mode = T2_USB_MODE_ULPI, | 295 | .usb_mode = T2_USB_MODE_ULPI, |
299 | }; | 296 | }; |
@@ -377,8 +374,6 @@ static void __init omap_ldp_init(void) | |||
377 | { | 374 | { |
378 | omap_i2c_init(); | 375 | omap_i2c_init(); |
379 | platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices)); | 376 | platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices)); |
380 | omap_board_config = ldp_config; | ||
381 | omap_board_config_size = ARRAY_SIZE(ldp_config); | ||
382 | ts_gpio = 54; | 377 | ts_gpio = 54; |
383 | ldp_spi_board_info[0].irq = gpio_to_irq(ts_gpio); | 378 | ldp_spi_board_info[0].irq = gpio_to_irq(ts_gpio); |
384 | spi_register_board_info(ldp_spi_board_info, | 379 | spi_register_board_info(ldp_spi_board_info, |
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c new file mode 100644 index 000000000000..8341632d260b --- /dev/null +++ b/arch/arm/mach-omap2/board-n8x0.c | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/board-n8x0.c | ||
3 | * | ||
4 | * Copyright (C) 2005-2009 Nokia Corporation | ||
5 | * Author: Juha Yrjola <juha.yrjola@nokia.com> | ||
6 | * | ||
7 | * Modified from mach-omap2/board-generic.c | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/clk.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/gpio.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/stddef.h> | ||
20 | #include <linux/spi/spi.h> | ||
21 | #include <linux/usb/musb.h> | ||
22 | |||
23 | #include <asm/mach/arch.h> | ||
24 | #include <asm/mach-types.h> | ||
25 | |||
26 | #include <mach/board.h> | ||
27 | #include <mach/common.h> | ||
28 | #include <mach/irqs.h> | ||
29 | #include <mach/mcspi.h> | ||
30 | #include <mach/onenand.h> | ||
31 | #include <mach/serial.h> | ||
32 | |||
33 | static struct omap2_mcspi_device_config p54spi_mcspi_config = { | ||
34 | .turbo_mode = 0, | ||
35 | .single_channel = 1, | ||
36 | }; | ||
37 | |||
38 | static struct spi_board_info n800_spi_board_info[] __initdata = { | ||
39 | { | ||
40 | .modalias = "p54spi", | ||
41 | .bus_num = 2, | ||
42 | .chip_select = 0, | ||
43 | .max_speed_hz = 48000000, | ||
44 | .controller_data = &p54spi_mcspi_config, | ||
45 | }, | ||
46 | }; | ||
47 | |||
48 | #if defined(CONFIG_MTD_ONENAND_OMAP2) || \ | ||
49 | defined(CONFIG_MTD_ONENAND_OMAP2_MODULE) | ||
50 | |||
51 | static struct mtd_partition onenand_partitions[] = { | ||
52 | { | ||
53 | .name = "bootloader", | ||
54 | .offset = 0, | ||
55 | .size = 0x20000, | ||
56 | .mask_flags = MTD_WRITEABLE, /* Force read-only */ | ||
57 | }, | ||
58 | { | ||
59 | .name = "config", | ||
60 | .offset = MTDPART_OFS_APPEND, | ||
61 | .size = 0x60000, | ||
62 | }, | ||
63 | { | ||
64 | .name = "kernel", | ||
65 | .offset = MTDPART_OFS_APPEND, | ||
66 | .size = 0x200000, | ||
67 | }, | ||
68 | { | ||
69 | .name = "initfs", | ||
70 | .offset = MTDPART_OFS_APPEND, | ||
71 | .size = 0x400000, | ||
72 | }, | ||
73 | { | ||
74 | .name = "rootfs", | ||
75 | .offset = MTDPART_OFS_APPEND, | ||
76 | .size = MTDPART_SIZ_FULL, | ||
77 | }, | ||
78 | }; | ||
79 | |||
80 | static struct omap_onenand_platform_data board_onenand_data = { | ||
81 | .cs = 0, | ||
82 | .gpio_irq = 26, | ||
83 | .parts = onenand_partitions, | ||
84 | .nr_parts = ARRAY_SIZE(onenand_partitions), | ||
85 | .flags = ONENAND_SYNC_READ, | ||
86 | }; | ||
87 | |||
88 | static void __init n8x0_onenand_init(void) | ||
89 | { | ||
90 | gpmc_onenand_init(&board_onenand_data); | ||
91 | } | ||
92 | |||
93 | #else | ||
94 | |||
95 | static void __init n8x0_onenand_init(void) {} | ||
96 | |||
97 | #endif | ||
98 | |||
99 | static void __init n8x0_map_io(void) | ||
100 | { | ||
101 | omap2_set_globals_242x(); | ||
102 | omap2_map_common_io(); | ||
103 | } | ||
104 | |||
105 | static void __init n8x0_init_irq(void) | ||
106 | { | ||
107 | omap2_init_common_hw(NULL, NULL); | ||
108 | omap_init_irq(); | ||
109 | omap_gpio_init(); | ||
110 | } | ||
111 | |||
112 | static void __init n8x0_init_machine(void) | ||
113 | { | ||
114 | /* FIXME: add n810 spi devices */ | ||
115 | spi_register_board_info(n800_spi_board_info, | ||
116 | ARRAY_SIZE(n800_spi_board_info)); | ||
117 | |||
118 | omap_serial_init(); | ||
119 | n8x0_onenand_init(); | ||
120 | } | ||
121 | |||
122 | MACHINE_START(NOKIA_N800, "Nokia N800") | ||
123 | .phys_io = 0x48000000, | ||
124 | .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, | ||
125 | .boot_params = 0x80000100, | ||
126 | .map_io = n8x0_map_io, | ||
127 | .init_irq = n8x0_init_irq, | ||
128 | .init_machine = n8x0_init_machine, | ||
129 | .timer = &omap_timer, | ||
130 | MACHINE_END | ||
131 | |||
132 | MACHINE_START(NOKIA_N810, "Nokia N810") | ||
133 | .phys_io = 0x48000000, | ||
134 | .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, | ||
135 | .boot_params = 0x80000100, | ||
136 | .map_io = n8x0_map_io, | ||
137 | .init_irq = n8x0_init_irq, | ||
138 | .init_machine = n8x0_init_machine, | ||
139 | .timer = &omap_timer, | ||
140 | MACHINE_END | ||
141 | |||
142 | MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX") | ||
143 | .phys_io = 0x48000000, | ||
144 | .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, | ||
145 | .boot_params = 0x80000100, | ||
146 | .map_io = n8x0_map_io, | ||
147 | .init_irq = n8x0_init_irq, | ||
148 | .init_machine = n8x0_init_machine, | ||
149 | .timer = &omap_timer, | ||
150 | MACHINE_END | ||
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index e00ba128cece..500c9956876d 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
@@ -108,10 +108,6 @@ static struct platform_device omap3beagle_nand_device = { | |||
108 | 108 | ||
109 | #include "sdram-micron-mt46h32m32lf-6.h" | 109 | #include "sdram-micron-mt46h32m32lf-6.h" |
110 | 110 | ||
111 | static struct omap_uart_config omap3_beagle_uart_config __initdata = { | ||
112 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
113 | }; | ||
114 | |||
115 | static struct twl4030_hsmmc_info mmc[] = { | 111 | static struct twl4030_hsmmc_info mmc[] = { |
116 | { | 112 | { |
117 | .mmc = 1, | 113 | .mmc = 1, |
@@ -249,11 +245,16 @@ static struct regulator_init_data beagle_vpll2 = { | |||
249 | .consumer_supplies = &beagle_vdvi_supply, | 245 | .consumer_supplies = &beagle_vdvi_supply, |
250 | }; | 246 | }; |
251 | 247 | ||
248 | static struct twl4030_usb_data beagle_usb_data = { | ||
249 | .usb_mode = T2_USB_MODE_ULPI, | ||
250 | }; | ||
251 | |||
252 | static struct twl4030_platform_data beagle_twldata = { | 252 | static struct twl4030_platform_data beagle_twldata = { |
253 | .irq_base = TWL4030_IRQ_BASE, | 253 | .irq_base = TWL4030_IRQ_BASE, |
254 | .irq_end = TWL4030_IRQ_END, | 254 | .irq_end = TWL4030_IRQ_END, |
255 | 255 | ||
256 | /* platform_data for children goes here */ | 256 | /* platform_data for children goes here */ |
257 | .usb = &beagle_usb_data, | ||
257 | .gpio = &beagle_gpio_data, | 258 | .gpio = &beagle_gpio_data, |
258 | .vmmc1 = &beagle_vmmc1, | 259 | .vmmc1 = &beagle_vmmc1, |
259 | .vsim = &beagle_vsim, | 260 | .vsim = &beagle_vsim, |
@@ -280,17 +281,6 @@ static int __init omap3_beagle_i2c_init(void) | |||
280 | return 0; | 281 | return 0; |
281 | } | 282 | } |
282 | 283 | ||
283 | static void __init omap3_beagle_init_irq(void) | ||
284 | { | ||
285 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params, | ||
286 | mt46h32m32lf6_sdrc_params); | ||
287 | omap_init_irq(); | ||
288 | #ifdef CONFIG_OMAP_32K_TIMER | ||
289 | omap2_gp_clockevent_set_gptimer(12); | ||
290 | #endif | ||
291 | omap_gpio_init(); | ||
292 | } | ||
293 | |||
294 | static struct gpio_led gpio_leds[] = { | 284 | static struct gpio_led gpio_leds[] = { |
295 | { | 285 | { |
296 | .name = "beagleboard::usr0", | 286 | .name = "beagleboard::usr0", |
@@ -345,10 +335,22 @@ static struct platform_device keys_gpio = { | |||
345 | }; | 335 | }; |
346 | 336 | ||
347 | static struct omap_board_config_kernel omap3_beagle_config[] __initdata = { | 337 | static struct omap_board_config_kernel omap3_beagle_config[] __initdata = { |
348 | { OMAP_TAG_UART, &omap3_beagle_uart_config }, | ||
349 | { OMAP_TAG_LCD, &omap3_beagle_lcd_config }, | 338 | { OMAP_TAG_LCD, &omap3_beagle_lcd_config }, |
350 | }; | 339 | }; |
351 | 340 | ||
341 | static void __init omap3_beagle_init_irq(void) | ||
342 | { | ||
343 | omap_board_config = omap3_beagle_config; | ||
344 | omap_board_config_size = ARRAY_SIZE(omap3_beagle_config); | ||
345 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params, | ||
346 | mt46h32m32lf6_sdrc_params); | ||
347 | omap_init_irq(); | ||
348 | #ifdef CONFIG_OMAP_32K_TIMER | ||
349 | omap2_gp_clockevent_set_gptimer(12); | ||
350 | #endif | ||
351 | omap_gpio_init(); | ||
352 | } | ||
353 | |||
352 | static struct platform_device *omap3_beagle_devices[] __initdata = { | 354 | static struct platform_device *omap3_beagle_devices[] __initdata = { |
353 | &omap3_beagle_lcd_device, | 355 | &omap3_beagle_lcd_device, |
354 | &leds_gpio, | 356 | &leds_gpio, |
@@ -398,8 +400,6 @@ static void __init omap3_beagle_init(void) | |||
398 | omap3_beagle_i2c_init(); | 400 | omap3_beagle_i2c_init(); |
399 | platform_add_devices(omap3_beagle_devices, | 401 | platform_add_devices(omap3_beagle_devices, |
400 | ARRAY_SIZE(omap3_beagle_devices)); | 402 | ARRAY_SIZE(omap3_beagle_devices)); |
401 | omap_board_config = omap3_beagle_config; | ||
402 | omap_board_config_size = ARRAY_SIZE(omap3_beagle_config); | ||
403 | omap_serial_init(); | 403 | omap_serial_init(); |
404 | 404 | ||
405 | omap_cfg_reg(J25_34XX_GPIO170); | 405 | omap_cfg_reg(J25_34XX_GPIO170); |
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index c4b144647dc5..d50b9be90580 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c | |||
@@ -92,10 +92,6 @@ static inline void __init omap3evm_init_smc911x(void) | |||
92 | gpio_direction_input(OMAP3EVM_ETHR_GPIO_IRQ); | 92 | gpio_direction_input(OMAP3EVM_ETHR_GPIO_IRQ); |
93 | } | 93 | } |
94 | 94 | ||
95 | static struct omap_uart_config omap3_evm_uart_config __initdata = { | ||
96 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
97 | }; | ||
98 | |||
99 | static struct twl4030_hsmmc_info mmc[] = { | 95 | static struct twl4030_hsmmc_info mmc[] = { |
100 | { | 96 | { |
101 | .mmc = 1, | 97 | .mmc = 1, |
@@ -278,19 +274,20 @@ struct spi_board_info omap3evm_spi_board_info[] = { | |||
278 | }, | 274 | }, |
279 | }; | 275 | }; |
280 | 276 | ||
277 | static struct omap_board_config_kernel omap3_evm_config[] __initdata = { | ||
278 | { OMAP_TAG_LCD, &omap3_evm_lcd_config }, | ||
279 | }; | ||
280 | |||
281 | static void __init omap3_evm_init_irq(void) | 281 | static void __init omap3_evm_init_irq(void) |
282 | { | 282 | { |
283 | omap_board_config = omap3_evm_config; | ||
284 | omap_board_config_size = ARRAY_SIZE(omap3_evm_config); | ||
283 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL); | 285 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL); |
284 | omap_init_irq(); | 286 | omap_init_irq(); |
285 | omap_gpio_init(); | 287 | omap_gpio_init(); |
286 | omap3evm_init_smc911x(); | 288 | omap3evm_init_smc911x(); |
287 | } | 289 | } |
288 | 290 | ||
289 | static struct omap_board_config_kernel omap3_evm_config[] __initdata = { | ||
290 | { OMAP_TAG_UART, &omap3_evm_uart_config }, | ||
291 | { OMAP_TAG_LCD, &omap3_evm_lcd_config }, | ||
292 | }; | ||
293 | |||
294 | static struct platform_device *omap3_evm_devices[] __initdata = { | 291 | static struct platform_device *omap3_evm_devices[] __initdata = { |
295 | &omap3_evm_lcd_device, | 292 | &omap3_evm_lcd_device, |
296 | &omap3evm_smc911x_device, | 293 | &omap3evm_smc911x_device, |
@@ -301,8 +298,6 @@ static void __init omap3_evm_init(void) | |||
301 | omap3_evm_i2c_init(); | 298 | omap3_evm_i2c_init(); |
302 | 299 | ||
303 | platform_add_devices(omap3_evm_devices, ARRAY_SIZE(omap3_evm_devices)); | 300 | platform_add_devices(omap3_evm_devices, ARRAY_SIZE(omap3_evm_devices)); |
304 | omap_board_config = omap3_evm_config; | ||
305 | omap_board_config_size = ARRAY_SIZE(omap3_evm_config); | ||
306 | 301 | ||
307 | spi_register_board_info(omap3evm_spi_board_info, | 302 | spi_register_board_info(omap3evm_spi_board_info, |
308 | ARRAY_SIZE(omap3evm_spi_board_info)); | 303 | ARRAY_SIZE(omap3evm_spi_board_info)); |
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 864ee3d021f7..b43f6e36b6d9 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c | |||
@@ -213,10 +213,6 @@ static struct twl4030_hsmmc_info omap3pandora_mmc[] = { | |||
213 | {} /* Terminator */ | 213 | {} /* Terminator */ |
214 | }; | 214 | }; |
215 | 215 | ||
216 | static struct omap_uart_config omap3pandora_uart_config __initdata = { | ||
217 | .enabled_uarts = (1 << 2), /* UART3 */ | ||
218 | }; | ||
219 | |||
220 | static struct regulator_consumer_supply pandora_vmmc1_supply = { | 216 | static struct regulator_consumer_supply pandora_vmmc1_supply = { |
221 | .supply = "vmmc", | 217 | .supply = "vmmc", |
222 | }; | 218 | }; |
@@ -309,14 +305,6 @@ static int __init omap3pandora_i2c_init(void) | |||
309 | return 0; | 305 | return 0; |
310 | } | 306 | } |
311 | 307 | ||
312 | static void __init omap3pandora_init_irq(void) | ||
313 | { | ||
314 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params, | ||
315 | mt46h32m32lf6_sdrc_params); | ||
316 | omap_init_irq(); | ||
317 | omap_gpio_init(); | ||
318 | } | ||
319 | |||
320 | static void __init omap3pandora_ads7846_init(void) | 308 | static void __init omap3pandora_ads7846_init(void) |
321 | { | 309 | { |
322 | int gpio = OMAP3_PANDORA_TS_GPIO; | 310 | int gpio = OMAP3_PANDORA_TS_GPIO; |
@@ -376,10 +364,19 @@ static struct omap_lcd_config omap3pandora_lcd_config __initdata = { | |||
376 | }; | 364 | }; |
377 | 365 | ||
378 | static struct omap_board_config_kernel omap3pandora_config[] __initdata = { | 366 | static struct omap_board_config_kernel omap3pandora_config[] __initdata = { |
379 | { OMAP_TAG_UART, &omap3pandora_uart_config }, | ||
380 | { OMAP_TAG_LCD, &omap3pandora_lcd_config }, | 367 | { OMAP_TAG_LCD, &omap3pandora_lcd_config }, |
381 | }; | 368 | }; |
382 | 369 | ||
370 | static void __init omap3pandora_init_irq(void) | ||
371 | { | ||
372 | omap_board_config = omap3pandora_config; | ||
373 | omap_board_config_size = ARRAY_SIZE(omap3pandora_config); | ||
374 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params, | ||
375 | mt46h32m32lf6_sdrc_params); | ||
376 | omap_init_irq(); | ||
377 | omap_gpio_init(); | ||
378 | } | ||
379 | |||
383 | static struct platform_device *omap3pandora_devices[] __initdata = { | 380 | static struct platform_device *omap3pandora_devices[] __initdata = { |
384 | &omap3pandora_lcd_device, | 381 | &omap3pandora_lcd_device, |
385 | &pandora_leds_gpio, | 382 | &pandora_leds_gpio, |
@@ -391,8 +388,6 @@ static void __init omap3pandora_init(void) | |||
391 | omap3pandora_i2c_init(); | 388 | omap3pandora_i2c_init(); |
392 | platform_add_devices(omap3pandora_devices, | 389 | platform_add_devices(omap3pandora_devices, |
393 | ARRAY_SIZE(omap3pandora_devices)); | 390 | ARRAY_SIZE(omap3pandora_devices)); |
394 | omap_board_config = omap3pandora_config; | ||
395 | omap_board_config_size = ARRAY_SIZE(omap3pandora_config); | ||
396 | omap_serial_init(); | 391 | omap_serial_init(); |
397 | spi_register_board_info(omap3pandora_spi_board_info, | 392 | spi_register_board_info(omap3pandora_spi_board_info, |
398 | ARRAY_SIZE(omap3pandora_spi_board_info)); | 393 | ARRAY_SIZE(omap3pandora_spi_board_info)); |
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index 6bce23004aa4..9917d2fddc2f 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c | |||
@@ -271,9 +271,6 @@ static void __init overo_flash_init(void) | |||
271 | printk(KERN_ERR "Unable to register NAND device\n"); | 271 | printk(KERN_ERR "Unable to register NAND device\n"); |
272 | } | 272 | } |
273 | } | 273 | } |
274 | static struct omap_uart_config overo_uart_config __initdata = { | ||
275 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
276 | }; | ||
277 | 274 | ||
278 | static struct twl4030_hsmmc_info mmc[] = { | 275 | static struct twl4030_hsmmc_info mmc[] = { |
279 | { | 276 | { |
@@ -360,14 +357,6 @@ static int __init overo_i2c_init(void) | |||
360 | return 0; | 357 | return 0; |
361 | } | 358 | } |
362 | 359 | ||
363 | static void __init overo_init_irq(void) | ||
364 | { | ||
365 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params, | ||
366 | mt46h32m32lf6_sdrc_params); | ||
367 | omap_init_irq(); | ||
368 | omap_gpio_init(); | ||
369 | } | ||
370 | |||
371 | static struct platform_device overo_lcd_device = { | 360 | static struct platform_device overo_lcd_device = { |
372 | .name = "overo_lcd", | 361 | .name = "overo_lcd", |
373 | .id = -1, | 362 | .id = -1, |
@@ -378,10 +367,19 @@ static struct omap_lcd_config overo_lcd_config __initdata = { | |||
378 | }; | 367 | }; |
379 | 368 | ||
380 | static struct omap_board_config_kernel overo_config[] __initdata = { | 369 | static struct omap_board_config_kernel overo_config[] __initdata = { |
381 | { OMAP_TAG_UART, &overo_uart_config }, | ||
382 | { OMAP_TAG_LCD, &overo_lcd_config }, | 370 | { OMAP_TAG_LCD, &overo_lcd_config }, |
383 | }; | 371 | }; |
384 | 372 | ||
373 | static void __init overo_init_irq(void) | ||
374 | { | ||
375 | omap_board_config = overo_config; | ||
376 | omap_board_config_size = ARRAY_SIZE(overo_config); | ||
377 | omap2_init_common_hw(mt46h32m32lf6_sdrc_params, | ||
378 | mt46h32m32lf6_sdrc_params); | ||
379 | omap_init_irq(); | ||
380 | omap_gpio_init(); | ||
381 | } | ||
382 | |||
385 | static struct platform_device *overo_devices[] __initdata = { | 383 | static struct platform_device *overo_devices[] __initdata = { |
386 | &overo_lcd_device, | 384 | &overo_lcd_device, |
387 | }; | 385 | }; |
@@ -390,8 +388,6 @@ static void __init overo_init(void) | |||
390 | { | 388 | { |
391 | overo_i2c_init(); | 389 | overo_i2c_init(); |
392 | platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices)); | 390 | platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices)); |
393 | omap_board_config = overo_config; | ||
394 | omap_board_config_size = ARRAY_SIZE(overo_config); | ||
395 | omap_serial_init(); | 391 | omap_serial_init(); |
396 | overo_flash_init(); | 392 | overo_flash_init(); |
397 | usb_musb_init(); | 393 | usb_musb_init(); |
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 56d931a425f7..e6e8290b7828 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-omap2/board-rx51-flash.c | 2 | * linux/arch/arm/mach-omap2/board-rx51-peripherals.c |
3 | * | 3 | * |
4 | * Copyright (C) 2008-2009 Nokia | 4 | * Copyright (C) 2008-2009 Nokia |
5 | * | 5 | * |
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/regulator/machine.h> | 20 | #include <linux/regulator/machine.h> |
21 | #include <linux/gpio.h> | 21 | #include <linux/gpio.h> |
22 | #include <linux/mmc/host.h> | ||
22 | 23 | ||
23 | #include <mach/mcspi.h> | 24 | #include <mach/mcspi.h> |
24 | #include <mach/mux.h> | 25 | #include <mach/mux.h> |
@@ -102,6 +103,7 @@ static struct twl4030_hsmmc_info mmc[] = { | |||
102 | .cover_only = true, | 103 | .cover_only = true, |
103 | .gpio_cd = 160, | 104 | .gpio_cd = 160, |
104 | .gpio_wp = -EINVAL, | 105 | .gpio_wp = -EINVAL, |
106 | .power_saving = true, | ||
105 | }, | 107 | }, |
106 | { | 108 | { |
107 | .name = "internal", | 109 | .name = "internal", |
@@ -109,6 +111,8 @@ static struct twl4030_hsmmc_info mmc[] = { | |||
109 | .wires = 8, | 111 | .wires = 8, |
110 | .gpio_cd = -EINVAL, | 112 | .gpio_cd = -EINVAL, |
111 | .gpio_wp = -EINVAL, | 113 | .gpio_wp = -EINVAL, |
114 | .nonremovable = true, | ||
115 | .power_saving = true, | ||
112 | }, | 116 | }, |
113 | {} /* Terminator */ | 117 | {} /* Terminator */ |
114 | }; | 118 | }; |
@@ -282,7 +286,124 @@ static struct twl4030_usb_data rx51_usb_data = { | |||
282 | .usb_mode = T2_USB_MODE_ULPI, | 286 | .usb_mode = T2_USB_MODE_ULPI, |
283 | }; | 287 | }; |
284 | 288 | ||
285 | static struct twl4030_platform_data rx51_twldata = { | 289 | static struct twl4030_ins sleep_on_seq[] __initdata = { |
290 | /* | ||
291 | * Turn off VDD1 and VDD2. | ||
292 | */ | ||
293 | {MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_OFF), 4}, | ||
294 | {MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_OFF), 2}, | ||
295 | /* | ||
296 | * And also turn off the OMAP3 PLLs and the sysclk output. | ||
297 | */ | ||
298 | {MSG_SINGULAR(DEV_GRP_P1, 0x7, RES_STATE_OFF), 3}, | ||
299 | {MSG_SINGULAR(DEV_GRP_P1, 0x17, RES_STATE_OFF), 3}, | ||
300 | }; | ||
301 | |||
302 | static struct twl4030_script sleep_on_script __initdata = { | ||
303 | .script = sleep_on_seq, | ||
304 | .size = ARRAY_SIZE(sleep_on_seq), | ||
305 | .flags = TWL4030_SLEEP_SCRIPT, | ||
306 | }; | ||
307 | |||
308 | static struct twl4030_ins wakeup_seq[] __initdata = { | ||
309 | /* | ||
310 | * Reenable the OMAP3 PLLs. | ||
311 | * Wakeup VDD1 and VDD2. | ||
312 | * Reenable sysclk output. | ||
313 | */ | ||
314 | {MSG_SINGULAR(DEV_GRP_P1, 0x7, RES_STATE_ACTIVE), 0x30}, | ||
315 | {MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_ACTIVE), 0x30}, | ||
316 | {MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_ACTIVE), 0x37}, | ||
317 | {MSG_SINGULAR(DEV_GRP_P1, 0x19, RES_STATE_ACTIVE), 3}, | ||
318 | }; | ||
319 | |||
320 | static struct twl4030_script wakeup_script __initdata = { | ||
321 | .script = wakeup_seq, | ||
322 | .size = ARRAY_SIZE(wakeup_seq), | ||
323 | .flags = TWL4030_WAKEUP12_SCRIPT, | ||
324 | }; | ||
325 | |||
326 | static struct twl4030_ins wakeup_p3_seq[] __initdata = { | ||
327 | /* | ||
328 | * Wakeup VDD1 (dummy to be able to insert a delay) | ||
329 | * Enable CLKEN | ||
330 | */ | ||
331 | {MSG_SINGULAR(DEV_GRP_P1, 0x17, RES_STATE_ACTIVE), 3}, | ||
332 | }; | ||
333 | |||
334 | static struct twl4030_script wakeup_p3_script __initdata = { | ||
335 | .script = wakeup_p3_seq, | ||
336 | .size = ARRAY_SIZE(wakeup_p3_seq), | ||
337 | .flags = TWL4030_WAKEUP3_SCRIPT, | ||
338 | }; | ||
339 | |||
340 | static struct twl4030_ins wrst_seq[] __initdata = { | ||
341 | /* | ||
342 | * Reset twl4030. | ||
343 | * Reset VDD1 regulator. | ||
344 | * Reset VDD2 regulator. | ||
345 | * Reset VPLL1 regulator. | ||
346 | * Enable sysclk output. | ||
347 | * Reenable twl4030. | ||
348 | */ | ||
349 | {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_OFF), 2}, | ||
350 | {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 0, 1, RES_STATE_ACTIVE), | ||
351 | 0x13}, | ||
352 | {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PP, 0, 2, RES_STATE_WRST), 0x13}, | ||
353 | {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PP, 0, 3, RES_STATE_OFF), 0x13}, | ||
354 | {MSG_SINGULAR(DEV_GRP_NULL, RES_VDD1, RES_STATE_WRST), 0x13}, | ||
355 | {MSG_SINGULAR(DEV_GRP_NULL, RES_VDD2, RES_STATE_WRST), 0x13}, | ||
356 | {MSG_SINGULAR(DEV_GRP_NULL, RES_VPLL1, RES_STATE_WRST), 0x35}, | ||
357 | {MSG_SINGULAR(DEV_GRP_P1, RES_HFCLKOUT, RES_STATE_ACTIVE), 2}, | ||
358 | {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_ACTIVE), 2}, | ||
359 | }; | ||
360 | |||
361 | static struct twl4030_script wrst_script __initdata = { | ||
362 | .script = wrst_seq, | ||
363 | .size = ARRAY_SIZE(wrst_seq), | ||
364 | .flags = TWL4030_WRST_SCRIPT, | ||
365 | }; | ||
366 | |||
367 | static struct twl4030_script *twl4030_scripts[] __initdata = { | ||
368 | /* wakeup12 script should be loaded before sleep script, otherwise a | ||
369 | board might hit retention before loading of wakeup script is | ||
370 | completed. This can cause boot failures depending on timing issues. | ||
371 | */ | ||
372 | &wakeup_script, | ||
373 | &sleep_on_script, | ||
374 | &wakeup_p3_script, | ||
375 | &wrst_script, | ||
376 | }; | ||
377 | |||
378 | static struct twl4030_resconfig twl4030_rconfig[] __initdata = { | ||
379 | { .resource = RES_VINTANA1, .devgroup = -1, .type = -1, .type2 = 1 }, | ||
380 | { .resource = RES_VINTANA2, .devgroup = -1, .type = -1, .type2 = 1 }, | ||
381 | { .resource = RES_VINTDIG, .devgroup = -1, .type = -1, .type2 = 1 }, | ||
382 | { .resource = RES_VMMC1, .devgroup = -1, .type = -1, .type2 = 3}, | ||
383 | { .resource = RES_VMMC2, .devgroup = DEV_GRP_NULL, .type = -1, | ||
384 | .type2 = 3}, | ||
385 | { .resource = RES_VAUX1, .devgroup = -1, .type = -1, .type2 = 3}, | ||
386 | { .resource = RES_VAUX2, .devgroup = -1, .type = -1, .type2 = 3}, | ||
387 | { .resource = RES_VAUX3, .devgroup = -1, .type = -1, .type2 = 3}, | ||
388 | { .resource = RES_VAUX4, .devgroup = -1, .type = -1, .type2 = 3}, | ||
389 | { .resource = RES_VPLL2, .devgroup = -1, .type = -1, .type2 = 3}, | ||
390 | { .resource = RES_VDAC, .devgroup = -1, .type = -1, .type2 = 3}, | ||
391 | { .resource = RES_VSIM, .devgroup = DEV_GRP_NULL, .type = -1, | ||
392 | .type2 = 3}, | ||
393 | { .resource = RES_CLKEN, .devgroup = DEV_GRP_P3, .type = -1, | ||
394 | .type2 = 1 }, | ||
395 | { 0, 0}, | ||
396 | }; | ||
397 | |||
398 | static struct twl4030_power_data rx51_t2scripts_data __initdata = { | ||
399 | .scripts = twl4030_scripts, | ||
400 | .num = ARRAY_SIZE(twl4030_scripts), | ||
401 | .resource_config = twl4030_rconfig, | ||
402 | }; | ||
403 | |||
404 | |||
405 | |||
406 | static struct twl4030_platform_data rx51_twldata __initdata = { | ||
286 | .irq_base = TWL4030_IRQ_BASE, | 407 | .irq_base = TWL4030_IRQ_BASE, |
287 | .irq_end = TWL4030_IRQ_END, | 408 | .irq_end = TWL4030_IRQ_END, |
288 | 409 | ||
@@ -291,6 +412,7 @@ static struct twl4030_platform_data rx51_twldata = { | |||
291 | .keypad = &rx51_kp_data, | 412 | .keypad = &rx51_kp_data, |
292 | .madc = &rx51_madc_data, | 413 | .madc = &rx51_madc_data, |
293 | .usb = &rx51_usb_data, | 414 | .usb = &rx51_usb_data, |
415 | .power = &rx51_t2scripts_data, | ||
294 | 416 | ||
295 | .vaux1 = &rx51_vaux1, | 417 | .vaux1 = &rx51_vaux1, |
296 | .vaux2 = &rx51_vaux2, | 418 | .vaux2 = &rx51_vaux2, |
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c index 1c9e07fe8266..f9196c3b1a7b 100644 --- a/arch/arm/mach-omap2/board-rx51.c +++ b/arch/arm/mach-omap2/board-rx51.c | |||
@@ -31,10 +31,6 @@ | |||
31 | #include <mach/gpmc.h> | 31 | #include <mach/gpmc.h> |
32 | #include <mach/usb.h> | 32 | #include <mach/usb.h> |
33 | 33 | ||
34 | static struct omap_uart_config rx51_uart_config = { | ||
35 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | ||
36 | }; | ||
37 | |||
38 | static struct omap_lcd_config rx51_lcd_config = { | 34 | static struct omap_lcd_config rx51_lcd_config = { |
39 | .ctrl_name = "internal", | 35 | .ctrl_name = "internal", |
40 | }; | 36 | }; |
@@ -52,7 +48,6 @@ static struct omap_fbmem_config rx51_fbmem2_config = { | |||
52 | }; | 48 | }; |
53 | 49 | ||
54 | static struct omap_board_config_kernel rx51_config[] = { | 50 | static struct omap_board_config_kernel rx51_config[] = { |
55 | { OMAP_TAG_UART, &rx51_uart_config }, | ||
56 | { OMAP_TAG_FBMEM, &rx51_fbmem0_config }, | 51 | { OMAP_TAG_FBMEM, &rx51_fbmem0_config }, |
57 | { OMAP_TAG_FBMEM, &rx51_fbmem1_config }, | 52 | { OMAP_TAG_FBMEM, &rx51_fbmem1_config }, |
58 | { OMAP_TAG_FBMEM, &rx51_fbmem2_config }, | 53 | { OMAP_TAG_FBMEM, &rx51_fbmem2_config }, |
@@ -61,6 +56,8 @@ static struct omap_board_config_kernel rx51_config[] = { | |||
61 | 56 | ||
62 | static void __init rx51_init_irq(void) | 57 | static void __init rx51_init_irq(void) |
63 | { | 58 | { |
59 | omap_board_config = rx51_config; | ||
60 | omap_board_config_size = ARRAY_SIZE(rx51_config); | ||
64 | omap2_init_common_hw(NULL, NULL); | 61 | omap2_init_common_hw(NULL, NULL); |
65 | omap_init_irq(); | 62 | omap_init_irq(); |
66 | omap_gpio_init(); | 63 | omap_gpio_init(); |
@@ -70,8 +67,6 @@ extern void __init rx51_peripherals_init(void); | |||
70 | 67 | ||
71 | static void __init rx51_init(void) | 68 | static void __init rx51_init(void) |
72 | { | 69 | { |
73 | omap_board_config = rx51_config; | ||
74 | omap_board_config_size = ARRAY_SIZE(rx51_config); | ||
75 | omap_serial_init(); | 70 | omap_serial_init(); |
76 | usb_musb_init(); | 71 | usb_musb_init(); |
77 | rx51_peripherals_init(); | 72 | rx51_peripherals_init(); |
diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c index bac5c4321ff7..1f13e2a1f322 100644 --- a/arch/arm/mach-omap2/board-zoom-debugboard.c +++ b/arch/arm/mach-omap2/board-zoom-debugboard.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/gpio.h> | 12 | #include <linux/gpio.h> |
13 | #include <linux/serial_8250.h> | 13 | #include <linux/serial_8250.h> |
14 | #include <linux/smsc911x.h> | 14 | #include <linux/smsc911x.h> |
15 | #include <linux/interrupt.h> | ||
15 | 16 | ||
16 | #include <mach/gpmc.h> | 17 | #include <mach/gpmc.h> |
17 | 18 | ||
@@ -84,6 +85,7 @@ static struct plat_serial8250_port serial_platform_data[] = { | |||
84 | .mapbase = 0x10000000, | 85 | .mapbase = 0x10000000, |
85 | .irq = OMAP_GPIO_IRQ(102), | 86 | .irq = OMAP_GPIO_IRQ(102), |
86 | .flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP|UPF_SHARE_IRQ, | 87 | .flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP|UPF_SHARE_IRQ, |
88 | .irqflags = IRQF_SHARED | IRQF_TRIGGER_RISING, | ||
87 | .iotype = UPIO_MEM, | 89 | .iotype = UPIO_MEM, |
88 | .regshift = 1, | 90 | .regshift = 1, |
89 | .uartclk = QUART_CLK, | 91 | .uartclk = QUART_CLK, |
@@ -94,7 +96,7 @@ static struct plat_serial8250_port serial_platform_data[] = { | |||
94 | 96 | ||
95 | static struct platform_device zoom2_debugboard_serial_device = { | 97 | static struct platform_device zoom2_debugboard_serial_device = { |
96 | .name = "serial8250", | 98 | .name = "serial8250", |
97 | .id = PLAT8250_DEV_PLATFORM1, | 99 | .id = 3, |
98 | .dev = { | 100 | .dev = { |
99 | .platform_data = serial_platform_data, | 101 | .platform_data = serial_platform_data, |
100 | }, | 102 | }, |
@@ -127,6 +129,7 @@ static inline void __init zoom2_init_quaduart(void) | |||
127 | static inline int omap_zoom2_debugboard_detect(void) | 129 | static inline int omap_zoom2_debugboard_detect(void) |
128 | { | 130 | { |
129 | int debug_board_detect = 0; | 131 | int debug_board_detect = 0; |
132 | int ret = 1; | ||
130 | 133 | ||
131 | debug_board_detect = ZOOM2_SMSC911X_GPIO; | 134 | debug_board_detect = ZOOM2_SMSC911X_GPIO; |
132 | 135 | ||
@@ -138,10 +141,10 @@ static inline int omap_zoom2_debugboard_detect(void) | |||
138 | gpio_direction_input(debug_board_detect); | 141 | gpio_direction_input(debug_board_detect); |
139 | 142 | ||
140 | if (!gpio_get_value(debug_board_detect)) { | 143 | if (!gpio_get_value(debug_board_detect)) { |
141 | gpio_free(debug_board_detect); | 144 | ret = 0; |
142 | return 0; | ||
143 | } | 145 | } |
144 | return 1; | 146 | gpio_free(debug_board_detect); |
147 | return ret; | ||
145 | } | 148 | } |
146 | 149 | ||
147 | static struct platform_device *zoom2_devices[] __initdata = { | 150 | static struct platform_device *zoom2_devices[] __initdata = { |
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c index 427b7b8b1237..324009edbd53 100644 --- a/arch/arm/mach-omap2/board-zoom2.c +++ b/arch/arm/mach-omap2/board-zoom2.c | |||
@@ -12,36 +12,217 @@ | |||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/input.h> | ||
15 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
16 | #include <linux/i2c/twl4030.h> | 17 | #include <linux/i2c/twl4030.h> |
18 | #include <linux/regulator/machine.h> | ||
17 | 19 | ||
18 | #include <asm/mach-types.h> | 20 | #include <asm/mach-types.h> |
19 | #include <asm/mach/arch.h> | 21 | #include <asm/mach/arch.h> |
20 | 22 | ||
21 | #include <mach/common.h> | 23 | #include <mach/common.h> |
22 | #include <mach/usb.h> | 24 | #include <mach/usb.h> |
25 | #include <mach/keypad.h> | ||
23 | 26 | ||
24 | #include "mmc-twl4030.h" | 27 | #include "mmc-twl4030.h" |
25 | 28 | ||
26 | static void __init omap_zoom2_init_irq(void) | 29 | /* Zoom2 has Qwerty keyboard*/ |
30 | static int zoom2_twl4030_keymap[] = { | ||
31 | KEY(0, 0, KEY_E), | ||
32 | KEY(1, 0, KEY_R), | ||
33 | KEY(2, 0, KEY_T), | ||
34 | KEY(3, 0, KEY_HOME), | ||
35 | KEY(6, 0, KEY_I), | ||
36 | KEY(7, 0, KEY_LEFTSHIFT), | ||
37 | KEY(0, 1, KEY_D), | ||
38 | KEY(1, 1, KEY_F), | ||
39 | KEY(2, 1, KEY_G), | ||
40 | KEY(3, 1, KEY_SEND), | ||
41 | KEY(6, 1, KEY_K), | ||
42 | KEY(7, 1, KEY_ENTER), | ||
43 | KEY(0, 2, KEY_X), | ||
44 | KEY(1, 2, KEY_C), | ||
45 | KEY(2, 2, KEY_V), | ||
46 | KEY(3, 2, KEY_END), | ||
47 | KEY(6, 2, KEY_DOT), | ||
48 | KEY(7, 2, KEY_CAPSLOCK), | ||
49 | KEY(0, 3, KEY_Z), | ||
50 | KEY(1, 3, KEY_KPPLUS), | ||
51 | KEY(2, 3, KEY_B), | ||
52 | KEY(3, 3, KEY_F1), | ||
53 | KEY(6, 3, KEY_O), | ||
54 | KEY(7, 3, KEY_SPACE), | ||
55 | KEY(0, 4, KEY_W), | ||
56 | KEY(1, 4, KEY_Y), | ||
57 | KEY(2, 4, KEY_U), | ||
58 | KEY(3, 4, KEY_F2), | ||
59 | KEY(4, 4, KEY_VOLUMEUP), | ||
60 | KEY(6, 4, KEY_L), | ||
61 | KEY(7, 4, KEY_LEFT), | ||
62 | KEY(0, 5, KEY_S), | ||
63 | KEY(1, 5, KEY_H), | ||
64 | KEY(2, 5, KEY_J), | ||
65 | KEY(3, 5, KEY_F3), | ||
66 | KEY(5, 5, KEY_VOLUMEDOWN), | ||
67 | KEY(6, 5, KEY_M), | ||
68 | KEY(4, 5, KEY_ENTER), | ||
69 | KEY(7, 5, KEY_RIGHT), | ||
70 | KEY(0, 6, KEY_Q), | ||
71 | KEY(1, 6, KEY_A), | ||
72 | KEY(2, 6, KEY_N), | ||
73 | KEY(3, 6, KEY_BACKSPACE), | ||
74 | KEY(6, 6, KEY_P), | ||
75 | KEY(7, 6, KEY_UP), | ||
76 | KEY(6, 7, KEY_SELECT), | ||
77 | KEY(7, 7, KEY_DOWN), | ||
78 | KEY(0, 7, KEY_PROG1), /*MACRO 1 <User defined> */ | ||
79 | KEY(1, 7, KEY_PROG2), /*MACRO 2 <User defined> */ | ||
80 | KEY(2, 7, KEY_PROG3), /*MACRO 3 <User defined> */ | ||
81 | KEY(3, 7, KEY_PROG4), /*MACRO 4 <User defined> */ | ||
82 | 0 | ||
83 | }; | ||
84 | |||
85 | static struct twl4030_keypad_data zoom2_kp_twl4030_data = { | ||
86 | .rows = 8, | ||
87 | .cols = 8, | ||
88 | .keymap = zoom2_twl4030_keymap, | ||
89 | .keymapsize = ARRAY_SIZE(zoom2_twl4030_keymap), | ||
90 | .rep = 1, | ||
91 | }; | ||
92 | |||
93 | static struct omap_board_config_kernel zoom2_config[] __initdata = { | ||
94 | }; | ||
95 | |||
96 | static struct regulator_consumer_supply zoom2_vmmc1_supply = { | ||
97 | .supply = "vmmc", | ||
98 | }; | ||
99 | |||
100 | static struct regulator_consumer_supply zoom2_vsim_supply = { | ||
101 | .supply = "vmmc_aux", | ||
102 | }; | ||
103 | |||
104 | static struct regulator_consumer_supply zoom2_vmmc2_supply = { | ||
105 | .supply = "vmmc", | ||
106 | }; | ||
107 | |||
108 | /* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ | ||
109 | static struct regulator_init_data zoom2_vmmc1 = { | ||
110 | .constraints = { | ||
111 | .min_uV = 1850000, | ||
112 | .max_uV = 3150000, | ||
113 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
114 | | REGULATOR_MODE_STANDBY, | ||
115 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | ||
116 | | REGULATOR_CHANGE_MODE | ||
117 | | REGULATOR_CHANGE_STATUS, | ||
118 | }, | ||
119 | .num_consumer_supplies = 1, | ||
120 | .consumer_supplies = &zoom2_vmmc1_supply, | ||
121 | }; | ||
122 | |||
123 | /* VMMC2 for MMC2 card */ | ||
124 | static struct regulator_init_data zoom2_vmmc2 = { | ||
125 | .constraints = { | ||
126 | .min_uV = 1850000, | ||
127 | .max_uV = 1850000, | ||
128 | .apply_uV = true, | ||
129 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
130 | | REGULATOR_MODE_STANDBY, | ||
131 | .valid_ops_mask = REGULATOR_CHANGE_MODE | ||
132 | | REGULATOR_CHANGE_STATUS, | ||
133 | }, | ||
134 | .num_consumer_supplies = 1, | ||
135 | .consumer_supplies = &zoom2_vmmc2_supply, | ||
136 | }; | ||
137 | |||
138 | /* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */ | ||
139 | static struct regulator_init_data zoom2_vsim = { | ||
140 | .constraints = { | ||
141 | .min_uV = 1800000, | ||
142 | .max_uV = 3000000, | ||
143 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
144 | | REGULATOR_MODE_STANDBY, | ||
145 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | ||
146 | | REGULATOR_CHANGE_MODE | ||
147 | | REGULATOR_CHANGE_STATUS, | ||
148 | }, | ||
149 | .num_consumer_supplies = 1, | ||
150 | .consumer_supplies = &zoom2_vsim_supply, | ||
151 | }; | ||
152 | |||
153 | static struct twl4030_hsmmc_info mmc[] __initdata = { | ||
154 | { | ||
155 | .mmc = 1, | ||
156 | .wires = 4, | ||
157 | .gpio_wp = -EINVAL, | ||
158 | }, | ||
159 | { | ||
160 | .mmc = 2, | ||
161 | .wires = 4, | ||
162 | .gpio_wp = -EINVAL, | ||
163 | }, | ||
164 | {} /* Terminator */ | ||
165 | }; | ||
166 | |||
167 | static int zoom2_twl_gpio_setup(struct device *dev, | ||
168 | unsigned gpio, unsigned ngpio) | ||
27 | { | 169 | { |
28 | omap2_init_common_hw(NULL, NULL); | 170 | /* gpio + 0 is "mmc0_cd" (input/IRQ), |
29 | omap_init_irq(); | 171 | * gpio + 1 is "mmc1_cd" (input/IRQ) |
30 | omap_gpio_init(); | 172 | */ |
173 | mmc[0].gpio_cd = gpio + 0; | ||
174 | mmc[1].gpio_cd = gpio + 1; | ||
175 | twl4030_mmc_init(mmc); | ||
176 | |||
177 | /* link regulators to MMC adapters ... we "know" the | ||
178 | * regulators will be set up only *after* we return. | ||
179 | */ | ||
180 | zoom2_vmmc1_supply.dev = mmc[0].dev; | ||
181 | zoom2_vsim_supply.dev = mmc[0].dev; | ||
182 | zoom2_vmmc2_supply.dev = mmc[1].dev; | ||
183 | |||
184 | return 0; | ||
31 | } | 185 | } |
32 | 186 | ||
33 | static struct omap_uart_config zoom2_uart_config __initdata = { | 187 | |
34 | .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), | 188 | static int zoom2_batt_table[] = { |
189 | /* 0 C*/ | ||
190 | 30800, 29500, 28300, 27100, | ||
191 | 26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900, | ||
192 | 17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100, | ||
193 | 11600, 11200, 10800, 10400, 10000, 9630, 9280, 8950, 8620, 8310, | ||
194 | 8020, 7730, 7460, 7200, 6950, 6710, 6470, 6250, 6040, 5830, | ||
195 | 5640, 5450, 5260, 5090, 4920, 4760, 4600, 4450, 4310, 4170, | ||
196 | 4040, 3910, 3790, 3670, 3550 | ||
35 | }; | 197 | }; |
36 | 198 | ||
37 | static struct omap_board_config_kernel zoom2_config[] __initdata = { | 199 | static struct twl4030_bci_platform_data zoom2_bci_data = { |
38 | { OMAP_TAG_UART, &zoom2_uart_config }, | 200 | .battery_tmp_tbl = zoom2_batt_table, |
201 | .tblsize = ARRAY_SIZE(zoom2_batt_table), | ||
39 | }; | 202 | }; |
40 | 203 | ||
204 | static struct twl4030_usb_data zoom2_usb_data = { | ||
205 | .usb_mode = T2_USB_MODE_ULPI, | ||
206 | }; | ||
207 | |||
208 | static void __init omap_zoom2_init_irq(void) | ||
209 | { | ||
210 | omap_board_config = zoom2_config; | ||
211 | omap_board_config_size = ARRAY_SIZE(zoom2_config); | ||
212 | omap2_init_common_hw(NULL, NULL); | ||
213 | omap_init_irq(); | ||
214 | omap_gpio_init(); | ||
215 | } | ||
216 | |||
41 | static struct twl4030_gpio_platform_data zoom2_gpio_data = { | 217 | static struct twl4030_gpio_platform_data zoom2_gpio_data = { |
42 | .gpio_base = OMAP_MAX_GPIO_LINES, | 218 | .gpio_base = OMAP_MAX_GPIO_LINES, |
43 | .irq_base = TWL4030_GPIO_IRQ_BASE, | 219 | .irq_base = TWL4030_GPIO_IRQ_BASE, |
44 | .irq_end = TWL4030_GPIO_IRQ_END, | 220 | .irq_end = TWL4030_GPIO_IRQ_END, |
221 | .setup = zoom2_twl_gpio_setup, | ||
222 | }; | ||
223 | |||
224 | static struct twl4030_madc_platform_data zoom2_madc_data = { | ||
225 | .irq_line = 1, | ||
45 | }; | 226 | }; |
46 | 227 | ||
47 | static struct twl4030_platform_data zoom2_twldata = { | 228 | static struct twl4030_platform_data zoom2_twldata = { |
@@ -49,7 +230,15 @@ static struct twl4030_platform_data zoom2_twldata = { | |||
49 | .irq_end = TWL4030_IRQ_END, | 230 | .irq_end = TWL4030_IRQ_END, |
50 | 231 | ||
51 | /* platform_data for children goes here */ | 232 | /* platform_data for children goes here */ |
233 | .bci = &zoom2_bci_data, | ||
234 | .madc = &zoom2_madc_data, | ||
235 | .usb = &zoom2_usb_data, | ||
52 | .gpio = &zoom2_gpio_data, | 236 | .gpio = &zoom2_gpio_data, |
237 | .keypad = &zoom2_kp_twl4030_data, | ||
238 | .vmmc1 = &zoom2_vmmc1, | ||
239 | .vmmc2 = &zoom2_vmmc2, | ||
240 | .vsim = &zoom2_vsim, | ||
241 | |||
53 | }; | 242 | }; |
54 | 243 | ||
55 | static struct i2c_board_info __initdata zoom2_i2c_boardinfo[] = { | 244 | static struct i2c_board_info __initdata zoom2_i2c_boardinfo[] = { |
@@ -70,26 +259,13 @@ static int __init omap_i2c_init(void) | |||
70 | return 0; | 259 | return 0; |
71 | } | 260 | } |
72 | 261 | ||
73 | static struct twl4030_hsmmc_info mmc[] __initdata = { | ||
74 | { | ||
75 | .mmc = 1, | ||
76 | .wires = 4, | ||
77 | .gpio_cd = -EINVAL, | ||
78 | .gpio_wp = -EINVAL, | ||
79 | }, | ||
80 | {} /* Terminator */ | ||
81 | }; | ||
82 | |||
83 | extern int __init omap_zoom2_debugboard_init(void); | 262 | extern int __init omap_zoom2_debugboard_init(void); |
84 | 263 | ||
85 | static void __init omap_zoom2_init(void) | 264 | static void __init omap_zoom2_init(void) |
86 | { | 265 | { |
87 | omap_i2c_init(); | 266 | omap_i2c_init(); |
88 | omap_board_config = zoom2_config; | ||
89 | omap_board_config_size = ARRAY_SIZE(zoom2_config); | ||
90 | omap_serial_init(); | 267 | omap_serial_init(); |
91 | omap_zoom2_debugboard_init(); | 268 | omap_zoom2_debugboard_init(); |
92 | twl4030_mmc_init(mmc); | ||
93 | usb_musb_init(); | 269 | usb_musb_init(); |
94 | } | 270 | } |
95 | 271 | ||
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 456e2ad5f621..f2a92d614f0f 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c | |||
@@ -1043,5 +1043,7 @@ void omap2_clk_disable_unused(struct clk *clk) | |||
1043 | omap2_clk_disable(clk); | 1043 | omap2_clk_disable(clk); |
1044 | } else | 1044 | } else |
1045 | _omap2_clk_disable(clk); | 1045 | _omap2_clk_disable(clk); |
1046 | if (clk->clkdm != NULL) | ||
1047 | pwrdm_clkdm_state_switch(clk->clkdm); | ||
1046 | } | 1048 | } |
1047 | #endif | 1049 | #endif |
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index cd7819cc0c9e..fafcd32e6907 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/limits.h> | 27 | #include <linux/limits.h> |
28 | #include <linux/bitops.h> | 28 | #include <linux/bitops.h> |
29 | 29 | ||
30 | #include <mach/cpu.h> | ||
30 | #include <mach/clock.h> | 31 | #include <mach/clock.h> |
31 | #include <mach/sram.h> | 32 | #include <mach/sram.h> |
32 | #include <asm/div64.h> | 33 | #include <asm/div64.h> |
@@ -1067,17 +1068,17 @@ static int __init omap2_clk_arch_init(void) | |||
1067 | return -EINVAL; | 1068 | return -EINVAL; |
1068 | 1069 | ||
1069 | /* REVISIT: not yet ready for 343x */ | 1070 | /* REVISIT: not yet ready for 343x */ |
1070 | #if 0 | 1071 | if (clk_set_rate(&dpll1_ck, mpurate)) |
1071 | if (clk_set_rate(&virt_prcm_set, mpurate)) | 1072 | printk(KERN_ERR "*** Unable to set MPU rate\n"); |
1072 | printk(KERN_ERR "Could not find matching MPU rate\n"); | ||
1073 | #endif | ||
1074 | 1073 | ||
1075 | recalculate_root_clocks(); | 1074 | recalculate_root_clocks(); |
1076 | 1075 | ||
1077 | printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL3/MPU): " | 1076 | printk(KERN_INFO "Switched to new clocking rate (Crystal/Core/MPU): " |
1078 | "%ld.%01ld/%ld/%ld MHz\n", | 1077 | "%ld.%01ld/%ld/%ld MHz\n", |
1079 | (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10, | 1078 | (osc_sys_ck.rate / 1000000), ((osc_sys_ck.rate / 100000) % 10), |
1080 | (core_ck.rate / 1000000), (dpll1_fck.rate / 1000000)) ; | 1079 | (core_ck.rate / 1000000), (arm_fck.rate / 1000000)) ; |
1080 | |||
1081 | calibrate_delay(); | ||
1081 | 1082 | ||
1082 | return 0; | 1083 | return 0; |
1083 | } | 1084 | } |
@@ -1136,7 +1137,7 @@ int __init omap2_clk_init(void) | |||
1136 | 1137 | ||
1137 | recalculate_root_clocks(); | 1138 | recalculate_root_clocks(); |
1138 | 1139 | ||
1139 | printk(KERN_INFO "Clocking rate (Crystal/DPLL/ARM core): " | 1140 | printk(KERN_INFO "Clocking rate (Crystal/Core/MPU): " |
1140 | "%ld.%01ld/%ld/%ld MHz\n", | 1141 | "%ld.%01ld/%ld/%ld MHz\n", |
1141 | (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10, | 1142 | (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10, |
1142 | (core_ck.rate / 1000000), (arm_fck.rate / 1000000)); | 1143 | (core_ck.rate / 1000000), (arm_fck.rate / 1000000)); |
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index 57cc2725b923..c8119781e00a 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h | |||
@@ -1020,6 +1020,7 @@ static struct clk arm_fck = { | |||
1020 | .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL), | 1020 | .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL), |
1021 | .clksel_mask = OMAP3430_ST_MPU_CLK_MASK, | 1021 | .clksel_mask = OMAP3430_ST_MPU_CLK_MASK, |
1022 | .clksel = arm_fck_clksel, | 1022 | .clksel = arm_fck_clksel, |
1023 | .clkdm_name = "mpu_clkdm", | ||
1023 | .recalc = &omap2_clksel_recalc, | 1024 | .recalc = &omap2_clksel_recalc, |
1024 | }; | 1025 | }; |
1025 | 1026 | ||
@@ -1155,7 +1156,6 @@ static struct clk gfx_cg1_ck = { | |||
1155 | .name = "gfx_cg1_ck", | 1156 | .name = "gfx_cg1_ck", |
1156 | .ops = &clkops_omap2_dflt_wait, | 1157 | .ops = &clkops_omap2_dflt_wait, |
1157 | .parent = &gfx_l3_fck, /* REVISIT: correct? */ | 1158 | .parent = &gfx_l3_fck, /* REVISIT: correct? */ |
1158 | .init = &omap2_init_clk_clkdm, | ||
1159 | .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), | 1159 | .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), |
1160 | .enable_bit = OMAP3430ES1_EN_2D_SHIFT, | 1160 | .enable_bit = OMAP3430ES1_EN_2D_SHIFT, |
1161 | .clkdm_name = "gfx_3430es1_clkdm", | 1161 | .clkdm_name = "gfx_3430es1_clkdm", |
@@ -1166,7 +1166,6 @@ static struct clk gfx_cg2_ck = { | |||
1166 | .name = "gfx_cg2_ck", | 1166 | .name = "gfx_cg2_ck", |
1167 | .ops = &clkops_omap2_dflt_wait, | 1167 | .ops = &clkops_omap2_dflt_wait, |
1168 | .parent = &gfx_l3_fck, /* REVISIT: correct? */ | 1168 | .parent = &gfx_l3_fck, /* REVISIT: correct? */ |
1169 | .init = &omap2_init_clk_clkdm, | ||
1170 | .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), | 1169 | .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), |
1171 | .enable_bit = OMAP3430ES1_EN_3D_SHIFT, | 1170 | .enable_bit = OMAP3430ES1_EN_3D_SHIFT, |
1172 | .clkdm_name = "gfx_3430es1_clkdm", | 1171 | .clkdm_name = "gfx_3430es1_clkdm", |
@@ -1210,7 +1209,6 @@ static struct clk sgx_ick = { | |||
1210 | .name = "sgx_ick", | 1209 | .name = "sgx_ick", |
1211 | .ops = &clkops_omap2_dflt_wait, | 1210 | .ops = &clkops_omap2_dflt_wait, |
1212 | .parent = &l3_ick, | 1211 | .parent = &l3_ick, |
1213 | .init = &omap2_init_clk_clkdm, | ||
1214 | .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN), | 1212 | .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN), |
1215 | .enable_bit = OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT, | 1213 | .enable_bit = OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT, |
1216 | .clkdm_name = "sgx_clkdm", | 1214 | .clkdm_name = "sgx_clkdm", |
@@ -1223,7 +1221,6 @@ static struct clk d2d_26m_fck = { | |||
1223 | .name = "d2d_26m_fck", | 1221 | .name = "d2d_26m_fck", |
1224 | .ops = &clkops_omap2_dflt_wait, | 1222 | .ops = &clkops_omap2_dflt_wait, |
1225 | .parent = &sys_ck, | 1223 | .parent = &sys_ck, |
1226 | .init = &omap2_init_clk_clkdm, | ||
1227 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), | 1224 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), |
1228 | .enable_bit = OMAP3430ES1_EN_D2D_SHIFT, | 1225 | .enable_bit = OMAP3430ES1_EN_D2D_SHIFT, |
1229 | .clkdm_name = "d2d_clkdm", | 1226 | .clkdm_name = "d2d_clkdm", |
@@ -1234,7 +1231,6 @@ static struct clk modem_fck = { | |||
1234 | .name = "modem_fck", | 1231 | .name = "modem_fck", |
1235 | .ops = &clkops_omap2_dflt_wait, | 1232 | .ops = &clkops_omap2_dflt_wait, |
1236 | .parent = &sys_ck, | 1233 | .parent = &sys_ck, |
1237 | .init = &omap2_init_clk_clkdm, | ||
1238 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), | 1234 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), |
1239 | .enable_bit = OMAP3430_EN_MODEM_SHIFT, | 1235 | .enable_bit = OMAP3430_EN_MODEM_SHIFT, |
1240 | .clkdm_name = "d2d_clkdm", | 1236 | .clkdm_name = "d2d_clkdm", |
@@ -1622,7 +1618,6 @@ static struct clk core_l3_ick = { | |||
1622 | .name = "core_l3_ick", | 1618 | .name = "core_l3_ick", |
1623 | .ops = &clkops_null, | 1619 | .ops = &clkops_null, |
1624 | .parent = &l3_ick, | 1620 | .parent = &l3_ick, |
1625 | .init = &omap2_init_clk_clkdm, | ||
1626 | .clkdm_name = "core_l3_clkdm", | 1621 | .clkdm_name = "core_l3_clkdm", |
1627 | .recalc = &followparent_recalc, | 1622 | .recalc = &followparent_recalc, |
1628 | }; | 1623 | }; |
@@ -1691,7 +1686,6 @@ static struct clk core_l4_ick = { | |||
1691 | .name = "core_l4_ick", | 1686 | .name = "core_l4_ick", |
1692 | .ops = &clkops_null, | 1687 | .ops = &clkops_null, |
1693 | .parent = &l4_ick, | 1688 | .parent = &l4_ick, |
1694 | .init = &omap2_init_clk_clkdm, | ||
1695 | .clkdm_name = "core_l4_clkdm", | 1689 | .clkdm_name = "core_l4_clkdm", |
1696 | .recalc = &followparent_recalc, | 1690 | .recalc = &followparent_recalc, |
1697 | }; | 1691 | }; |
@@ -2089,7 +2083,6 @@ static struct clk dss_tv_fck = { | |||
2089 | .name = "dss_tv_fck", | 2083 | .name = "dss_tv_fck", |
2090 | .ops = &clkops_omap2_dflt, | 2084 | .ops = &clkops_omap2_dflt, |
2091 | .parent = &omap_54m_fck, | 2085 | .parent = &omap_54m_fck, |
2092 | .init = &omap2_init_clk_clkdm, | ||
2093 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), | 2086 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), |
2094 | .enable_bit = OMAP3430_EN_TV_SHIFT, | 2087 | .enable_bit = OMAP3430_EN_TV_SHIFT, |
2095 | .clkdm_name = "dss_clkdm", | 2088 | .clkdm_name = "dss_clkdm", |
@@ -2100,7 +2093,6 @@ static struct clk dss_96m_fck = { | |||
2100 | .name = "dss_96m_fck", | 2093 | .name = "dss_96m_fck", |
2101 | .ops = &clkops_omap2_dflt, | 2094 | .ops = &clkops_omap2_dflt, |
2102 | .parent = &omap_96m_fck, | 2095 | .parent = &omap_96m_fck, |
2103 | .init = &omap2_init_clk_clkdm, | ||
2104 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), | 2096 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), |
2105 | .enable_bit = OMAP3430_EN_TV_SHIFT, | 2097 | .enable_bit = OMAP3430_EN_TV_SHIFT, |
2106 | .clkdm_name = "dss_clkdm", | 2098 | .clkdm_name = "dss_clkdm", |
@@ -2111,7 +2103,6 @@ static struct clk dss2_alwon_fck = { | |||
2111 | .name = "dss2_alwon_fck", | 2103 | .name = "dss2_alwon_fck", |
2112 | .ops = &clkops_omap2_dflt, | 2104 | .ops = &clkops_omap2_dflt, |
2113 | .parent = &sys_ck, | 2105 | .parent = &sys_ck, |
2114 | .init = &omap2_init_clk_clkdm, | ||
2115 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), | 2106 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), |
2116 | .enable_bit = OMAP3430_EN_DSS2_SHIFT, | 2107 | .enable_bit = OMAP3430_EN_DSS2_SHIFT, |
2117 | .clkdm_name = "dss_clkdm", | 2108 | .clkdm_name = "dss_clkdm", |
@@ -2123,7 +2114,6 @@ static struct clk dss_ick_3430es1 = { | |||
2123 | .name = "dss_ick", | 2114 | .name = "dss_ick", |
2124 | .ops = &clkops_omap2_dflt, | 2115 | .ops = &clkops_omap2_dflt, |
2125 | .parent = &l4_ick, | 2116 | .parent = &l4_ick, |
2126 | .init = &omap2_init_clk_clkdm, | ||
2127 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN), | 2117 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN), |
2128 | .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT, | 2118 | .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT, |
2129 | .clkdm_name = "dss_clkdm", | 2119 | .clkdm_name = "dss_clkdm", |
@@ -2135,7 +2125,6 @@ static struct clk dss_ick_3430es2 = { | |||
2135 | .name = "dss_ick", | 2125 | .name = "dss_ick", |
2136 | .ops = &clkops_omap3430es2_dss_usbhost_wait, | 2126 | .ops = &clkops_omap3430es2_dss_usbhost_wait, |
2137 | .parent = &l4_ick, | 2127 | .parent = &l4_ick, |
2138 | .init = &omap2_init_clk_clkdm, | ||
2139 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN), | 2128 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN), |
2140 | .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT, | 2129 | .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT, |
2141 | .clkdm_name = "dss_clkdm", | 2130 | .clkdm_name = "dss_clkdm", |
@@ -2159,7 +2148,6 @@ static struct clk cam_ick = { | |||
2159 | .name = "cam_ick", | 2148 | .name = "cam_ick", |
2160 | .ops = &clkops_omap2_dflt, | 2149 | .ops = &clkops_omap2_dflt, |
2161 | .parent = &l4_ick, | 2150 | .parent = &l4_ick, |
2162 | .init = &omap2_init_clk_clkdm, | ||
2163 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN), | 2151 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN), |
2164 | .enable_bit = OMAP3430_EN_CAM_SHIFT, | 2152 | .enable_bit = OMAP3430_EN_CAM_SHIFT, |
2165 | .clkdm_name = "cam_clkdm", | 2153 | .clkdm_name = "cam_clkdm", |
@@ -2170,7 +2158,6 @@ static struct clk csi2_96m_fck = { | |||
2170 | .name = "csi2_96m_fck", | 2158 | .name = "csi2_96m_fck", |
2171 | .ops = &clkops_omap2_dflt, | 2159 | .ops = &clkops_omap2_dflt, |
2172 | .parent = &core_96m_fck, | 2160 | .parent = &core_96m_fck, |
2173 | .init = &omap2_init_clk_clkdm, | ||
2174 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN), | 2161 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN), |
2175 | .enable_bit = OMAP3430_EN_CSI2_SHIFT, | 2162 | .enable_bit = OMAP3430_EN_CSI2_SHIFT, |
2176 | .clkdm_name = "cam_clkdm", | 2163 | .clkdm_name = "cam_clkdm", |
@@ -2183,7 +2170,6 @@ static struct clk usbhost_120m_fck = { | |||
2183 | .name = "usbhost_120m_fck", | 2170 | .name = "usbhost_120m_fck", |
2184 | .ops = &clkops_omap2_dflt, | 2171 | .ops = &clkops_omap2_dflt, |
2185 | .parent = &dpll5_m2_ck, | 2172 | .parent = &dpll5_m2_ck, |
2186 | .init = &omap2_init_clk_clkdm, | ||
2187 | .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), | 2173 | .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), |
2188 | .enable_bit = OMAP3430ES2_EN_USBHOST2_SHIFT, | 2174 | .enable_bit = OMAP3430ES2_EN_USBHOST2_SHIFT, |
2189 | .clkdm_name = "usbhost_clkdm", | 2175 | .clkdm_name = "usbhost_clkdm", |
@@ -2194,7 +2180,6 @@ static struct clk usbhost_48m_fck = { | |||
2194 | .name = "usbhost_48m_fck", | 2180 | .name = "usbhost_48m_fck", |
2195 | .ops = &clkops_omap3430es2_dss_usbhost_wait, | 2181 | .ops = &clkops_omap3430es2_dss_usbhost_wait, |
2196 | .parent = &omap_48m_fck, | 2182 | .parent = &omap_48m_fck, |
2197 | .init = &omap2_init_clk_clkdm, | ||
2198 | .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), | 2183 | .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), |
2199 | .enable_bit = OMAP3430ES2_EN_USBHOST1_SHIFT, | 2184 | .enable_bit = OMAP3430ES2_EN_USBHOST1_SHIFT, |
2200 | .clkdm_name = "usbhost_clkdm", | 2185 | .clkdm_name = "usbhost_clkdm", |
@@ -2206,7 +2191,6 @@ static struct clk usbhost_ick = { | |||
2206 | .name = "usbhost_ick", | 2191 | .name = "usbhost_ick", |
2207 | .ops = &clkops_omap3430es2_dss_usbhost_wait, | 2192 | .ops = &clkops_omap3430es2_dss_usbhost_wait, |
2208 | .parent = &l4_ick, | 2193 | .parent = &l4_ick, |
2209 | .init = &omap2_init_clk_clkdm, | ||
2210 | .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN), | 2194 | .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN), |
2211 | .enable_bit = OMAP3430ES2_EN_USBHOST_SHIFT, | 2195 | .enable_bit = OMAP3430ES2_EN_USBHOST_SHIFT, |
2212 | .clkdm_name = "usbhost_clkdm", | 2196 | .clkdm_name = "usbhost_clkdm", |
@@ -2268,7 +2252,6 @@ static struct clk gpt1_fck = { | |||
2268 | static struct clk wkup_32k_fck = { | 2252 | static struct clk wkup_32k_fck = { |
2269 | .name = "wkup_32k_fck", | 2253 | .name = "wkup_32k_fck", |
2270 | .ops = &clkops_null, | 2254 | .ops = &clkops_null, |
2271 | .init = &omap2_init_clk_clkdm, | ||
2272 | .parent = &omap_32k_fck, | 2255 | .parent = &omap_32k_fck, |
2273 | .clkdm_name = "wkup_clkdm", | 2256 | .clkdm_name = "wkup_clkdm", |
2274 | .recalc = &followparent_recalc, | 2257 | .recalc = &followparent_recalc, |
@@ -2383,7 +2366,6 @@ static struct clk per_96m_fck = { | |||
2383 | .name = "per_96m_fck", | 2366 | .name = "per_96m_fck", |
2384 | .ops = &clkops_null, | 2367 | .ops = &clkops_null, |
2385 | .parent = &omap_96m_alwon_fck, | 2368 | .parent = &omap_96m_alwon_fck, |
2386 | .init = &omap2_init_clk_clkdm, | ||
2387 | .clkdm_name = "per_clkdm", | 2369 | .clkdm_name = "per_clkdm", |
2388 | .recalc = &followparent_recalc, | 2370 | .recalc = &followparent_recalc, |
2389 | }; | 2371 | }; |
@@ -2392,7 +2374,6 @@ static struct clk per_48m_fck = { | |||
2392 | .name = "per_48m_fck", | 2374 | .name = "per_48m_fck", |
2393 | .ops = &clkops_null, | 2375 | .ops = &clkops_null, |
2394 | .parent = &omap_48m_fck, | 2376 | .parent = &omap_48m_fck, |
2395 | .init = &omap2_init_clk_clkdm, | ||
2396 | .clkdm_name = "per_clkdm", | 2377 | .clkdm_name = "per_clkdm", |
2397 | .recalc = &followparent_recalc, | 2378 | .recalc = &followparent_recalc, |
2398 | }; | 2379 | }; |
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 0e7d501865b6..4ef7b4f5474e 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c | |||
@@ -299,7 +299,8 @@ struct clockdomain *clkdm_lookup(const char *name) | |||
299 | * anything else to indicate failure; or -EINVAL if the function pointer | 299 | * anything else to indicate failure; or -EINVAL if the function pointer |
300 | * is null. | 300 | * is null. |
301 | */ | 301 | */ |
302 | int clkdm_for_each(int (*fn)(struct clockdomain *clkdm)) | 302 | int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user), |
303 | void *user) | ||
303 | { | 304 | { |
304 | struct clockdomain *clkdm; | 305 | struct clockdomain *clkdm; |
305 | int ret = 0; | 306 | int ret = 0; |
@@ -309,7 +310,7 @@ int clkdm_for_each(int (*fn)(struct clockdomain *clkdm)) | |||
309 | 310 | ||
310 | mutex_lock(&clkdm_mutex); | 311 | mutex_lock(&clkdm_mutex); |
311 | list_for_each_entry(clkdm, &clkdm_list, node) { | 312 | list_for_each_entry(clkdm, &clkdm_list, node) { |
312 | ret = (*fn)(clkdm); | 313 | ret = (*fn)(clkdm, user); |
313 | if (ret) | 314 | if (ret) |
314 | break; | 315 | break; |
315 | } | 316 | } |
@@ -484,6 +485,8 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm) | |||
484 | v << __ffs(clkdm->clktrctrl_mask), | 485 | v << __ffs(clkdm->clktrctrl_mask), |
485 | clkdm->pwrdm.ptr->prcm_offs, | 486 | clkdm->pwrdm.ptr->prcm_offs, |
486 | CM_CLKSTCTRL); | 487 | CM_CLKSTCTRL); |
488 | |||
489 | pwrdm_clkdm_state_switch(clkdm); | ||
487 | } | 490 | } |
488 | 491 | ||
489 | /** | 492 | /** |
@@ -572,6 +575,7 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk) | |||
572 | omap2_clkdm_wakeup(clkdm); | 575 | omap2_clkdm_wakeup(clkdm); |
573 | 576 | ||
574 | pwrdm_wait_transition(clkdm->pwrdm.ptr); | 577 | pwrdm_wait_transition(clkdm->pwrdm.ptr); |
578 | pwrdm_clkdm_state_switch(clkdm); | ||
575 | 579 | ||
576 | return 0; | 580 | return 0; |
577 | } | 581 | } |
@@ -624,6 +628,8 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) | |||
624 | else | 628 | else |
625 | omap2_clkdm_sleep(clkdm); | 629 | omap2_clkdm_sleep(clkdm); |
626 | 630 | ||
631 | pwrdm_clkdm_state_switch(clkdm); | ||
632 | |||
627 | return 0; | 633 | return 0; |
628 | } | 634 | } |
629 | 635 | ||
diff --git a/arch/arm/mach-omap2/cm.c b/arch/arm/mach-omap2/cm.c new file mode 100644 index 000000000000..8eb2dab8c7db --- /dev/null +++ b/arch/arm/mach-omap2/cm.c | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * OMAP2/3 CM module functions | ||
3 | * | ||
4 | * Copyright (C) 2009 Nokia Corporation | ||
5 | * Paul Walmsley | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/spinlock.h> | ||
17 | #include <linux/list.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/err.h> | ||
20 | #include <linux/io.h> | ||
21 | |||
22 | #include <asm/atomic.h> | ||
23 | |||
24 | #include "cm.h" | ||
25 | #include "cm-regbits-24xx.h" | ||
26 | #include "cm-regbits-34xx.h" | ||
27 | |||
28 | /* MAX_MODULE_READY_TIME: max milliseconds for module to leave idle */ | ||
29 | #define MAX_MODULE_READY_TIME 20000 | ||
30 | |||
31 | static const u8 cm_idlest_offs[] = { | ||
32 | CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3 | ||
33 | }; | ||
34 | |||
35 | /** | ||
36 | * omap2_cm_wait_idlest_ready - wait for a module to leave idle or standby | ||
37 | * @prcm_mod: PRCM module offset | ||
38 | * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3) | ||
39 | * @idlest_shift: shift of the bit in the CM_IDLEST* register to check | ||
40 | * | ||
41 | * XXX document | ||
42 | */ | ||
43 | int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift) | ||
44 | { | ||
45 | int ena = 0, i = 0; | ||
46 | u8 cm_idlest_reg; | ||
47 | u32 mask; | ||
48 | |||
49 | if (!idlest_id || (idlest_id > ARRAY_SIZE(cm_idlest_offs))) | ||
50 | return -EINVAL; | ||
51 | |||
52 | cm_idlest_reg = cm_idlest_offs[idlest_id - 1]; | ||
53 | |||
54 | if (cpu_is_omap24xx()) | ||
55 | ena = idlest_shift; | ||
56 | else if (cpu_is_omap34xx()) | ||
57 | ena = 0; | ||
58 | else | ||
59 | BUG(); | ||
60 | |||
61 | mask = 1 << idlest_shift; | ||
62 | |||
63 | /* XXX should be OMAP2 CM */ | ||
64 | while (((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) != ena) && | ||
65 | (i++ < MAX_MODULE_READY_TIME)) | ||
66 | udelay(1); | ||
67 | |||
68 | return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; | ||
69 | } | ||
70 | |||
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index f3c91a1ca391..cfd0b726ba44 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h | |||
@@ -17,11 +17,11 @@ | |||
17 | #include "prcm-common.h" | 17 | #include "prcm-common.h" |
18 | 18 | ||
19 | #define OMAP2420_CM_REGADDR(module, reg) \ | 19 | #define OMAP2420_CM_REGADDR(module, reg) \ |
20 | IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg)) | 20 | OMAP2_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg)) |
21 | #define OMAP2430_CM_REGADDR(module, reg) \ | 21 | #define OMAP2430_CM_REGADDR(module, reg) \ |
22 | IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg)) | 22 | OMAP2_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg)) |
23 | #define OMAP34XX_CM_REGADDR(module, reg) \ | 23 | #define OMAP34XX_CM_REGADDR(module, reg) \ |
24 | IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg)) | 24 | OMAP2_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg)) |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * Architecture-specific global CM registers | 27 | * Architecture-specific global CM registers |
@@ -98,6 +98,10 @@ extern u32 cm_read_mod_reg(s16 module, u16 idx); | |||
98 | extern void cm_write_mod_reg(u32 val, s16 module, u16 idx); | 98 | extern void cm_write_mod_reg(u32 val, s16 module, u16 idx); |
99 | extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); | 99 | extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); |
100 | 100 | ||
101 | extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, | ||
102 | u8 idlest_shift); | ||
103 | extern int omap4_cm_wait_module_ready(u32 prcm_mod, u8 prcm_dev_offs); | ||
104 | |||
101 | static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) | 105 | static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) |
102 | { | 106 | { |
103 | return cm_rmw_mod_reg_bits(bits, bits, module, idx); | 107 | return cm_rmw_mod_reg_bits(bits, bits, module, idx); |
diff --git a/arch/arm/mach-omap2/cm4xxx.c b/arch/arm/mach-omap2/cm4xxx.c new file mode 100644 index 000000000000..e4ebd6d53135 --- /dev/null +++ b/arch/arm/mach-omap2/cm4xxx.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * OMAP4 CM module functions | ||
3 | * | ||
4 | * Copyright (C) 2009 Nokia Corporation | ||
5 | * Paul Walmsley | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/spinlock.h> | ||
17 | #include <linux/list.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/err.h> | ||
20 | #include <linux/io.h> | ||
21 | |||
22 | #include <asm/atomic.h> | ||
23 | |||
24 | #include "cm.h" | ||
25 | #include "cm-regbits-4xxx.h" | ||
26 | |||
27 | /* XXX move this to cm.h */ | ||
28 | /* MAX_MODULE_READY_TIME: max milliseconds for module to leave idle */ | ||
29 | #define MAX_MODULE_READY_TIME 20000 | ||
30 | |||
31 | /* | ||
32 | * OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK: isolates the IDLEST field in the | ||
33 | * CM_CLKCTRL register. | ||
34 | */ | ||
35 | #define OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK (0x2 << 16) | ||
36 | |||
37 | /* | ||
38 | * OMAP4 prcm_mod u32 fields contain packed data: the CM ID in bit 16 and | ||
39 | * the PRCM module offset address (from the CM module base) in bits 15-0. | ||
40 | */ | ||
41 | #define OMAP4_PRCM_MOD_CM_ID_SHIFT 16 | ||
42 | #define OMAP4_PRCM_MOD_OFFS_MASK 0xffff | ||
43 | |||
44 | /** | ||
45 | * omap4_cm_wait_idlest_ready - wait for a module to leave idle or standby | ||
46 | * @prcm_mod: PRCM module offset (XXX example) | ||
47 | * @prcm_dev_offs: PRCM device offset (e.g. MCASP XXX example) | ||
48 | * | ||
49 | * XXX document | ||
50 | */ | ||
51 | int omap4_cm_wait_idlest_ready(u32 prcm_mod, u8 prcm_dev_offs) | ||
52 | { | ||
53 | int i = 0; | ||
54 | u8 cm_id; | ||
55 | u16 prcm_mod_offs; | ||
56 | u32 mask = OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK; | ||
57 | |||
58 | cm_id = prcm_mod >> OMAP4_PRCM_MOD_CM_ID_SHIFT; | ||
59 | prcm_mod_offs = prcm_mod & OMAP4_PRCM_MOD_OFFS_MASK; | ||
60 | |||
61 | while (((omap4_cm_read_mod_reg(cm_id, prcm_mod_offs, prcm_dev_offs, | ||
62 | OMAP4_CM_CLKCTRL_DREG) & mask) != 0) && | ||
63 | (i++ < MAX_MODULE_READY_TIME)) | ||
64 | udelay(1); | ||
65 | |||
66 | return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY; | ||
67 | } | ||
68 | |||
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 894cc355818a..bcfcfc7fdb9b 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
@@ -257,6 +257,11 @@ static inline void omap_init_sti(void) {} | |||
257 | #define OMAP2_MCSPI3_BASE 0x480b8000 | 257 | #define OMAP2_MCSPI3_BASE 0x480b8000 |
258 | #define OMAP2_MCSPI4_BASE 0x480ba000 | 258 | #define OMAP2_MCSPI4_BASE 0x480ba000 |
259 | 259 | ||
260 | #define OMAP4_MCSPI1_BASE 0x48098100 | ||
261 | #define OMAP4_MCSPI2_BASE 0x4809a100 | ||
262 | #define OMAP4_MCSPI3_BASE 0x480b8100 | ||
263 | #define OMAP4_MCSPI4_BASE 0x480ba100 | ||
264 | |||
260 | static struct omap2_mcspi_platform_config omap2_mcspi1_config = { | 265 | static struct omap2_mcspi_platform_config omap2_mcspi1_config = { |
261 | .num_cs = 4, | 266 | .num_cs = 4, |
262 | }; | 267 | }; |
@@ -301,7 +306,8 @@ static struct platform_device omap2_mcspi2 = { | |||
301 | }, | 306 | }, |
302 | }; | 307 | }; |
303 | 308 | ||
304 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) | 309 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ |
310 | defined(CONFIG_ARCH_OMAP4) | ||
305 | static struct omap2_mcspi_platform_config omap2_mcspi3_config = { | 311 | static struct omap2_mcspi_platform_config omap2_mcspi3_config = { |
306 | .num_cs = 2, | 312 | .num_cs = 2, |
307 | }; | 313 | }; |
@@ -325,7 +331,7 @@ static struct platform_device omap2_mcspi3 = { | |||
325 | }; | 331 | }; |
326 | #endif | 332 | #endif |
327 | 333 | ||
328 | #ifdef CONFIG_ARCH_OMAP3 | 334 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) |
329 | static struct omap2_mcspi_platform_config omap2_mcspi4_config = { | 335 | static struct omap2_mcspi_platform_config omap2_mcspi4_config = { |
330 | .num_cs = 1, | 336 | .num_cs = 1, |
331 | }; | 337 | }; |
@@ -351,14 +357,25 @@ static struct platform_device omap2_mcspi4 = { | |||
351 | 357 | ||
352 | static void omap_init_mcspi(void) | 358 | static void omap_init_mcspi(void) |
353 | { | 359 | { |
360 | if (cpu_is_omap44xx()) { | ||
361 | omap2_mcspi1_resources[0].start = OMAP4_MCSPI1_BASE; | ||
362 | omap2_mcspi1_resources[0].end = OMAP4_MCSPI1_BASE + 0xff; | ||
363 | omap2_mcspi2_resources[0].start = OMAP4_MCSPI2_BASE; | ||
364 | omap2_mcspi2_resources[0].end = OMAP4_MCSPI2_BASE + 0xff; | ||
365 | omap2_mcspi3_resources[0].start = OMAP4_MCSPI3_BASE; | ||
366 | omap2_mcspi3_resources[0].end = OMAP4_MCSPI3_BASE + 0xff; | ||
367 | omap2_mcspi4_resources[0].start = OMAP4_MCSPI4_BASE; | ||
368 | omap2_mcspi4_resources[0].end = OMAP4_MCSPI4_BASE + 0xff; | ||
369 | } | ||
354 | platform_device_register(&omap2_mcspi1); | 370 | platform_device_register(&omap2_mcspi1); |
355 | platform_device_register(&omap2_mcspi2); | 371 | platform_device_register(&omap2_mcspi2); |
356 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) | 372 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ |
357 | if (cpu_is_omap2430() || cpu_is_omap343x()) | 373 | defined(CONFIG_ARCH_OMAP4) |
374 | if (cpu_is_omap2430() || cpu_is_omap343x() || cpu_is_omap44xx()) | ||
358 | platform_device_register(&omap2_mcspi3); | 375 | platform_device_register(&omap2_mcspi3); |
359 | #endif | 376 | #endif |
360 | #ifdef CONFIG_ARCH_OMAP3 | 377 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) |
361 | if (cpu_is_omap343x()) | 378 | if (cpu_is_omap343x() || cpu_is_omap44xx()) |
362 | platform_device_register(&omap2_mcspi4); | 379 | platform_device_register(&omap2_mcspi4); |
363 | #endif | 380 | #endif |
364 | } | 381 | } |
@@ -397,7 +414,7 @@ static inline void omap_init_sha1_md5(void) { } | |||
397 | 414 | ||
398 | /*-------------------------------------------------------------------------*/ | 415 | /*-------------------------------------------------------------------------*/ |
399 | 416 | ||
400 | #ifdef CONFIG_ARCH_OMAP3 | 417 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) |
401 | 418 | ||
402 | #define MMCHS_SYSCONFIG 0x0010 | 419 | #define MMCHS_SYSCONFIG 0x0010 |
403 | #define MMCHS_SYSCONFIG_SWRESET (1 << 1) | 420 | #define MMCHS_SYSCONFIG_SWRESET (1 << 1) |
@@ -424,8 +441,8 @@ static struct platform_device dummy_pdev = { | |||
424 | **/ | 441 | **/ |
425 | static void __init omap_hsmmc_reset(void) | 442 | static void __init omap_hsmmc_reset(void) |
426 | { | 443 | { |
427 | u32 i, nr_controllers = cpu_is_omap34xx() ? OMAP34XX_NR_MMC : | 444 | u32 i, nr_controllers = cpu_is_omap44xx() ? OMAP44XX_NR_MMC : |
428 | OMAP24XX_NR_MMC; | 445 | (cpu_is_omap34xx() ? OMAP34XX_NR_MMC : OMAP24XX_NR_MMC); |
429 | 446 | ||
430 | for (i = 0; i < nr_controllers; i++) { | 447 | for (i = 0; i < nr_controllers; i++) { |
431 | u32 v, base = 0; | 448 | u32 v, base = 0; |
@@ -442,8 +459,21 @@ static void __init omap_hsmmc_reset(void) | |||
442 | case 2: | 459 | case 2: |
443 | base = OMAP3_MMC3_BASE; | 460 | base = OMAP3_MMC3_BASE; |
444 | break; | 461 | break; |
462 | case 3: | ||
463 | if (!cpu_is_omap44xx()) | ||
464 | return; | ||
465 | base = OMAP4_MMC4_BASE; | ||
466 | break; | ||
467 | case 4: | ||
468 | if (!cpu_is_omap44xx()) | ||
469 | return; | ||
470 | base = OMAP4_MMC5_BASE; | ||
471 | break; | ||
445 | } | 472 | } |
446 | 473 | ||
474 | if (cpu_is_omap44xx()) | ||
475 | base += OMAP4_MMC_REG_OFFSET; | ||
476 | |||
447 | dummy_pdev.id = i; | 477 | dummy_pdev.id = i; |
448 | dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%d", i); | 478 | dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%d", i); |
449 | iclk = clk_get(dev, "ick"); | 479 | iclk = clk_get(dev, "ick"); |
@@ -513,6 +543,47 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, | |||
513 | omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); | 543 | omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); |
514 | } | 544 | } |
515 | } | 545 | } |
546 | |||
547 | if (cpu_is_omap3430()) { | ||
548 | if (controller_nr == 0) { | ||
549 | omap_cfg_reg(N28_3430_MMC1_CLK); | ||
550 | omap_cfg_reg(M27_3430_MMC1_CMD); | ||
551 | omap_cfg_reg(N27_3430_MMC1_DAT0); | ||
552 | if (mmc_controller->slots[0].wires == 4 || | ||
553 | mmc_controller->slots[0].wires == 8) { | ||
554 | omap_cfg_reg(N26_3430_MMC1_DAT1); | ||
555 | omap_cfg_reg(N25_3430_MMC1_DAT2); | ||
556 | omap_cfg_reg(P28_3430_MMC1_DAT3); | ||
557 | } | ||
558 | if (mmc_controller->slots[0].wires == 8) { | ||
559 | omap_cfg_reg(P27_3430_MMC1_DAT4); | ||
560 | omap_cfg_reg(P26_3430_MMC1_DAT5); | ||
561 | omap_cfg_reg(R27_3430_MMC1_DAT6); | ||
562 | omap_cfg_reg(R25_3430_MMC1_DAT7); | ||
563 | } | ||
564 | } | ||
565 | if (controller_nr == 1) { | ||
566 | /* MMC2 */ | ||
567 | omap_cfg_reg(AE2_3430_MMC2_CLK); | ||
568 | omap_cfg_reg(AG5_3430_MMC2_CMD); | ||
569 | omap_cfg_reg(AH5_3430_MMC2_DAT0); | ||
570 | |||
571 | /* | ||
572 | * For 8 wire configurations, Lines DAT4, 5, 6 and 7 need to be muxed | ||
573 | * in the board-*.c files | ||
574 | */ | ||
575 | if (mmc_controller->slots[0].wires == 4 || | ||
576 | mmc_controller->slots[0].wires == 8) { | ||
577 | omap_cfg_reg(AH4_3430_MMC2_DAT1); | ||
578 | omap_cfg_reg(AG4_3430_MMC2_DAT2); | ||
579 | omap_cfg_reg(AF4_3430_MMC2_DAT3); | ||
580 | } | ||
581 | } | ||
582 | |||
583 | /* | ||
584 | * For MMC3 the pins need to be muxed in the board-*.c files | ||
585 | */ | ||
586 | } | ||
516 | } | 587 | } |
517 | 588 | ||
518 | void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, | 589 | void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, |
@@ -540,11 +611,23 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, | |||
540 | irq = INT_24XX_MMC2_IRQ; | 611 | irq = INT_24XX_MMC2_IRQ; |
541 | break; | 612 | break; |
542 | case 2: | 613 | case 2: |
543 | if (!cpu_is_omap34xx()) | 614 | if (!cpu_is_omap44xx() && !cpu_is_omap34xx()) |
544 | return; | 615 | return; |
545 | base = OMAP3_MMC3_BASE; | 616 | base = OMAP3_MMC3_BASE; |
546 | irq = INT_34XX_MMC3_IRQ; | 617 | irq = INT_34XX_MMC3_IRQ; |
547 | break; | 618 | break; |
619 | case 3: | ||
620 | if (!cpu_is_omap44xx()) | ||
621 | return; | ||
622 | base = OMAP4_MMC4_BASE + OMAP4_MMC_REG_OFFSET; | ||
623 | irq = INT_44XX_MMC4_IRQ; | ||
624 | break; | ||
625 | case 4: | ||
626 | if (!cpu_is_omap44xx()) | ||
627 | return; | ||
628 | base = OMAP4_MMC5_BASE + OMAP4_MMC_REG_OFFSET; | ||
629 | irq = INT_44XX_MMC5_IRQ; | ||
630 | break; | ||
548 | default: | 631 | default: |
549 | continue; | 632 | continue; |
550 | } | 633 | } |
@@ -552,8 +635,15 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, | |||
552 | if (cpu_is_omap2420()) { | 635 | if (cpu_is_omap2420()) { |
553 | size = OMAP2420_MMC_SIZE; | 636 | size = OMAP2420_MMC_SIZE; |
554 | name = "mmci-omap"; | 637 | name = "mmci-omap"; |
638 | } else if (cpu_is_omap44xx()) { | ||
639 | if (i < 3) { | ||
640 | base += OMAP4_MMC_REG_OFFSET; | ||
641 | irq += IRQ_GIC_START; | ||
642 | } | ||
643 | size = OMAP4_HSMMC_SIZE; | ||
644 | name = "mmci-omap-hs"; | ||
555 | } else { | 645 | } else { |
556 | size = HSMMC_SIZE; | 646 | size = OMAP3_HSMMC_SIZE; |
557 | name = "mmci-omap-hs"; | 647 | name = "mmci-omap-hs"; |
558 | } | 648 | } |
559 | omap_mmc_add(name, i, base, size, irq, mmc_data[i]); | 649 | omap_mmc_add(name, i, base, size, irq, mmc_data[i]); |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index f91934b2b092..15876828db23 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -57,6 +57,11 @@ | |||
57 | #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ | 57 | #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ |
58 | #define GPMC_SECTION_SHIFT 28 /* 128 MB */ | 58 | #define GPMC_SECTION_SHIFT 28 /* 128 MB */ |
59 | 59 | ||
60 | #define PREFETCH_FIFOTHRESHOLD (0x40 << 8) | ||
61 | #define CS_NUM_SHIFT 24 | ||
62 | #define ENABLE_PREFETCH (0x1 << 7) | ||
63 | #define DMA_MPU_MODE 2 | ||
64 | |||
60 | static struct resource gpmc_mem_root; | 65 | static struct resource gpmc_mem_root; |
61 | static struct resource gpmc_cs_mem[GPMC_CS_NUM]; | 66 | static struct resource gpmc_cs_mem[GPMC_CS_NUM]; |
62 | static DEFINE_SPINLOCK(gpmc_mem_lock); | 67 | static DEFINE_SPINLOCK(gpmc_mem_lock); |
@@ -386,6 +391,63 @@ void gpmc_cs_free(int cs) | |||
386 | } | 391 | } |
387 | EXPORT_SYMBOL(gpmc_cs_free); | 392 | EXPORT_SYMBOL(gpmc_cs_free); |
388 | 393 | ||
394 | /** | ||
395 | * gpmc_prefetch_enable - configures and starts prefetch transfer | ||
396 | * @cs: nand cs (chip select) number | ||
397 | * @dma_mode: dma mode enable (1) or disable (0) | ||
398 | * @u32_count: number of bytes to be transferred | ||
399 | * @is_write: prefetch read(0) or write post(1) mode | ||
400 | */ | ||
401 | int gpmc_prefetch_enable(int cs, int dma_mode, | ||
402 | unsigned int u32_count, int is_write) | ||
403 | { | ||
404 | uint32_t prefetch_config1; | ||
405 | |||
406 | if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { | ||
407 | /* Set the amount of bytes to be prefetched */ | ||
408 | gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); | ||
409 | |||
410 | /* Set dma/mpu mode, the prefetch read / post write and | ||
411 | * enable the engine. Set which cs is has requested for. | ||
412 | */ | ||
413 | prefetch_config1 = ((cs << CS_NUM_SHIFT) | | ||
414 | PREFETCH_FIFOTHRESHOLD | | ||
415 | ENABLE_PREFETCH | | ||
416 | (dma_mode << DMA_MPU_MODE) | | ||
417 | (0x1 & is_write)); | ||
418 | gpmc_write_reg(GPMC_PREFETCH_CONFIG1, prefetch_config1); | ||
419 | } else { | ||
420 | return -EBUSY; | ||
421 | } | ||
422 | /* Start the prefetch engine */ | ||
423 | gpmc_write_reg(GPMC_PREFETCH_CONTROL, 0x1); | ||
424 | |||
425 | return 0; | ||
426 | } | ||
427 | EXPORT_SYMBOL(gpmc_prefetch_enable); | ||
428 | |||
429 | /** | ||
430 | * gpmc_prefetch_reset - disables and stops the prefetch engine | ||
431 | */ | ||
432 | void gpmc_prefetch_reset(void) | ||
433 | { | ||
434 | /* Stop the PFPW engine */ | ||
435 | gpmc_write_reg(GPMC_PREFETCH_CONTROL, 0x0); | ||
436 | |||
437 | /* Reset/disable the PFPW engine */ | ||
438 | gpmc_write_reg(GPMC_PREFETCH_CONFIG1, 0x0); | ||
439 | } | ||
440 | EXPORT_SYMBOL(gpmc_prefetch_reset); | ||
441 | |||
442 | /** | ||
443 | * gpmc_prefetch_status - reads prefetch status of engine | ||
444 | */ | ||
445 | int gpmc_prefetch_status(void) | ||
446 | { | ||
447 | return gpmc_read_reg(GPMC_PREFETCH_STATUS); | ||
448 | } | ||
449 | EXPORT_SYMBOL(gpmc_prefetch_status); | ||
450 | |||
389 | static void __init gpmc_mem_init(void) | 451 | static void __init gpmc_mem_init(void) |
390 | { | 452 | { |
391 | int cs; | 453 | int cs; |
@@ -452,6 +514,5 @@ void __init gpmc_init(void) | |||
452 | l &= 0x03 << 3; | 514 | l &= 0x03 << 3; |
453 | l |= (0x02 << 3) | (1 << 0); | 515 | l |= (0x02 << 3) | (1 << 0); |
454 | gpmc_write_reg(GPMC_SYSCONFIG, l); | 516 | gpmc_write_reg(GPMC_SYSCONFIG, l); |
455 | |||
456 | gpmc_mem_init(); | 517 | gpmc_mem_init(); |
457 | } | 518 | } |
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index e9b9bcb19b4e..7574b6f20e8e 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c | |||
@@ -32,17 +32,23 @@ | |||
32 | #include <mach/sram.h> | 32 | #include <mach/sram.h> |
33 | #include <mach/sdrc.h> | 33 | #include <mach/sdrc.h> |
34 | #include <mach/gpmc.h> | 34 | #include <mach/gpmc.h> |
35 | #include <mach/serial.h> | ||
35 | 36 | ||
36 | #ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdev is ready */ | 37 | #ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdev is ready */ |
37 | #include "clock.h" | 38 | #include "clock.h" |
38 | 39 | ||
40 | #include <mach/omap-pm.h> | ||
39 | #include <mach/powerdomain.h> | 41 | #include <mach/powerdomain.h> |
40 | |||
41 | #include "powerdomains.h" | 42 | #include "powerdomains.h" |
42 | 43 | ||
43 | #include <mach/clockdomain.h> | 44 | #include <mach/clockdomain.h> |
44 | #include "clockdomains.h" | 45 | #include "clockdomains.h" |
45 | #endif | 46 | #endif |
47 | #include <mach/omap_hwmod.h> | ||
48 | #include "omap_hwmod_2420.h" | ||
49 | #include "omap_hwmod_2430.h" | ||
50 | #include "omap_hwmod_34xx.h" | ||
51 | |||
46 | /* | 52 | /* |
47 | * The machine specific code may provide the extra mapping besides the | 53 | * The machine specific code may provide the extra mapping besides the |
48 | * default mapping provided here. | 54 | * default mapping provided here. |
@@ -279,11 +285,26 @@ static int __init _omap2_init_reprogram_sdrc(void) | |||
279 | void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, | 285 | void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, |
280 | struct omap_sdrc_params *sdrc_cs1) | 286 | struct omap_sdrc_params *sdrc_cs1) |
281 | { | 287 | { |
288 | struct omap_hwmod **hwmods = NULL; | ||
289 | |||
290 | if (cpu_is_omap2420()) | ||
291 | hwmods = omap2420_hwmods; | ||
292 | else if (cpu_is_omap2430()) | ||
293 | hwmods = omap2430_hwmods; | ||
294 | else if (cpu_is_omap34xx()) | ||
295 | hwmods = omap34xx_hwmods; | ||
296 | |||
297 | omap_hwmod_init(hwmods); | ||
282 | omap2_mux_init(); | 298 | omap2_mux_init(); |
283 | #ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */ | 299 | #ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */ |
300 | /* The OPP tables have to be registered before a clk init */ | ||
301 | omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps); | ||
284 | pwrdm_init(powerdomains_omap); | 302 | pwrdm_init(powerdomains_omap); |
285 | clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps); | 303 | clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps); |
286 | omap2_clk_init(); | 304 | omap2_clk_init(); |
305 | omap_serial_early_init(); | ||
306 | omap_hwmod_late_init(); | ||
307 | omap_pm_if_init(); | ||
287 | omap2_sdrc_init(sdrc_cs0, sdrc_cs1); | 308 | omap2_sdrc_init(sdrc_cs0, sdrc_cs1); |
288 | _omap2_init_reprogram_sdrc(); | 309 | _omap2_init_reprogram_sdrc(); |
289 | #endif | 310 | #endif |
diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c index 015f22a53ead..2d9b5cc981cd 100644 --- a/arch/arm/mach-omap2/iommu2.c +++ b/arch/arm/mach-omap2/iommu2.c | |||
@@ -217,10 +217,19 @@ static ssize_t omap2_dump_cr(struct iommu *obj, struct cr_regs *cr, char *buf) | |||
217 | } | 217 | } |
218 | 218 | ||
219 | #define pr_reg(name) \ | 219 | #define pr_reg(name) \ |
220 | p += sprintf(p, "%20s: %08x\n", \ | 220 | do { \ |
221 | __stringify(name), iommu_read_reg(obj, MMU_##name)); | 221 | ssize_t bytes; \ |
222 | 222 | const char *str = "%20s: %08x\n"; \ | |
223 | static ssize_t omap2_iommu_dump_ctx(struct iommu *obj, char *buf) | 223 | const int maxcol = 32; \ |
224 | bytes = snprintf(p, maxcol, str, __stringify(name), \ | ||
225 | iommu_read_reg(obj, MMU_##name)); \ | ||
226 | p += bytes; \ | ||
227 | len -= bytes; \ | ||
228 | if (len < maxcol) \ | ||
229 | goto out; \ | ||
230 | } while (0) | ||
231 | |||
232 | static ssize_t omap2_iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t len) | ||
224 | { | 233 | { |
225 | char *p = buf; | 234 | char *p = buf; |
226 | 235 | ||
@@ -242,7 +251,7 @@ static ssize_t omap2_iommu_dump_ctx(struct iommu *obj, char *buf) | |||
242 | pr_reg(READ_CAM); | 251 | pr_reg(READ_CAM); |
243 | pr_reg(READ_RAM); | 252 | pr_reg(READ_RAM); |
244 | pr_reg(EMU_FAULT_AD); | 253 | pr_reg(EMU_FAULT_AD); |
245 | 254 | out: | |
246 | return p - buf; | 255 | return p - buf; |
247 | } | 256 | } |
248 | 257 | ||
diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c index 3c04c2f1b23f..c9c59a2db4e2 100644 --- a/arch/arm/mach-omap2/mmc-twl4030.c +++ b/arch/arm/mach-omap2/mmc-twl4030.c | |||
@@ -198,6 +198,18 @@ static int twl_mmc_resume(struct device *dev, int slot) | |||
198 | #define twl_mmc_resume NULL | 198 | #define twl_mmc_resume NULL |
199 | #endif | 199 | #endif |
200 | 200 | ||
201 | #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) | ||
202 | |||
203 | static int twl4030_mmc_get_context_loss(struct device *dev) | ||
204 | { | ||
205 | /* FIXME: PM DPS not implemented yet */ | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | #else | ||
210 | #define twl4030_mmc_get_context_loss NULL | ||
211 | #endif | ||
212 | |||
201 | static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, | 213 | static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, |
202 | int vdd) | 214 | int vdd) |
203 | { | 215 | { |
@@ -328,6 +340,61 @@ static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int v | |||
328 | return ret; | 340 | return ret; |
329 | } | 341 | } |
330 | 342 | ||
343 | static int twl_mmc1_set_sleep(struct device *dev, int slot, int sleep, int vdd, | ||
344 | int cardsleep) | ||
345 | { | ||
346 | struct twl_mmc_controller *c = &hsmmc[0]; | ||
347 | int mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL; | ||
348 | |||
349 | return regulator_set_mode(c->vcc, mode); | ||
350 | } | ||
351 | |||
352 | static int twl_mmc23_set_sleep(struct device *dev, int slot, int sleep, int vdd, | ||
353 | int cardsleep) | ||
354 | { | ||
355 | struct twl_mmc_controller *c = NULL; | ||
356 | struct omap_mmc_platform_data *mmc = dev->platform_data; | ||
357 | int i, err, mode; | ||
358 | |||
359 | for (i = 1; i < ARRAY_SIZE(hsmmc); i++) { | ||
360 | if (mmc == hsmmc[i].mmc) { | ||
361 | c = &hsmmc[i]; | ||
362 | break; | ||
363 | } | ||
364 | } | ||
365 | |||
366 | if (c == NULL) | ||
367 | return -ENODEV; | ||
368 | |||
369 | /* | ||
370 | * If we don't see a Vcc regulator, assume it's a fixed | ||
371 | * voltage always-on regulator. | ||
372 | */ | ||
373 | if (!c->vcc) | ||
374 | return 0; | ||
375 | |||
376 | mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL; | ||
377 | |||
378 | if (!c->vcc_aux) | ||
379 | return regulator_set_mode(c->vcc, mode); | ||
380 | |||
381 | if (cardsleep) { | ||
382 | /* VCC can be turned off if card is asleep */ | ||
383 | struct regulator *vcc_aux = c->vcc_aux; | ||
384 | |||
385 | c->vcc_aux = NULL; | ||
386 | if (sleep) | ||
387 | err = twl_mmc23_set_power(dev, slot, 0, 0); | ||
388 | else | ||
389 | err = twl_mmc23_set_power(dev, slot, 1, vdd); | ||
390 | c->vcc_aux = vcc_aux; | ||
391 | } else | ||
392 | err = regulator_set_mode(c->vcc, mode); | ||
393 | if (err) | ||
394 | return err; | ||
395 | return regulator_set_mode(c->vcc_aux, mode); | ||
396 | } | ||
397 | |||
331 | static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; | 398 | static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; |
332 | 399 | ||
333 | void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | 400 | void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) |
@@ -390,6 +457,9 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | |||
390 | } else | 457 | } else |
391 | mmc->slots[0].switch_pin = -EINVAL; | 458 | mmc->slots[0].switch_pin = -EINVAL; |
392 | 459 | ||
460 | mmc->get_context_loss_count = | ||
461 | twl4030_mmc_get_context_loss; | ||
462 | |||
393 | /* write protect normally uses an OMAP gpio */ | 463 | /* write protect normally uses an OMAP gpio */ |
394 | if (gpio_is_valid(c->gpio_wp)) { | 464 | if (gpio_is_valid(c->gpio_wp)) { |
395 | gpio_request(c->gpio_wp, "mmc_wp"); | 465 | gpio_request(c->gpio_wp, "mmc_wp"); |
@@ -400,6 +470,12 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | |||
400 | } else | 470 | } else |
401 | mmc->slots[0].gpio_wp = -EINVAL; | 471 | mmc->slots[0].gpio_wp = -EINVAL; |
402 | 472 | ||
473 | if (c->nonremovable) | ||
474 | mmc->slots[0].nonremovable = 1; | ||
475 | |||
476 | if (c->power_saving) | ||
477 | mmc->slots[0].power_saving = 1; | ||
478 | |||
403 | /* NOTE: MMC slots should have a Vcc regulator set up. | 479 | /* NOTE: MMC slots should have a Vcc regulator set up. |
404 | * This may be from a TWL4030-family chip, another | 480 | * This may be from a TWL4030-family chip, another |
405 | * controllable regulator, or a fixed supply. | 481 | * controllable regulator, or a fixed supply. |
@@ -412,6 +488,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | |||
412 | case 1: | 488 | case 1: |
413 | /* on-chip level shifting via PBIAS0/PBIAS1 */ | 489 | /* on-chip level shifting via PBIAS0/PBIAS1 */ |
414 | mmc->slots[0].set_power = twl_mmc1_set_power; | 490 | mmc->slots[0].set_power = twl_mmc1_set_power; |
491 | mmc->slots[0].set_sleep = twl_mmc1_set_sleep; | ||
415 | break; | 492 | break; |
416 | case 2: | 493 | case 2: |
417 | if (c->ext_clock) | 494 | if (c->ext_clock) |
@@ -422,6 +499,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | |||
422 | case 3: | 499 | case 3: |
423 | /* off-chip level shifting, or none */ | 500 | /* off-chip level shifting, or none */ |
424 | mmc->slots[0].set_power = twl_mmc23_set_power; | 501 | mmc->slots[0].set_power = twl_mmc23_set_power; |
502 | mmc->slots[0].set_sleep = twl_mmc23_set_sleep; | ||
425 | break; | 503 | break; |
426 | default: | 504 | default: |
427 | pr_err("MMC%d configuration not supported!\n", c->mmc); | 505 | pr_err("MMC%d configuration not supported!\n", c->mmc); |
diff --git a/arch/arm/mach-omap2/mmc-twl4030.h b/arch/arm/mach-omap2/mmc-twl4030.h index 3807c45c9a6c..a47e68563fb6 100644 --- a/arch/arm/mach-omap2/mmc-twl4030.h +++ b/arch/arm/mach-omap2/mmc-twl4030.h | |||
@@ -12,6 +12,8 @@ struct twl4030_hsmmc_info { | |||
12 | bool transceiver; /* MMC-2 option */ | 12 | bool transceiver; /* MMC-2 option */ |
13 | bool ext_clock; /* use external pin for input clock */ | 13 | bool ext_clock; /* use external pin for input clock */ |
14 | bool cover_only; /* No card detect - just cover switch */ | 14 | bool cover_only; /* No card detect - just cover switch */ |
15 | bool nonremovable; /* Nonremovable e.g. eMMC */ | ||
16 | bool power_saving; /* Try to sleep or power off when possible */ | ||
15 | int gpio_cd; /* or -EINVAL */ | 17 | int gpio_cd; /* or -EINVAL */ |
16 | int gpio_wp; /* or -EINVAL */ | 18 | int gpio_wp; /* or -EINVAL */ |
17 | char *name; /* or NULL for default */ | 19 | char *name; /* or NULL for default */ |
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 43d6b92b65f2..2daa595aaff4 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c | |||
@@ -492,6 +492,61 @@ MUX_CFG_34XX("H16_34XX_SDRC_CKE0", 0x262, | |||
492 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) | 492 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) |
493 | MUX_CFG_34XX("H17_34XX_SDRC_CKE1", 0x264, | 493 | MUX_CFG_34XX("H17_34XX_SDRC_CKE1", 0x264, |
494 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) | 494 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT) |
495 | |||
496 | /* MMC1 */ | ||
497 | MUX_CFG_34XX("N28_3430_MMC1_CLK", 0x144, | ||
498 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
499 | MUX_CFG_34XX("M27_3430_MMC1_CMD", 0x146, | ||
500 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
501 | MUX_CFG_34XX("N27_3430_MMC1_DAT0", 0x148, | ||
502 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
503 | MUX_CFG_34XX("N26_3430_MMC1_DAT1", 0x14a, | ||
504 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
505 | MUX_CFG_34XX("N25_3430_MMC1_DAT2", 0x14c, | ||
506 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
507 | MUX_CFG_34XX("P28_3430_MMC1_DAT3", 0x14e, | ||
508 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
509 | MUX_CFG_34XX("P27_3430_MMC1_DAT4", 0x150, | ||
510 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
511 | MUX_CFG_34XX("P26_3430_MMC1_DAT5", 0x152, | ||
512 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
513 | MUX_CFG_34XX("R27_3430_MMC1_DAT6", 0x154, | ||
514 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
515 | MUX_CFG_34XX("R25_3430_MMC1_DAT7", 0x156, | ||
516 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
517 | |||
518 | /* MMC2 */ | ||
519 | MUX_CFG_34XX("AE2_3430_MMC2_CLK", 0x158, | ||
520 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
521 | MUX_CFG_34XX("AG5_3430_MMC2_CMD", 0x15A, | ||
522 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
523 | MUX_CFG_34XX("AH5_3430_MMC2_DAT0", 0x15c, | ||
524 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
525 | MUX_CFG_34XX("AH4_3430_MMC2_DAT1", 0x15e, | ||
526 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
527 | MUX_CFG_34XX("AG4_3430_MMC2_DAT2", 0x160, | ||
528 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
529 | MUX_CFG_34XX("AF4_3430_MMC2_DAT3", 0x162, | ||
530 | OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP) | ||
531 | |||
532 | /* MMC3 */ | ||
533 | MUX_CFG_34XX("AF10_3430_MMC3_CLK", 0x5d8, | ||
534 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP) | ||
535 | MUX_CFG_34XX("AC3_3430_MMC3_CMD", 0x1d0, | ||
536 | OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLUP) | ||
537 | MUX_CFG_34XX("AE11_3430_MMC3_DAT0", 0x5e4, | ||
538 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP) | ||
539 | MUX_CFG_34XX("AH9_3430_MMC3_DAT1", 0x5e6, | ||
540 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP) | ||
541 | MUX_CFG_34XX("AF13_3430_MMC3_DAT2", 0x5e8, | ||
542 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP) | ||
543 | MUX_CFG_34XX("AF13_3430_MMC3_DAT3", 0x5e2, | ||
544 | OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP) | ||
545 | |||
546 | /* SYS_NIRQ T2 INT1 */ | ||
547 | MUX_CFG_34XX("AF26_34XX_SYS_NIRQ", 0x1E0, | ||
548 | OMAP3_WAKEUP_EN | OMAP34XX_PIN_INPUT_PULLUP | | ||
549 | OMAP34XX_MUX_MODE0) | ||
495 | }; | 550 | }; |
496 | 551 | ||
497 | #define OMAP34XX_PINS_SZ ARRAY_SIZE(omap34xx_pins) | 552 | #define OMAP34XX_PINS_SZ ARRAY_SIZE(omap34xx_pins) |
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 8fe8d230f21b..48ee295db275 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c | |||
@@ -54,7 +54,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu) | |||
54 | * for us: do so | 54 | * for us: do so |
55 | */ | 55 | */ |
56 | 56 | ||
57 | gic_cpu_init(0, IO_ADDRESS(OMAP44XX_GIC_CPU_BASE)); | 57 | gic_cpu_init(0, OMAP2_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE)); |
58 | 58 | ||
59 | /* | 59 | /* |
60 | * Synchronise with the boot thread. | 60 | * Synchronise with the boot thread. |
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c new file mode 100644 index 000000000000..d2e0f1c95961 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -0,0 +1,1554 @@ | |||
1 | /* | ||
2 | * omap_hwmod implementation for OMAP2/3/4 | ||
3 | * | ||
4 | * Copyright (C) 2009 Nokia Corporation | ||
5 | * Paul Walmsley | ||
6 | * With fixes and testing from Kevin Hilman | ||
7 | * | ||
8 | * Created in collaboration with (alphabetical order): Benoit Cousson, | ||
9 | * Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari | ||
10 | * Poussa, Anand Sawant, Santosh Shilimkar, Richard Woodruff | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | * | ||
16 | * This code manages "OMAP modules" (on-chip devices) and their | ||
17 | * integration with Linux device driver and bus code. | ||
18 | * | ||
19 | * References: | ||
20 | * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064) | ||
21 | * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090) | ||
22 | * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108) | ||
23 | * - OMAP4430 Multimedia Device Silicon Revision 1.0 (SWPU140) | ||
24 | * - Open Core Protocol Specification 2.2 | ||
25 | * | ||
26 | * To do: | ||
27 | * - pin mux handling | ||
28 | * - handle IO mapping | ||
29 | * - bus throughput & module latency measurement code | ||
30 | * | ||
31 | * XXX add tests at the beginning of each function to ensure the hwmod is | ||
32 | * in the appropriate state | ||
33 | * XXX error return values should be checked to ensure that they are | ||
34 | * appropriate | ||
35 | */ | ||
36 | #undef DEBUG | ||
37 | |||
38 | #include <linux/kernel.h> | ||
39 | #include <linux/errno.h> | ||
40 | #include <linux/io.h> | ||
41 | #include <linux/clk.h> | ||
42 | #include <linux/delay.h> | ||
43 | #include <linux/err.h> | ||
44 | #include <linux/list.h> | ||
45 | #include <linux/mutex.h> | ||
46 | #include <linux/bootmem.h> | ||
47 | |||
48 | #include <mach/cpu.h> | ||
49 | #include <mach/clockdomain.h> | ||
50 | #include <mach/powerdomain.h> | ||
51 | #include <mach/clock.h> | ||
52 | #include <mach/omap_hwmod.h> | ||
53 | |||
54 | #include "cm.h" | ||
55 | |||
56 | /* Maximum microseconds to wait for OMAP module to reset */ | ||
57 | #define MAX_MODULE_RESET_WAIT 10000 | ||
58 | |||
59 | /* Name of the OMAP hwmod for the MPU */ | ||
60 | #define MPU_INITIATOR_NAME "mpu_hwmod" | ||
61 | |||
62 | /* omap_hwmod_list contains all registered struct omap_hwmods */ | ||
63 | static LIST_HEAD(omap_hwmod_list); | ||
64 | |||
65 | static DEFINE_MUTEX(omap_hwmod_mutex); | ||
66 | |||
67 | /* mpu_oh: used to add/remove MPU initiator from sleepdep list */ | ||
68 | static struct omap_hwmod *mpu_oh; | ||
69 | |||
70 | /* inited: 0 if omap_hwmod_init() has not yet been called; 1 otherwise */ | ||
71 | static u8 inited; | ||
72 | |||
73 | |||
74 | /* Private functions */ | ||
75 | |||
76 | /** | ||
77 | * _update_sysc_cache - return the module OCP_SYSCONFIG register, keep copy | ||
78 | * @oh: struct omap_hwmod * | ||
79 | * | ||
80 | * Load the current value of the hwmod OCP_SYSCONFIG register into the | ||
81 | * struct omap_hwmod for later use. Returns -EINVAL if the hwmod has no | ||
82 | * OCP_SYSCONFIG register or 0 upon success. | ||
83 | */ | ||
84 | static int _update_sysc_cache(struct omap_hwmod *oh) | ||
85 | { | ||
86 | if (!oh->sysconfig) { | ||
87 | WARN(!oh->sysconfig, "omap_hwmod: %s: cannot read " | ||
88 | "OCP_SYSCONFIG: not defined on hwmod\n", oh->name); | ||
89 | return -EINVAL; | ||
90 | } | ||
91 | |||
92 | /* XXX ensure module interface clock is up */ | ||
93 | |||
94 | oh->_sysc_cache = omap_hwmod_readl(oh, oh->sysconfig->sysc_offs); | ||
95 | |||
96 | oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED; | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | /** | ||
102 | * _write_sysconfig - write a value to the module's OCP_SYSCONFIG register | ||
103 | * @v: OCP_SYSCONFIG value to write | ||
104 | * @oh: struct omap_hwmod * | ||
105 | * | ||
106 | * Write @v into the module OCP_SYSCONFIG register, if it has one. No | ||
107 | * return value. | ||
108 | */ | ||
109 | static void _write_sysconfig(u32 v, struct omap_hwmod *oh) | ||
110 | { | ||
111 | if (!oh->sysconfig) { | ||
112 | WARN(!oh->sysconfig, "omap_hwmod: %s: cannot write " | ||
113 | "OCP_SYSCONFIG: not defined on hwmod\n", oh->name); | ||
114 | return; | ||
115 | } | ||
116 | |||
117 | /* XXX ensure module interface clock is up */ | ||
118 | |||
119 | if (oh->_sysc_cache != v) { | ||
120 | oh->_sysc_cache = v; | ||
121 | omap_hwmod_writel(v, oh, oh->sysconfig->sysc_offs); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | /** | ||
126 | * _set_master_standbymode: set the OCP_SYSCONFIG MIDLEMODE field in @v | ||
127 | * @oh: struct omap_hwmod * | ||
128 | * @standbymode: MIDLEMODE field bits | ||
129 | * @v: pointer to register contents to modify | ||
130 | * | ||
131 | * Update the master standby mode bits in @v to be @standbymode for | ||
132 | * the @oh hwmod. Does not write to the hardware. Returns -EINVAL | ||
133 | * upon error or 0 upon success. | ||
134 | */ | ||
135 | static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode, | ||
136 | u32 *v) | ||
137 | { | ||
138 | if (!oh->sysconfig || | ||
139 | !(oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE)) | ||
140 | return -EINVAL; | ||
141 | |||
142 | *v &= ~SYSC_MIDLEMODE_MASK; | ||
143 | *v |= __ffs(standbymode) << SYSC_MIDLEMODE_SHIFT; | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | /** | ||
149 | * _set_slave_idlemode: set the OCP_SYSCONFIG SIDLEMODE field in @v | ||
150 | * @oh: struct omap_hwmod * | ||
151 | * @idlemode: SIDLEMODE field bits | ||
152 | * @v: pointer to register contents to modify | ||
153 | * | ||
154 | * Update the slave idle mode bits in @v to be @idlemode for the @oh | ||
155 | * hwmod. Does not write to the hardware. Returns -EINVAL upon error | ||
156 | * or 0 upon success. | ||
157 | */ | ||
158 | static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v) | ||
159 | { | ||
160 | if (!oh->sysconfig || | ||
161 | !(oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE)) | ||
162 | return -EINVAL; | ||
163 | |||
164 | *v &= ~SYSC_SIDLEMODE_MASK; | ||
165 | *v |= __ffs(idlemode) << SYSC_SIDLEMODE_SHIFT; | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | /** | ||
171 | * _set_clockactivity: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v | ||
172 | * @oh: struct omap_hwmod * | ||
173 | * @clockact: CLOCKACTIVITY field bits | ||
174 | * @v: pointer to register contents to modify | ||
175 | * | ||
176 | * Update the clockactivity mode bits in @v to be @clockact for the | ||
177 | * @oh hwmod. Used for additional powersaving on some modules. Does | ||
178 | * not write to the hardware. Returns -EINVAL upon error or 0 upon | ||
179 | * success. | ||
180 | */ | ||
181 | static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v) | ||
182 | { | ||
183 | if (!oh->sysconfig || | ||
184 | !(oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY)) | ||
185 | return -EINVAL; | ||
186 | |||
187 | *v &= ~SYSC_CLOCKACTIVITY_MASK; | ||
188 | *v |= clockact << SYSC_CLOCKACTIVITY_SHIFT; | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | /** | ||
194 | * _set_softreset: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v | ||
195 | * @oh: struct omap_hwmod * | ||
196 | * @v: pointer to register contents to modify | ||
197 | * | ||
198 | * Set the SOFTRESET bit in @v for hwmod @oh. Returns -EINVAL upon | ||
199 | * error or 0 upon success. | ||
200 | */ | ||
201 | static int _set_softreset(struct omap_hwmod *oh, u32 *v) | ||
202 | { | ||
203 | if (!oh->sysconfig || | ||
204 | !(oh->sysconfig->sysc_flags & SYSC_HAS_SOFTRESET)) | ||
205 | return -EINVAL; | ||
206 | |||
207 | *v |= SYSC_SOFTRESET_MASK; | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | /** | ||
213 | * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware | ||
214 | * @oh: struct omap_hwmod * | ||
215 | * | ||
216 | * Allow the hardware module @oh to send wakeups. Returns -EINVAL | ||
217 | * upon error or 0 upon success. | ||
218 | */ | ||
219 | static int _enable_wakeup(struct omap_hwmod *oh) | ||
220 | { | ||
221 | u32 v; | ||
222 | |||
223 | if (!oh->sysconfig || | ||
224 | !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP)) | ||
225 | return -EINVAL; | ||
226 | |||
227 | v = oh->_sysc_cache; | ||
228 | v |= SYSC_ENAWAKEUP_MASK; | ||
229 | _write_sysconfig(v, oh); | ||
230 | |||
231 | /* XXX test pwrdm_get_wken for this hwmod's subsystem */ | ||
232 | |||
233 | oh->_int_flags |= _HWMOD_WAKEUP_ENABLED; | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | /** | ||
239 | * _disable_wakeup: clear OCP_SYSCONFIG.ENAWAKEUP bit in the hardware | ||
240 | * @oh: struct omap_hwmod * | ||
241 | * | ||
242 | * Prevent the hardware module @oh to send wakeups. Returns -EINVAL | ||
243 | * upon error or 0 upon success. | ||
244 | */ | ||
245 | static int _disable_wakeup(struct omap_hwmod *oh) | ||
246 | { | ||
247 | u32 v; | ||
248 | |||
249 | if (!oh->sysconfig || | ||
250 | !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP)) | ||
251 | return -EINVAL; | ||
252 | |||
253 | v = oh->_sysc_cache; | ||
254 | v &= ~SYSC_ENAWAKEUP_MASK; | ||
255 | _write_sysconfig(v, oh); | ||
256 | |||
257 | /* XXX test pwrdm_get_wken for this hwmod's subsystem */ | ||
258 | |||
259 | oh->_int_flags &= ~_HWMOD_WAKEUP_ENABLED; | ||
260 | |||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | /** | ||
265 | * _add_initiator_dep: prevent @oh from smart-idling while @init_oh is active | ||
266 | * @oh: struct omap_hwmod * | ||
267 | * | ||
268 | * Prevent the hardware module @oh from entering idle while the | ||
269 | * hardare module initiator @init_oh is active. Useful when a module | ||
270 | * will be accessed by a particular initiator (e.g., if a module will | ||
271 | * be accessed by the IVA, there should be a sleepdep between the IVA | ||
272 | * initiator and the module). Only applies to modules in smart-idle | ||
273 | * mode. Returns -EINVAL upon error or passes along | ||
274 | * pwrdm_add_sleepdep() value upon success. | ||
275 | */ | ||
276 | static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) | ||
277 | { | ||
278 | if (!oh->_clk) | ||
279 | return -EINVAL; | ||
280 | |||
281 | return pwrdm_add_sleepdep(oh->_clk->clkdm->pwrdm.ptr, | ||
282 | init_oh->_clk->clkdm->pwrdm.ptr); | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * _del_initiator_dep: allow @oh to smart-idle even if @init_oh is active | ||
287 | * @oh: struct omap_hwmod * | ||
288 | * | ||
289 | * Allow the hardware module @oh to enter idle while the hardare | ||
290 | * module initiator @init_oh is active. Useful when a module will not | ||
291 | * be accessed by a particular initiator (e.g., if a module will not | ||
292 | * be accessed by the IVA, there should be no sleepdep between the IVA | ||
293 | * initiator and the module). Only applies to modules in smart-idle | ||
294 | * mode. Returns -EINVAL upon error or passes along | ||
295 | * pwrdm_add_sleepdep() value upon success. | ||
296 | */ | ||
297 | static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) | ||
298 | { | ||
299 | if (!oh->_clk) | ||
300 | return -EINVAL; | ||
301 | |||
302 | return pwrdm_del_sleepdep(oh->_clk->clkdm->pwrdm.ptr, | ||
303 | init_oh->_clk->clkdm->pwrdm.ptr); | ||
304 | } | ||
305 | |||
306 | /** | ||
307 | * _init_main_clk - get a struct clk * for the the hwmod's main functional clk | ||
308 | * @oh: struct omap_hwmod * | ||
309 | * | ||
310 | * Called from _init_clocks(). Populates the @oh _clk (main | ||
311 | * functional clock pointer) if a main_clk is present. Returns 0 on | ||
312 | * success or -EINVAL on error. | ||
313 | */ | ||
314 | static int _init_main_clk(struct omap_hwmod *oh) | ||
315 | { | ||
316 | struct clk *c; | ||
317 | int ret = 0; | ||
318 | |||
319 | if (!oh->clkdev_con_id) | ||
320 | return 0; | ||
321 | |||
322 | c = clk_get_sys(oh->clkdev_dev_id, oh->clkdev_con_id); | ||
323 | WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get main_clk %s.%s\n", | ||
324 | oh->name, oh->clkdev_dev_id, oh->clkdev_con_id); | ||
325 | if (IS_ERR(c)) | ||
326 | ret = -EINVAL; | ||
327 | oh->_clk = c; | ||
328 | |||
329 | return ret; | ||
330 | } | ||
331 | |||
332 | /** | ||
333 | * _init_interface_clk - get a struct clk * for the the hwmod's interface clks | ||
334 | * @oh: struct omap_hwmod * | ||
335 | * | ||
336 | * Called from _init_clocks(). Populates the @oh OCP slave interface | ||
337 | * clock pointers. Returns 0 on success or -EINVAL on error. | ||
338 | */ | ||
339 | static int _init_interface_clks(struct omap_hwmod *oh) | ||
340 | { | ||
341 | struct omap_hwmod_ocp_if *os; | ||
342 | struct clk *c; | ||
343 | int i; | ||
344 | int ret = 0; | ||
345 | |||
346 | if (oh->slaves_cnt == 0) | ||
347 | return 0; | ||
348 | |||
349 | for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) { | ||
350 | if (!os->clkdev_con_id) | ||
351 | continue; | ||
352 | |||
353 | c = clk_get_sys(os->clkdev_dev_id, os->clkdev_con_id); | ||
354 | WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get " | ||
355 | "interface_clk %s.%s\n", oh->name, | ||
356 | os->clkdev_dev_id, os->clkdev_con_id); | ||
357 | if (IS_ERR(c)) | ||
358 | ret = -EINVAL; | ||
359 | os->_clk = c; | ||
360 | } | ||
361 | |||
362 | return ret; | ||
363 | } | ||
364 | |||
365 | /** | ||
366 | * _init_opt_clk - get a struct clk * for the the hwmod's optional clocks | ||
367 | * @oh: struct omap_hwmod * | ||
368 | * | ||
369 | * Called from _init_clocks(). Populates the @oh omap_hwmod_opt_clk | ||
370 | * clock pointers. Returns 0 on success or -EINVAL on error. | ||
371 | */ | ||
372 | static int _init_opt_clks(struct omap_hwmod *oh) | ||
373 | { | ||
374 | struct omap_hwmod_opt_clk *oc; | ||
375 | struct clk *c; | ||
376 | int i; | ||
377 | int ret = 0; | ||
378 | |||
379 | for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) { | ||
380 | c = clk_get_sys(oc->clkdev_dev_id, oc->clkdev_con_id); | ||
381 | WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get opt_clk " | ||
382 | "%s.%s\n", oh->name, oc->clkdev_dev_id, | ||
383 | oc->clkdev_con_id); | ||
384 | if (IS_ERR(c)) | ||
385 | ret = -EINVAL; | ||
386 | oc->_clk = c; | ||
387 | } | ||
388 | |||
389 | return ret; | ||
390 | } | ||
391 | |||
392 | /** | ||
393 | * _enable_clocks - enable hwmod main clock and interface clocks | ||
394 | * @oh: struct omap_hwmod * | ||
395 | * | ||
396 | * Enables all clocks necessary for register reads and writes to succeed | ||
397 | * on the hwmod @oh. Returns 0. | ||
398 | */ | ||
399 | static int _enable_clocks(struct omap_hwmod *oh) | ||
400 | { | ||
401 | struct omap_hwmod_ocp_if *os; | ||
402 | int i; | ||
403 | |||
404 | pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name); | ||
405 | |||
406 | if (oh->_clk && !IS_ERR(oh->_clk)) | ||
407 | clk_enable(oh->_clk); | ||
408 | |||
409 | if (oh->slaves_cnt > 0) { | ||
410 | for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) { | ||
411 | struct clk *c = os->_clk; | ||
412 | |||
413 | if (c && !IS_ERR(c) && (os->flags & OCPIF_SWSUP_IDLE)) | ||
414 | clk_enable(c); | ||
415 | } | ||
416 | } | ||
417 | |||
418 | /* The opt clocks are controlled by the device driver. */ | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | /** | ||
424 | * _disable_clocks - disable hwmod main clock and interface clocks | ||
425 | * @oh: struct omap_hwmod * | ||
426 | * | ||
427 | * Disables the hwmod @oh main functional and interface clocks. Returns 0. | ||
428 | */ | ||
429 | static int _disable_clocks(struct omap_hwmod *oh) | ||
430 | { | ||
431 | struct omap_hwmod_ocp_if *os; | ||
432 | int i; | ||
433 | |||
434 | pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name); | ||
435 | |||
436 | if (oh->_clk && !IS_ERR(oh->_clk)) | ||
437 | clk_disable(oh->_clk); | ||
438 | |||
439 | if (oh->slaves_cnt > 0) { | ||
440 | for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) { | ||
441 | struct clk *c = os->_clk; | ||
442 | |||
443 | if (c && !IS_ERR(c) && (os->flags & OCPIF_SWSUP_IDLE)) | ||
444 | clk_disable(c); | ||
445 | } | ||
446 | } | ||
447 | |||
448 | /* The opt clocks are controlled by the device driver. */ | ||
449 | |||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | /** | ||
454 | * _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use | ||
455 | * @oh: struct omap_hwmod * | ||
456 | * | ||
457 | * Returns the array index of the OCP slave port that the MPU | ||
458 | * addresses the device on, or -EINVAL upon error or not found. | ||
459 | */ | ||
460 | static int _find_mpu_port_index(struct omap_hwmod *oh) | ||
461 | { | ||
462 | struct omap_hwmod_ocp_if *os; | ||
463 | int i; | ||
464 | int found = 0; | ||
465 | |||
466 | if (!oh || oh->slaves_cnt == 0) | ||
467 | return -EINVAL; | ||
468 | |||
469 | for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) { | ||
470 | if (os->user & OCP_USER_MPU) { | ||
471 | found = 1; | ||
472 | break; | ||
473 | } | ||
474 | } | ||
475 | |||
476 | if (found) | ||
477 | pr_debug("omap_hwmod: %s: MPU OCP slave port ID %d\n", | ||
478 | oh->name, i); | ||
479 | else | ||
480 | pr_debug("omap_hwmod: %s: no MPU OCP slave port found\n", | ||
481 | oh->name); | ||
482 | |||
483 | return (found) ? i : -EINVAL; | ||
484 | } | ||
485 | |||
486 | /** | ||
487 | * _find_mpu_rt_base - find hwmod register target base addr accessible by MPU | ||
488 | * @oh: struct omap_hwmod * | ||
489 | * | ||
490 | * Return the virtual address of the base of the register target of | ||
491 | * device @oh, or NULL on error. | ||
492 | */ | ||
493 | static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index) | ||
494 | { | ||
495 | struct omap_hwmod_ocp_if *os; | ||
496 | struct omap_hwmod_addr_space *mem; | ||
497 | int i; | ||
498 | int found = 0; | ||
499 | |||
500 | if (!oh || oh->slaves_cnt == 0) | ||
501 | return NULL; | ||
502 | |||
503 | os = *oh->slaves + index; | ||
504 | |||
505 | for (i = 0, mem = os->addr; i < os->addr_cnt; i++, mem++) { | ||
506 | if (mem->flags & ADDR_TYPE_RT) { | ||
507 | found = 1; | ||
508 | break; | ||
509 | } | ||
510 | } | ||
511 | |||
512 | /* XXX use ioremap() instead? */ | ||
513 | |||
514 | if (found) | ||
515 | pr_debug("omap_hwmod: %s: MPU register target at va %p\n", | ||
516 | oh->name, OMAP2_IO_ADDRESS(mem->pa_start)); | ||
517 | else | ||
518 | pr_debug("omap_hwmod: %s: no MPU register target found\n", | ||
519 | oh->name); | ||
520 | |||
521 | return (found) ? OMAP2_IO_ADDRESS(mem->pa_start) : NULL; | ||
522 | } | ||
523 | |||
524 | /** | ||
525 | * _sysc_enable - try to bring a module out of idle via OCP_SYSCONFIG | ||
526 | * @oh: struct omap_hwmod * | ||
527 | * | ||
528 | * If module is marked as SWSUP_SIDLE, force the module out of slave | ||
529 | * idle; otherwise, configure it for smart-idle. If module is marked | ||
530 | * as SWSUP_MSUSPEND, force the module out of master standby; | ||
531 | * otherwise, configure it for smart-standby. No return value. | ||
532 | */ | ||
533 | static void _sysc_enable(struct omap_hwmod *oh) | ||
534 | { | ||
535 | u8 idlemode; | ||
536 | u32 v; | ||
537 | |||
538 | if (!oh->sysconfig) | ||
539 | return; | ||
540 | |||
541 | v = oh->_sysc_cache; | ||
542 | |||
543 | if (oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE) { | ||
544 | idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? | ||
545 | HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART; | ||
546 | _set_slave_idlemode(oh, idlemode, &v); | ||
547 | } | ||
548 | |||
549 | if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE) { | ||
550 | idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ? | ||
551 | HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART; | ||
552 | _set_master_standbymode(oh, idlemode, &v); | ||
553 | } | ||
554 | |||
555 | /* XXX OCP AUTOIDLE bit? */ | ||
556 | |||
557 | if (oh->flags & HWMOD_SET_DEFAULT_CLOCKACT && | ||
558 | oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY) | ||
559 | _set_clockactivity(oh, oh->sysconfig->clockact, &v); | ||
560 | |||
561 | _write_sysconfig(v, oh); | ||
562 | } | ||
563 | |||
564 | /** | ||
565 | * _sysc_idle - try to put a module into idle via OCP_SYSCONFIG | ||
566 | * @oh: struct omap_hwmod * | ||
567 | * | ||
568 | * If module is marked as SWSUP_SIDLE, force the module into slave | ||
569 | * idle; otherwise, configure it for smart-idle. If module is marked | ||
570 | * as SWSUP_MSUSPEND, force the module into master standby; otherwise, | ||
571 | * configure it for smart-standby. No return value. | ||
572 | */ | ||
573 | static void _sysc_idle(struct omap_hwmod *oh) | ||
574 | { | ||
575 | u8 idlemode; | ||
576 | u32 v; | ||
577 | |||
578 | if (!oh->sysconfig) | ||
579 | return; | ||
580 | |||
581 | v = oh->_sysc_cache; | ||
582 | |||
583 | if (oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE) { | ||
584 | idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ? | ||
585 | HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART; | ||
586 | _set_slave_idlemode(oh, idlemode, &v); | ||
587 | } | ||
588 | |||
589 | if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE) { | ||
590 | idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ? | ||
591 | HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART; | ||
592 | _set_master_standbymode(oh, idlemode, &v); | ||
593 | } | ||
594 | |||
595 | _write_sysconfig(v, oh); | ||
596 | } | ||
597 | |||
598 | /** | ||
599 | * _sysc_shutdown - force a module into idle via OCP_SYSCONFIG | ||
600 | * @oh: struct omap_hwmod * | ||
601 | * | ||
602 | * Force the module into slave idle and master suspend. No return | ||
603 | * value. | ||
604 | */ | ||
605 | static void _sysc_shutdown(struct omap_hwmod *oh) | ||
606 | { | ||
607 | u32 v; | ||
608 | |||
609 | if (!oh->sysconfig) | ||
610 | return; | ||
611 | |||
612 | v = oh->_sysc_cache; | ||
613 | |||
614 | if (oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE) | ||
615 | _set_slave_idlemode(oh, HWMOD_IDLEMODE_FORCE, &v); | ||
616 | |||
617 | if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE) | ||
618 | _set_master_standbymode(oh, HWMOD_IDLEMODE_FORCE, &v); | ||
619 | |||
620 | /* XXX clear OCP AUTOIDLE bit? */ | ||
621 | |||
622 | _write_sysconfig(v, oh); | ||
623 | } | ||
624 | |||
625 | /** | ||
626 | * _lookup - find an omap_hwmod by name | ||
627 | * @name: find an omap_hwmod by name | ||
628 | * | ||
629 | * Return a pointer to an omap_hwmod by name, or NULL if not found. | ||
630 | * Caller must hold omap_hwmod_mutex. | ||
631 | */ | ||
632 | static struct omap_hwmod *_lookup(const char *name) | ||
633 | { | ||
634 | struct omap_hwmod *oh, *temp_oh; | ||
635 | |||
636 | oh = NULL; | ||
637 | |||
638 | list_for_each_entry(temp_oh, &omap_hwmod_list, node) { | ||
639 | if (!strcmp(name, temp_oh->name)) { | ||
640 | oh = temp_oh; | ||
641 | break; | ||
642 | } | ||
643 | } | ||
644 | |||
645 | return oh; | ||
646 | } | ||
647 | |||
648 | /** | ||
649 | * _init_clocks - clk_get() all clocks associated with this hwmod | ||
650 | * @oh: struct omap_hwmod * | ||
651 | * | ||
652 | * Called by omap_hwmod_late_init() (after omap2_clk_init()). | ||
653 | * Resolves all clock names embedded in the hwmod. Must be called | ||
654 | * with omap_hwmod_mutex held. Returns -EINVAL if the omap_hwmod | ||
655 | * has not yet been registered or if the clocks have already been | ||
656 | * initialized, 0 on success, or a non-zero error on failure. | ||
657 | */ | ||
658 | static int _init_clocks(struct omap_hwmod *oh) | ||
659 | { | ||
660 | int ret = 0; | ||
661 | |||
662 | if (!oh || (oh->_state != _HWMOD_STATE_REGISTERED)) | ||
663 | return -EINVAL; | ||
664 | |||
665 | pr_debug("omap_hwmod: %s: looking up clocks\n", oh->name); | ||
666 | |||
667 | ret |= _init_main_clk(oh); | ||
668 | ret |= _init_interface_clks(oh); | ||
669 | ret |= _init_opt_clks(oh); | ||
670 | |||
671 | oh->_state = _HWMOD_STATE_CLKS_INITED; | ||
672 | |||
673 | return ret; | ||
674 | } | ||
675 | |||
676 | /** | ||
677 | * _wait_target_ready - wait for a module to leave slave idle | ||
678 | * @oh: struct omap_hwmod * | ||
679 | * | ||
680 | * Wait for a module @oh to leave slave idle. Returns 0 if the module | ||
681 | * does not have an IDLEST bit or if the module successfully leaves | ||
682 | * slave idle; otherwise, pass along the return value of the | ||
683 | * appropriate *_cm_wait_module_ready() function. | ||
684 | */ | ||
685 | static int _wait_target_ready(struct omap_hwmod *oh) | ||
686 | { | ||
687 | struct omap_hwmod_ocp_if *os; | ||
688 | int ret; | ||
689 | |||
690 | if (!oh) | ||
691 | return -EINVAL; | ||
692 | |||
693 | if (oh->_int_flags & _HWMOD_NO_MPU_PORT) | ||
694 | return 0; | ||
695 | |||
696 | os = *oh->slaves + oh->_mpu_port_index; | ||
697 | |||
698 | if (!(os->flags & OCPIF_HAS_IDLEST)) | ||
699 | return 0; | ||
700 | |||
701 | /* XXX check module SIDLEMODE */ | ||
702 | |||
703 | /* XXX check clock enable states */ | ||
704 | |||
705 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) { | ||
706 | ret = omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs, | ||
707 | oh->prcm.omap2.idlest_reg_id, | ||
708 | oh->prcm.omap2.idlest_idle_bit); | ||
709 | #if 0 | ||
710 | } else if (cpu_is_omap44xx()) { | ||
711 | ret = omap4_cm_wait_module_ready(oh->prcm.omap4.module_offs, | ||
712 | oh->prcm.omap4.device_offs); | ||
713 | #endif | ||
714 | } else { | ||
715 | BUG(); | ||
716 | }; | ||
717 | |||
718 | return ret; | ||
719 | } | ||
720 | |||
721 | /** | ||
722 | * _reset - reset an omap_hwmod | ||
723 | * @oh: struct omap_hwmod * | ||
724 | * | ||
725 | * Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit. hwmod must be | ||
726 | * enabled for this to work. Must be called with omap_hwmod_mutex | ||
727 | * held. Returns -EINVAL if the hwmod cannot be reset this way or if | ||
728 | * the hwmod is in the wrong state, -ETIMEDOUT if the module did not | ||
729 | * reset in time, or 0 upon success. | ||
730 | */ | ||
731 | static int _reset(struct omap_hwmod *oh) | ||
732 | { | ||
733 | u32 r, v; | ||
734 | int c; | ||
735 | |||
736 | if (!oh->sysconfig || | ||
737 | !(oh->sysconfig->sysc_flags & SYSC_HAS_SOFTRESET) || | ||
738 | (oh->sysconfig->sysc_flags & SYSS_MISSING)) | ||
739 | return -EINVAL; | ||
740 | |||
741 | /* clocks must be on for this operation */ | ||
742 | if (oh->_state != _HWMOD_STATE_ENABLED) { | ||
743 | WARN(1, "omap_hwmod: %s: reset can only be entered from " | ||
744 | "enabled state\n", oh->name); | ||
745 | return -EINVAL; | ||
746 | } | ||
747 | |||
748 | pr_debug("omap_hwmod: %s: resetting\n", oh->name); | ||
749 | |||
750 | v = oh->_sysc_cache; | ||
751 | r = _set_softreset(oh, &v); | ||
752 | if (r) | ||
753 | return r; | ||
754 | _write_sysconfig(v, oh); | ||
755 | |||
756 | c = 0; | ||
757 | while (c < MAX_MODULE_RESET_WAIT && | ||
758 | !(omap_hwmod_readl(oh, oh->sysconfig->syss_offs) & | ||
759 | SYSS_RESETDONE_MASK)) { | ||
760 | udelay(1); | ||
761 | c++; | ||
762 | } | ||
763 | |||
764 | if (c == MAX_MODULE_RESET_WAIT) | ||
765 | WARN(1, "omap_hwmod: %s: failed to reset in %d usec\n", | ||
766 | oh->name, MAX_MODULE_RESET_WAIT); | ||
767 | else | ||
768 | pr_debug("omap_hwmod: %s: reset in %d usec\n", oh->name, c); | ||
769 | |||
770 | /* | ||
771 | * XXX add _HWMOD_STATE_WEDGED for modules that don't come back from | ||
772 | * _wait_target_ready() or _reset() | ||
773 | */ | ||
774 | |||
775 | return (c == MAX_MODULE_RESET_WAIT) ? -ETIMEDOUT : 0; | ||
776 | } | ||
777 | |||
778 | /** | ||
779 | * _enable - enable an omap_hwmod | ||
780 | * @oh: struct omap_hwmod * | ||
781 | * | ||
782 | * Enables an omap_hwmod @oh such that the MPU can access the hwmod's | ||
783 | * register target. Must be called with omap_hwmod_mutex held. | ||
784 | * Returns -EINVAL if the hwmod is in the wrong state or passes along | ||
785 | * the return value of _wait_target_ready(). | ||
786 | */ | ||
787 | static int _enable(struct omap_hwmod *oh) | ||
788 | { | ||
789 | int r; | ||
790 | |||
791 | if (oh->_state != _HWMOD_STATE_INITIALIZED && | ||
792 | oh->_state != _HWMOD_STATE_IDLE && | ||
793 | oh->_state != _HWMOD_STATE_DISABLED) { | ||
794 | WARN(1, "omap_hwmod: %s: enabled state can only be entered " | ||
795 | "from initialized, idle, or disabled state\n", oh->name); | ||
796 | return -EINVAL; | ||
797 | } | ||
798 | |||
799 | pr_debug("omap_hwmod: %s: enabling\n", oh->name); | ||
800 | |||
801 | /* XXX mux balls */ | ||
802 | |||
803 | _add_initiator_dep(oh, mpu_oh); | ||
804 | _enable_clocks(oh); | ||
805 | |||
806 | if (oh->sysconfig) { | ||
807 | if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED)) | ||
808 | _update_sysc_cache(oh); | ||
809 | _sysc_enable(oh); | ||
810 | } | ||
811 | |||
812 | r = _wait_target_ready(oh); | ||
813 | if (!r) | ||
814 | oh->_state = _HWMOD_STATE_ENABLED; | ||
815 | |||
816 | return r; | ||
817 | } | ||
818 | |||
819 | /** | ||
820 | * _idle - idle an omap_hwmod | ||
821 | * @oh: struct omap_hwmod * | ||
822 | * | ||
823 | * Idles an omap_hwmod @oh. This should be called once the hwmod has | ||
824 | * no further work. Returns -EINVAL if the hwmod is in the wrong | ||
825 | * state or returns 0. | ||
826 | */ | ||
827 | static int _idle(struct omap_hwmod *oh) | ||
828 | { | ||
829 | if (oh->_state != _HWMOD_STATE_ENABLED) { | ||
830 | WARN(1, "omap_hwmod: %s: idle state can only be entered from " | ||
831 | "enabled state\n", oh->name); | ||
832 | return -EINVAL; | ||
833 | } | ||
834 | |||
835 | pr_debug("omap_hwmod: %s: idling\n", oh->name); | ||
836 | |||
837 | if (oh->sysconfig) | ||
838 | _sysc_idle(oh); | ||
839 | _del_initiator_dep(oh, mpu_oh); | ||
840 | _disable_clocks(oh); | ||
841 | |||
842 | oh->_state = _HWMOD_STATE_IDLE; | ||
843 | |||
844 | return 0; | ||
845 | } | ||
846 | |||
847 | /** | ||
848 | * _shutdown - shutdown an omap_hwmod | ||
849 | * @oh: struct omap_hwmod * | ||
850 | * | ||
851 | * Shut down an omap_hwmod @oh. This should be called when the driver | ||
852 | * used for the hwmod is removed or unloaded or if the driver is not | ||
853 | * used by the system. Returns -EINVAL if the hwmod is in the wrong | ||
854 | * state or returns 0. | ||
855 | */ | ||
856 | static int _shutdown(struct omap_hwmod *oh) | ||
857 | { | ||
858 | if (oh->_state != _HWMOD_STATE_IDLE && | ||
859 | oh->_state != _HWMOD_STATE_ENABLED) { | ||
860 | WARN(1, "omap_hwmod: %s: disabled state can only be entered " | ||
861 | "from idle, or enabled state\n", oh->name); | ||
862 | return -EINVAL; | ||
863 | } | ||
864 | |||
865 | pr_debug("omap_hwmod: %s: disabling\n", oh->name); | ||
866 | |||
867 | if (oh->sysconfig) | ||
868 | _sysc_shutdown(oh); | ||
869 | _del_initiator_dep(oh, mpu_oh); | ||
870 | /* XXX what about the other system initiators here? DMA, tesla, d2d */ | ||
871 | _disable_clocks(oh); | ||
872 | /* XXX Should this code also force-disable the optional clocks? */ | ||
873 | |||
874 | /* XXX mux any associated balls to safe mode */ | ||
875 | |||
876 | oh->_state = _HWMOD_STATE_DISABLED; | ||
877 | |||
878 | return 0; | ||
879 | } | ||
880 | |||
881 | /** | ||
882 | * _write_clockact_lock - set the module's clockactivity bits | ||
883 | * @oh: struct omap_hwmod * | ||
884 | * @clockact: CLOCKACTIVITY field bits | ||
885 | * | ||
886 | * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh | ||
887 | * OCP_SYSCONFIG register. Returns -EINVAL if the hwmod is in the | ||
888 | * wrong state or returns 0. | ||
889 | */ | ||
890 | static int _write_clockact_lock(struct omap_hwmod *oh, u8 clockact) | ||
891 | { | ||
892 | u32 v; | ||
893 | |||
894 | if (!oh->sysconfig || | ||
895 | !(oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY)) | ||
896 | return -EINVAL; | ||
897 | |||
898 | mutex_lock(&omap_hwmod_mutex); | ||
899 | v = oh->_sysc_cache; | ||
900 | _set_clockactivity(oh, clockact, &v); | ||
901 | _write_sysconfig(v, oh); | ||
902 | mutex_unlock(&omap_hwmod_mutex); | ||
903 | |||
904 | return 0; | ||
905 | } | ||
906 | |||
907 | |||
908 | /** | ||
909 | * _setup - do initial configuration of omap_hwmod | ||
910 | * @oh: struct omap_hwmod * | ||
911 | * | ||
912 | * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh | ||
913 | * OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex | ||
914 | * held. Returns -EINVAL if the hwmod is in the wrong state or returns | ||
915 | * 0. | ||
916 | */ | ||
917 | static int _setup(struct omap_hwmod *oh) | ||
918 | { | ||
919 | struct omap_hwmod_ocp_if *os; | ||
920 | int i; | ||
921 | |||
922 | if (!oh) | ||
923 | return -EINVAL; | ||
924 | |||
925 | /* Set iclk autoidle mode */ | ||
926 | if (oh->slaves_cnt > 0) { | ||
927 | for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) { | ||
928 | struct clk *c = os->_clk; | ||
929 | |||
930 | if (!c || IS_ERR(c)) | ||
931 | continue; | ||
932 | |||
933 | if (os->flags & OCPIF_SWSUP_IDLE) { | ||
934 | /* XXX omap_iclk_deny_idle(c); */ | ||
935 | } else { | ||
936 | /* XXX omap_iclk_allow_idle(c); */ | ||
937 | clk_enable(c); | ||
938 | } | ||
939 | } | ||
940 | } | ||
941 | |||
942 | oh->_state = _HWMOD_STATE_INITIALIZED; | ||
943 | |||
944 | _enable(oh); | ||
945 | |||
946 | if (!(oh->flags & HWMOD_INIT_NO_RESET)) | ||
947 | _reset(oh); | ||
948 | |||
949 | /* XXX OCP AUTOIDLE bit? */ | ||
950 | /* XXX OCP ENAWAKEUP bit? */ | ||
951 | |||
952 | if (!(oh->flags & HWMOD_INIT_NO_IDLE)) | ||
953 | _idle(oh); | ||
954 | |||
955 | return 0; | ||
956 | } | ||
957 | |||
958 | |||
959 | |||
960 | /* Public functions */ | ||
961 | |||
962 | u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs) | ||
963 | { | ||
964 | return __raw_readl(oh->_rt_va + reg_offs); | ||
965 | } | ||
966 | |||
967 | void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs) | ||
968 | { | ||
969 | __raw_writel(v, oh->_rt_va + reg_offs); | ||
970 | } | ||
971 | |||
972 | /** | ||
973 | * omap_hwmod_register - register a struct omap_hwmod | ||
974 | * @oh: struct omap_hwmod * | ||
975 | * | ||
976 | * Registers the omap_hwmod @oh. Returns -EEXIST if an omap_hwmod already | ||
977 | * has been registered by the same name; -EINVAL if the omap_hwmod is in the | ||
978 | * wrong state, or 0 on success. | ||
979 | * | ||
980 | * XXX The data should be copied into bootmem, so the original data | ||
981 | * should be marked __initdata and freed after init. This would allow | ||
982 | * unneeded omap_hwmods to be freed on multi-OMAP configurations. Note | ||
983 | * that the copy process would be relatively complex due to the large number | ||
984 | * of substructures. | ||
985 | */ | ||
986 | int omap_hwmod_register(struct omap_hwmod *oh) | ||
987 | { | ||
988 | int ret, ms_id; | ||
989 | |||
990 | if (!oh || (oh->_state != _HWMOD_STATE_UNKNOWN)) | ||
991 | return -EINVAL; | ||
992 | |||
993 | mutex_lock(&omap_hwmod_mutex); | ||
994 | |||
995 | pr_debug("omap_hwmod: %s: registering\n", oh->name); | ||
996 | |||
997 | if (_lookup(oh->name)) { | ||
998 | ret = -EEXIST; | ||
999 | goto ohr_unlock; | ||
1000 | } | ||
1001 | |||
1002 | ms_id = _find_mpu_port_index(oh); | ||
1003 | if (!IS_ERR_VALUE(ms_id)) { | ||
1004 | oh->_mpu_port_index = ms_id; | ||
1005 | oh->_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index); | ||
1006 | } else { | ||
1007 | oh->_int_flags |= _HWMOD_NO_MPU_PORT; | ||
1008 | } | ||
1009 | |||
1010 | list_add_tail(&oh->node, &omap_hwmod_list); | ||
1011 | |||
1012 | oh->_state = _HWMOD_STATE_REGISTERED; | ||
1013 | |||
1014 | ret = 0; | ||
1015 | |||
1016 | ohr_unlock: | ||
1017 | mutex_unlock(&omap_hwmod_mutex); | ||
1018 | return ret; | ||
1019 | } | ||
1020 | |||
1021 | /** | ||
1022 | * omap_hwmod_lookup - look up a registered omap_hwmod by name | ||
1023 | * @name: name of the omap_hwmod to look up | ||
1024 | * | ||
1025 | * Given a @name of an omap_hwmod, return a pointer to the registered | ||
1026 | * struct omap_hwmod *, or NULL upon error. | ||
1027 | */ | ||
1028 | struct omap_hwmod *omap_hwmod_lookup(const char *name) | ||
1029 | { | ||
1030 | struct omap_hwmod *oh; | ||
1031 | |||
1032 | if (!name) | ||
1033 | return NULL; | ||
1034 | |||
1035 | mutex_lock(&omap_hwmod_mutex); | ||
1036 | oh = _lookup(name); | ||
1037 | mutex_unlock(&omap_hwmod_mutex); | ||
1038 | |||
1039 | return oh; | ||
1040 | } | ||
1041 | |||
1042 | /** | ||
1043 | * omap_hwmod_for_each - call function for each registered omap_hwmod | ||
1044 | * @fn: pointer to a callback function | ||
1045 | * | ||
1046 | * Call @fn for each registered omap_hwmod, passing @data to each | ||
1047 | * function. @fn must return 0 for success or any other value for | ||
1048 | * failure. If @fn returns non-zero, the iteration across omap_hwmods | ||
1049 | * will stop and the non-zero return value will be passed to the | ||
1050 | * caller of omap_hwmod_for_each(). @fn is called with | ||
1051 | * omap_hwmod_for_each() held. | ||
1052 | */ | ||
1053 | int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh)) | ||
1054 | { | ||
1055 | struct omap_hwmod *temp_oh; | ||
1056 | int ret; | ||
1057 | |||
1058 | if (!fn) | ||
1059 | return -EINVAL; | ||
1060 | |||
1061 | mutex_lock(&omap_hwmod_mutex); | ||
1062 | list_for_each_entry(temp_oh, &omap_hwmod_list, node) { | ||
1063 | ret = (*fn)(temp_oh); | ||
1064 | if (ret) | ||
1065 | break; | ||
1066 | } | ||
1067 | mutex_unlock(&omap_hwmod_mutex); | ||
1068 | |||
1069 | return ret; | ||
1070 | } | ||
1071 | |||
1072 | |||
1073 | /** | ||
1074 | * omap_hwmod_init - init omap_hwmod code and register hwmods | ||
1075 | * @ohs: pointer to an array of omap_hwmods to register | ||
1076 | * | ||
1077 | * Intended to be called early in boot before the clock framework is | ||
1078 | * initialized. If @ohs is not null, will register all omap_hwmods | ||
1079 | * listed in @ohs that are valid for this chip. Returns -EINVAL if | ||
1080 | * omap_hwmod_init() has already been called or 0 otherwise. | ||
1081 | */ | ||
1082 | int omap_hwmod_init(struct omap_hwmod **ohs) | ||
1083 | { | ||
1084 | struct omap_hwmod *oh; | ||
1085 | int r; | ||
1086 | |||
1087 | if (inited) | ||
1088 | return -EINVAL; | ||
1089 | |||
1090 | inited = 1; | ||
1091 | |||
1092 | if (!ohs) | ||
1093 | return 0; | ||
1094 | |||
1095 | oh = *ohs; | ||
1096 | while (oh) { | ||
1097 | if (omap_chip_is(oh->omap_chip)) { | ||
1098 | r = omap_hwmod_register(oh); | ||
1099 | WARN(r, "omap_hwmod: %s: omap_hwmod_register returned " | ||
1100 | "%d\n", oh->name, r); | ||
1101 | } | ||
1102 | oh = *++ohs; | ||
1103 | } | ||
1104 | |||
1105 | return 0; | ||
1106 | } | ||
1107 | |||
1108 | /** | ||
1109 | * omap_hwmod_late_init - do some post-clock framework initialization | ||
1110 | * | ||
1111 | * Must be called after omap2_clk_init(). Resolves the struct clk names | ||
1112 | * to struct clk pointers for each registered omap_hwmod. Also calls | ||
1113 | * _setup() on each hwmod. Returns 0. | ||
1114 | */ | ||
1115 | int omap_hwmod_late_init(void) | ||
1116 | { | ||
1117 | int r; | ||
1118 | |||
1119 | /* XXX check return value */ | ||
1120 | r = omap_hwmod_for_each(_init_clocks); | ||
1121 | WARN(r, "omap_hwmod: omap_hwmod_late_init(): _init_clocks failed\n"); | ||
1122 | |||
1123 | mpu_oh = omap_hwmod_lookup(MPU_INITIATOR_NAME); | ||
1124 | WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n", | ||
1125 | MPU_INITIATOR_NAME); | ||
1126 | |||
1127 | omap_hwmod_for_each(_setup); | ||
1128 | |||
1129 | return 0; | ||
1130 | } | ||
1131 | |||
1132 | /** | ||
1133 | * omap_hwmod_unregister - unregister an omap_hwmod | ||
1134 | * @oh: struct omap_hwmod * | ||
1135 | * | ||
1136 | * Unregisters a previously-registered omap_hwmod @oh. There's probably | ||
1137 | * no use case for this, so it is likely to be removed in a later version. | ||
1138 | * | ||
1139 | * XXX Free all of the bootmem-allocated structures here when that is | ||
1140 | * implemented. Make it clear that core code is the only code that is | ||
1141 | * expected to unregister modules. | ||
1142 | */ | ||
1143 | int omap_hwmod_unregister(struct omap_hwmod *oh) | ||
1144 | { | ||
1145 | if (!oh) | ||
1146 | return -EINVAL; | ||
1147 | |||
1148 | pr_debug("omap_hwmod: %s: unregistering\n", oh->name); | ||
1149 | |||
1150 | mutex_lock(&omap_hwmod_mutex); | ||
1151 | list_del(&oh->node); | ||
1152 | mutex_unlock(&omap_hwmod_mutex); | ||
1153 | |||
1154 | return 0; | ||
1155 | } | ||
1156 | |||
1157 | /** | ||
1158 | * omap_hwmod_enable - enable an omap_hwmod | ||
1159 | * @oh: struct omap_hwmod * | ||
1160 | * | ||
1161 | * Enable an omap_hwomd @oh. Intended to be called by omap_device_enable(). | ||
1162 | * Returns -EINVAL on error or passes along the return value from _enable(). | ||
1163 | */ | ||
1164 | int omap_hwmod_enable(struct omap_hwmod *oh) | ||
1165 | { | ||
1166 | int r; | ||
1167 | |||
1168 | if (!oh) | ||
1169 | return -EINVAL; | ||
1170 | |||
1171 | mutex_lock(&omap_hwmod_mutex); | ||
1172 | r = _enable(oh); | ||
1173 | mutex_unlock(&omap_hwmod_mutex); | ||
1174 | |||
1175 | return r; | ||
1176 | } | ||
1177 | |||
1178 | /** | ||
1179 | * omap_hwmod_idle - idle an omap_hwmod | ||
1180 | * @oh: struct omap_hwmod * | ||
1181 | * | ||
1182 | * Idle an omap_hwomd @oh. Intended to be called by omap_device_idle(). | ||
1183 | * Returns -EINVAL on error or passes along the return value from _idle(). | ||
1184 | */ | ||
1185 | int omap_hwmod_idle(struct omap_hwmod *oh) | ||
1186 | { | ||
1187 | if (!oh) | ||
1188 | return -EINVAL; | ||
1189 | |||
1190 | mutex_lock(&omap_hwmod_mutex); | ||
1191 | _idle(oh); | ||
1192 | mutex_unlock(&omap_hwmod_mutex); | ||
1193 | |||
1194 | return 0; | ||
1195 | } | ||
1196 | |||
1197 | /** | ||
1198 | * omap_hwmod_shutdown - shutdown an omap_hwmod | ||
1199 | * @oh: struct omap_hwmod * | ||
1200 | * | ||
1201 | * Shutdown an omap_hwomd @oh. Intended to be called by | ||
1202 | * omap_device_shutdown(). Returns -EINVAL on error or passes along | ||
1203 | * the return value from _shutdown(). | ||
1204 | */ | ||
1205 | int omap_hwmod_shutdown(struct omap_hwmod *oh) | ||
1206 | { | ||
1207 | if (!oh) | ||
1208 | return -EINVAL; | ||
1209 | |||
1210 | mutex_lock(&omap_hwmod_mutex); | ||
1211 | _shutdown(oh); | ||
1212 | mutex_unlock(&omap_hwmod_mutex); | ||
1213 | |||
1214 | return 0; | ||
1215 | } | ||
1216 | |||
1217 | /** | ||
1218 | * omap_hwmod_enable_clocks - enable main_clk, all interface clocks | ||
1219 | * @oh: struct omap_hwmod *oh | ||
1220 | * | ||
1221 | * Intended to be called by the omap_device code. | ||
1222 | */ | ||
1223 | int omap_hwmod_enable_clocks(struct omap_hwmod *oh) | ||
1224 | { | ||
1225 | mutex_lock(&omap_hwmod_mutex); | ||
1226 | _enable_clocks(oh); | ||
1227 | mutex_unlock(&omap_hwmod_mutex); | ||
1228 | |||
1229 | return 0; | ||
1230 | } | ||
1231 | |||
1232 | /** | ||
1233 | * omap_hwmod_disable_clocks - disable main_clk, all interface clocks | ||
1234 | * @oh: struct omap_hwmod *oh | ||
1235 | * | ||
1236 | * Intended to be called by the omap_device code. | ||
1237 | */ | ||
1238 | int omap_hwmod_disable_clocks(struct omap_hwmod *oh) | ||
1239 | { | ||
1240 | mutex_lock(&omap_hwmod_mutex); | ||
1241 | _disable_clocks(oh); | ||
1242 | mutex_unlock(&omap_hwmod_mutex); | ||
1243 | |||
1244 | return 0; | ||
1245 | } | ||
1246 | |||
1247 | /** | ||
1248 | * omap_hwmod_ocp_barrier - wait for posted writes against the hwmod to complete | ||
1249 | * @oh: struct omap_hwmod *oh | ||
1250 | * | ||
1251 | * Intended to be called by drivers and core code when all posted | ||
1252 | * writes to a device must complete before continuing further | ||
1253 | * execution (for example, after clearing some device IRQSTATUS | ||
1254 | * register bits) | ||
1255 | * | ||
1256 | * XXX what about targets with multiple OCP threads? | ||
1257 | */ | ||
1258 | void omap_hwmod_ocp_barrier(struct omap_hwmod *oh) | ||
1259 | { | ||
1260 | BUG_ON(!oh); | ||
1261 | |||
1262 | if (!oh->sysconfig || !oh->sysconfig->sysc_flags) { | ||
1263 | WARN(1, "omap_device: %s: OCP barrier impossible due to " | ||
1264 | "device configuration\n", oh->name); | ||
1265 | return; | ||
1266 | } | ||
1267 | |||
1268 | /* | ||
1269 | * Forces posted writes to complete on the OCP thread handling | ||
1270 | * register writes | ||
1271 | */ | ||
1272 | omap_hwmod_readl(oh, oh->sysconfig->sysc_offs); | ||
1273 | } | ||
1274 | |||
1275 | /** | ||
1276 | * omap_hwmod_reset - reset the hwmod | ||
1277 | * @oh: struct omap_hwmod * | ||
1278 | * | ||
1279 | * Under some conditions, a driver may wish to reset the entire device. | ||
1280 | * Called from omap_device code. Returns -EINVAL on error or passes along | ||
1281 | * the return value from _reset()/_enable(). | ||
1282 | */ | ||
1283 | int omap_hwmod_reset(struct omap_hwmod *oh) | ||
1284 | { | ||
1285 | int r; | ||
1286 | |||
1287 | if (!oh || !(oh->_state & _HWMOD_STATE_ENABLED)) | ||
1288 | return -EINVAL; | ||
1289 | |||
1290 | mutex_lock(&omap_hwmod_mutex); | ||
1291 | r = _reset(oh); | ||
1292 | if (!r) | ||
1293 | r = _enable(oh); | ||
1294 | mutex_unlock(&omap_hwmod_mutex); | ||
1295 | |||
1296 | return r; | ||
1297 | } | ||
1298 | |||
1299 | /** | ||
1300 | * omap_hwmod_count_resources - count number of struct resources needed by hwmod | ||
1301 | * @oh: struct omap_hwmod * | ||
1302 | * @res: pointer to the first element of an array of struct resource to fill | ||
1303 | * | ||
1304 | * Count the number of struct resource array elements necessary to | ||
1305 | * contain omap_hwmod @oh resources. Intended to be called by code | ||
1306 | * that registers omap_devices. Intended to be used to determine the | ||
1307 | * size of a dynamically-allocated struct resource array, before | ||
1308 | * calling omap_hwmod_fill_resources(). Returns the number of struct | ||
1309 | * resource array elements needed. | ||
1310 | * | ||
1311 | * XXX This code is not optimized. It could attempt to merge adjacent | ||
1312 | * resource IDs. | ||
1313 | * | ||
1314 | */ | ||
1315 | int omap_hwmod_count_resources(struct omap_hwmod *oh) | ||
1316 | { | ||
1317 | int ret, i; | ||
1318 | |||
1319 | ret = oh->mpu_irqs_cnt + oh->sdma_chs_cnt; | ||
1320 | |||
1321 | for (i = 0; i < oh->slaves_cnt; i++) | ||
1322 | ret += (*oh->slaves + i)->addr_cnt; | ||
1323 | |||
1324 | return ret; | ||
1325 | } | ||
1326 | |||
1327 | /** | ||
1328 | * omap_hwmod_fill_resources - fill struct resource array with hwmod data | ||
1329 | * @oh: struct omap_hwmod * | ||
1330 | * @res: pointer to the first element of an array of struct resource to fill | ||
1331 | * | ||
1332 | * Fill the struct resource array @res with resource data from the | ||
1333 | * omap_hwmod @oh. Intended to be called by code that registers | ||
1334 | * omap_devices. See also omap_hwmod_count_resources(). Returns the | ||
1335 | * number of array elements filled. | ||
1336 | */ | ||
1337 | int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) | ||
1338 | { | ||
1339 | int i, j; | ||
1340 | int r = 0; | ||
1341 | |||
1342 | /* For each IRQ, DMA, memory area, fill in array.*/ | ||
1343 | |||
1344 | for (i = 0; i < oh->mpu_irqs_cnt; i++) { | ||
1345 | (res + r)->start = *(oh->mpu_irqs + i); | ||
1346 | (res + r)->end = *(oh->mpu_irqs + i); | ||
1347 | (res + r)->flags = IORESOURCE_IRQ; | ||
1348 | r++; | ||
1349 | } | ||
1350 | |||
1351 | for (i = 0; i < oh->sdma_chs_cnt; i++) { | ||
1352 | (res + r)->name = (oh->sdma_chs + i)->name; | ||
1353 | (res + r)->start = (oh->sdma_chs + i)->dma_ch; | ||
1354 | (res + r)->end = (oh->sdma_chs + i)->dma_ch; | ||
1355 | (res + r)->flags = IORESOURCE_DMA; | ||
1356 | r++; | ||
1357 | } | ||
1358 | |||
1359 | for (i = 0; i < oh->slaves_cnt; i++) { | ||
1360 | struct omap_hwmod_ocp_if *os; | ||
1361 | |||
1362 | os = *oh->slaves + i; | ||
1363 | |||
1364 | for (j = 0; j < os->addr_cnt; j++) { | ||
1365 | (res + r)->start = (os->addr + j)->pa_start; | ||
1366 | (res + r)->end = (os->addr + j)->pa_end; | ||
1367 | (res + r)->flags = IORESOURCE_MEM; | ||
1368 | r++; | ||
1369 | } | ||
1370 | } | ||
1371 | |||
1372 | return r; | ||
1373 | } | ||
1374 | |||
1375 | /** | ||
1376 | * omap_hwmod_get_pwrdm - return pointer to this module's main powerdomain | ||
1377 | * @oh: struct omap_hwmod * | ||
1378 | * | ||
1379 | * Return the powerdomain pointer associated with the OMAP module | ||
1380 | * @oh's main clock. If @oh does not have a main clk, return the | ||
1381 | * powerdomain associated with the interface clock associated with the | ||
1382 | * module's MPU port. (XXX Perhaps this should use the SDMA port | ||
1383 | * instead?) Returns NULL on error, or a struct powerdomain * on | ||
1384 | * success. | ||
1385 | */ | ||
1386 | struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh) | ||
1387 | { | ||
1388 | struct clk *c; | ||
1389 | |||
1390 | if (!oh) | ||
1391 | return NULL; | ||
1392 | |||
1393 | if (oh->_clk) { | ||
1394 | c = oh->_clk; | ||
1395 | } else { | ||
1396 | if (oh->_int_flags & _HWMOD_NO_MPU_PORT) | ||
1397 | return NULL; | ||
1398 | c = oh->slaves[oh->_mpu_port_index]->_clk; | ||
1399 | } | ||
1400 | |||
1401 | return c->clkdm->pwrdm.ptr; | ||
1402 | |||
1403 | } | ||
1404 | |||
1405 | /** | ||
1406 | * omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh | ||
1407 | * @oh: struct omap_hwmod * | ||
1408 | * @init_oh: struct omap_hwmod * (initiator) | ||
1409 | * | ||
1410 | * Add a sleep dependency between the initiator @init_oh and @oh. | ||
1411 | * Intended to be called by DSP/Bridge code via platform_data for the | ||
1412 | * DSP case; and by the DMA code in the sDMA case. DMA code, *Bridge | ||
1413 | * code needs to add/del initiator dependencies dynamically | ||
1414 | * before/after accessing a device. Returns the return value from | ||
1415 | * _add_initiator_dep(). | ||
1416 | * | ||
1417 | * XXX Keep a usecount in the clockdomain code | ||
1418 | */ | ||
1419 | int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh, | ||
1420 | struct omap_hwmod *init_oh) | ||
1421 | { | ||
1422 | return _add_initiator_dep(oh, init_oh); | ||
1423 | } | ||
1424 | |||
1425 | /* | ||
1426 | * XXX what about functions for drivers to save/restore ocp_sysconfig | ||
1427 | * for context save/restore operations? | ||
1428 | */ | ||
1429 | |||
1430 | /** | ||
1431 | * omap_hwmod_del_initiator_dep - remove sleepdep from @init_oh to @oh | ||
1432 | * @oh: struct omap_hwmod * | ||
1433 | * @init_oh: struct omap_hwmod * (initiator) | ||
1434 | * | ||
1435 | * Remove a sleep dependency between the initiator @init_oh and @oh. | ||
1436 | * Intended to be called by DSP/Bridge code via platform_data for the | ||
1437 | * DSP case; and by the DMA code in the sDMA case. DMA code, *Bridge | ||
1438 | * code needs to add/del initiator dependencies dynamically | ||
1439 | * before/after accessing a device. Returns the return value from | ||
1440 | * _del_initiator_dep(). | ||
1441 | * | ||
1442 | * XXX Keep a usecount in the clockdomain code | ||
1443 | */ | ||
1444 | int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh, | ||
1445 | struct omap_hwmod *init_oh) | ||
1446 | { | ||
1447 | return _del_initiator_dep(oh, init_oh); | ||
1448 | } | ||
1449 | |||
1450 | /** | ||
1451 | * omap_hwmod_set_clockact_none - set clockactivity test to BOTH | ||
1452 | * @oh: struct omap_hwmod * | ||
1453 | * | ||
1454 | * On some modules, this function can affect the wakeup latency vs. | ||
1455 | * power consumption balance. Intended to be called by the | ||
1456 | * omap_device layer. Passes along the return value from | ||
1457 | * _write_clockact_lock(). | ||
1458 | */ | ||
1459 | int omap_hwmod_set_clockact_both(struct omap_hwmod *oh) | ||
1460 | { | ||
1461 | return _write_clockact_lock(oh, CLOCKACT_TEST_BOTH); | ||
1462 | } | ||
1463 | |||
1464 | /** | ||
1465 | * omap_hwmod_set_clockact_none - set clockactivity test to MAIN | ||
1466 | * @oh: struct omap_hwmod * | ||
1467 | * | ||
1468 | * On some modules, this function can affect the wakeup latency vs. | ||
1469 | * power consumption balance. Intended to be called by the | ||
1470 | * omap_device layer. Passes along the return value from | ||
1471 | * _write_clockact_lock(). | ||
1472 | */ | ||
1473 | int omap_hwmod_set_clockact_main(struct omap_hwmod *oh) | ||
1474 | { | ||
1475 | return _write_clockact_lock(oh, CLOCKACT_TEST_MAIN); | ||
1476 | } | ||
1477 | |||
1478 | /** | ||
1479 | * omap_hwmod_set_clockact_none - set clockactivity test to ICLK | ||
1480 | * @oh: struct omap_hwmod * | ||
1481 | * | ||
1482 | * On some modules, this function can affect the wakeup latency vs. | ||
1483 | * power consumption balance. Intended to be called by the | ||
1484 | * omap_device layer. Passes along the return value from | ||
1485 | * _write_clockact_lock(). | ||
1486 | */ | ||
1487 | int omap_hwmod_set_clockact_iclk(struct omap_hwmod *oh) | ||
1488 | { | ||
1489 | return _write_clockact_lock(oh, CLOCKACT_TEST_ICLK); | ||
1490 | } | ||
1491 | |||
1492 | /** | ||
1493 | * omap_hwmod_set_clockact_none - set clockactivity test to NONE | ||
1494 | * @oh: struct omap_hwmod * | ||
1495 | * | ||
1496 | * On some modules, this function can affect the wakeup latency vs. | ||
1497 | * power consumption balance. Intended to be called by the | ||
1498 | * omap_device layer. Passes along the return value from | ||
1499 | * _write_clockact_lock(). | ||
1500 | */ | ||
1501 | int omap_hwmod_set_clockact_none(struct omap_hwmod *oh) | ||
1502 | { | ||
1503 | return _write_clockact_lock(oh, CLOCKACT_TEST_NONE); | ||
1504 | } | ||
1505 | |||
1506 | /** | ||
1507 | * omap_hwmod_enable_wakeup - allow device to wake up the system | ||
1508 | * @oh: struct omap_hwmod * | ||
1509 | * | ||
1510 | * Sets the module OCP socket ENAWAKEUP bit to allow the module to | ||
1511 | * send wakeups to the PRCM. Eventually this should sets PRCM wakeup | ||
1512 | * registers to cause the PRCM to receive wakeup events from the | ||
1513 | * module. Does not set any wakeup routing registers beyond this | ||
1514 | * point - if the module is to wake up any other module or subsystem, | ||
1515 | * that must be set separately. Called by omap_device code. Returns | ||
1516 | * -EINVAL on error or 0 upon success. | ||
1517 | */ | ||
1518 | int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) | ||
1519 | { | ||
1520 | if (!oh->sysconfig || | ||
1521 | !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP)) | ||
1522 | return -EINVAL; | ||
1523 | |||
1524 | mutex_lock(&omap_hwmod_mutex); | ||
1525 | _enable_wakeup(oh); | ||
1526 | mutex_unlock(&omap_hwmod_mutex); | ||
1527 | |||
1528 | return 0; | ||
1529 | } | ||
1530 | |||
1531 | /** | ||
1532 | * omap_hwmod_disable_wakeup - prevent device from waking the system | ||
1533 | * @oh: struct omap_hwmod * | ||
1534 | * | ||
1535 | * Clears the module OCP socket ENAWAKEUP bit to prevent the module | ||
1536 | * from sending wakeups to the PRCM. Eventually this should clear | ||
1537 | * PRCM wakeup registers to cause the PRCM to ignore wakeup events | ||
1538 | * from the module. Does not set any wakeup routing registers beyond | ||
1539 | * this point - if the module is to wake up any other module or | ||
1540 | * subsystem, that must be set separately. Called by omap_device | ||
1541 | * code. Returns -EINVAL on error or 0 upon success. | ||
1542 | */ | ||
1543 | int omap_hwmod_disable_wakeup(struct omap_hwmod *oh) | ||
1544 | { | ||
1545 | if (!oh->sysconfig || | ||
1546 | !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP)) | ||
1547 | return -EINVAL; | ||
1548 | |||
1549 | mutex_lock(&omap_hwmod_mutex); | ||
1550 | _disable_wakeup(oh); | ||
1551 | mutex_unlock(&omap_hwmod_mutex); | ||
1552 | |||
1553 | return 0; | ||
1554 | } | ||
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420.h b/arch/arm/mach-omap2/omap_hwmod_2420.h new file mode 100644 index 000000000000..767e4965ac4e --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_2420.h | |||
@@ -0,0 +1,141 @@ | |||
1 | /* | ||
2 | * omap_hwmod_2420.h - hardware modules present on the OMAP2420 chips | ||
3 | * | ||
4 | * Copyright (C) 2009 Nokia Corporation | ||
5 | * Paul Walmsley | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * XXX handle crossbar/shared link difference for L3? | ||
12 | * | ||
13 | */ | ||
14 | #ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2420_H | ||
15 | #define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2420_H | ||
16 | |||
17 | #ifdef CONFIG_ARCH_OMAP2420 | ||
18 | |||
19 | #include <mach/omap_hwmod.h> | ||
20 | #include <mach/irqs.h> | ||
21 | #include <mach/cpu.h> | ||
22 | #include <mach/dma.h> | ||
23 | |||
24 | #include "prm-regbits-24xx.h" | ||
25 | |||
26 | static struct omap_hwmod omap2420_mpu_hwmod; | ||
27 | static struct omap_hwmod omap2420_l3_hwmod; | ||
28 | static struct omap_hwmod omap2420_l4_core_hwmod; | ||
29 | |||
30 | /* L3 -> L4_CORE interface */ | ||
31 | static struct omap_hwmod_ocp_if omap2420_l3__l4_core = { | ||
32 | .master = &omap2420_l3_hwmod, | ||
33 | .slave = &omap2420_l4_core_hwmod, | ||
34 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
35 | }; | ||
36 | |||
37 | /* MPU -> L3 interface */ | ||
38 | static struct omap_hwmod_ocp_if omap2420_mpu__l3 = { | ||
39 | .master = &omap2420_mpu_hwmod, | ||
40 | .slave = &omap2420_l3_hwmod, | ||
41 | .user = OCP_USER_MPU, | ||
42 | }; | ||
43 | |||
44 | /* Slave interfaces on the L3 interconnect */ | ||
45 | static struct omap_hwmod_ocp_if *omap2420_l3_slaves[] = { | ||
46 | &omap2420_mpu__l3, | ||
47 | }; | ||
48 | |||
49 | /* Master interfaces on the L3 interconnect */ | ||
50 | static struct omap_hwmod_ocp_if *omap2420_l3_masters[] = { | ||
51 | &omap2420_l3__l4_core, | ||
52 | }; | ||
53 | |||
54 | /* L3 */ | ||
55 | static struct omap_hwmod omap2420_l3_hwmod = { | ||
56 | .name = "l3_hwmod", | ||
57 | .masters = omap2420_l3_masters, | ||
58 | .masters_cnt = ARRAY_SIZE(omap2420_l3_masters), | ||
59 | .slaves = omap2420_l3_slaves, | ||
60 | .slaves_cnt = ARRAY_SIZE(omap2420_l3_slaves), | ||
61 | .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) | ||
62 | }; | ||
63 | |||
64 | static struct omap_hwmod omap2420_l4_wkup_hwmod; | ||
65 | |||
66 | /* L4_CORE -> L4_WKUP interface */ | ||
67 | static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = { | ||
68 | .master = &omap2420_l4_core_hwmod, | ||
69 | .slave = &omap2420_l4_wkup_hwmod, | ||
70 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
71 | }; | ||
72 | |||
73 | /* Slave interfaces on the L4_CORE interconnect */ | ||
74 | static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = { | ||
75 | &omap2420_l3__l4_core, | ||
76 | }; | ||
77 | |||
78 | /* Master interfaces on the L4_CORE interconnect */ | ||
79 | static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = { | ||
80 | &omap2420_l4_core__l4_wkup, | ||
81 | }; | ||
82 | |||
83 | /* L4 CORE */ | ||
84 | static struct omap_hwmod omap2420_l4_core_hwmod = { | ||
85 | .name = "l4_core_hwmod", | ||
86 | .masters = omap2420_l4_core_masters, | ||
87 | .masters_cnt = ARRAY_SIZE(omap2420_l4_core_masters), | ||
88 | .slaves = omap2420_l4_core_slaves, | ||
89 | .slaves_cnt = ARRAY_SIZE(omap2420_l4_core_slaves), | ||
90 | .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) | ||
91 | }; | ||
92 | |||
93 | /* Slave interfaces on the L4_WKUP interconnect */ | ||
94 | static struct omap_hwmod_ocp_if *omap2420_l4_wkup_slaves[] = { | ||
95 | &omap2420_l4_core__l4_wkup, | ||
96 | }; | ||
97 | |||
98 | /* Master interfaces on the L4_WKUP interconnect */ | ||
99 | static struct omap_hwmod_ocp_if *omap2420_l4_wkup_masters[] = { | ||
100 | }; | ||
101 | |||
102 | /* L4 WKUP */ | ||
103 | static struct omap_hwmod omap2420_l4_wkup_hwmod = { | ||
104 | .name = "l4_wkup_hwmod", | ||
105 | .masters = omap2420_l4_wkup_masters, | ||
106 | .masters_cnt = ARRAY_SIZE(omap2420_l4_wkup_masters), | ||
107 | .slaves = omap2420_l4_wkup_slaves, | ||
108 | .slaves_cnt = ARRAY_SIZE(omap2420_l4_wkup_slaves), | ||
109 | .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) | ||
110 | }; | ||
111 | |||
112 | /* Master interfaces on the MPU device */ | ||
113 | static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = { | ||
114 | &omap2420_mpu__l3, | ||
115 | }; | ||
116 | |||
117 | /* MPU */ | ||
118 | static struct omap_hwmod omap2420_mpu_hwmod = { | ||
119 | .name = "mpu_hwmod", | ||
120 | .clkdev_dev_id = NULL, | ||
121 | .clkdev_con_id = "mpu_ck", | ||
122 | .masters = omap2420_mpu_masters, | ||
123 | .masters_cnt = ARRAY_SIZE(omap2420_mpu_masters), | ||
124 | .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), | ||
125 | }; | ||
126 | |||
127 | static __initdata struct omap_hwmod *omap2420_hwmods[] = { | ||
128 | &omap2420_l3_hwmod, | ||
129 | &omap2420_l4_core_hwmod, | ||
130 | &omap2420_l4_wkup_hwmod, | ||
131 | &omap2420_mpu_hwmod, | ||
132 | NULL, | ||
133 | }; | ||
134 | |||
135 | #else | ||
136 | # define omap2420_hwmods 0 | ||
137 | #endif | ||
138 | |||
139 | #endif | ||
140 | |||
141 | |||
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430.h b/arch/arm/mach-omap2/omap_hwmod_2430.h new file mode 100644 index 000000000000..a412be6420ec --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_2430.h | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * omap_hwmod_2430.h - hardware modules present on the OMAP2430 chips | ||
3 | * | ||
4 | * Copyright (C) 2009 Nokia Corporation | ||
5 | * Paul Walmsley | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * XXX handle crossbar/shared link difference for L3? | ||
12 | * | ||
13 | */ | ||
14 | #ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2430_H | ||
15 | #define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2430_H | ||
16 | |||
17 | #ifdef CONFIG_ARCH_OMAP2430 | ||
18 | |||
19 | #include <mach/omap_hwmod.h> | ||
20 | #include <mach/irqs.h> | ||
21 | #include <mach/cpu.h> | ||
22 | #include <mach/dma.h> | ||
23 | |||
24 | #include "prm-regbits-24xx.h" | ||
25 | |||
26 | static struct omap_hwmod omap2430_mpu_hwmod; | ||
27 | static struct omap_hwmod omap2430_l3_hwmod; | ||
28 | static struct omap_hwmod omap2430_l4_core_hwmod; | ||
29 | |||
30 | /* L3 -> L4_CORE interface */ | ||
31 | static struct omap_hwmod_ocp_if omap2430_l3__l4_core = { | ||
32 | .master = &omap2430_l3_hwmod, | ||
33 | .slave = &omap2430_l4_core_hwmod, | ||
34 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
35 | }; | ||
36 | |||
37 | /* MPU -> L3 interface */ | ||
38 | static struct omap_hwmod_ocp_if omap2430_mpu__l3 = { | ||
39 | .master = &omap2430_mpu_hwmod, | ||
40 | .slave = &omap2430_l3_hwmod, | ||
41 | .user = OCP_USER_MPU, | ||
42 | }; | ||
43 | |||
44 | /* Slave interfaces on the L3 interconnect */ | ||
45 | static struct omap_hwmod_ocp_if *omap2430_l3_slaves[] = { | ||
46 | &omap2430_mpu__l3, | ||
47 | }; | ||
48 | |||
49 | /* Master interfaces on the L3 interconnect */ | ||
50 | static struct omap_hwmod_ocp_if *omap2430_l3_masters[] = { | ||
51 | &omap2430_l3__l4_core, | ||
52 | }; | ||
53 | |||
54 | /* L3 */ | ||
55 | static struct omap_hwmod omap2430_l3_hwmod = { | ||
56 | .name = "l3_hwmod", | ||
57 | .masters = omap2430_l3_masters, | ||
58 | .masters_cnt = ARRAY_SIZE(omap2430_l3_masters), | ||
59 | .slaves = omap2430_l3_slaves, | ||
60 | .slaves_cnt = ARRAY_SIZE(omap2430_l3_slaves), | ||
61 | .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) | ||
62 | }; | ||
63 | |||
64 | static struct omap_hwmod omap2430_l4_wkup_hwmod; | ||
65 | static struct omap_hwmod omap2430_mmc1_hwmod; | ||
66 | static struct omap_hwmod omap2430_mmc2_hwmod; | ||
67 | |||
68 | /* L4_CORE -> L4_WKUP interface */ | ||
69 | static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = { | ||
70 | .master = &omap2430_l4_core_hwmod, | ||
71 | .slave = &omap2430_l4_wkup_hwmod, | ||
72 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
73 | }; | ||
74 | |||
75 | /* Slave interfaces on the L4_CORE interconnect */ | ||
76 | static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = { | ||
77 | &omap2430_l3__l4_core, | ||
78 | }; | ||
79 | |||
80 | /* Master interfaces on the L4_CORE interconnect */ | ||
81 | static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = { | ||
82 | &omap2430_l4_core__l4_wkup, | ||
83 | }; | ||
84 | |||
85 | /* L4 CORE */ | ||
86 | static struct omap_hwmod omap2430_l4_core_hwmod = { | ||
87 | .name = "l4_core_hwmod", | ||
88 | .masters = omap2430_l4_core_masters, | ||
89 | .masters_cnt = ARRAY_SIZE(omap2430_l4_core_masters), | ||
90 | .slaves = omap2430_l4_core_slaves, | ||
91 | .slaves_cnt = ARRAY_SIZE(omap2430_l4_core_slaves), | ||
92 | .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) | ||
93 | }; | ||
94 | |||
95 | /* Slave interfaces on the L4_WKUP interconnect */ | ||
96 | static struct omap_hwmod_ocp_if *omap2430_l4_wkup_slaves[] = { | ||
97 | &omap2430_l4_core__l4_wkup, | ||
98 | }; | ||
99 | |||
100 | /* Master interfaces on the L4_WKUP interconnect */ | ||
101 | static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = { | ||
102 | }; | ||
103 | |||
104 | /* L4 WKUP */ | ||
105 | static struct omap_hwmod omap2430_l4_wkup_hwmod = { | ||
106 | .name = "l4_wkup_hwmod", | ||
107 | .masters = omap2430_l4_wkup_masters, | ||
108 | .masters_cnt = ARRAY_SIZE(omap2430_l4_wkup_masters), | ||
109 | .slaves = omap2430_l4_wkup_slaves, | ||
110 | .slaves_cnt = ARRAY_SIZE(omap2430_l4_wkup_slaves), | ||
111 | .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) | ||
112 | }; | ||
113 | |||
114 | /* Master interfaces on the MPU device */ | ||
115 | static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = { | ||
116 | &omap2430_mpu__l3, | ||
117 | }; | ||
118 | |||
119 | /* MPU */ | ||
120 | static struct omap_hwmod omap2430_mpu_hwmod = { | ||
121 | .name = "mpu_hwmod", | ||
122 | .clkdev_dev_id = NULL, | ||
123 | .clkdev_con_id = "mpu_ck", | ||
124 | .masters = omap2430_mpu_masters, | ||
125 | .masters_cnt = ARRAY_SIZE(omap2430_mpu_masters), | ||
126 | .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), | ||
127 | }; | ||
128 | |||
129 | static __initdata struct omap_hwmod *omap2430_hwmods[] = { | ||
130 | &omap2430_l3_hwmod, | ||
131 | &omap2430_l4_core_hwmod, | ||
132 | &omap2430_l4_wkup_hwmod, | ||
133 | &omap2430_mpu_hwmod, | ||
134 | NULL, | ||
135 | }; | ||
136 | |||
137 | #else | ||
138 | # define omap2430_hwmods 0 | ||
139 | #endif | ||
140 | |||
141 | #endif | ||
142 | |||
143 | |||
diff --git a/arch/arm/mach-omap2/omap_hwmod_34xx.h b/arch/arm/mach-omap2/omap_hwmod_34xx.h new file mode 100644 index 000000000000..1e069f831575 --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_34xx.h | |||
@@ -0,0 +1,168 @@ | |||
1 | /* | ||
2 | * omap_hwmod_34xx.h - hardware modules present on the OMAP34xx chips | ||
3 | * | ||
4 | * Copyright (C) 2009 Nokia Corporation | ||
5 | * Paul Walmsley | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | */ | ||
12 | #ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD34XX_H | ||
13 | #define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD34XX_H | ||
14 | |||
15 | #ifdef CONFIG_ARCH_OMAP34XX | ||
16 | |||
17 | #include <mach/omap_hwmod.h> | ||
18 | #include <mach/irqs.h> | ||
19 | #include <mach/cpu.h> | ||
20 | #include <mach/dma.h> | ||
21 | |||
22 | #include "prm-regbits-34xx.h" | ||
23 | |||
24 | static struct omap_hwmod omap34xx_mpu_hwmod; | ||
25 | static struct omap_hwmod omap34xx_l3_hwmod; | ||
26 | static struct omap_hwmod omap34xx_l4_core_hwmod; | ||
27 | static struct omap_hwmod omap34xx_l4_per_hwmod; | ||
28 | |||
29 | /* L3 -> L4_CORE interface */ | ||
30 | static struct omap_hwmod_ocp_if omap34xx_l3__l4_core = { | ||
31 | .master = &omap34xx_l3_hwmod, | ||
32 | .slave = &omap34xx_l4_core_hwmod, | ||
33 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
34 | }; | ||
35 | |||
36 | /* L3 -> L4_PER interface */ | ||
37 | static struct omap_hwmod_ocp_if omap34xx_l3__l4_per = { | ||
38 | .master = &omap34xx_l3_hwmod, | ||
39 | .slave = &omap34xx_l4_per_hwmod, | ||
40 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
41 | }; | ||
42 | |||
43 | /* MPU -> L3 interface */ | ||
44 | static struct omap_hwmod_ocp_if omap34xx_mpu__l3 = { | ||
45 | .master = &omap34xx_mpu_hwmod, | ||
46 | .slave = &omap34xx_l3_hwmod, | ||
47 | .user = OCP_USER_MPU, | ||
48 | }; | ||
49 | |||
50 | /* Slave interfaces on the L3 interconnect */ | ||
51 | static struct omap_hwmod_ocp_if *omap34xx_l3_slaves[] = { | ||
52 | &omap34xx_mpu__l3, | ||
53 | }; | ||
54 | |||
55 | /* Master interfaces on the L3 interconnect */ | ||
56 | static struct omap_hwmod_ocp_if *omap34xx_l3_masters[] = { | ||
57 | &omap34xx_l3__l4_core, | ||
58 | &omap34xx_l3__l4_per, | ||
59 | }; | ||
60 | |||
61 | /* L3 */ | ||
62 | static struct omap_hwmod omap34xx_l3_hwmod = { | ||
63 | .name = "l3_hwmod", | ||
64 | .masters = omap34xx_l3_masters, | ||
65 | .masters_cnt = ARRAY_SIZE(omap34xx_l3_masters), | ||
66 | .slaves = omap34xx_l3_slaves, | ||
67 | .slaves_cnt = ARRAY_SIZE(omap34xx_l3_slaves), | ||
68 | .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) | ||
69 | }; | ||
70 | |||
71 | static struct omap_hwmod omap34xx_l4_wkup_hwmod; | ||
72 | |||
73 | /* L4_CORE -> L4_WKUP interface */ | ||
74 | static struct omap_hwmod_ocp_if omap34xx_l4_core__l4_wkup = { | ||
75 | .master = &omap34xx_l4_core_hwmod, | ||
76 | .slave = &omap34xx_l4_wkup_hwmod, | ||
77 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
78 | }; | ||
79 | |||
80 | /* Slave interfaces on the L4_CORE interconnect */ | ||
81 | static struct omap_hwmod_ocp_if *omap34xx_l4_core_slaves[] = { | ||
82 | &omap34xx_l3__l4_core, | ||
83 | }; | ||
84 | |||
85 | /* Master interfaces on the L4_CORE interconnect */ | ||
86 | static struct omap_hwmod_ocp_if *omap34xx_l4_core_masters[] = { | ||
87 | &omap34xx_l4_core__l4_wkup, | ||
88 | }; | ||
89 | |||
90 | /* L4 CORE */ | ||
91 | static struct omap_hwmod omap34xx_l4_core_hwmod = { | ||
92 | .name = "l4_core_hwmod", | ||
93 | .masters = omap34xx_l4_core_masters, | ||
94 | .masters_cnt = ARRAY_SIZE(omap34xx_l4_core_masters), | ||
95 | .slaves = omap34xx_l4_core_slaves, | ||
96 | .slaves_cnt = ARRAY_SIZE(omap34xx_l4_core_slaves), | ||
97 | .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) | ||
98 | }; | ||
99 | |||
100 | /* Slave interfaces on the L4_PER interconnect */ | ||
101 | static struct omap_hwmod_ocp_if *omap34xx_l4_per_slaves[] = { | ||
102 | &omap34xx_l3__l4_per, | ||
103 | }; | ||
104 | |||
105 | /* Master interfaces on the L4_PER interconnect */ | ||
106 | static struct omap_hwmod_ocp_if *omap34xx_l4_per_masters[] = { | ||
107 | }; | ||
108 | |||
109 | /* L4 PER */ | ||
110 | static struct omap_hwmod omap34xx_l4_per_hwmod = { | ||
111 | .name = "l4_per_hwmod", | ||
112 | .masters = omap34xx_l4_per_masters, | ||
113 | .masters_cnt = ARRAY_SIZE(omap34xx_l4_per_masters), | ||
114 | .slaves = omap34xx_l4_per_slaves, | ||
115 | .slaves_cnt = ARRAY_SIZE(omap34xx_l4_per_slaves), | ||
116 | .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) | ||
117 | }; | ||
118 | |||
119 | /* Slave interfaces on the L4_WKUP interconnect */ | ||
120 | static struct omap_hwmod_ocp_if *omap34xx_l4_wkup_slaves[] = { | ||
121 | &omap34xx_l4_core__l4_wkup, | ||
122 | }; | ||
123 | |||
124 | /* Master interfaces on the L4_WKUP interconnect */ | ||
125 | static struct omap_hwmod_ocp_if *omap34xx_l4_wkup_masters[] = { | ||
126 | }; | ||
127 | |||
128 | /* L4 WKUP */ | ||
129 | static struct omap_hwmod omap34xx_l4_wkup_hwmod = { | ||
130 | .name = "l4_wkup_hwmod", | ||
131 | .masters = omap34xx_l4_wkup_masters, | ||
132 | .masters_cnt = ARRAY_SIZE(omap34xx_l4_wkup_masters), | ||
133 | .slaves = omap34xx_l4_wkup_slaves, | ||
134 | .slaves_cnt = ARRAY_SIZE(omap34xx_l4_wkup_slaves), | ||
135 | .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) | ||
136 | }; | ||
137 | |||
138 | /* Master interfaces on the MPU device */ | ||
139 | static struct omap_hwmod_ocp_if *omap34xx_mpu_masters[] = { | ||
140 | &omap34xx_mpu__l3, | ||
141 | }; | ||
142 | |||
143 | /* MPU */ | ||
144 | static struct omap_hwmod omap34xx_mpu_hwmod = { | ||
145 | .name = "mpu_hwmod", | ||
146 | .clkdev_dev_id = NULL, | ||
147 | .clkdev_con_id = "arm_fck", | ||
148 | .masters = omap34xx_mpu_masters, | ||
149 | .masters_cnt = ARRAY_SIZE(omap34xx_mpu_masters), | ||
150 | .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), | ||
151 | }; | ||
152 | |||
153 | static __initdata struct omap_hwmod *omap34xx_hwmods[] = { | ||
154 | &omap34xx_l3_hwmod, | ||
155 | &omap34xx_l4_core_hwmod, | ||
156 | &omap34xx_l4_per_hwmod, | ||
157 | &omap34xx_l4_wkup_hwmod, | ||
158 | &omap34xx_mpu_hwmod, | ||
159 | NULL, | ||
160 | }; | ||
161 | |||
162 | #else | ||
163 | # define omap34xx_hwmods 0 | ||
164 | #endif | ||
165 | |||
166 | #endif | ||
167 | |||
168 | |||
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 6cc375a275be..1b4c1600f8d8 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c | |||
@@ -20,13 +20,16 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/timer.h> | 23 | #include <linux/sched.h> |
24 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
25 | #include <linux/err.h> | 25 | #include <linux/err.h> |
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/module.h> | ||
27 | 28 | ||
28 | #include <mach/clock.h> | 29 | #include <mach/clock.h> |
29 | #include <mach/board.h> | 30 | #include <mach/board.h> |
31 | #include <mach/powerdomain.h> | ||
32 | #include <mach/clockdomain.h> | ||
30 | 33 | ||
31 | #include "prm.h" | 34 | #include "prm.h" |
32 | #include "cm.h" | 35 | #include "cm.h" |
@@ -48,7 +51,9 @@ int omap2_pm_debug; | |||
48 | regs[reg_count++].val = __raw_readl(reg) | 51 | regs[reg_count++].val = __raw_readl(reg) |
49 | #define DUMP_INTC_REG(reg, off) \ | 52 | #define DUMP_INTC_REG(reg, off) \ |
50 | regs[reg_count].name = #reg; \ | 53 | regs[reg_count].name = #reg; \ |
51 | regs[reg_count++].val = __raw_readl(IO_ADDRESS(0x480fe000 + (off))) | 54 | regs[reg_count++].val = __raw_readl(OMAP2_IO_ADDRESS(0x480fe000 + (off))) |
55 | |||
56 | static int __init pm_dbg_init(void); | ||
52 | 57 | ||
53 | void omap2_pm_dump(int mode, int resume, unsigned int us) | 58 | void omap2_pm_dump(int mode, int resume, unsigned int us) |
54 | { | 59 | { |
@@ -150,3 +155,425 @@ void omap2_pm_dump(int mode, int resume, unsigned int us) | |||
150 | for (i = 0; i < reg_count; i++) | 155 | for (i = 0; i < reg_count; i++) |
151 | printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val); | 156 | printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val); |
152 | } | 157 | } |
158 | |||
159 | #ifdef CONFIG_DEBUG_FS | ||
160 | #include <linux/debugfs.h> | ||
161 | #include <linux/seq_file.h> | ||
162 | |||
163 | static void pm_dbg_regset_store(u32 *ptr); | ||
164 | |||
165 | struct dentry *pm_dbg_dir; | ||
166 | |||
167 | static int pm_dbg_init_done; | ||
168 | |||
169 | enum { | ||
170 | DEBUG_FILE_COUNTERS = 0, | ||
171 | DEBUG_FILE_TIMERS, | ||
172 | }; | ||
173 | |||
174 | struct pm_module_def { | ||
175 | char name[8]; /* Name of the module */ | ||
176 | short type; /* CM or PRM */ | ||
177 | unsigned short offset; | ||
178 | int low; /* First register address on this module */ | ||
179 | int high; /* Last register address on this module */ | ||
180 | }; | ||
181 | |||
182 | #define MOD_CM 0 | ||
183 | #define MOD_PRM 1 | ||
184 | |||
185 | static const struct pm_module_def *pm_dbg_reg_modules; | ||
186 | static const struct pm_module_def omap3_pm_reg_modules[] = { | ||
187 | { "IVA2", MOD_CM, OMAP3430_IVA2_MOD, 0, 0x4c }, | ||
188 | { "OCP", MOD_CM, OCP_MOD, 0, 0x10 }, | ||
189 | { "MPU", MOD_CM, MPU_MOD, 4, 0x4c }, | ||
190 | { "CORE", MOD_CM, CORE_MOD, 0, 0x4c }, | ||
191 | { "SGX", MOD_CM, OMAP3430ES2_SGX_MOD, 0, 0x4c }, | ||
192 | { "WKUP", MOD_CM, WKUP_MOD, 0, 0x40 }, | ||
193 | { "CCR", MOD_CM, PLL_MOD, 0, 0x70 }, | ||
194 | { "DSS", MOD_CM, OMAP3430_DSS_MOD, 0, 0x4c }, | ||
195 | { "CAM", MOD_CM, OMAP3430_CAM_MOD, 0, 0x4c }, | ||
196 | { "PER", MOD_CM, OMAP3430_PER_MOD, 0, 0x4c }, | ||
197 | { "EMU", MOD_CM, OMAP3430_EMU_MOD, 0x40, 0x54 }, | ||
198 | { "NEON", MOD_CM, OMAP3430_NEON_MOD, 0x20, 0x48 }, | ||
199 | { "USB", MOD_CM, OMAP3430ES2_USBHOST_MOD, 0, 0x4c }, | ||
200 | |||
201 | { "IVA2", MOD_PRM, OMAP3430_IVA2_MOD, 0x50, 0xfc }, | ||
202 | { "OCP", MOD_PRM, OCP_MOD, 4, 0x1c }, | ||
203 | { "MPU", MOD_PRM, MPU_MOD, 0x58, 0xe8 }, | ||
204 | { "CORE", MOD_PRM, CORE_MOD, 0x58, 0xf8 }, | ||
205 | { "SGX", MOD_PRM, OMAP3430ES2_SGX_MOD, 0x58, 0xe8 }, | ||
206 | { "WKUP", MOD_PRM, WKUP_MOD, 0xa0, 0xb0 }, | ||
207 | { "CCR", MOD_PRM, PLL_MOD, 0x40, 0x70 }, | ||
208 | { "DSS", MOD_PRM, OMAP3430_DSS_MOD, 0x58, 0xe8 }, | ||
209 | { "CAM", MOD_PRM, OMAP3430_CAM_MOD, 0x58, 0xe8 }, | ||
210 | { "PER", MOD_PRM, OMAP3430_PER_MOD, 0x58, 0xe8 }, | ||
211 | { "EMU", MOD_PRM, OMAP3430_EMU_MOD, 0x58, 0xe4 }, | ||
212 | { "GLBL", MOD_PRM, OMAP3430_GR_MOD, 0x20, 0xe4 }, | ||
213 | { "NEON", MOD_PRM, OMAP3430_NEON_MOD, 0x58, 0xe8 }, | ||
214 | { "USB", MOD_PRM, OMAP3430ES2_USBHOST_MOD, 0x58, 0xe8 }, | ||
215 | { "", 0, 0, 0, 0 }, | ||
216 | }; | ||
217 | |||
218 | #define PM_DBG_MAX_REG_SETS 4 | ||
219 | |||
220 | static void *pm_dbg_reg_set[PM_DBG_MAX_REG_SETS]; | ||
221 | |||
222 | static int pm_dbg_get_regset_size(void) | ||
223 | { | ||
224 | static int regset_size; | ||
225 | |||
226 | if (regset_size == 0) { | ||
227 | int i = 0; | ||
228 | |||
229 | while (pm_dbg_reg_modules[i].name[0] != 0) { | ||
230 | regset_size += pm_dbg_reg_modules[i].high + | ||
231 | 4 - pm_dbg_reg_modules[i].low; | ||
232 | i++; | ||
233 | } | ||
234 | } | ||
235 | return regset_size; | ||
236 | } | ||
237 | |||
238 | static int pm_dbg_show_regs(struct seq_file *s, void *unused) | ||
239 | { | ||
240 | int i, j; | ||
241 | unsigned long val; | ||
242 | int reg_set = (int)s->private; | ||
243 | u32 *ptr; | ||
244 | void *store = NULL; | ||
245 | int regs; | ||
246 | int linefeed; | ||
247 | |||
248 | if (reg_set == 0) { | ||
249 | store = kmalloc(pm_dbg_get_regset_size(), GFP_KERNEL); | ||
250 | ptr = store; | ||
251 | pm_dbg_regset_store(ptr); | ||
252 | } else { | ||
253 | ptr = pm_dbg_reg_set[reg_set - 1]; | ||
254 | } | ||
255 | |||
256 | i = 0; | ||
257 | |||
258 | while (pm_dbg_reg_modules[i].name[0] != 0) { | ||
259 | regs = 0; | ||
260 | linefeed = 0; | ||
261 | if (pm_dbg_reg_modules[i].type == MOD_CM) | ||
262 | seq_printf(s, "MOD: CM_%s (%08x)\n", | ||
263 | pm_dbg_reg_modules[i].name, | ||
264 | (u32)(OMAP3430_CM_BASE + | ||
265 | pm_dbg_reg_modules[i].offset)); | ||
266 | else | ||
267 | seq_printf(s, "MOD: PRM_%s (%08x)\n", | ||
268 | pm_dbg_reg_modules[i].name, | ||
269 | (u32)(OMAP3430_PRM_BASE + | ||
270 | pm_dbg_reg_modules[i].offset)); | ||
271 | |||
272 | for (j = pm_dbg_reg_modules[i].low; | ||
273 | j <= pm_dbg_reg_modules[i].high; j += 4) { | ||
274 | val = *(ptr++); | ||
275 | if (val != 0) { | ||
276 | regs++; | ||
277 | if (linefeed) { | ||
278 | seq_printf(s, "\n"); | ||
279 | linefeed = 0; | ||
280 | } | ||
281 | seq_printf(s, " %02x => %08lx", j, val); | ||
282 | if (regs % 4 == 0) | ||
283 | linefeed = 1; | ||
284 | } | ||
285 | } | ||
286 | seq_printf(s, "\n"); | ||
287 | i++; | ||
288 | } | ||
289 | |||
290 | if (store != NULL) | ||
291 | kfree(store); | ||
292 | |||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static void pm_dbg_regset_store(u32 *ptr) | ||
297 | { | ||
298 | int i, j; | ||
299 | u32 val; | ||
300 | |||
301 | i = 0; | ||
302 | |||
303 | while (pm_dbg_reg_modules[i].name[0] != 0) { | ||
304 | for (j = pm_dbg_reg_modules[i].low; | ||
305 | j <= pm_dbg_reg_modules[i].high; j += 4) { | ||
306 | if (pm_dbg_reg_modules[i].type == MOD_CM) | ||
307 | val = cm_read_mod_reg( | ||
308 | pm_dbg_reg_modules[i].offset, j); | ||
309 | else | ||
310 | val = prm_read_mod_reg( | ||
311 | pm_dbg_reg_modules[i].offset, j); | ||
312 | *(ptr++) = val; | ||
313 | } | ||
314 | i++; | ||
315 | } | ||
316 | } | ||
317 | |||
318 | int pm_dbg_regset_save(int reg_set) | ||
319 | { | ||
320 | if (pm_dbg_reg_set[reg_set-1] == NULL) | ||
321 | return -EINVAL; | ||
322 | |||
323 | pm_dbg_regset_store(pm_dbg_reg_set[reg_set-1]); | ||
324 | |||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | static const char pwrdm_state_names[][4] = { | ||
329 | "OFF", | ||
330 | "RET", | ||
331 | "INA", | ||
332 | "ON" | ||
333 | }; | ||
334 | |||
335 | void pm_dbg_update_time(struct powerdomain *pwrdm, int prev) | ||
336 | { | ||
337 | s64 t; | ||
338 | |||
339 | if (!pm_dbg_init_done) | ||
340 | return ; | ||
341 | |||
342 | /* Update timer for previous state */ | ||
343 | t = sched_clock(); | ||
344 | |||
345 | pwrdm->state_timer[prev] += t - pwrdm->timer; | ||
346 | |||
347 | pwrdm->timer = t; | ||
348 | } | ||
349 | |||
350 | static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user) | ||
351 | { | ||
352 | struct seq_file *s = (struct seq_file *)user; | ||
353 | |||
354 | if (strcmp(clkdm->name, "emu_clkdm") == 0 || | ||
355 | strcmp(clkdm->name, "wkup_clkdm") == 0 || | ||
356 | strncmp(clkdm->name, "dpll", 4) == 0) | ||
357 | return 0; | ||
358 | |||
359 | seq_printf(s, "%s->%s (%d)", clkdm->name, | ||
360 | clkdm->pwrdm.ptr->name, | ||
361 | atomic_read(&clkdm->usecount)); | ||
362 | seq_printf(s, "\n"); | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | static int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *user) | ||
368 | { | ||
369 | struct seq_file *s = (struct seq_file *)user; | ||
370 | int i; | ||
371 | |||
372 | if (strcmp(pwrdm->name, "emu_pwrdm") == 0 || | ||
373 | strcmp(pwrdm->name, "wkup_pwrdm") == 0 || | ||
374 | strncmp(pwrdm->name, "dpll", 4) == 0) | ||
375 | return 0; | ||
376 | |||
377 | if (pwrdm->state != pwrdm_read_pwrst(pwrdm)) | ||
378 | printk(KERN_ERR "pwrdm state mismatch(%s) %d != %d\n", | ||
379 | pwrdm->name, pwrdm->state, pwrdm_read_pwrst(pwrdm)); | ||
380 | |||
381 | seq_printf(s, "%s (%s)", pwrdm->name, | ||
382 | pwrdm_state_names[pwrdm->state]); | ||
383 | for (i = 0; i < 4; i++) | ||
384 | seq_printf(s, ",%s:%d", pwrdm_state_names[i], | ||
385 | pwrdm->state_counter[i]); | ||
386 | |||
387 | seq_printf(s, "\n"); | ||
388 | |||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user) | ||
393 | { | ||
394 | struct seq_file *s = (struct seq_file *)user; | ||
395 | int i; | ||
396 | |||
397 | if (strcmp(pwrdm->name, "emu_pwrdm") == 0 || | ||
398 | strcmp(pwrdm->name, "wkup_pwrdm") == 0 || | ||
399 | strncmp(pwrdm->name, "dpll", 4) == 0) | ||
400 | return 0; | ||
401 | |||
402 | pwrdm_state_switch(pwrdm); | ||
403 | |||
404 | seq_printf(s, "%s (%s)", pwrdm->name, | ||
405 | pwrdm_state_names[pwrdm->state]); | ||
406 | |||
407 | for (i = 0; i < 4; i++) | ||
408 | seq_printf(s, ",%s:%lld", pwrdm_state_names[i], | ||
409 | pwrdm->state_timer[i]); | ||
410 | |||
411 | seq_printf(s, "\n"); | ||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | static int pm_dbg_show_counters(struct seq_file *s, void *unused) | ||
416 | { | ||
417 | pwrdm_for_each(pwrdm_dbg_show_counter, s); | ||
418 | clkdm_for_each(clkdm_dbg_show_counter, s); | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static int pm_dbg_show_timers(struct seq_file *s, void *unused) | ||
424 | { | ||
425 | pwrdm_for_each(pwrdm_dbg_show_timer, s); | ||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | static int pm_dbg_open(struct inode *inode, struct file *file) | ||
430 | { | ||
431 | switch ((int)inode->i_private) { | ||
432 | case DEBUG_FILE_COUNTERS: | ||
433 | return single_open(file, pm_dbg_show_counters, | ||
434 | &inode->i_private); | ||
435 | case DEBUG_FILE_TIMERS: | ||
436 | default: | ||
437 | return single_open(file, pm_dbg_show_timers, | ||
438 | &inode->i_private); | ||
439 | }; | ||
440 | } | ||
441 | |||
442 | static int pm_dbg_reg_open(struct inode *inode, struct file *file) | ||
443 | { | ||
444 | return single_open(file, pm_dbg_show_regs, inode->i_private); | ||
445 | } | ||
446 | |||
447 | static const struct file_operations debug_fops = { | ||
448 | .open = pm_dbg_open, | ||
449 | .read = seq_read, | ||
450 | .llseek = seq_lseek, | ||
451 | .release = single_release, | ||
452 | }; | ||
453 | |||
454 | static const struct file_operations debug_reg_fops = { | ||
455 | .open = pm_dbg_reg_open, | ||
456 | .read = seq_read, | ||
457 | .llseek = seq_lseek, | ||
458 | .release = single_release, | ||
459 | }; | ||
460 | |||
461 | int pm_dbg_regset_init(int reg_set) | ||
462 | { | ||
463 | char name[2]; | ||
464 | |||
465 | if (!pm_dbg_init_done) | ||
466 | pm_dbg_init(); | ||
467 | |||
468 | if (reg_set < 1 || reg_set > PM_DBG_MAX_REG_SETS || | ||
469 | pm_dbg_reg_set[reg_set-1] != NULL) | ||
470 | return -EINVAL; | ||
471 | |||
472 | pm_dbg_reg_set[reg_set-1] = | ||
473 | kmalloc(pm_dbg_get_regset_size(), GFP_KERNEL); | ||
474 | |||
475 | if (pm_dbg_reg_set[reg_set-1] == NULL) | ||
476 | return -ENOMEM; | ||
477 | |||
478 | if (pm_dbg_dir != NULL) { | ||
479 | sprintf(name, "%d", reg_set); | ||
480 | |||
481 | (void) debugfs_create_file(name, S_IRUGO, | ||
482 | pm_dbg_dir, (void *)reg_set, &debug_reg_fops); | ||
483 | } | ||
484 | |||
485 | return 0; | ||
486 | } | ||
487 | |||
488 | static int pwrdm_suspend_get(void *data, u64 *val) | ||
489 | { | ||
490 | *val = omap3_pm_get_suspend_state((struct powerdomain *)data); | ||
491 | |||
492 | if (*val >= 0) | ||
493 | return 0; | ||
494 | return *val; | ||
495 | } | ||
496 | |||
497 | static int pwrdm_suspend_set(void *data, u64 val) | ||
498 | { | ||
499 | return omap3_pm_set_suspend_state((struct powerdomain *)data, (int)val); | ||
500 | } | ||
501 | |||
502 | DEFINE_SIMPLE_ATTRIBUTE(pwrdm_suspend_fops, pwrdm_suspend_get, | ||
503 | pwrdm_suspend_set, "%llu\n"); | ||
504 | |||
505 | static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir) | ||
506 | { | ||
507 | int i; | ||
508 | s64 t; | ||
509 | struct dentry *d; | ||
510 | |||
511 | t = sched_clock(); | ||
512 | |||
513 | for (i = 0; i < 4; i++) | ||
514 | pwrdm->state_timer[i] = 0; | ||
515 | |||
516 | pwrdm->timer = t; | ||
517 | |||
518 | if (strncmp(pwrdm->name, "dpll", 4) == 0) | ||
519 | return 0; | ||
520 | |||
521 | d = debugfs_create_dir(pwrdm->name, (struct dentry *)dir); | ||
522 | |||
523 | (void) debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d, | ||
524 | (void *)pwrdm, &pwrdm_suspend_fops); | ||
525 | |||
526 | return 0; | ||
527 | } | ||
528 | |||
529 | static int __init pm_dbg_init(void) | ||
530 | { | ||
531 | int i; | ||
532 | struct dentry *d; | ||
533 | char name[2]; | ||
534 | |||
535 | if (pm_dbg_init_done) | ||
536 | return 0; | ||
537 | |||
538 | if (cpu_is_omap34xx()) | ||
539 | pm_dbg_reg_modules = omap3_pm_reg_modules; | ||
540 | else { | ||
541 | printk(KERN_ERR "%s: only OMAP3 supported\n", __func__); | ||
542 | return -ENODEV; | ||
543 | } | ||
544 | |||
545 | d = debugfs_create_dir("pm_debug", NULL); | ||
546 | if (IS_ERR(d)) | ||
547 | return PTR_ERR(d); | ||
548 | |||
549 | (void) debugfs_create_file("count", S_IRUGO, | ||
550 | d, (void *)DEBUG_FILE_COUNTERS, &debug_fops); | ||
551 | (void) debugfs_create_file("time", S_IRUGO, | ||
552 | d, (void *)DEBUG_FILE_TIMERS, &debug_fops); | ||
553 | |||
554 | pwrdm_for_each(pwrdms_setup, (void *)d); | ||
555 | |||
556 | pm_dbg_dir = debugfs_create_dir("registers", d); | ||
557 | if (IS_ERR(pm_dbg_dir)) | ||
558 | return PTR_ERR(pm_dbg_dir); | ||
559 | |||
560 | (void) debugfs_create_file("current", S_IRUGO, | ||
561 | pm_dbg_dir, (void *)0, &debug_reg_fops); | ||
562 | |||
563 | for (i = 0; i < PM_DBG_MAX_REG_SETS; i++) | ||
564 | if (pm_dbg_reg_set[i] != NULL) { | ||
565 | sprintf(name, "%d", i+1); | ||
566 | (void) debugfs_create_file(name, S_IRUGO, | ||
567 | pm_dbg_dir, (void *)(i+1), &debug_reg_fops); | ||
568 | |||
569 | } | ||
570 | |||
571 | pm_dbg_init_done = 1; | ||
572 | |||
573 | return 0; | ||
574 | } | ||
575 | arch_initcall(pm_dbg_init); | ||
576 | |||
577 | #else | ||
578 | void pm_dbg_update_time(struct powerdomain *pwrdm, int prev) {} | ||
579 | #endif | ||
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 21201cd4117b..8400f5768923 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h | |||
@@ -11,12 +11,23 @@ | |||
11 | #ifndef __ARCH_ARM_MACH_OMAP2_PM_H | 11 | #ifndef __ARCH_ARM_MACH_OMAP2_PM_H |
12 | #define __ARCH_ARM_MACH_OMAP2_PM_H | 12 | #define __ARCH_ARM_MACH_OMAP2_PM_H |
13 | 13 | ||
14 | #include <mach/powerdomain.h> | ||
15 | |||
16 | extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); | ||
17 | extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); | ||
18 | |||
14 | #ifdef CONFIG_PM_DEBUG | 19 | #ifdef CONFIG_PM_DEBUG |
15 | extern void omap2_pm_dump(int mode, int resume, unsigned int us); | 20 | extern void omap2_pm_dump(int mode, int resume, unsigned int us); |
16 | extern int omap2_pm_debug; | 21 | extern int omap2_pm_debug; |
22 | extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev); | ||
23 | extern int pm_dbg_regset_save(int reg_set); | ||
24 | extern int pm_dbg_regset_init(int reg_set); | ||
17 | #else | 25 | #else |
18 | #define omap2_pm_dump(mode, resume, us) do {} while (0); | 26 | #define omap2_pm_dump(mode, resume, us) do {} while (0); |
19 | #define omap2_pm_debug 0 | 27 | #define omap2_pm_debug 0 |
28 | #define pm_dbg_update_time(pwrdm, prev) do {} while (0); | ||
29 | #define pm_dbg_regset_save(reg_set) do {} while (0); | ||
30 | #define pm_dbg_regset_init(reg_set) do {} while (0); | ||
20 | #endif /* CONFIG_PM_DEBUG */ | 31 | #endif /* CONFIG_PM_DEBUG */ |
21 | 32 | ||
22 | extern void omap24xx_idle_loop_suspend(void); | 33 | extern void omap24xx_idle_loop_suspend(void); |
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index 528dbdc26e23..bff5c4e89742 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c | |||
@@ -333,7 +333,7 @@ static struct platform_suspend_ops omap_pm_ops = { | |||
333 | .valid = suspend_valid_only_mem, | 333 | .valid = suspend_valid_only_mem, |
334 | }; | 334 | }; |
335 | 335 | ||
336 | static int _pm_clkdm_enable_hwsup(struct clockdomain *clkdm) | 336 | static int _pm_clkdm_enable_hwsup(struct clockdomain *clkdm, void *unused) |
337 | { | 337 | { |
338 | omap2_clkdm_allow_idle(clkdm); | 338 | omap2_clkdm_allow_idle(clkdm); |
339 | return 0; | 339 | return 0; |
@@ -385,7 +385,7 @@ static void __init prcm_setup_regs(void) | |||
385 | omap2_clkdm_sleep(gfx_clkdm); | 385 | omap2_clkdm_sleep(gfx_clkdm); |
386 | 386 | ||
387 | /* Enable clockdomain hardware-supervised control for all clkdms */ | 387 | /* Enable clockdomain hardware-supervised control for all clkdms */ |
388 | clkdm_for_each(_pm_clkdm_enable_hwsup); | 388 | clkdm_for_each(_pm_clkdm_enable_hwsup, NULL); |
389 | 389 | ||
390 | /* Enable clock autoidle for all domains */ | 390 | /* Enable clock autoidle for all domains */ |
391 | cm_write_mod_reg(OMAP24XX_AUTO_CAM | | 391 | cm_write_mod_reg(OMAP24XX_AUTO_CAM | |
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 488d595d8e4b..0ff5a6c53aa0 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -170,6 +170,8 @@ static void omap_sram_idle(void) | |||
170 | printk(KERN_ERR "Invalid mpu state in sram_idle\n"); | 170 | printk(KERN_ERR "Invalid mpu state in sram_idle\n"); |
171 | return; | 171 | return; |
172 | } | 172 | } |
173 | pwrdm_pre_transition(); | ||
174 | |||
173 | omap2_gpio_prepare_for_retention(); | 175 | omap2_gpio_prepare_for_retention(); |
174 | omap_uart_prepare_idle(0); | 176 | omap_uart_prepare_idle(0); |
175 | omap_uart_prepare_idle(1); | 177 | omap_uart_prepare_idle(1); |
@@ -182,6 +184,9 @@ static void omap_sram_idle(void) | |||
182 | omap_uart_resume_idle(1); | 184 | omap_uart_resume_idle(1); |
183 | omap_uart_resume_idle(0); | 185 | omap_uart_resume_idle(0); |
184 | omap2_gpio_resume_after_retention(); | 186 | omap2_gpio_resume_after_retention(); |
187 | |||
188 | pwrdm_post_transition(); | ||
189 | |||
185 | } | 190 | } |
186 | 191 | ||
187 | /* | 192 | /* |
@@ -271,6 +276,7 @@ static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state) | |||
271 | if (sleep_switch) { | 276 | if (sleep_switch) { |
272 | omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]); | 277 | omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]); |
273 | pwrdm_wait_transition(pwrdm); | 278 | pwrdm_wait_transition(pwrdm); |
279 | pwrdm_state_switch(pwrdm); | ||
274 | } | 280 | } |
275 | 281 | ||
276 | err: | 282 | err: |
@@ -658,14 +664,38 @@ static void __init prcm_setup_regs(void) | |||
658 | omap3_d2d_idle(); | 664 | omap3_d2d_idle(); |
659 | } | 665 | } |
660 | 666 | ||
661 | static int __init pwrdms_setup(struct powerdomain *pwrdm) | 667 | int omap3_pm_get_suspend_state(struct powerdomain *pwrdm) |
668 | { | ||
669 | struct power_state *pwrst; | ||
670 | |||
671 | list_for_each_entry(pwrst, &pwrst_list, node) { | ||
672 | if (pwrst->pwrdm == pwrdm) | ||
673 | return pwrst->next_state; | ||
674 | } | ||
675 | return -EINVAL; | ||
676 | } | ||
677 | |||
678 | int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state) | ||
679 | { | ||
680 | struct power_state *pwrst; | ||
681 | |||
682 | list_for_each_entry(pwrst, &pwrst_list, node) { | ||
683 | if (pwrst->pwrdm == pwrdm) { | ||
684 | pwrst->next_state = state; | ||
685 | return 0; | ||
686 | } | ||
687 | } | ||
688 | return -EINVAL; | ||
689 | } | ||
690 | |||
691 | static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) | ||
662 | { | 692 | { |
663 | struct power_state *pwrst; | 693 | struct power_state *pwrst; |
664 | 694 | ||
665 | if (!pwrdm->pwrsts) | 695 | if (!pwrdm->pwrsts) |
666 | return 0; | 696 | return 0; |
667 | 697 | ||
668 | pwrst = kmalloc(sizeof(struct power_state), GFP_KERNEL); | 698 | pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); |
669 | if (!pwrst) | 699 | if (!pwrst) |
670 | return -ENOMEM; | 700 | return -ENOMEM; |
671 | pwrst->pwrdm = pwrdm; | 701 | pwrst->pwrdm = pwrdm; |
@@ -683,7 +713,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm) | |||
683 | * supported. Initiate sleep transition for other clockdomains, if | 713 | * supported. Initiate sleep transition for other clockdomains, if |
684 | * they are not used | 714 | * they are not used |
685 | */ | 715 | */ |
686 | static int __init clkdms_setup(struct clockdomain *clkdm) | 716 | static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) |
687 | { | 717 | { |
688 | if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) | 718 | if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) |
689 | omap2_clkdm_allow_idle(clkdm); | 719 | omap2_clkdm_allow_idle(clkdm); |
@@ -716,13 +746,13 @@ static int __init omap3_pm_init(void) | |||
716 | goto err1; | 746 | goto err1; |
717 | } | 747 | } |
718 | 748 | ||
719 | ret = pwrdm_for_each(pwrdms_setup); | 749 | ret = pwrdm_for_each(pwrdms_setup, NULL); |
720 | if (ret) { | 750 | if (ret) { |
721 | printk(KERN_ERR "Failed to setup powerdomains\n"); | 751 | printk(KERN_ERR "Failed to setup powerdomains\n"); |
722 | goto err2; | 752 | goto err2; |
723 | } | 753 | } |
724 | 754 | ||
725 | (void) clkdm_for_each(clkdms_setup); | 755 | (void) clkdm_for_each(clkdms_setup, NULL); |
726 | 756 | ||
727 | mpu_pwrdm = pwrdm_lookup("mpu_pwrdm"); | 757 | mpu_pwrdm = pwrdm_lookup("mpu_pwrdm"); |
728 | if (mpu_pwrdm == NULL) { | 758 | if (mpu_pwrdm == NULL) { |
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 983f1cb676be..2594cbff3947 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c | |||
@@ -35,6 +35,13 @@ | |||
35 | #include <mach/powerdomain.h> | 35 | #include <mach/powerdomain.h> |
36 | #include <mach/clockdomain.h> | 36 | #include <mach/clockdomain.h> |
37 | 37 | ||
38 | #include "pm.h" | ||
39 | |||
40 | enum { | ||
41 | PWRDM_STATE_NOW = 0, | ||
42 | PWRDM_STATE_PREV, | ||
43 | }; | ||
44 | |||
38 | /* pwrdm_list contains all registered struct powerdomains */ | 45 | /* pwrdm_list contains all registered struct powerdomains */ |
39 | static LIST_HEAD(pwrdm_list); | 46 | static LIST_HEAD(pwrdm_list); |
40 | 47 | ||
@@ -83,7 +90,7 @@ static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm, | |||
83 | if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip)) | 90 | if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip)) |
84 | return ERR_PTR(-EINVAL); | 91 | return ERR_PTR(-EINVAL); |
85 | 92 | ||
86 | for (pd = deps; pd; pd++) { | 93 | for (pd = deps; pd->pwrdm_name; pd++) { |
87 | 94 | ||
88 | if (!omap_chip_is(pd->omap_chip)) | 95 | if (!omap_chip_is(pd->omap_chip)) |
89 | continue; | 96 | continue; |
@@ -96,12 +103,71 @@ static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm, | |||
96 | 103 | ||
97 | } | 104 | } |
98 | 105 | ||
99 | if (!pd) | 106 | if (!pd->pwrdm_name) |
100 | return ERR_PTR(-ENOENT); | 107 | return ERR_PTR(-ENOENT); |
101 | 108 | ||
102 | return pd->pwrdm; | 109 | return pd->pwrdm; |
103 | } | 110 | } |
104 | 111 | ||
112 | static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) | ||
113 | { | ||
114 | |||
115 | int prev; | ||
116 | int state; | ||
117 | |||
118 | if (pwrdm == NULL) | ||
119 | return -EINVAL; | ||
120 | |||
121 | state = pwrdm_read_pwrst(pwrdm); | ||
122 | |||
123 | switch (flag) { | ||
124 | case PWRDM_STATE_NOW: | ||
125 | prev = pwrdm->state; | ||
126 | break; | ||
127 | case PWRDM_STATE_PREV: | ||
128 | prev = pwrdm_read_prev_pwrst(pwrdm); | ||
129 | if (pwrdm->state != prev) | ||
130 | pwrdm->state_counter[prev]++; | ||
131 | break; | ||
132 | default: | ||
133 | return -EINVAL; | ||
134 | } | ||
135 | |||
136 | if (state != prev) | ||
137 | pwrdm->state_counter[state]++; | ||
138 | |||
139 | pm_dbg_update_time(pwrdm, prev); | ||
140 | |||
141 | pwrdm->state = state; | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused) | ||
147 | { | ||
148 | pwrdm_clear_all_prev_pwrst(pwrdm); | ||
149 | _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused) | ||
154 | { | ||
155 | _pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV); | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static __init void _pwrdm_setup(struct powerdomain *pwrdm) | ||
160 | { | ||
161 | int i; | ||
162 | |||
163 | for (i = 0; i < 4; i++) | ||
164 | pwrdm->state_counter[i] = 0; | ||
165 | |||
166 | pwrdm_wait_transition(pwrdm); | ||
167 | pwrdm->state = pwrdm_read_pwrst(pwrdm); | ||
168 | pwrdm->state_counter[pwrdm->state] = 1; | ||
169 | |||
170 | } | ||
105 | 171 | ||
106 | /* Public functions */ | 172 | /* Public functions */ |
107 | 173 | ||
@@ -117,9 +183,12 @@ void pwrdm_init(struct powerdomain **pwrdm_list) | |||
117 | { | 183 | { |
118 | struct powerdomain **p = NULL; | 184 | struct powerdomain **p = NULL; |
119 | 185 | ||
120 | if (pwrdm_list) | 186 | if (pwrdm_list) { |
121 | for (p = pwrdm_list; *p; p++) | 187 | for (p = pwrdm_list; *p; p++) { |
122 | pwrdm_register(*p); | 188 | pwrdm_register(*p); |
189 | _pwrdm_setup(*p); | ||
190 | } | ||
191 | } | ||
123 | } | 192 | } |
124 | 193 | ||
125 | /** | 194 | /** |
@@ -217,7 +286,8 @@ struct powerdomain *pwrdm_lookup(const char *name) | |||
217 | * anything else to indicate failure; or -EINVAL if the function | 286 | * anything else to indicate failure; or -EINVAL if the function |
218 | * pointer is null. | 287 | * pointer is null. |
219 | */ | 288 | */ |
220 | int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm)) | 289 | int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user), |
290 | void *user) | ||
221 | { | 291 | { |
222 | struct powerdomain *temp_pwrdm; | 292 | struct powerdomain *temp_pwrdm; |
223 | unsigned long flags; | 293 | unsigned long flags; |
@@ -228,7 +298,7 @@ int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm)) | |||
228 | 298 | ||
229 | read_lock_irqsave(&pwrdm_rwlock, flags); | 299 | read_lock_irqsave(&pwrdm_rwlock, flags); |
230 | list_for_each_entry(temp_pwrdm, &pwrdm_list, node) { | 300 | list_for_each_entry(temp_pwrdm, &pwrdm_list, node) { |
231 | ret = (*fn)(temp_pwrdm); | 301 | ret = (*fn)(temp_pwrdm, user); |
232 | if (ret) | 302 | if (ret) |
233 | break; | 303 | break; |
234 | } | 304 | } |
@@ -1110,4 +1180,36 @@ int pwrdm_wait_transition(struct powerdomain *pwrdm) | |||
1110 | return 0; | 1180 | return 0; |
1111 | } | 1181 | } |
1112 | 1182 | ||
1183 | int pwrdm_state_switch(struct powerdomain *pwrdm) | ||
1184 | { | ||
1185 | return _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); | ||
1186 | } | ||
1187 | |||
1188 | int pwrdm_clkdm_state_switch(struct clockdomain *clkdm) | ||
1189 | { | ||
1190 | if (clkdm != NULL && clkdm->pwrdm.ptr != NULL) { | ||
1191 | pwrdm_wait_transition(clkdm->pwrdm.ptr); | ||
1192 | return pwrdm_state_switch(clkdm->pwrdm.ptr); | ||
1193 | } | ||
1194 | |||
1195 | return -EINVAL; | ||
1196 | } | ||
1197 | int pwrdm_clk_state_switch(struct clk *clk) | ||
1198 | { | ||
1199 | if (clk != NULL && clk->clkdm != NULL) | ||
1200 | return pwrdm_clkdm_state_switch(clk->clkdm); | ||
1201 | return -EINVAL; | ||
1202 | } | ||
1203 | |||
1204 | int pwrdm_pre_transition(void) | ||
1205 | { | ||
1206 | pwrdm_for_each(_pwrdm_pre_transition_cb, NULL); | ||
1207 | return 0; | ||
1208 | } | ||
1209 | |||
1210 | int pwrdm_post_transition(void) | ||
1211 | { | ||
1212 | pwrdm_for_each(_pwrdm_post_transition_cb, NULL); | ||
1213 | return 0; | ||
1214 | } | ||
1113 | 1215 | ||
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index 9937e2814696..03c467c35f54 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h | |||
@@ -17,11 +17,11 @@ | |||
17 | #include "prcm-common.h" | 17 | #include "prcm-common.h" |
18 | 18 | ||
19 | #define OMAP2420_PRM_REGADDR(module, reg) \ | 19 | #define OMAP2420_PRM_REGADDR(module, reg) \ |
20 | IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg)) | 20 | OMAP2_IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg)) |
21 | #define OMAP2430_PRM_REGADDR(module, reg) \ | 21 | #define OMAP2430_PRM_REGADDR(module, reg) \ |
22 | IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg)) | 22 | OMAP2_IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg)) |
23 | #define OMAP34XX_PRM_REGADDR(module, reg) \ | 23 | #define OMAP34XX_PRM_REGADDR(module, reg) \ |
24 | IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg)) | 24 | OMAP2_IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg)) |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * Architecture-specific global PRM registers | 27 | * Architecture-specific global PRM registers |
diff --git a/arch/arm/mach-omap2/sdrc.h b/arch/arm/mach-omap2/sdrc.h index 1a8bbd094066..0837eda5f2b6 100644 --- a/arch/arm/mach-omap2/sdrc.h +++ b/arch/arm/mach-omap2/sdrc.h | |||
@@ -48,9 +48,9 @@ static inline u32 sms_read_reg(u16 reg) | |||
48 | return __raw_readl(OMAP_SMS_REGADDR(reg)); | 48 | return __raw_readl(OMAP_SMS_REGADDR(reg)); |
49 | } | 49 | } |
50 | #else | 50 | #else |
51 | #define OMAP242X_SDRC_REGADDR(reg) IO_ADDRESS(OMAP2420_SDRC_BASE + (reg)) | 51 | #define OMAP242X_SDRC_REGADDR(reg) OMAP2_IO_ADDRESS(OMAP2420_SDRC_BASE + (reg)) |
52 | #define OMAP243X_SDRC_REGADDR(reg) IO_ADDRESS(OMAP243X_SDRC_BASE + (reg)) | 52 | #define OMAP243X_SDRC_REGADDR(reg) OMAP2_IO_ADDRESS(OMAP243X_SDRC_BASE + (reg)) |
53 | #define OMAP34XX_SDRC_REGADDR(reg) IO_ADDRESS(OMAP343X_SDRC_BASE + (reg)) | 53 | #define OMAP34XX_SDRC_REGADDR(reg) OMAP2_IO_ADDRESS(OMAP343X_SDRC_BASE + (reg)) |
54 | #endif /* __ASSEMBLER__ */ | 54 | #endif /* __ASSEMBLER__ */ |
55 | 55 | ||
56 | #endif | 56 | #endif |
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index ce22344b94e7..3a529c77daa8 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
@@ -73,7 +73,7 @@ static LIST_HEAD(uart_list); | |||
73 | 73 | ||
74 | static struct plat_serial8250_port serial_platform_data0[] = { | 74 | static struct plat_serial8250_port serial_platform_data0[] = { |
75 | { | 75 | { |
76 | .membase = IO_ADDRESS(OMAP_UART1_BASE), | 76 | .membase = OMAP2_IO_ADDRESS(OMAP_UART1_BASE), |
77 | .mapbase = OMAP_UART1_BASE, | 77 | .mapbase = OMAP_UART1_BASE, |
78 | .irq = 72, | 78 | .irq = 72, |
79 | .flags = UPF_BOOT_AUTOCONF, | 79 | .flags = UPF_BOOT_AUTOCONF, |
@@ -87,7 +87,7 @@ static struct plat_serial8250_port serial_platform_data0[] = { | |||
87 | 87 | ||
88 | static struct plat_serial8250_port serial_platform_data1[] = { | 88 | static struct plat_serial8250_port serial_platform_data1[] = { |
89 | { | 89 | { |
90 | .membase = IO_ADDRESS(OMAP_UART2_BASE), | 90 | .membase = OMAP2_IO_ADDRESS(OMAP_UART2_BASE), |
91 | .mapbase = OMAP_UART2_BASE, | 91 | .mapbase = OMAP_UART2_BASE, |
92 | .irq = 73, | 92 | .irq = 73, |
93 | .flags = UPF_BOOT_AUTOCONF, | 93 | .flags = UPF_BOOT_AUTOCONF, |
@@ -101,7 +101,7 @@ static struct plat_serial8250_port serial_platform_data1[] = { | |||
101 | 101 | ||
102 | static struct plat_serial8250_port serial_platform_data2[] = { | 102 | static struct plat_serial8250_port serial_platform_data2[] = { |
103 | { | 103 | { |
104 | .membase = IO_ADDRESS(OMAP_UART3_BASE), | 104 | .membase = OMAP2_IO_ADDRESS(OMAP_UART3_BASE), |
105 | .mapbase = OMAP_UART3_BASE, | 105 | .mapbase = OMAP_UART3_BASE, |
106 | .irq = 74, | 106 | .irq = 74, |
107 | .flags = UPF_BOOT_AUTOCONF, | 107 | .flags = UPF_BOOT_AUTOCONF, |
@@ -123,6 +123,21 @@ static struct plat_serial8250_port serial_platform_data2[] = { | |||
123 | } | 123 | } |
124 | }; | 124 | }; |
125 | 125 | ||
126 | #ifdef CONFIG_ARCH_OMAP4 | ||
127 | static struct plat_serial8250_port serial_platform_data3[] = { | ||
128 | { | ||
129 | .membase = IO_ADDRESS(OMAP_UART4_BASE), | ||
130 | .mapbase = OMAP_UART4_BASE, | ||
131 | .irq = 70, | ||
132 | .flags = UPF_BOOT_AUTOCONF, | ||
133 | .iotype = UPIO_MEM, | ||
134 | .regshift = 2, | ||
135 | .uartclk = OMAP24XX_BASE_BAUD * 16, | ||
136 | }, { | ||
137 | .flags = 0 | ||
138 | } | ||
139 | }; | ||
140 | #endif | ||
126 | static inline unsigned int serial_read_reg(struct plat_serial8250_port *up, | 141 | static inline unsigned int serial_read_reg(struct plat_serial8250_port *up, |
127 | int offset) | 142 | int offset) |
128 | { | 143 | { |
@@ -470,7 +485,7 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) | |||
470 | uart->padconf = 0; | 485 | uart->padconf = 0; |
471 | } | 486 | } |
472 | 487 | ||
473 | p->flags |= UPF_SHARE_IRQ; | 488 | p->irqflags |= IRQF_SHARED; |
474 | ret = request_irq(p->irq, omap_uart_interrupt, IRQF_SHARED, | 489 | ret = request_irq(p->irq, omap_uart_interrupt, IRQF_SHARED, |
475 | "serial idle", (void *)uart); | 490 | "serial idle", (void *)uart); |
476 | WARN_ON(ret); | 491 | WARN_ON(ret); |
@@ -560,12 +575,22 @@ static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS] = { | |||
560 | }, | 575 | }, |
561 | }, | 576 | }, |
562 | }, | 577 | }, |
578 | #ifdef CONFIG_ARCH_OMAP4 | ||
579 | { | ||
580 | .pdev = { | ||
581 | .name = "serial8250", | ||
582 | .id = 3 | ||
583 | .dev = { | ||
584 | .platform_data = serial_platform_data3, | ||
585 | }, | ||
586 | }, | ||
587 | }, | ||
588 | #endif | ||
563 | }; | 589 | }; |
564 | 590 | ||
565 | void __init omap_serial_init(void) | 591 | void __init omap_serial_early_init(void) |
566 | { | 592 | { |
567 | int i; | 593 | int i; |
568 | const struct omap_uart_config *info; | ||
569 | char name[16]; | 594 | char name[16]; |
570 | 595 | ||
571 | /* | 596 | /* |
@@ -574,23 +599,12 @@ void __init omap_serial_init(void) | |||
574 | * if not needed. | 599 | * if not needed. |
575 | */ | 600 | */ |
576 | 601 | ||
577 | info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config); | ||
578 | |||
579 | if (info == NULL) | ||
580 | return; | ||
581 | |||
582 | for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { | 602 | for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { |
583 | struct omap_uart_state *uart = &omap_uart[i]; | 603 | struct omap_uart_state *uart = &omap_uart[i]; |
584 | struct platform_device *pdev = &uart->pdev; | 604 | struct platform_device *pdev = &uart->pdev; |
585 | struct device *dev = &pdev->dev; | 605 | struct device *dev = &pdev->dev; |
586 | struct plat_serial8250_port *p = dev->platform_data; | 606 | struct plat_serial8250_port *p = dev->platform_data; |
587 | 607 | ||
588 | if (!(info->enabled_uarts & (1 << i))) { | ||
589 | p->membase = NULL; | ||
590 | p->mapbase = 0; | ||
591 | continue; | ||
592 | } | ||
593 | |||
594 | sprintf(name, "uart%d_ick", i+1); | 608 | sprintf(name, "uart%d_ick", i+1); |
595 | uart->ick = clk_get(NULL, name); | 609 | uart->ick = clk_get(NULL, name); |
596 | if (IS_ERR(uart->ick)) { | 610 | if (IS_ERR(uart->ick)) { |
@@ -605,8 +619,11 @@ void __init omap_serial_init(void) | |||
605 | uart->fck = NULL; | 619 | uart->fck = NULL; |
606 | } | 620 | } |
607 | 621 | ||
608 | if (!uart->ick || !uart->fck) | 622 | /* FIXME: Remove this once the clkdev is ready */ |
609 | continue; | 623 | if (!cpu_is_omap44xx()) { |
624 | if (!uart->ick || !uart->fck) | ||
625 | continue; | ||
626 | } | ||
610 | 627 | ||
611 | uart->num = i; | 628 | uart->num = i; |
612 | p->private_data = uart; | 629 | p->private_data = uart; |
@@ -617,6 +634,18 @@ void __init omap_serial_init(void) | |||
617 | p->irq += 32; | 634 | p->irq += 32; |
618 | 635 | ||
619 | omap_uart_enable_clocks(uart); | 636 | omap_uart_enable_clocks(uart); |
637 | } | ||
638 | } | ||
639 | |||
640 | void __init omap_serial_init(void) | ||
641 | { | ||
642 | int i; | ||
643 | |||
644 | for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { | ||
645 | struct omap_uart_state *uart = &omap_uart[i]; | ||
646 | struct platform_device *pdev = &uart->pdev; | ||
647 | struct device *dev = &pdev->dev; | ||
648 | |||
620 | omap_uart_reset(uart); | 649 | omap_uart_reset(uart); |
621 | omap_uart_idle_init(uart); | 650 | omap_uart_idle_init(uart); |
622 | 651 | ||
diff --git a/arch/arm/mach-omap2/sram242x.S b/arch/arm/mach-omap2/sram242x.S index bb299851116d..9b62208658bc 100644 --- a/arch/arm/mach-omap2/sram242x.S +++ b/arch/arm/mach-omap2/sram242x.S | |||
@@ -128,7 +128,7 @@ omap242x_sdi_prcm_voltctrl: | |||
128 | prcm_mask_val: | 128 | prcm_mask_val: |
129 | .word 0xFFFF3FFC | 129 | .word 0xFFFF3FFC |
130 | omap242x_sdi_timer_32ksynct_cr: | 130 | omap242x_sdi_timer_32ksynct_cr: |
131 | .word IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010) | 131 | .word OMAP2_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010) |
132 | ENTRY(omap242x_sram_ddr_init_sz) | 132 | ENTRY(omap242x_sram_ddr_init_sz) |
133 | .word . - omap242x_sram_ddr_init | 133 | .word . - omap242x_sram_ddr_init |
134 | 134 | ||
@@ -224,7 +224,7 @@ omap242x_srs_prcm_voltctrl: | |||
224 | ddr_prcm_mask_val: | 224 | ddr_prcm_mask_val: |
225 | .word 0xFFFF3FFC | 225 | .word 0xFFFF3FFC |
226 | omap242x_srs_timer_32ksynct: | 226 | omap242x_srs_timer_32ksynct: |
227 | .word IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010) | 227 | .word OMAP2_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010) |
228 | 228 | ||
229 | ENTRY(omap242x_sram_reprogram_sdrc_sz) | 229 | ENTRY(omap242x_sram_reprogram_sdrc_sz) |
230 | .word . - omap242x_sram_reprogram_sdrc | 230 | .word . - omap242x_sram_reprogram_sdrc |
diff --git a/arch/arm/mach-omap2/sram243x.S b/arch/arm/mach-omap2/sram243x.S index 9955abcaeb31..df2cd9277c00 100644 --- a/arch/arm/mach-omap2/sram243x.S +++ b/arch/arm/mach-omap2/sram243x.S | |||
@@ -128,7 +128,7 @@ omap243x_sdi_prcm_voltctrl: | |||
128 | prcm_mask_val: | 128 | prcm_mask_val: |
129 | .word 0xFFFF3FFC | 129 | .word 0xFFFF3FFC |
130 | omap243x_sdi_timer_32ksynct_cr: | 130 | omap243x_sdi_timer_32ksynct_cr: |
131 | .word IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010) | 131 | .word OMAP2_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010) |
132 | ENTRY(omap243x_sram_ddr_init_sz) | 132 | ENTRY(omap243x_sram_ddr_init_sz) |
133 | .word . - omap243x_sram_ddr_init | 133 | .word . - omap243x_sram_ddr_init |
134 | 134 | ||
@@ -224,7 +224,7 @@ omap243x_srs_prcm_voltctrl: | |||
224 | ddr_prcm_mask_val: | 224 | ddr_prcm_mask_val: |
225 | .word 0xFFFF3FFC | 225 | .word 0xFFFF3FFC |
226 | omap243x_srs_timer_32ksynct: | 226 | omap243x_srs_timer_32ksynct: |
227 | .word IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010) | 227 | .word OMAP2_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010) |
228 | 228 | ||
229 | ENTRY(omap243x_sram_reprogram_sdrc_sz) | 229 | ENTRY(omap243x_sram_reprogram_sdrc_sz) |
230 | .word . - omap243x_sram_reprogram_sdrc | 230 | .word . - omap243x_sram_reprogram_sdrc |
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c index 97eeeebcb066..e2338c0aebcf 100644 --- a/arch/arm/mach-omap2/timer-gp.c +++ b/arch/arm/mach-omap2/timer-gp.c | |||
@@ -231,7 +231,7 @@ static void __init omap2_gp_clocksource_init(void) | |||
231 | static void __init omap2_gp_timer_init(void) | 231 | static void __init omap2_gp_timer_init(void) |
232 | { | 232 | { |
233 | #ifdef CONFIG_LOCAL_TIMERS | 233 | #ifdef CONFIG_LOCAL_TIMERS |
234 | twd_base = IO_ADDRESS(OMAP44XX_LOCAL_TWD_BASE); | 234 | twd_base = OMAP2_IO_ADDRESS(OMAP44XX_LOCAL_TWD_BASE); |
235 | #endif | 235 | #endif |
236 | omap_dm_timer_init(); | 236 | omap_dm_timer_init(); |
237 | 237 | ||
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index 739e59e8025c..1145a2562b0f 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c | |||
@@ -31,15 +31,6 @@ | |||
31 | #include <mach/mux.h> | 31 | #include <mach/mux.h> |
32 | #include <mach/usb.h> | 32 | #include <mach/usb.h> |
33 | 33 | ||
34 | #define OTG_SYSCONFIG (OMAP34XX_HSUSB_OTG_BASE + 0x404) | ||
35 | |||
36 | static void __init usb_musb_pm_init(void) | ||
37 | { | ||
38 | /* Ensure force-idle mode for OTG controller */ | ||
39 | if (cpu_is_omap34xx()) | ||
40 | omap_writel(0, OTG_SYSCONFIG); | ||
41 | } | ||
42 | |||
43 | #ifdef CONFIG_USB_MUSB_SOC | 34 | #ifdef CONFIG_USB_MUSB_SOC |
44 | 35 | ||
45 | static struct resource musb_resources[] = { | 36 | static struct resource musb_resources[] = { |
@@ -173,13 +164,10 @@ void __init usb_musb_init(void) | |||
173 | printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n"); | 164 | printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n"); |
174 | return; | 165 | return; |
175 | } | 166 | } |
176 | |||
177 | usb_musb_pm_init(); | ||
178 | } | 167 | } |
179 | 168 | ||
180 | #else | 169 | #else |
181 | void __init usb_musb_init(void) | 170 | void __init usb_musb_init(void) |
182 | { | 171 | { |
183 | usb_musb_pm_init(); | ||
184 | } | 172 | } |
185 | #endif /* CONFIG_USB_MUSB_SOC */ | 173 | #endif /* CONFIG_USB_MUSB_SOC */ |