diff options
Diffstat (limited to 'arch/arm/mach-omap2')
32 files changed, 1014 insertions, 533 deletions
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 594c6335496e..23b004afa3f8 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c | |||
@@ -428,16 +428,23 @@ static void enable_board_wakeup_source(void) | |||
428 | OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); | 428 | OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); |
429 | } | 429 | } |
430 | 430 | ||
431 | static struct usbhs_phy_data phy_data[] __initdata = { | ||
432 | { | ||
433 | .port = 1, | ||
434 | .reset_gpio = 57, | ||
435 | .vcc_gpio = -EINVAL, | ||
436 | }, | ||
437 | { | ||
438 | .port = 2, | ||
439 | .reset_gpio = 61, | ||
440 | .vcc_gpio = -EINVAL, | ||
441 | }, | ||
442 | }; | ||
443 | |||
431 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 444 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
432 | 445 | ||
433 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 446 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
434 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 447 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
435 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
436 | |||
437 | .phy_reset = true, | ||
438 | .reset_gpio_port[0] = 57, | ||
439 | .reset_gpio_port[1] = 61, | ||
440 | .reset_gpio_port[2] = -EINVAL | ||
441 | }; | 448 | }; |
442 | 449 | ||
443 | #ifdef CONFIG_OMAP_MUX | 450 | #ifdef CONFIG_OMAP_MUX |
@@ -589,6 +596,8 @@ static void __init omap_3430sdp_init(void) | |||
589 | board_flash_init(sdp_flash_partitions, chip_sel_3430, 0); | 596 | board_flash_init(sdp_flash_partitions, chip_sel_3430, 0); |
590 | sdp3430_display_init(); | 597 | sdp3430_display_init(); |
591 | enable_board_wakeup_source(); | 598 | enable_board_wakeup_source(); |
599 | |||
600 | usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); | ||
592 | usbhs_init(&usbhs_bdata); | 601 | usbhs_init(&usbhs_bdata); |
593 | } | 602 | } |
594 | 603 | ||
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 67447bd4564f..20d6d8189240 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c | |||
@@ -53,16 +53,23 @@ static void enable_board_wakeup_source(void) | |||
53 | OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); | 53 | OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP); |
54 | } | 54 | } |
55 | 55 | ||
56 | static struct usbhs_phy_data phy_data[] __initdata = { | ||
57 | { | ||
58 | .port = 1, | ||
59 | .reset_gpio = 126, | ||
60 | .vcc_gpio = -EINVAL, | ||
61 | }, | ||
62 | { | ||
63 | .port = 2, | ||
64 | .reset_gpio = 61, | ||
65 | .vcc_gpio = -EINVAL, | ||
66 | }, | ||
67 | }; | ||
68 | |||
56 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 69 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
57 | 70 | ||
58 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 71 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
59 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 72 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
60 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
61 | |||
62 | .phy_reset = true, | ||
63 | .reset_gpio_port[0] = 126, | ||
64 | .reset_gpio_port[1] = 61, | ||
65 | .reset_gpio_port[2] = -EINVAL | ||
66 | }; | 73 | }; |
67 | 74 | ||
68 | #ifdef CONFIG_OMAP_MUX | 75 | #ifdef CONFIG_OMAP_MUX |
@@ -199,6 +206,8 @@ static void __init omap_sdp_init(void) | |||
199 | board_smc91x_init(); | 206 | board_smc91x_init(); |
200 | board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16); | 207 | board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16); |
201 | enable_board_wakeup_source(); | 208 | enable_board_wakeup_source(); |
209 | |||
210 | usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); | ||
202 | usbhs_init(&usbhs_bdata); | 211 | usbhs_init(&usbhs_bdata); |
203 | } | 212 | } |
204 | 213 | ||
diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c index 7d3358b2e593..fc53911d0d13 100644 --- a/arch/arm/mach-omap2/board-am3517crane.c +++ b/arch/arm/mach-omap2/board-am3517crane.c | |||
@@ -47,15 +47,17 @@ static struct omap_board_mux board_mux[] __initdata = { | |||
47 | }; | 47 | }; |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | static struct usbhs_phy_data phy_data[] __initdata = { | ||
51 | { | ||
52 | .port = 1, | ||
53 | .reset_gpio = GPIO_USB_NRESET, | ||
54 | .vcc_gpio = GPIO_USB_POWER, | ||
55 | .vcc_polarity = 1, | ||
56 | }, | ||
57 | }; | ||
58 | |||
50 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 59 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
51 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 60 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
52 | .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
53 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
54 | |||
55 | .phy_reset = true, | ||
56 | .reset_gpio_port[0] = GPIO_USB_NRESET, | ||
57 | .reset_gpio_port[1] = -EINVAL, | ||
58 | .reset_gpio_port[2] = -EINVAL | ||
59 | }; | 61 | }; |
60 | 62 | ||
61 | static struct mtd_partition crane_nand_partitions[] = { | 63 | static struct mtd_partition crane_nand_partitions[] = { |
@@ -131,13 +133,7 @@ static void __init am3517_crane_init(void) | |||
131 | return; | 133 | return; |
132 | } | 134 | } |
133 | 135 | ||
134 | ret = gpio_request_one(GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH, | 136 | usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); |
135 | "usb_ehci_enable"); | ||
136 | if (ret < 0) { | ||
137 | pr_err("Can not request GPIO %d\n", GPIO_USB_POWER); | ||
138 | return; | ||
139 | } | ||
140 | |||
141 | usbhs_init(&usbhs_bdata); | 137 | usbhs_init(&usbhs_bdata); |
142 | am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1); | 138 | am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1); |
143 | } | 139 | } |
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 2b9eb3de7aa6..d63f14b534b5 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c | |||
@@ -213,6 +213,14 @@ static __init void am3517_evm_mcbsp1_init(void) | |||
213 | omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0); | 213 | omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0); |
214 | } | 214 | } |
215 | 215 | ||
216 | static struct usbhs_phy_data phy_data[] __initdata = { | ||
217 | { | ||
218 | .port = 1, | ||
219 | .reset_gpio = 57, | ||
220 | .vcc_gpio = -EINVAL, | ||
221 | }, | ||
222 | }; | ||
223 | |||
216 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 224 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
217 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 225 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
218 | #if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \ | 226 | #if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \ |
@@ -221,12 +229,6 @@ static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | |||
221 | #else | 229 | #else |
222 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 230 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
223 | #endif | 231 | #endif |
224 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
225 | |||
226 | .phy_reset = true, | ||
227 | .reset_gpio_port[0] = 57, | ||
228 | .reset_gpio_port[1] = -EINVAL, | ||
229 | .reset_gpio_port[2] = -EINVAL | ||
230 | }; | 232 | }; |
231 | 233 | ||
232 | #ifdef CONFIG_OMAP_MUX | 234 | #ifdef CONFIG_OMAP_MUX |
@@ -288,7 +290,6 @@ static struct omap2_hsmmc_info mmc[] = { | |||
288 | {} /* Terminator */ | 290 | {} /* Terminator */ |
289 | }; | 291 | }; |
290 | 292 | ||
291 | |||
292 | static void __init am3517_evm_init(void) | 293 | static void __init am3517_evm_init(void) |
293 | { | 294 | { |
294 | omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); | 295 | omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); |
@@ -300,6 +301,8 @@ static void __init am3517_evm_init(void) | |||
300 | 301 | ||
301 | /* Configure GPIO for EHCI port */ | 302 | /* Configure GPIO for EHCI port */ |
302 | omap_mux_init_gpio(57, OMAP_PIN_OUTPUT); | 303 | omap_mux_init_gpio(57, OMAP_PIN_OUTPUT); |
304 | |||
305 | usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); | ||
303 | usbhs_init(&usbhs_bdata); | 306 | usbhs_init(&usbhs_bdata); |
304 | am3517_evm_hecc_init(&am3517_evm_hecc_pdata); | 307 | am3517_evm_hecc_init(&am3517_evm_hecc_pdata); |
305 | 308 | ||
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 710e99da266c..ee6218c74807 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c | |||
@@ -376,15 +376,22 @@ static struct omap2_hsmmc_info mmc[] = { | |||
376 | {} /* Terminator */ | 376 | {} /* Terminator */ |
377 | }; | 377 | }; |
378 | 378 | ||
379 | static struct usbhs_phy_data phy_data[] __initdata = { | ||
380 | { | ||
381 | .port = 1, | ||
382 | .reset_gpio = OMAP_MAX_GPIO_LINES + 6, | ||
383 | .vcc_gpio = -EINVAL, | ||
384 | }, | ||
385 | { | ||
386 | .port = 2, | ||
387 | .reset_gpio = OMAP_MAX_GPIO_LINES + 7, | ||
388 | .vcc_gpio = -EINVAL, | ||
389 | }, | ||
390 | }; | ||
391 | |||
379 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 392 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
380 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 393 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
381 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 394 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
382 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
383 | |||
384 | .phy_reset = true, | ||
385 | .reset_gpio_port[0] = OMAP_MAX_GPIO_LINES + 6, | ||
386 | .reset_gpio_port[1] = OMAP_MAX_GPIO_LINES + 7, | ||
387 | .reset_gpio_port[2] = -EINVAL | ||
388 | }; | 395 | }; |
389 | 396 | ||
390 | static void __init cm_t35_init_usbh(void) | 397 | static void __init cm_t35_init_usbh(void) |
@@ -401,6 +408,7 @@ static void __init cm_t35_init_usbh(void) | |||
401 | msleep(1); | 408 | msleep(1); |
402 | } | 409 | } |
403 | 410 | ||
411 | usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); | ||
404 | usbhs_init(&usbhs_bdata); | 412 | usbhs_init(&usbhs_bdata); |
405 | } | 413 | } |
406 | 414 | ||
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c index a66da808cc4a..4eb5e6f2f7f5 100644 --- a/arch/arm/mach-omap2/board-cm-t3517.c +++ b/arch/arm/mach-omap2/board-cm-t3517.c | |||
@@ -188,15 +188,22 @@ static inline void cm_t3517_init_rtc(void) {} | |||
188 | #define HSUSB2_RESET_GPIO (147) | 188 | #define HSUSB2_RESET_GPIO (147) |
189 | #define USB_HUB_RESET_GPIO (152) | 189 | #define USB_HUB_RESET_GPIO (152) |
190 | 190 | ||
191 | static struct usbhs_phy_data phy_data[] __initdata = { | ||
192 | { | ||
193 | .port = 1, | ||
194 | .reset_gpio = HSUSB1_RESET_GPIO, | ||
195 | .vcc_gpio = -EINVAL, | ||
196 | }, | ||
197 | { | ||
198 | .port = 2, | ||
199 | .reset_gpio = HSUSB2_RESET_GPIO, | ||
200 | .vcc_gpio = -EINVAL, | ||
201 | }, | ||
202 | }; | ||
203 | |||
191 | static struct usbhs_omap_platform_data cm_t3517_ehci_pdata __initdata = { | 204 | static struct usbhs_omap_platform_data cm_t3517_ehci_pdata __initdata = { |
192 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 205 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
193 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 206 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
194 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
195 | |||
196 | .phy_reset = true, | ||
197 | .reset_gpio_port[0] = HSUSB1_RESET_GPIO, | ||
198 | .reset_gpio_port[1] = HSUSB2_RESET_GPIO, | ||
199 | .reset_gpio_port[2] = -EINVAL, | ||
200 | }; | 207 | }; |
201 | 208 | ||
202 | static int __init cm_t3517_init_usbh(void) | 209 | static int __init cm_t3517_init_usbh(void) |
@@ -213,6 +220,7 @@ static int __init cm_t3517_init_usbh(void) | |||
213 | msleep(1); | 220 | msleep(1); |
214 | } | 221 | } |
215 | 222 | ||
223 | usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); | ||
216 | usbhs_init(&cm_t3517_ehci_pdata); | 224 | usbhs_init(&cm_t3517_ehci_pdata); |
217 | 225 | ||
218 | return 0; | 226 | return 0; |
@@ -324,6 +332,6 @@ MACHINE_START(CM_T3517, "Compulab CM-T3517") | |||
324 | .handle_irq = omap3_intc_handle_irq, | 332 | .handle_irq = omap3_intc_handle_irq, |
325 | .init_machine = cm_t3517_init, | 333 | .init_machine = cm_t3517_init, |
326 | .init_late = am35xx_init_late, | 334 | .init_late = am35xx_init_late, |
327 | .init_time = omap3_gp_gptimer_timer_init, | 335 | .init_time = omap3_gptimer_timer_init, |
328 | .restart = omap3xxx_restart, | 336 | .restart = omap3xxx_restart, |
329 | MACHINE_END | 337 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 34944cfdfbd9..576420544178 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c | |||
@@ -415,15 +415,7 @@ static struct platform_device *devkit8000_devices[] __initdata = { | |||
415 | }; | 415 | }; |
416 | 416 | ||
417 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 417 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
418 | |||
419 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 418 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
420 | .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
421 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
422 | |||
423 | .phy_reset = true, | ||
424 | .reset_gpio_port[0] = -EINVAL, | ||
425 | .reset_gpio_port[1] = -EINVAL, | ||
426 | .reset_gpio_port[2] = -EINVAL | ||
427 | }; | 419 | }; |
428 | 420 | ||
429 | #ifdef CONFIG_OMAP_MUX | 421 | #ifdef CONFIG_OMAP_MUX |
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index e54a48060198..78813b397209 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c | |||
@@ -140,7 +140,7 @@ DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)") | |||
140 | .init_irq = omap_intc_of_init, | 140 | .init_irq = omap_intc_of_init, |
141 | .handle_irq = omap3_intc_handle_irq, | 141 | .handle_irq = omap3_intc_handle_irq, |
142 | .init_machine = omap_generic_init, | 142 | .init_machine = omap_generic_init, |
143 | .init_time = omap3_am33xx_gptimer_timer_init, | 143 | .init_time = omap3_gptimer_timer_init, |
144 | .dt_compat = am33xx_boards_compat, | 144 | .dt_compat = am33xx_boards_compat, |
145 | .restart = am33xx_restart, | 145 | .restart = am33xx_restart, |
146 | MACHINE_END | 146 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index e979d48270c9..b54562d1235e 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c | |||
@@ -527,26 +527,28 @@ static void __init igep_i2c_init(void) | |||
527 | omap3_pmic_init("twl4030", &igep_twldata); | 527 | omap3_pmic_init("twl4030", &igep_twldata); |
528 | } | 528 | } |
529 | 529 | ||
530 | static struct usbhs_phy_data igep2_phy_data[] __initdata = { | ||
531 | { | ||
532 | .port = 1, | ||
533 | .reset_gpio = IGEP2_GPIO_USBH_NRESET, | ||
534 | .vcc_gpio = -EINVAL, | ||
535 | }, | ||
536 | }; | ||
537 | |||
538 | static struct usbhs_phy_data igep3_phy_data[] __initdata = { | ||
539 | { | ||
540 | .port = 2, | ||
541 | .reset_gpio = IGEP3_GPIO_USBH_NRESET, | ||
542 | .vcc_gpio = -EINVAL, | ||
543 | }, | ||
544 | }; | ||
545 | |||
530 | static struct usbhs_omap_platform_data igep2_usbhs_bdata __initdata = { | 546 | static struct usbhs_omap_platform_data igep2_usbhs_bdata __initdata = { |
531 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 547 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
532 | .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
533 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
534 | |||
535 | .phy_reset = true, | ||
536 | .reset_gpio_port[0] = IGEP2_GPIO_USBH_NRESET, | ||
537 | .reset_gpio_port[1] = -EINVAL, | ||
538 | .reset_gpio_port[2] = -EINVAL, | ||
539 | }; | 548 | }; |
540 | 549 | ||
541 | static struct usbhs_omap_platform_data igep3_usbhs_bdata __initdata = { | 550 | static struct usbhs_omap_platform_data igep3_usbhs_bdata __initdata = { |
542 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
543 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 551 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
544 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
545 | |||
546 | .phy_reset = true, | ||
547 | .reset_gpio_port[0] = -EINVAL, | ||
548 | .reset_gpio_port[1] = IGEP3_GPIO_USBH_NRESET, | ||
549 | .reset_gpio_port[2] = -EINVAL, | ||
550 | }; | 552 | }; |
551 | 553 | ||
552 | #ifdef CONFIG_OMAP_MUX | 554 | #ifdef CONFIG_OMAP_MUX |
@@ -642,8 +644,10 @@ static void __init igep_init(void) | |||
642 | if (machine_is_igep0020()) { | 644 | if (machine_is_igep0020()) { |
643 | omap_display_init(&igep2_dss_data); | 645 | omap_display_init(&igep2_dss_data); |
644 | igep2_init_smsc911x(); | 646 | igep2_init_smsc911x(); |
647 | usbhs_init_phys(igep2_phy_data, ARRAY_SIZE(igep2_phy_data)); | ||
645 | usbhs_init(&igep2_usbhs_bdata); | 648 | usbhs_init(&igep2_usbhs_bdata); |
646 | } else { | 649 | } else { |
650 | usbhs_init_phys(igep3_phy_data, ARRAY_SIZE(igep3_phy_data)); | ||
647 | usbhs_init(&igep3_usbhs_bdata); | 651 | usbhs_init(&igep3_usbhs_bdata); |
648 | } | 652 | } |
649 | } | 653 | } |
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 0ce91af753fa..6de78605c0af 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/mtd/nand.h> | 33 | #include <linux/mtd/nand.h> |
34 | #include <linux/mmc/host.h> | 34 | #include <linux/mmc/host.h> |
35 | #include <linux/usb/phy.h> | 35 | #include <linux/usb/phy.h> |
36 | #include <linux/usb/nop-usb-xceiv.h> | ||
36 | 37 | ||
37 | #include <linux/regulator/machine.h> | 38 | #include <linux/regulator/machine.h> |
38 | #include <linux/i2c/twl.h> | 39 | #include <linux/i2c/twl.h> |
@@ -277,6 +278,21 @@ static struct regulator_consumer_supply beagle_vsim_supply[] = { | |||
277 | 278 | ||
278 | static struct gpio_led gpio_leds[]; | 279 | static struct gpio_led gpio_leds[]; |
279 | 280 | ||
281 | /* PHY's VCC regulator might be added later, so flag that we need it */ | ||
282 | static struct nop_usb_xceiv_platform_data hsusb2_phy_data = { | ||
283 | .needs_vcc = true, | ||
284 | }; | ||
285 | |||
286 | static struct usbhs_phy_data phy_data[] = { | ||
287 | { | ||
288 | .port = 2, | ||
289 | .reset_gpio = 147, | ||
290 | .vcc_gpio = -1, /* updated in beagle_twl_gpio_setup */ | ||
291 | .vcc_polarity = 1, /* updated in beagle_twl_gpio_setup */ | ||
292 | .platform_data = &hsusb2_phy_data, | ||
293 | }, | ||
294 | }; | ||
295 | |||
280 | static int beagle_twl_gpio_setup(struct device *dev, | 296 | static int beagle_twl_gpio_setup(struct device *dev, |
281 | unsigned gpio, unsigned ngpio) | 297 | unsigned gpio, unsigned ngpio) |
282 | { | 298 | { |
@@ -318,9 +334,11 @@ static int beagle_twl_gpio_setup(struct device *dev, | |||
318 | } | 334 | } |
319 | dvi_panel.power_down_gpio = beagle_config.dvi_pd_gpio; | 335 | dvi_panel.power_down_gpio = beagle_config.dvi_pd_gpio; |
320 | 336 | ||
321 | gpio_request_one(gpio + TWL4030_GPIO_MAX, beagle_config.usb_pwr_level, | 337 | /* TWL4030_GPIO_MAX i.e. LED_GPO controls HS USB Port 2 power */ |
322 | "nEN_USB_PWR"); | 338 | phy_data[0].vcc_gpio = gpio + TWL4030_GPIO_MAX; |
339 | phy_data[0].vcc_polarity = beagle_config.usb_pwr_level; | ||
323 | 340 | ||
341 | usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); | ||
324 | return 0; | 342 | return 0; |
325 | } | 343 | } |
326 | 344 | ||
@@ -453,15 +471,7 @@ static struct platform_device *omap3_beagle_devices[] __initdata = { | |||
453 | }; | 471 | }; |
454 | 472 | ||
455 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 473 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
456 | |||
457 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
458 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 474 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
459 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
460 | |||
461 | .phy_reset = true, | ||
462 | .reset_gpio_port[0] = -EINVAL, | ||
463 | .reset_gpio_port[1] = 147, | ||
464 | .reset_gpio_port[2] = -EINVAL | ||
465 | }; | 475 | }; |
466 | 476 | ||
467 | #ifdef CONFIG_OMAP_MUX | 477 | #ifdef CONFIG_OMAP_MUX |
@@ -479,7 +489,7 @@ static int __init beagle_opp_init(void) | |||
479 | 489 | ||
480 | /* Initialize the omap3 opp table if not already created. */ | 490 | /* Initialize the omap3 opp table if not already created. */ |
481 | r = omap3_opp_init(); | 491 | r = omap3_opp_init(); |
482 | if (IS_ERR_VALUE(r) && (r != -EEXIST)) { | 492 | if (r < 0 && (r != -EEXIST)) { |
483 | pr_err("%s: opp default init failed\n", __func__); | 493 | pr_err("%s: opp default init failed\n", __func__); |
484 | return r; | 494 | return r; |
485 | } | 495 | } |
@@ -543,7 +553,9 @@ static void __init omap3_beagle_init(void) | |||
543 | 553 | ||
544 | usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); | 554 | usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); |
545 | usb_musb_init(NULL); | 555 | usb_musb_init(NULL); |
556 | |||
546 | usbhs_init(&usbhs_bdata); | 557 | usbhs_init(&usbhs_bdata); |
558 | |||
547 | board_nand_init(omap3beagle_nand_partitions, | 559 | board_nand_init(omap3beagle_nand_partitions, |
548 | ARRAY_SIZE(omap3beagle_nand_partitions), NAND_CS, | 560 | ARRAY_SIZE(omap3beagle_nand_partitions), NAND_CS, |
549 | NAND_BUSWIDTH_16, NULL); | 561 | NAND_BUSWIDTH_16, NULL); |
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index 5eecc178f8bf..f76d0de7b406 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c | |||
@@ -466,7 +466,7 @@ struct wl12xx_platform_data omap3evm_wlan_data __initdata = { | |||
466 | static struct regulator_consumer_supply omap3evm_vaux2_supplies[] = { | 466 | static struct regulator_consumer_supply omap3evm_vaux2_supplies[] = { |
467 | REGULATOR_SUPPLY("VDD_CSIPHY1", "omap3isp"), /* OMAP ISP */ | 467 | REGULATOR_SUPPLY("VDD_CSIPHY1", "omap3isp"), /* OMAP ISP */ |
468 | REGULATOR_SUPPLY("VDD_CSIPHY2", "omap3isp"), /* OMAP ISP */ | 468 | REGULATOR_SUPPLY("VDD_CSIPHY2", "omap3isp"), /* OMAP ISP */ |
469 | REGULATOR_SUPPLY("hsusb1", "ehci-omap.0"), | 469 | REGULATOR_SUPPLY("vcc", "nop_usb_xceiv.2"), /* hsusb port 2 */ |
470 | REGULATOR_SUPPLY("vaux2", NULL), | 470 | REGULATOR_SUPPLY("vaux2", NULL), |
471 | }; | 471 | }; |
472 | 472 | ||
@@ -509,17 +509,16 @@ static int __init omap3_evm_i2c_init(void) | |||
509 | return 0; | 509 | return 0; |
510 | } | 510 | } |
511 | 511 | ||
512 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 512 | static struct usbhs_phy_data phy_data[] __initdata = { |
513 | { | ||
514 | .port = 2, | ||
515 | .reset_gpio = -1, /* set at runtime */ | ||
516 | .vcc_gpio = -EINVAL, | ||
517 | }, | ||
518 | }; | ||
513 | 519 | ||
514 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, | 520 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
515 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 521 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
516 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
517 | |||
518 | .phy_reset = true, | ||
519 | /* PHY reset GPIO will be runtime programmed based on EVM version */ | ||
520 | .reset_gpio_port[0] = -EINVAL, | ||
521 | .reset_gpio_port[1] = -EINVAL, | ||
522 | .reset_gpio_port[2] = -EINVAL | ||
523 | }; | 522 | }; |
524 | 523 | ||
525 | #ifdef CONFIG_OMAP_MUX | 524 | #ifdef CONFIG_OMAP_MUX |
@@ -695,7 +694,7 @@ static void __init omap3_evm_init(void) | |||
695 | 694 | ||
696 | /* setup EHCI phy reset config */ | 695 | /* setup EHCI phy reset config */ |
697 | omap_mux_init_gpio(21, OMAP_PIN_INPUT_PULLUP); | 696 | omap_mux_init_gpio(21, OMAP_PIN_INPUT_PULLUP); |
698 | usbhs_bdata.reset_gpio_port[1] = 21; | 697 | phy_data[0].reset_gpio = 21; |
699 | 698 | ||
700 | /* EVM REV >= E can supply 500mA with EXTVBUS programming */ | 699 | /* EVM REV >= E can supply 500mA with EXTVBUS programming */ |
701 | musb_board_data.power = 500; | 700 | musb_board_data.power = 500; |
@@ -703,10 +702,12 @@ static void __init omap3_evm_init(void) | |||
703 | } else { | 702 | } else { |
704 | /* setup EHCI phy reset on MDC */ | 703 | /* setup EHCI phy reset on MDC */ |
705 | omap_mux_init_gpio(135, OMAP_PIN_OUTPUT); | 704 | omap_mux_init_gpio(135, OMAP_PIN_OUTPUT); |
706 | usbhs_bdata.reset_gpio_port[1] = 135; | 705 | phy_data[0].reset_gpio = 135; |
707 | } | 706 | } |
708 | usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); | 707 | usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); |
709 | usb_musb_init(&musb_board_data); | 708 | usb_musb_init(&musb_board_data); |
709 | |||
710 | usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); | ||
710 | usbhs_init(&usbhs_bdata); | 711 | usbhs_init(&usbhs_bdata); |
711 | board_nand_init(omap3evm_nand_partitions, | 712 | board_nand_init(omap3evm_nand_partitions, |
712 | ARRAY_SIZE(omap3evm_nand_partitions), NAND_CS, | 713 | ARRAY_SIZE(omap3evm_nand_partitions), NAND_CS, |
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 533180f8bf41..28133d5b4fed 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c | |||
@@ -351,7 +351,7 @@ static struct regulator_consumer_supply pandora_vcc_lcd_supply[] = { | |||
351 | }; | 351 | }; |
352 | 352 | ||
353 | static struct regulator_consumer_supply pandora_usb_phy_supply[] = { | 353 | static struct regulator_consumer_supply pandora_usb_phy_supply[] = { |
354 | REGULATOR_SUPPLY("hsusb1", "ehci-omap.0"), | 354 | REGULATOR_SUPPLY("vcc", "nop_usb_xceiv.2"), /* hsusb port 2 */ |
355 | }; | 355 | }; |
356 | 356 | ||
357 | /* ads7846 on SPI and 2 nub controllers on I2C */ | 357 | /* ads7846 on SPI and 2 nub controllers on I2C */ |
@@ -566,6 +566,14 @@ fail: | |||
566 | printk(KERN_ERR "wl1251 board initialisation failed\n"); | 566 | printk(KERN_ERR "wl1251 board initialisation failed\n"); |
567 | } | 567 | } |
568 | 568 | ||
569 | static struct usbhs_phy_data phy_data[] __initdata = { | ||
570 | { | ||
571 | .port = 2, | ||
572 | .reset_gpio = 16, | ||
573 | .vcc_gpio = -EINVAL, | ||
574 | }, | ||
575 | }; | ||
576 | |||
569 | static struct platform_device *omap3pandora_devices[] __initdata = { | 577 | static struct platform_device *omap3pandora_devices[] __initdata = { |
570 | &pandora_leds_gpio, | 578 | &pandora_leds_gpio, |
571 | &pandora_keys_gpio, | 579 | &pandora_keys_gpio, |
@@ -574,15 +582,7 @@ static struct platform_device *omap3pandora_devices[] __initdata = { | |||
574 | }; | 582 | }; |
575 | 583 | ||
576 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 584 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
577 | |||
578 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
579 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 585 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
580 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
581 | |||
582 | .phy_reset = true, | ||
583 | .reset_gpio_port[0] = -EINVAL, | ||
584 | .reset_gpio_port[1] = 16, | ||
585 | .reset_gpio_port[2] = -EINVAL | ||
586 | }; | 586 | }; |
587 | 587 | ||
588 | #ifdef CONFIG_OMAP_MUX | 588 | #ifdef CONFIG_OMAP_MUX |
@@ -606,7 +606,10 @@ static void __init omap3pandora_init(void) | |||
606 | spi_register_board_info(omap3pandora_spi_board_info, | 606 | spi_register_board_info(omap3pandora_spi_board_info, |
607 | ARRAY_SIZE(omap3pandora_spi_board_info)); | 607 | ARRAY_SIZE(omap3pandora_spi_board_info)); |
608 | omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL); | 608 | omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL); |
609 | |||
610 | usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); | ||
609 | usbhs_init(&usbhs_bdata); | 611 | usbhs_init(&usbhs_bdata); |
612 | |||
610 | usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); | 613 | usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); |
611 | usb_musb_init(NULL); | 614 | usb_musb_init(NULL); |
612 | gpmc_nand_init(&pandora_nand_data, NULL); | 615 | gpmc_nand_init(&pandora_nand_data, NULL); |
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c index 5e63f0758cef..d37e6b187ae4 100644 --- a/arch/arm/mach-omap2/board-omap3stalker.c +++ b/arch/arm/mach-omap2/board-omap3stalker.c | |||
@@ -346,19 +346,20 @@ static int __init omap3_stalker_i2c_init(void) | |||
346 | 346 | ||
347 | #define OMAP3_STALKER_TS_GPIO 175 | 347 | #define OMAP3_STALKER_TS_GPIO 175 |
348 | 348 | ||
349 | static struct usbhs_phy_data phy_data[] __initdata = { | ||
350 | { | ||
351 | .port = 2, | ||
352 | .reset_gpio = 21, | ||
353 | .vcc_gpio = -EINVAL, | ||
354 | }, | ||
355 | }; | ||
356 | |||
349 | static struct platform_device *omap3_stalker_devices[] __initdata = { | 357 | static struct platform_device *omap3_stalker_devices[] __initdata = { |
350 | &keys_gpio, | 358 | &keys_gpio, |
351 | }; | 359 | }; |
352 | 360 | ||
353 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 361 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
354 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
355 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 362 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
356 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
357 | |||
358 | .phy_reset = true, | ||
359 | .reset_gpio_port[0] = -EINVAL, | ||
360 | .reset_gpio_port[1] = 21, | ||
361 | .reset_gpio_port[2] = -EINVAL, | ||
362 | }; | 363 | }; |
363 | 364 | ||
364 | #ifdef CONFIG_OMAP_MUX | 365 | #ifdef CONFIG_OMAP_MUX |
@@ -395,6 +396,8 @@ static void __init omap3_stalker_init(void) | |||
395 | omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL); | 396 | omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL); |
396 | usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); | 397 | usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); |
397 | usb_musb_init(NULL); | 398 | usb_musb_init(NULL); |
399 | |||
400 | usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); | ||
398 | usbhs_init(&usbhs_bdata); | 401 | usbhs_init(&usbhs_bdata); |
399 | omap_ads7846_init(1, OMAP3_STALKER_TS_GPIO, 310, NULL); | 402 | omap_ads7846_init(1, OMAP3_STALKER_TS_GPIO, 310, NULL); |
400 | 403 | ||
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c index bcd44fbcd877..7da48bc42bbf 100644 --- a/arch/arm/mach-omap2/board-omap3touchbook.c +++ b/arch/arm/mach-omap2/board-omap3touchbook.c | |||
@@ -305,21 +305,22 @@ static struct omap_board_mux board_mux[] __initdata = { | |||
305 | }; | 305 | }; |
306 | #endif | 306 | #endif |
307 | 307 | ||
308 | static struct usbhs_phy_data phy_data[] __initdata = { | ||
309 | { | ||
310 | .port = 2, | ||
311 | .reset_gpio = 147, | ||
312 | .vcc_gpio = -EINVAL, | ||
313 | }, | ||
314 | }; | ||
315 | |||
308 | static struct platform_device *omap3_touchbook_devices[] __initdata = { | 316 | static struct platform_device *omap3_touchbook_devices[] __initdata = { |
309 | &leds_gpio, | 317 | &leds_gpio, |
310 | &keys_gpio, | 318 | &keys_gpio, |
311 | }; | 319 | }; |
312 | 320 | ||
313 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 321 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
314 | |||
315 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 322 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
316 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 323 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
317 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
318 | |||
319 | .phy_reset = true, | ||
320 | .reset_gpio_port[0] = -EINVAL, | ||
321 | .reset_gpio_port[1] = 147, | ||
322 | .reset_gpio_port[2] = -EINVAL | ||
323 | }; | 324 | }; |
324 | 325 | ||
325 | static void omap3_touchbook_poweroff(void) | 326 | static void omap3_touchbook_poweroff(void) |
@@ -368,6 +369,8 @@ static void __init omap3_touchbook_init(void) | |||
368 | omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata); | 369 | omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata); |
369 | usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); | 370 | usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); |
370 | usb_musb_init(NULL); | 371 | usb_musb_init(NULL); |
372 | |||
373 | usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); | ||
371 | usbhs_init(&usbhs_bdata); | 374 | usbhs_init(&usbhs_bdata); |
372 | board_nand_init(omap3touchbook_nand_partitions, | 375 | board_nand_init(omap3touchbook_nand_partitions, |
373 | ARRAY_SIZE(omap3touchbook_nand_partitions), NAND_CS, | 376 | ARRAY_SIZE(omap3touchbook_nand_partitions), NAND_CS, |
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index b02c2f00609b..a71ad345f20d 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/ti_wilink_st.h> | 31 | #include <linux/ti_wilink_st.h> |
32 | #include <linux/usb/musb.h> | 32 | #include <linux/usb/musb.h> |
33 | #include <linux/usb/phy.h> | 33 | #include <linux/usb/phy.h> |
34 | #include <linux/usb/nop-usb-xceiv.h> | ||
34 | #include <linux/wl12xx.h> | 35 | #include <linux/wl12xx.h> |
35 | #include <linux/irqchip/arm-gic.h> | 36 | #include <linux/irqchip/arm-gic.h> |
36 | #include <linux/platform_data/omap-abe-twl6040.h> | 37 | #include <linux/platform_data/omap-abe-twl6040.h> |
@@ -132,6 +133,22 @@ static struct platform_device btwilink_device = { | |||
132 | .id = -1, | 133 | .id = -1, |
133 | }; | 134 | }; |
134 | 135 | ||
136 | /* PHY device on HS USB Port 1 i.e. nop_usb_xceiv.1 */ | ||
137 | static struct nop_usb_xceiv_platform_data hsusb1_phy_data = { | ||
138 | /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */ | ||
139 | .clk_rate = 19200000, | ||
140 | }; | ||
141 | |||
142 | static struct usbhs_phy_data phy_data[] __initdata = { | ||
143 | { | ||
144 | .port = 1, | ||
145 | .reset_gpio = GPIO_HUB_NRESET, | ||
146 | .vcc_gpio = GPIO_HUB_POWER, | ||
147 | .vcc_polarity = 1, | ||
148 | .platform_data = &hsusb1_phy_data, | ||
149 | }, | ||
150 | }; | ||
151 | |||
135 | static struct platform_device *panda_devices[] __initdata = { | 152 | static struct platform_device *panda_devices[] __initdata = { |
136 | &leds_gpio, | 153 | &leds_gpio, |
137 | &wl1271_device, | 154 | &wl1271_device, |
@@ -142,49 +159,19 @@ static struct platform_device *panda_devices[] __initdata = { | |||
142 | 159 | ||
143 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 160 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
144 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, | 161 | .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, |
145 | .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
146 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
147 | .phy_reset = false, | ||
148 | .reset_gpio_port[0] = -EINVAL, | ||
149 | .reset_gpio_port[1] = -EINVAL, | ||
150 | .reset_gpio_port[2] = -EINVAL | ||
151 | }; | ||
152 | |||
153 | static struct gpio panda_ehci_gpios[] __initdata = { | ||
154 | { GPIO_HUB_POWER, GPIOF_OUT_INIT_LOW, "hub_power" }, | ||
155 | { GPIO_HUB_NRESET, GPIOF_OUT_INIT_LOW, "hub_nreset" }, | ||
156 | }; | 162 | }; |
157 | 163 | ||
158 | static void __init omap4_ehci_init(void) | 164 | static void __init omap4_ehci_init(void) |
159 | { | 165 | { |
160 | int ret; | 166 | int ret; |
161 | struct clk *phy_ref_clk; | ||
162 | 167 | ||
163 | /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */ | 168 | /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */ |
164 | phy_ref_clk = clk_get(NULL, "auxclk3_ck"); | 169 | ret = clk_add_alias("main_clk", "nop_usb_xceiv.1", "auxclk3_ck", NULL); |
165 | if (IS_ERR(phy_ref_clk)) { | 170 | if (ret) |
166 | pr_err("Cannot request auxclk3\n"); | 171 | pr_err("Failed to add main_clk alias to auxclk3_ck\n"); |
167 | return; | ||
168 | } | ||
169 | clk_set_rate(phy_ref_clk, 19200000); | ||
170 | clk_prepare_enable(phy_ref_clk); | ||
171 | |||
172 | /* disable the power to the usb hub prior to init and reset phy+hub */ | ||
173 | ret = gpio_request_array(panda_ehci_gpios, | ||
174 | ARRAY_SIZE(panda_ehci_gpios)); | ||
175 | if (ret) { | ||
176 | pr_err("Unable to initialize EHCI power/reset\n"); | ||
177 | return; | ||
178 | } | ||
179 | |||
180 | gpio_export(GPIO_HUB_POWER, 0); | ||
181 | gpio_export(GPIO_HUB_NRESET, 0); | ||
182 | gpio_set_value(GPIO_HUB_NRESET, 1); | ||
183 | 172 | ||
173 | usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); | ||
184 | usbhs_init(&usbhs_bdata); | 174 | usbhs_init(&usbhs_bdata); |
185 | |||
186 | /* enable power to hub */ | ||
187 | gpio_set_value(GPIO_HUB_POWER, 1); | ||
188 | } | 175 | } |
189 | 176 | ||
190 | static struct omap_musb_board_data musb_board_data = { | 177 | static struct omap_musb_board_data musb_board_data = { |
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index f790ce5aaa34..4ca6b680aa72 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c | |||
@@ -428,14 +428,16 @@ static int __init overo_spi_init(void) | |||
428 | return 0; | 428 | return 0; |
429 | } | 429 | } |
430 | 430 | ||
431 | static struct usbhs_phy_data phy_data[] __initdata = { | ||
432 | { | ||
433 | .port = 2, | ||
434 | .reset_gpio = OVERO_GPIO_USBH_NRESET, | ||
435 | .vcc_gpio = -EINVAL, | ||
436 | }, | ||
437 | }; | ||
438 | |||
431 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 439 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
432 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
433 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 440 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
434 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
435 | .phy_reset = true, | ||
436 | .reset_gpio_port[0] = -EINVAL, | ||
437 | .reset_gpio_port[1] = OVERO_GPIO_USBH_NRESET, | ||
438 | .reset_gpio_port[2] = -EINVAL | ||
439 | }; | 441 | }; |
440 | 442 | ||
441 | #ifdef CONFIG_OMAP_MUX | 443 | #ifdef CONFIG_OMAP_MUX |
@@ -472,6 +474,8 @@ static void __init overo_init(void) | |||
472 | ARRAY_SIZE(overo_nand_partitions), NAND_CS, 0, NULL); | 474 | ARRAY_SIZE(overo_nand_partitions), NAND_CS, 0, NULL); |
473 | usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); | 475 | usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb"); |
474 | usb_musb_init(NULL); | 476 | usb_musb_init(NULL); |
477 | |||
478 | usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); | ||
475 | usbhs_init(&usbhs_bdata); | 479 | usbhs_init(&usbhs_bdata); |
476 | overo_spi_init(); | 480 | overo_spi_init(); |
477 | overo_init_smsc911x(); | 481 | overo_init_smsc911x(); |
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c index 5e4d4c9fe61a..1a3dd865d8eb 100644 --- a/arch/arm/mach-omap2/board-zoom.c +++ b/arch/arm/mach-omap2/board-zoom.c | |||
@@ -92,14 +92,16 @@ static struct mtd_partition zoom_nand_partitions[] = { | |||
92 | }, | 92 | }, |
93 | }; | 93 | }; |
94 | 94 | ||
95 | static struct usbhs_phy_data phy_data[] __initdata = { | ||
96 | { | ||
97 | .port = 2, | ||
98 | .reset_gpio = ZOOM3_EHCI_RESET_GPIO, | ||
99 | .vcc_gpio = -EINVAL, | ||
100 | }, | ||
101 | }; | ||
102 | |||
95 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { | 103 | static struct usbhs_omap_platform_data usbhs_bdata __initdata = { |
96 | .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
97 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, | 104 | .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, |
98 | .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, | ||
99 | .phy_reset = true, | ||
100 | .reset_gpio_port[0] = -EINVAL, | ||
101 | .reset_gpio_port[1] = ZOOM3_EHCI_RESET_GPIO, | ||
102 | .reset_gpio_port[2] = -EINVAL, | ||
103 | }; | 105 | }; |
104 | 106 | ||
105 | static void __init omap_zoom_init(void) | 107 | static void __init omap_zoom_init(void) |
@@ -109,6 +111,8 @@ static void __init omap_zoom_init(void) | |||
109 | } else if (machine_is_omap_zoom3()) { | 111 | } else if (machine_is_omap_zoom3()) { |
110 | omap3_mux_init(board_mux, OMAP_PACKAGE_CBP); | 112 | omap3_mux_init(board_mux, OMAP_PACKAGE_CBP); |
111 | omap_mux_init_gpio(ZOOM3_EHCI_RESET_GPIO, OMAP_PIN_OUTPUT); | 113 | omap_mux_init_gpio(ZOOM3_EHCI_RESET_GPIO, OMAP_PIN_OUTPUT); |
114 | |||
115 | usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data)); | ||
112 | usbhs_init(&usbhs_bdata); | 116 | usbhs_init(&usbhs_bdata); |
113 | } | 117 | } |
114 | 118 | ||
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index e4ec3a69ee2e..2191f25ad21b 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c | |||
@@ -596,7 +596,7 @@ int __init omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name) | |||
596 | return -ENOENT; | 596 | return -ENOENT; |
597 | 597 | ||
598 | r = clk_set_rate(mpurate_ck, mpurate); | 598 | r = clk_set_rate(mpurate_ck, mpurate); |
599 | if (IS_ERR_VALUE(r)) { | 599 | if (r < 0) { |
600 | WARN(1, "clock: %s: unable to set MPU rate to %d: %d\n", | 600 | WARN(1, "clock: %s: unable to set MPU rate to %d: %d\n", |
601 | mpurate_ck_name, mpurate, r); | 601 | mpurate_ck_name, mpurate, r); |
602 | clk_put(mpurate_ck); | 602 | clk_put(mpurate_ck); |
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index d6ba13e1c540..272490e72ee0 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h | |||
@@ -82,8 +82,7 @@ extern void omap2_init_common_infrastructure(void); | |||
82 | extern void omap2_sync32k_timer_init(void); | 82 | extern void omap2_sync32k_timer_init(void); |
83 | extern void omap3_sync32k_timer_init(void); | 83 | extern void omap3_sync32k_timer_init(void); |
84 | extern void omap3_secure_sync32k_timer_init(void); | 84 | extern void omap3_secure_sync32k_timer_init(void); |
85 | extern void omap3_gp_gptimer_timer_init(void); | 85 | extern void omap3_gptimer_timer_init(void); |
86 | extern void omap3_am33xx_gptimer_timer_init(void); | ||
87 | extern void omap4_local_timer_init(void); | 86 | extern void omap4_local_timer_init(void); |
88 | extern void omap5_realtime_timer_init(void); | 87 | extern void omap5_realtime_timer_init(void); |
89 | 88 | ||
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c index afc1e8c32d6c..d9c27195caf0 100644 --- a/arch/arm/mach-omap2/gpmc-nand.c +++ b/arch/arm/mach-omap2/gpmc-nand.c | |||
@@ -74,14 +74,6 @@ static int omap2_nand_gpmc_retime( | |||
74 | t.cs_wr_off = gpmc_t->cs_wr_off; | 74 | t.cs_wr_off = gpmc_t->cs_wr_off; |
75 | t.wr_cycle = gpmc_t->wr_cycle; | 75 | t.wr_cycle = gpmc_t->wr_cycle; |
76 | 76 | ||
77 | /* Configure GPMC */ | ||
78 | if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16) | ||
79 | gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_DEV_SIZE, 1); | ||
80 | else | ||
81 | gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_DEV_SIZE, 0); | ||
82 | gpmc_cs_configure(gpmc_nand_data->cs, | ||
83 | GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND); | ||
84 | gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_WP, 0); | ||
85 | err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t); | 77 | err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t); |
86 | if (err) | 78 | if (err) |
87 | return err; | 79 | return err; |
@@ -115,14 +107,18 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, | |||
115 | struct gpmc_timings *gpmc_t) | 107 | struct gpmc_timings *gpmc_t) |
116 | { | 108 | { |
117 | int err = 0; | 109 | int err = 0; |
110 | struct gpmc_settings s; | ||
118 | struct device *dev = &gpmc_nand_device.dev; | 111 | struct device *dev = &gpmc_nand_device.dev; |
119 | 112 | ||
113 | memset(&s, 0, sizeof(struct gpmc_settings)); | ||
114 | |||
120 | gpmc_nand_device.dev.platform_data = gpmc_nand_data; | 115 | gpmc_nand_device.dev.platform_data = gpmc_nand_data; |
121 | 116 | ||
122 | err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE, | 117 | err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE, |
123 | (unsigned long *)&gpmc_nand_resource[0].start); | 118 | (unsigned long *)&gpmc_nand_resource[0].start); |
124 | if (err < 0) { | 119 | if (err < 0) { |
125 | dev_err(dev, "Cannot request GPMC CS\n"); | 120 | dev_err(dev, "Cannot request GPMC CS %d, error %d\n", |
121 | gpmc_nand_data->cs, err); | ||
126 | return err; | 122 | return err; |
127 | } | 123 | } |
128 | 124 | ||
@@ -140,11 +136,31 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, | |||
140 | dev_err(dev, "Unable to set gpmc timings: %d\n", err); | 136 | dev_err(dev, "Unable to set gpmc timings: %d\n", err); |
141 | return err; | 137 | return err; |
142 | } | 138 | } |
143 | } | ||
144 | 139 | ||
145 | /* Enable RD PIN Monitoring Reg */ | 140 | if (gpmc_nand_data->of_node) { |
146 | if (gpmc_nand_data->dev_ready) { | 141 | gpmc_read_settings_dt(gpmc_nand_data->of_node, &s); |
147 | gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_RDY_BSY, 1); | 142 | } else { |
143 | s.device_nand = true; | ||
144 | |||
145 | /* Enable RD PIN Monitoring Reg */ | ||
146 | if (gpmc_nand_data->dev_ready) { | ||
147 | s.wait_on_read = true; | ||
148 | s.wait_on_write = true; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16) | ||
153 | s.device_width = GPMC_DEVWIDTH_16BIT; | ||
154 | else | ||
155 | s.device_width = GPMC_DEVWIDTH_8BIT; | ||
156 | |||
157 | err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s); | ||
158 | if (err < 0) | ||
159 | goto out_free_cs; | ||
160 | |||
161 | err = gpmc_configure(GPMC_CONFIG_WP, 0); | ||
162 | if (err < 0) | ||
163 | goto out_free_cs; | ||
148 | } | 164 | } |
149 | 165 | ||
150 | gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs); | 166 | gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs); |
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index fadd87435cd0..64b5a8346982 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c | |||
@@ -47,11 +47,23 @@ static struct platform_device gpmc_onenand_device = { | |||
47 | .resource = &gpmc_onenand_resource, | 47 | .resource = &gpmc_onenand_resource, |
48 | }; | 48 | }; |
49 | 49 | ||
50 | static struct gpmc_timings omap2_onenand_calc_async_timings(void) | 50 | static struct gpmc_settings onenand_async = { |
51 | .device_width = GPMC_DEVWIDTH_16BIT, | ||
52 | .mux_add_data = GPMC_MUX_AD, | ||
53 | }; | ||
54 | |||
55 | static struct gpmc_settings onenand_sync = { | ||
56 | .burst_read = true, | ||
57 | .burst_wrap = true, | ||
58 | .burst_len = GPMC_BURST_16, | ||
59 | .device_width = GPMC_DEVWIDTH_16BIT, | ||
60 | .mux_add_data = GPMC_MUX_AD, | ||
61 | .wait_pin = 0, | ||
62 | }; | ||
63 | |||
64 | static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) | ||
51 | { | 65 | { |
52 | struct gpmc_device_timings dev_t; | 66 | struct gpmc_device_timings dev_t; |
53 | struct gpmc_timings t; | ||
54 | |||
55 | const int t_cer = 15; | 67 | const int t_cer = 15; |
56 | const int t_avdp = 12; | 68 | const int t_avdp = 12; |
57 | const int t_aavdh = 7; | 69 | const int t_aavdh = 7; |
@@ -64,7 +76,6 @@ static struct gpmc_timings omap2_onenand_calc_async_timings(void) | |||
64 | 76 | ||
65 | memset(&dev_t, 0, sizeof(dev_t)); | 77 | memset(&dev_t, 0, sizeof(dev_t)); |
66 | 78 | ||
67 | dev_t.mux = true; | ||
68 | dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000; | 79 | dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000; |
69 | dev_t.t_avdp_w = dev_t.t_avdp_r; | 80 | dev_t.t_avdp_w = dev_t.t_avdp_r; |
70 | dev_t.t_aavdh = t_aavdh * 1000; | 81 | dev_t.t_aavdh = t_aavdh * 1000; |
@@ -76,19 +87,7 @@ static struct gpmc_timings omap2_onenand_calc_async_timings(void) | |||
76 | dev_t.t_wpl = t_wpl * 1000; | 87 | dev_t.t_wpl = t_wpl * 1000; |
77 | dev_t.t_wph = t_wph * 1000; | 88 | dev_t.t_wph = t_wph * 1000; |
78 | 89 | ||
79 | gpmc_calc_timings(&t, &dev_t); | 90 | gpmc_calc_timings(t, &onenand_async, &dev_t); |
80 | |||
81 | return t; | ||
82 | } | ||
83 | |||
84 | static int gpmc_set_async_mode(int cs, struct gpmc_timings *t) | ||
85 | { | ||
86 | /* Configure GPMC for asynchronous read */ | ||
87 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, | ||
88 | GPMC_CONFIG1_DEVICESIZE_16 | | ||
89 | GPMC_CONFIG1_MUXADDDATA); | ||
90 | |||
91 | return gpmc_cs_set_timings(cs, t); | ||
92 | } | 91 | } |
93 | 92 | ||
94 | static void omap2_onenand_set_async_mode(void __iomem *onenand_base) | 93 | static void omap2_onenand_set_async_mode(void __iomem *onenand_base) |
@@ -158,12 +157,11 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg, | |||
158 | return freq; | 157 | return freq; |
159 | } | 158 | } |
160 | 159 | ||
161 | static struct gpmc_timings | 160 | static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t, |
162 | omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, | 161 | unsigned int flags, |
163 | int freq) | 162 | int freq) |
164 | { | 163 | { |
165 | struct gpmc_device_timings dev_t; | 164 | struct gpmc_device_timings dev_t; |
166 | struct gpmc_timings t; | ||
167 | const int t_cer = 15; | 165 | const int t_cer = 15; |
168 | const int t_avdp = 12; | 166 | const int t_avdp = 12; |
169 | const int t_cez = 20; /* max of t_cez, t_oez */ | 167 | const int t_cez = 20; /* max of t_cez, t_oez */ |
@@ -172,9 +170,9 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, | |||
172 | int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; | 170 | int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; |
173 | int div, gpmc_clk_ns; | 171 | int div, gpmc_clk_ns; |
174 | 172 | ||
175 | if (cfg->flags & ONENAND_SYNC_READ) | 173 | if (flags & ONENAND_SYNC_READ) |
176 | onenand_flags = ONENAND_FLAG_SYNCREAD; | 174 | onenand_flags = ONENAND_FLAG_SYNCREAD; |
177 | else if (cfg->flags & ONENAND_SYNC_READWRITE) | 175 | else if (flags & ONENAND_SYNC_READWRITE) |
178 | onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE; | 176 | onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE; |
179 | 177 | ||
180 | switch (freq) { | 178 | switch (freq) { |
@@ -239,10 +237,11 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, | |||
239 | /* Set synchronous read timings */ | 237 | /* Set synchronous read timings */ |
240 | memset(&dev_t, 0, sizeof(dev_t)); | 238 | memset(&dev_t, 0, sizeof(dev_t)); |
241 | 239 | ||
242 | dev_t.mux = true; | 240 | if (onenand_flags & ONENAND_FLAG_SYNCREAD) |
243 | dev_t.sync_read = true; | 241 | onenand_sync.sync_read = true; |
244 | if (onenand_flags & ONENAND_FLAG_SYNCWRITE) { | 242 | if (onenand_flags & ONENAND_FLAG_SYNCWRITE) { |
245 | dev_t.sync_write = true; | 243 | onenand_sync.sync_write = true; |
244 | onenand_sync.burst_write = true; | ||
246 | } else { | 245 | } else { |
247 | dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000; | 246 | dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000; |
248 | dev_t.t_wpl = t_wpl * 1000; | 247 | dev_t.t_wpl = t_wpl * 1000; |
@@ -265,32 +264,7 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, | |||
265 | dev_t.cyc_aavdh_oe = 1; | 264 | dev_t.cyc_aavdh_oe = 1; |
266 | dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period; | 265 | dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period; |
267 | 266 | ||
268 | gpmc_calc_timings(&t, &dev_t); | 267 | gpmc_calc_timings(t, &onenand_sync, &dev_t); |
269 | |||
270 | return t; | ||
271 | } | ||
272 | |||
273 | static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t) | ||
274 | { | ||
275 | unsigned sync_read = onenand_flags & ONENAND_FLAG_SYNCREAD; | ||
276 | unsigned sync_write = onenand_flags & ONENAND_FLAG_SYNCWRITE; | ||
277 | |||
278 | /* Configure GPMC for synchronous read */ | ||
279 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, | ||
280 | GPMC_CONFIG1_WRAPBURST_SUPP | | ||
281 | GPMC_CONFIG1_READMULTIPLE_SUPP | | ||
282 | (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) | | ||
283 | (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) | | ||
284 | (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) | | ||
285 | GPMC_CONFIG1_PAGE_LEN(2) | | ||
286 | (cpu_is_omap34xx() ? 0 : | ||
287 | (GPMC_CONFIG1_WAIT_READ_MON | | ||
288 | GPMC_CONFIG1_WAIT_PIN_SEL(0))) | | ||
289 | GPMC_CONFIG1_DEVICESIZE_16 | | ||
290 | GPMC_CONFIG1_DEVICETYPE_NOR | | ||
291 | GPMC_CONFIG1_MUXADDDATA); | ||
292 | |||
293 | return gpmc_cs_set_timings(cs, t); | ||
294 | } | 268 | } |
295 | 269 | ||
296 | static int omap2_onenand_setup_async(void __iomem *onenand_base) | 270 | static int omap2_onenand_setup_async(void __iomem *onenand_base) |
@@ -298,12 +272,20 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base) | |||
298 | struct gpmc_timings t; | 272 | struct gpmc_timings t; |
299 | int ret; | 273 | int ret; |
300 | 274 | ||
275 | if (gpmc_onenand_data->of_node) | ||
276 | gpmc_read_settings_dt(gpmc_onenand_data->of_node, | ||
277 | &onenand_async); | ||
278 | |||
301 | omap2_onenand_set_async_mode(onenand_base); | 279 | omap2_onenand_set_async_mode(onenand_base); |
302 | 280 | ||
303 | t = omap2_onenand_calc_async_timings(); | 281 | omap2_onenand_calc_async_timings(&t); |
282 | |||
283 | ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_async); | ||
284 | if (ret < 0) | ||
285 | return ret; | ||
304 | 286 | ||
305 | ret = gpmc_set_async_mode(gpmc_onenand_data->cs, &t); | 287 | ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t); |
306 | if (IS_ERR_VALUE(ret)) | 288 | if (ret < 0) |
307 | return ret; | 289 | return ret; |
308 | 290 | ||
309 | omap2_onenand_set_async_mode(onenand_base); | 291 | omap2_onenand_set_async_mode(onenand_base); |
@@ -322,10 +304,26 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr) | |||
322 | set_onenand_cfg(onenand_base); | 304 | set_onenand_cfg(onenand_base); |
323 | } | 305 | } |
324 | 306 | ||
325 | t = omap2_onenand_calc_sync_timings(gpmc_onenand_data, freq); | 307 | if (gpmc_onenand_data->of_node) { |
308 | gpmc_read_settings_dt(gpmc_onenand_data->of_node, | ||
309 | &onenand_sync); | ||
310 | } else { | ||
311 | /* | ||
312 | * FIXME: Appears to be legacy code from initial ONENAND commit. | ||
313 | * Unclear what boards this is for and if this can be removed. | ||
314 | */ | ||
315 | if (!cpu_is_omap34xx()) | ||
316 | onenand_sync.wait_on_read = true; | ||
317 | } | ||
318 | |||
319 | omap2_onenand_calc_sync_timings(&t, gpmc_onenand_data->flags, freq); | ||
326 | 320 | ||
327 | ret = gpmc_set_sync_mode(gpmc_onenand_data->cs, &t); | 321 | ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_sync); |
328 | if (IS_ERR_VALUE(ret)) | 322 | if (ret < 0) |
323 | return ret; | ||
324 | |||
325 | ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t); | ||
326 | if (ret < 0) | ||
329 | return ret; | 327 | return ret; |
330 | 328 | ||
331 | set_onenand_cfg(onenand_base); | 329 | set_onenand_cfg(onenand_base); |
@@ -359,6 +357,7 @@ static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr) | |||
359 | void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) | 357 | void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) |
360 | { | 358 | { |
361 | int err; | 359 | int err; |
360 | struct device *dev = &gpmc_onenand_device.dev; | ||
362 | 361 | ||
363 | gpmc_onenand_data = _onenand_data; | 362 | gpmc_onenand_data = _onenand_data; |
364 | gpmc_onenand_data->onenand_setup = gpmc_onenand_setup; | 363 | gpmc_onenand_data->onenand_setup = gpmc_onenand_setup; |
@@ -366,7 +365,7 @@ void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) | |||
366 | 365 | ||
367 | if (cpu_is_omap24xx() && | 366 | if (cpu_is_omap24xx() && |
368 | (gpmc_onenand_data->flags & ONENAND_SYNC_READWRITE)) { | 367 | (gpmc_onenand_data->flags & ONENAND_SYNC_READWRITE)) { |
369 | printk(KERN_ERR "Onenand using only SYNC_READ on 24xx\n"); | 368 | dev_warn(dev, "OneNAND using only SYNC_READ on 24xx\n"); |
370 | gpmc_onenand_data->flags &= ~ONENAND_SYNC_READWRITE; | 369 | gpmc_onenand_data->flags &= ~ONENAND_SYNC_READWRITE; |
371 | gpmc_onenand_data->flags |= ONENAND_SYNC_READ; | 370 | gpmc_onenand_data->flags |= ONENAND_SYNC_READ; |
372 | } | 371 | } |
@@ -379,7 +378,8 @@ void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) | |||
379 | err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE, | 378 | err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE, |
380 | (unsigned long *)&gpmc_onenand_resource.start); | 379 | (unsigned long *)&gpmc_onenand_resource.start); |
381 | if (err < 0) { | 380 | if (err < 0) { |
382 | pr_err("%s: Cannot request GPMC CS\n", __func__); | 381 | dev_err(dev, "Cannot request GPMC CS %d, error %d\n", |
382 | gpmc_onenand_data->cs, err); | ||
383 | return; | 383 | return; |
384 | } | 384 | } |
385 | 385 | ||
@@ -387,7 +387,7 @@ void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) | |||
387 | ONENAND_IO_SIZE - 1; | 387 | ONENAND_IO_SIZE - 1; |
388 | 388 | ||
389 | if (platform_device_register(&gpmc_onenand_device) < 0) { | 389 | if (platform_device_register(&gpmc_onenand_device) < 0) { |
390 | pr_err("%s: Unable to register OneNAND device\n", __func__); | 390 | dev_err(dev, "Unable to register OneNAND device\n"); |
391 | gpmc_cs_free(gpmc_onenand_data->cs); | 391 | gpmc_cs_free(gpmc_onenand_data->cs); |
392 | return; | 392 | return; |
393 | } | 393 | } |
diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c index 11d0b756f098..61a063595e66 100644 --- a/arch/arm/mach-omap2/gpmc-smc91x.c +++ b/arch/arm/mach-omap2/gpmc-smc91x.c | |||
@@ -49,6 +49,10 @@ static struct platform_device gpmc_smc91x_device = { | |||
49 | .resource = gpmc_smc91x_resources, | 49 | .resource = gpmc_smc91x_resources, |
50 | }; | 50 | }; |
51 | 51 | ||
52 | static struct gpmc_settings smc91x_settings = { | ||
53 | .device_width = GPMC_DEVWIDTH_16BIT, | ||
54 | }; | ||
55 | |||
52 | /* | 56 | /* |
53 | * Set the gpmc timings for smc91c96. The timings are taken | 57 | * Set the gpmc timings for smc91c96. The timings are taken |
54 | * from the data sheet available at: | 58 | * from the data sheet available at: |
@@ -67,18 +71,6 @@ static int smc91c96_gpmc_retime(void) | |||
67 | const int t7 = 5; /* Figure 12.4 write */ | 71 | const int t7 = 5; /* Figure 12.4 write */ |
68 | const int t8 = 5; /* Figure 12.4 write */ | 72 | const int t8 = 5; /* Figure 12.4 write */ |
69 | const int t20 = 185; /* Figure 12.2 read and 12.4 write */ | 73 | const int t20 = 185; /* Figure 12.2 read and 12.4 write */ |
70 | u32 l; | ||
71 | |||
72 | l = GPMC_CONFIG1_DEVICESIZE_16; | ||
73 | if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA) | ||
74 | l |= GPMC_CONFIG1_MUXADDDATA; | ||
75 | if (gpmc_cfg->flags & GPMC_READ_MON) | ||
76 | l |= GPMC_CONFIG1_WAIT_READ_MON; | ||
77 | if (gpmc_cfg->flags & GPMC_WRITE_MON) | ||
78 | l |= GPMC_CONFIG1_WAIT_WRITE_MON; | ||
79 | if (gpmc_cfg->wait_pin) | ||
80 | l |= GPMC_CONFIG1_WAIT_PIN_SEL(gpmc_cfg->wait_pin); | ||
81 | gpmc_cs_write_reg(gpmc_cfg->cs, GPMC_CS_CONFIG1, l); | ||
82 | 74 | ||
83 | /* | 75 | /* |
84 | * FIXME: Calculate the address and data bus muxed timings. | 76 | * FIXME: Calculate the address and data bus muxed timings. |
@@ -104,7 +96,7 @@ static int smc91c96_gpmc_retime(void) | |||
104 | dev_t.t_cez_w = t4_w * 1000; | 96 | dev_t.t_cez_w = t4_w * 1000; |
105 | dev_t.t_wr_cycle = (t20 - t3) * 1000; | 97 | dev_t.t_wr_cycle = (t20 - t3) * 1000; |
106 | 98 | ||
107 | gpmc_calc_timings(&t, &dev_t); | 99 | gpmc_calc_timings(&t, &smc91x_settings, &dev_t); |
108 | 100 | ||
109 | return gpmc_cs_set_timings(gpmc_cfg->cs, &t); | 101 | return gpmc_cs_set_timings(gpmc_cfg->cs, &t); |
110 | } | 102 | } |
@@ -133,6 +125,18 @@ void __init gpmc_smc91x_init(struct omap_smc91x_platform_data *board_data) | |||
133 | gpmc_smc91x_resources[0].end = cs_mem_base + 0x30f; | 125 | gpmc_smc91x_resources[0].end = cs_mem_base + 0x30f; |
134 | gpmc_smc91x_resources[1].flags |= (gpmc_cfg->flags & IRQF_TRIGGER_MASK); | 126 | gpmc_smc91x_resources[1].flags |= (gpmc_cfg->flags & IRQF_TRIGGER_MASK); |
135 | 127 | ||
128 | if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA) | ||
129 | smc91x_settings.mux_add_data = GPMC_MUX_AD; | ||
130 | if (gpmc_cfg->flags & GPMC_READ_MON) | ||
131 | smc91x_settings.wait_on_read = true; | ||
132 | if (gpmc_cfg->flags & GPMC_WRITE_MON) | ||
133 | smc91x_settings.wait_on_write = true; | ||
134 | if (gpmc_cfg->wait_pin) | ||
135 | smc91x_settings.wait_pin = gpmc_cfg->wait_pin; | ||
136 | ret = gpmc_cs_program_settings(gpmc_cfg->cs, &smc91x_settings); | ||
137 | if (ret < 0) | ||
138 | goto free1; | ||
139 | |||
136 | if (gpmc_cfg->retime) { | 140 | if (gpmc_cfg->retime) { |
137 | ret = gpmc_cfg->retime(); | 141 | ret = gpmc_cfg->retime(); |
138 | if (ret != 0) | 142 | if (ret != 0) |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 410e1bac7815..ed946df5ad8a 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/of.h> | 28 | #include <linux/of.h> |
29 | #include <linux/of_address.h> | ||
29 | #include <linux/of_mtd.h> | 30 | #include <linux/of_mtd.h> |
30 | #include <linux/of_device.h> | 31 | #include <linux/of_device.h> |
31 | #include <linux/mtd/nand.h> | 32 | #include <linux/mtd/nand.h> |
@@ -91,9 +92,7 @@ | |||
91 | #define GPMC_CS_SIZE 0x30 | 92 | #define GPMC_CS_SIZE 0x30 |
92 | #define GPMC_BCH_SIZE 0x10 | 93 | #define GPMC_BCH_SIZE 0x10 |
93 | 94 | ||
94 | #define GPMC_MEM_START 0x00000000 | ||
95 | #define GPMC_MEM_END 0x3FFFFFFF | 95 | #define GPMC_MEM_END 0x3FFFFFFF |
96 | #define BOOT_ROM_SPACE 0x100000 /* 1MB */ | ||
97 | 96 | ||
98 | #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ | 97 | #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ |
99 | #define GPMC_SECTION_SHIFT 28 /* 128 MB */ | 98 | #define GPMC_SECTION_SHIFT 28 /* 128 MB */ |
@@ -107,6 +106,9 @@ | |||
107 | 106 | ||
108 | #define GPMC_HAS_WR_ACCESS 0x1 | 107 | #define GPMC_HAS_WR_ACCESS 0x1 |
109 | #define GPMC_HAS_WR_DATA_MUX_BUS 0x2 | 108 | #define GPMC_HAS_WR_DATA_MUX_BUS 0x2 |
109 | #define GPMC_HAS_MUX_AAD 0x4 | ||
110 | |||
111 | #define GPMC_NR_WAITPINS 4 | ||
110 | 112 | ||
111 | /* XXX: Only NAND irq has been considered,currently these are the only ones used | 113 | /* XXX: Only NAND irq has been considered,currently these are the only ones used |
112 | */ | 114 | */ |
@@ -153,6 +155,7 @@ static struct resource gpmc_cs_mem[GPMC_CS_NUM]; | |||
153 | static DEFINE_SPINLOCK(gpmc_mem_lock); | 155 | static DEFINE_SPINLOCK(gpmc_mem_lock); |
154 | /* Define chip-selects as reserved by default until probe completes */ | 156 | /* Define chip-selects as reserved by default until probe completes */ |
155 | static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1); | 157 | static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1); |
158 | static unsigned int gpmc_nr_waitpins; | ||
156 | static struct device *gpmc_dev; | 159 | static struct device *gpmc_dev; |
157 | static int gpmc_irq; | 160 | static int gpmc_irq; |
158 | static resource_size_t phys_base, mem_size; | 161 | static resource_size_t phys_base, mem_size; |
@@ -181,7 +184,7 @@ void gpmc_cs_write_reg(int cs, int idx, u32 val) | |||
181 | __raw_writel(val, reg_addr); | 184 | __raw_writel(val, reg_addr); |
182 | } | 185 | } |
183 | 186 | ||
184 | u32 gpmc_cs_read_reg(int cs, int idx) | 187 | static u32 gpmc_cs_read_reg(int cs, int idx) |
185 | { | 188 | { |
186 | void __iomem *reg_addr; | 189 | void __iomem *reg_addr; |
187 | 190 | ||
@@ -190,7 +193,7 @@ u32 gpmc_cs_read_reg(int cs, int idx) | |||
190 | } | 193 | } |
191 | 194 | ||
192 | /* TODO: Add support for gpmc_fck to clock framework and use it */ | 195 | /* TODO: Add support for gpmc_fck to clock framework and use it */ |
193 | unsigned long gpmc_get_fclk_period(void) | 196 | static unsigned long gpmc_get_fclk_period(void) |
194 | { | 197 | { |
195 | unsigned long rate = clk_get_rate(gpmc_l3_clk); | 198 | unsigned long rate = clk_get_rate(gpmc_l3_clk); |
196 | 199 | ||
@@ -205,7 +208,7 @@ unsigned long gpmc_get_fclk_period(void) | |||
205 | return rate; | 208 | return rate; |
206 | } | 209 | } |
207 | 210 | ||
208 | unsigned int gpmc_ns_to_ticks(unsigned int time_ns) | 211 | static unsigned int gpmc_ns_to_ticks(unsigned int time_ns) |
209 | { | 212 | { |
210 | unsigned long tick_ps; | 213 | unsigned long tick_ps; |
211 | 214 | ||
@@ -215,7 +218,7 @@ unsigned int gpmc_ns_to_ticks(unsigned int time_ns) | |||
215 | return (time_ns * 1000 + tick_ps - 1) / tick_ps; | 218 | return (time_ns * 1000 + tick_ps - 1) / tick_ps; |
216 | } | 219 | } |
217 | 220 | ||
218 | unsigned int gpmc_ps_to_ticks(unsigned int time_ps) | 221 | static unsigned int gpmc_ps_to_ticks(unsigned int time_ps) |
219 | { | 222 | { |
220 | unsigned long tick_ps; | 223 | unsigned long tick_ps; |
221 | 224 | ||
@@ -230,13 +233,6 @@ unsigned int gpmc_ticks_to_ns(unsigned int ticks) | |||
230 | return ticks * gpmc_get_fclk_period() / 1000; | 233 | return ticks * gpmc_get_fclk_period() / 1000; |
231 | } | 234 | } |
232 | 235 | ||
233 | unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns) | ||
234 | { | ||
235 | unsigned long ticks = gpmc_ns_to_ticks(time_ns); | ||
236 | |||
237 | return ticks * gpmc_get_fclk_period() / 1000; | ||
238 | } | ||
239 | |||
240 | static unsigned int gpmc_ticks_to_ps(unsigned int ticks) | 236 | static unsigned int gpmc_ticks_to_ps(unsigned int ticks) |
241 | { | 237 | { |
242 | return ticks * gpmc_get_fclk_period(); | 238 | return ticks * gpmc_get_fclk_period(); |
@@ -405,11 +401,18 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) | |||
405 | return 0; | 401 | return 0; |
406 | } | 402 | } |
407 | 403 | ||
408 | static void gpmc_cs_enable_mem(int cs, u32 base, u32 size) | 404 | static int gpmc_cs_enable_mem(int cs, u32 base, u32 size) |
409 | { | 405 | { |
410 | u32 l; | 406 | u32 l; |
411 | u32 mask; | 407 | u32 mask; |
412 | 408 | ||
409 | /* | ||
410 | * Ensure that base address is aligned on a | ||
411 | * boundary equal to or greater than size. | ||
412 | */ | ||
413 | if (base & (size - 1)) | ||
414 | return -EINVAL; | ||
415 | |||
413 | mask = (1 << GPMC_SECTION_SHIFT) - size; | 416 | mask = (1 << GPMC_SECTION_SHIFT) - size; |
414 | l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); | 417 | l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); |
415 | l &= ~0x3f; | 418 | l &= ~0x3f; |
@@ -418,6 +421,8 @@ static void gpmc_cs_enable_mem(int cs, u32 base, u32 size) | |||
418 | l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8; | 421 | l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8; |
419 | l |= GPMC_CONFIG7_CSVALID; | 422 | l |= GPMC_CONFIG7_CSVALID; |
420 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); | 423 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); |
424 | |||
425 | return 0; | ||
421 | } | 426 | } |
422 | 427 | ||
423 | static void gpmc_cs_disable_mem(int cs) | 428 | static void gpmc_cs_disable_mem(int cs) |
@@ -448,22 +453,14 @@ static int gpmc_cs_mem_enabled(int cs) | |||
448 | return l & GPMC_CONFIG7_CSVALID; | 453 | return l & GPMC_CONFIG7_CSVALID; |
449 | } | 454 | } |
450 | 455 | ||
451 | int gpmc_cs_set_reserved(int cs, int reserved) | 456 | static void gpmc_cs_set_reserved(int cs, int reserved) |
452 | { | 457 | { |
453 | if (cs > GPMC_CS_NUM) | ||
454 | return -ENODEV; | ||
455 | |||
456 | gpmc_cs_map &= ~(1 << cs); | 458 | gpmc_cs_map &= ~(1 << cs); |
457 | gpmc_cs_map |= (reserved ? 1 : 0) << cs; | 459 | gpmc_cs_map |= (reserved ? 1 : 0) << cs; |
458 | |||
459 | return 0; | ||
460 | } | 460 | } |
461 | 461 | ||
462 | int gpmc_cs_reserved(int cs) | 462 | static bool gpmc_cs_reserved(int cs) |
463 | { | 463 | { |
464 | if (cs > GPMC_CS_NUM) | ||
465 | return -ENODEV; | ||
466 | |||
467 | return gpmc_cs_map & (1 << cs); | 464 | return gpmc_cs_map & (1 << cs); |
468 | } | 465 | } |
469 | 466 | ||
@@ -510,6 +507,39 @@ static int gpmc_cs_delete_mem(int cs) | |||
510 | return r; | 507 | return r; |
511 | } | 508 | } |
512 | 509 | ||
510 | /** | ||
511 | * gpmc_cs_remap - remaps a chip-select physical base address | ||
512 | * @cs: chip-select to remap | ||
513 | * @base: physical base address to re-map chip-select to | ||
514 | * | ||
515 | * Re-maps a chip-select to a new physical base address specified by | ||
516 | * "base". Returns 0 on success and appropriate negative error code | ||
517 | * on failure. | ||
518 | */ | ||
519 | static int gpmc_cs_remap(int cs, u32 base) | ||
520 | { | ||
521 | int ret; | ||
522 | u32 old_base, size; | ||
523 | |||
524 | if (cs > GPMC_CS_NUM) | ||
525 | return -ENODEV; | ||
526 | gpmc_cs_get_memconf(cs, &old_base, &size); | ||
527 | if (base == old_base) | ||
528 | return 0; | ||
529 | gpmc_cs_disable_mem(cs); | ||
530 | ret = gpmc_cs_delete_mem(cs); | ||
531 | if (ret < 0) | ||
532 | return ret; | ||
533 | ret = gpmc_cs_insert_mem(cs, base, size); | ||
534 | if (ret < 0) | ||
535 | return ret; | ||
536 | ret = gpmc_cs_enable_mem(cs, base, size); | ||
537 | if (ret < 0) | ||
538 | return ret; | ||
539 | |||
540 | return 0; | ||
541 | } | ||
542 | |||
513 | int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) | 543 | int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) |
514 | { | 544 | { |
515 | struct resource *res = &gpmc_cs_mem[cs]; | 545 | struct resource *res = &gpmc_cs_mem[cs]; |
@@ -535,7 +565,12 @@ int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) | |||
535 | if (r < 0) | 565 | if (r < 0) |
536 | goto out; | 566 | goto out; |
537 | 567 | ||
538 | gpmc_cs_enable_mem(cs, res->start, resource_size(res)); | 568 | r = gpmc_cs_enable_mem(cs, res->start, resource_size(res)); |
569 | if (r < 0) { | ||
570 | release_resource(res); | ||
571 | goto out; | ||
572 | } | ||
573 | |||
539 | *base = res->start; | 574 | *base = res->start; |
540 | gpmc_cs_set_reserved(cs, 1); | 575 | gpmc_cs_set_reserved(cs, 1); |
541 | out: | 576 | out: |
@@ -561,16 +596,14 @@ void gpmc_cs_free(int cs) | |||
561 | EXPORT_SYMBOL(gpmc_cs_free); | 596 | EXPORT_SYMBOL(gpmc_cs_free); |
562 | 597 | ||
563 | /** | 598 | /** |
564 | * gpmc_cs_configure - write request to configure gpmc | 599 | * gpmc_configure - write request to configure gpmc |
565 | * @cs: chip select number | ||
566 | * @cmd: command type | 600 | * @cmd: command type |
567 | * @wval: value to write | 601 | * @wval: value to write |
568 | * @return status of the operation | 602 | * @return status of the operation |
569 | */ | 603 | */ |
570 | int gpmc_cs_configure(int cs, int cmd, int wval) | 604 | int gpmc_configure(int cmd, int wval) |
571 | { | 605 | { |
572 | int err = 0; | 606 | u32 regval; |
573 | u32 regval = 0; | ||
574 | 607 | ||
575 | switch (cmd) { | 608 | switch (cmd) { |
576 | case GPMC_ENABLE_IRQ: | 609 | case GPMC_ENABLE_IRQ: |
@@ -590,43 +623,14 @@ int gpmc_cs_configure(int cs, int cmd, int wval) | |||
590 | gpmc_write_reg(GPMC_CONFIG, regval); | 623 | gpmc_write_reg(GPMC_CONFIG, regval); |
591 | break; | 624 | break; |
592 | 625 | ||
593 | case GPMC_CONFIG_RDY_BSY: | ||
594 | regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); | ||
595 | if (wval) | ||
596 | regval |= WR_RD_PIN_MONITORING; | ||
597 | else | ||
598 | regval &= ~WR_RD_PIN_MONITORING; | ||
599 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); | ||
600 | break; | ||
601 | |||
602 | case GPMC_CONFIG_DEV_SIZE: | ||
603 | regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); | ||
604 | |||
605 | /* clear 2 target bits */ | ||
606 | regval &= ~GPMC_CONFIG1_DEVICESIZE(3); | ||
607 | |||
608 | /* set the proper value */ | ||
609 | regval |= GPMC_CONFIG1_DEVICESIZE(wval); | ||
610 | |||
611 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); | ||
612 | break; | ||
613 | |||
614 | case GPMC_CONFIG_DEV_TYPE: | ||
615 | regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); | ||
616 | regval |= GPMC_CONFIG1_DEVICETYPE(wval); | ||
617 | if (wval == GPMC_DEVICETYPE_NOR) | ||
618 | regval |= GPMC_CONFIG1_MUXADDDATA; | ||
619 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); | ||
620 | break; | ||
621 | |||
622 | default: | 626 | default: |
623 | printk(KERN_ERR "gpmc_configure_cs: Not supported\n"); | 627 | pr_err("%s: command not supported\n", __func__); |
624 | err = -EINVAL; | 628 | return -EINVAL; |
625 | } | 629 | } |
626 | 630 | ||
627 | return err; | 631 | return 0; |
628 | } | 632 | } |
629 | EXPORT_SYMBOL(gpmc_cs_configure); | 633 | EXPORT_SYMBOL(gpmc_configure); |
630 | 634 | ||
631 | void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs) | 635 | void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs) |
632 | { | 636 | { |
@@ -716,7 +720,7 @@ static int gpmc_setup_irq(void) | |||
716 | return -EINVAL; | 720 | return -EINVAL; |
717 | 721 | ||
718 | gpmc_irq_start = irq_alloc_descs(-1, 0, GPMC_NR_IRQ, 0); | 722 | gpmc_irq_start = irq_alloc_descs(-1, 0, GPMC_NR_IRQ, 0); |
719 | if (IS_ERR_VALUE(gpmc_irq_start)) { | 723 | if (gpmc_irq_start < 0) { |
720 | pr_err("irq_alloc_descs failed\n"); | 724 | pr_err("irq_alloc_descs failed\n"); |
721 | return gpmc_irq_start; | 725 | return gpmc_irq_start; |
722 | } | 726 | } |
@@ -781,16 +785,16 @@ static void gpmc_mem_exit(void) | |||
781 | 785 | ||
782 | } | 786 | } |
783 | 787 | ||
784 | static int gpmc_mem_init(void) | 788 | static void gpmc_mem_init(void) |
785 | { | 789 | { |
786 | int cs, rc; | 790 | int cs; |
787 | unsigned long boot_rom_space = 0; | ||
788 | 791 | ||
789 | /* never allocate the first page, to facilitate bug detection; | 792 | /* |
790 | * even if we didn't boot from ROM. | 793 | * The first 1MB of GPMC address space is typically mapped to |
794 | * the internal ROM. Never allocate the first page, to | ||
795 | * facilitate bug detection; even if we didn't boot from ROM. | ||
791 | */ | 796 | */ |
792 | boot_rom_space = BOOT_ROM_SPACE; | 797 | gpmc_mem_root.start = SZ_1M; |
793 | gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space; | ||
794 | gpmc_mem_root.end = GPMC_MEM_END; | 798 | gpmc_mem_root.end = GPMC_MEM_END; |
795 | 799 | ||
796 | /* Reserve all regions that has been set up by bootloader */ | 800 | /* Reserve all regions that has been set up by bootloader */ |
@@ -800,16 +804,12 @@ static int gpmc_mem_init(void) | |||
800 | if (!gpmc_cs_mem_enabled(cs)) | 804 | if (!gpmc_cs_mem_enabled(cs)) |
801 | continue; | 805 | continue; |
802 | gpmc_cs_get_memconf(cs, &base, &size); | 806 | gpmc_cs_get_memconf(cs, &base, &size); |
803 | rc = gpmc_cs_insert_mem(cs, base, size); | 807 | if (gpmc_cs_insert_mem(cs, base, size)) { |
804 | if (IS_ERR_VALUE(rc)) { | 808 | pr_warn("%s: disabling cs %d mapped at 0x%x-0x%x\n", |
805 | while (--cs >= 0) | 809 | __func__, cs, base, base + size); |
806 | if (gpmc_cs_mem_enabled(cs)) | 810 | gpmc_cs_disable_mem(cs); |
807 | gpmc_cs_delete_mem(cs); | ||
808 | return rc; | ||
809 | } | 811 | } |
810 | } | 812 | } |
811 | |||
812 | return 0; | ||
813 | } | 813 | } |
814 | 814 | ||
815 | static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk) | 815 | static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk) |
@@ -825,9 +825,9 @@ static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk) | |||
825 | 825 | ||
826 | /* XXX: can the cycles be avoided ? */ | 826 | /* XXX: can the cycles be avoided ? */ |
827 | static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t, | 827 | static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t, |
828 | struct gpmc_device_timings *dev_t) | 828 | struct gpmc_device_timings *dev_t, |
829 | bool mux) | ||
829 | { | 830 | { |
830 | bool mux = dev_t->mux; | ||
831 | u32 temp; | 831 | u32 temp; |
832 | 832 | ||
833 | /* adv_rd_off */ | 833 | /* adv_rd_off */ |
@@ -880,9 +880,9 @@ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t, | |||
880 | } | 880 | } |
881 | 881 | ||
882 | static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t, | 882 | static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t, |
883 | struct gpmc_device_timings *dev_t) | 883 | struct gpmc_device_timings *dev_t, |
884 | bool mux) | ||
884 | { | 885 | { |
885 | bool mux = dev_t->mux; | ||
886 | u32 temp; | 886 | u32 temp; |
887 | 887 | ||
888 | /* adv_wr_off */ | 888 | /* adv_wr_off */ |
@@ -942,9 +942,9 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t, | |||
942 | } | 942 | } |
943 | 943 | ||
944 | static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t, | 944 | static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t, |
945 | struct gpmc_device_timings *dev_t) | 945 | struct gpmc_device_timings *dev_t, |
946 | bool mux) | ||
946 | { | 947 | { |
947 | bool mux = dev_t->mux; | ||
948 | u32 temp; | 948 | u32 temp; |
949 | 949 | ||
950 | /* adv_rd_off */ | 950 | /* adv_rd_off */ |
@@ -982,9 +982,9 @@ static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t, | |||
982 | } | 982 | } |
983 | 983 | ||
984 | static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t, | 984 | static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t, |
985 | struct gpmc_device_timings *dev_t) | 985 | struct gpmc_device_timings *dev_t, |
986 | bool mux) | ||
986 | { | 987 | { |
987 | bool mux = dev_t->mux; | ||
988 | u32 temp; | 988 | u32 temp; |
989 | 989 | ||
990 | /* adv_wr_off */ | 990 | /* adv_wr_off */ |
@@ -1054,7 +1054,8 @@ static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t, | |||
1054 | } | 1054 | } |
1055 | 1055 | ||
1056 | static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t, | 1056 | static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t, |
1057 | struct gpmc_device_timings *dev_t) | 1057 | struct gpmc_device_timings *dev_t, |
1058 | bool sync) | ||
1058 | { | 1059 | { |
1059 | u32 temp; | 1060 | u32 temp; |
1060 | 1061 | ||
@@ -1068,7 +1069,7 @@ static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t, | |||
1068 | gpmc_t->cs_on + dev_t->t_ce_avd); | 1069 | gpmc_t->cs_on + dev_t->t_ce_avd); |
1069 | gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp); | 1070 | gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp); |
1070 | 1071 | ||
1071 | if (dev_t->sync_write || dev_t->sync_read) | 1072 | if (sync) |
1072 | gpmc_calc_sync_common_timings(gpmc_t, dev_t); | 1073 | gpmc_calc_sync_common_timings(gpmc_t, dev_t); |
1073 | 1074 | ||
1074 | return 0; | 1075 | return 0; |
@@ -1103,21 +1104,29 @@ static void gpmc_convert_ps_to_ns(struct gpmc_timings *t) | |||
1103 | } | 1104 | } |
1104 | 1105 | ||
1105 | int gpmc_calc_timings(struct gpmc_timings *gpmc_t, | 1106 | int gpmc_calc_timings(struct gpmc_timings *gpmc_t, |
1106 | struct gpmc_device_timings *dev_t) | 1107 | struct gpmc_settings *gpmc_s, |
1108 | struct gpmc_device_timings *dev_t) | ||
1107 | { | 1109 | { |
1110 | bool mux = false, sync = false; | ||
1111 | |||
1112 | if (gpmc_s) { | ||
1113 | mux = gpmc_s->mux_add_data ? true : false; | ||
1114 | sync = (gpmc_s->sync_read || gpmc_s->sync_write); | ||
1115 | } | ||
1116 | |||
1108 | memset(gpmc_t, 0, sizeof(*gpmc_t)); | 1117 | memset(gpmc_t, 0, sizeof(*gpmc_t)); |
1109 | 1118 | ||
1110 | gpmc_calc_common_timings(gpmc_t, dev_t); | 1119 | gpmc_calc_common_timings(gpmc_t, dev_t, sync); |
1111 | 1120 | ||
1112 | if (dev_t->sync_read) | 1121 | if (gpmc_s && gpmc_s->sync_read) |
1113 | gpmc_calc_sync_read_timings(gpmc_t, dev_t); | 1122 | gpmc_calc_sync_read_timings(gpmc_t, dev_t, mux); |
1114 | else | 1123 | else |
1115 | gpmc_calc_async_read_timings(gpmc_t, dev_t); | 1124 | gpmc_calc_async_read_timings(gpmc_t, dev_t, mux); |
1116 | 1125 | ||
1117 | if (dev_t->sync_write) | 1126 | if (gpmc_s && gpmc_s->sync_write) |
1118 | gpmc_calc_sync_write_timings(gpmc_t, dev_t); | 1127 | gpmc_calc_sync_write_timings(gpmc_t, dev_t, mux); |
1119 | else | 1128 | else |
1120 | gpmc_calc_async_write_timings(gpmc_t, dev_t); | 1129 | gpmc_calc_async_write_timings(gpmc_t, dev_t, mux); |
1121 | 1130 | ||
1122 | /* TODO: remove, see function definition */ | 1131 | /* TODO: remove, see function definition */ |
1123 | gpmc_convert_ps_to_ns(gpmc_t); | 1132 | gpmc_convert_ps_to_ns(gpmc_t); |
@@ -1125,6 +1134,90 @@ int gpmc_calc_timings(struct gpmc_timings *gpmc_t, | |||
1125 | return 0; | 1134 | return 0; |
1126 | } | 1135 | } |
1127 | 1136 | ||
1137 | /** | ||
1138 | * gpmc_cs_program_settings - programs non-timing related settings | ||
1139 | * @cs: GPMC chip-select to program | ||
1140 | * @p: pointer to GPMC settings structure | ||
1141 | * | ||
1142 | * Programs non-timing related settings for a GPMC chip-select, such as | ||
1143 | * bus-width, burst configuration, etc. Function should be called once | ||
1144 | * for each chip-select that is being used and must be called before | ||
1145 | * calling gpmc_cs_set_timings() as timing parameters in the CONFIG1 | ||
1146 | * register will be initialised to zero by this function. Returns 0 on | ||
1147 | * success and appropriate negative error code on failure. | ||
1148 | */ | ||
1149 | int gpmc_cs_program_settings(int cs, struct gpmc_settings *p) | ||
1150 | { | ||
1151 | u32 config1; | ||
1152 | |||
1153 | if ((!p->device_width) || (p->device_width > GPMC_DEVWIDTH_16BIT)) { | ||
1154 | pr_err("%s: invalid width %d!", __func__, p->device_width); | ||
1155 | return -EINVAL; | ||
1156 | } | ||
1157 | |||
1158 | /* Address-data multiplexing not supported for NAND devices */ | ||
1159 | if (p->device_nand && p->mux_add_data) { | ||
1160 | pr_err("%s: invalid configuration!\n", __func__); | ||
1161 | return -EINVAL; | ||
1162 | } | ||
1163 | |||
1164 | if ((p->mux_add_data > GPMC_MUX_AD) || | ||
1165 | ((p->mux_add_data == GPMC_MUX_AAD) && | ||
1166 | !(gpmc_capability & GPMC_HAS_MUX_AAD))) { | ||
1167 | pr_err("%s: invalid multiplex configuration!\n", __func__); | ||
1168 | return -EINVAL; | ||
1169 | } | ||
1170 | |||
1171 | /* Page/burst mode supports lengths of 4, 8 and 16 bytes */ | ||
1172 | if (p->burst_read || p->burst_write) { | ||
1173 | switch (p->burst_len) { | ||
1174 | case GPMC_BURST_4: | ||
1175 | case GPMC_BURST_8: | ||
1176 | case GPMC_BURST_16: | ||
1177 | break; | ||
1178 | default: | ||
1179 | pr_err("%s: invalid page/burst-length (%d)\n", | ||
1180 | __func__, p->burst_len); | ||
1181 | return -EINVAL; | ||
1182 | } | ||
1183 | } | ||
1184 | |||
1185 | if ((p->wait_on_read || p->wait_on_write) && | ||
1186 | (p->wait_pin > gpmc_nr_waitpins)) { | ||
1187 | pr_err("%s: invalid wait-pin (%d)\n", __func__, p->wait_pin); | ||
1188 | return -EINVAL; | ||
1189 | } | ||
1190 | |||
1191 | config1 = GPMC_CONFIG1_DEVICESIZE((p->device_width - 1)); | ||
1192 | |||
1193 | if (p->sync_read) | ||
1194 | config1 |= GPMC_CONFIG1_READTYPE_SYNC; | ||
1195 | if (p->sync_write) | ||
1196 | config1 |= GPMC_CONFIG1_WRITETYPE_SYNC; | ||
1197 | if (p->wait_on_read) | ||
1198 | config1 |= GPMC_CONFIG1_WAIT_READ_MON; | ||
1199 | if (p->wait_on_write) | ||
1200 | config1 |= GPMC_CONFIG1_WAIT_WRITE_MON; | ||
1201 | if (p->wait_on_read || p->wait_on_write) | ||
1202 | config1 |= GPMC_CONFIG1_WAIT_PIN_SEL(p->wait_pin); | ||
1203 | if (p->device_nand) | ||
1204 | config1 |= GPMC_CONFIG1_DEVICETYPE(GPMC_DEVICETYPE_NAND); | ||
1205 | if (p->mux_add_data) | ||
1206 | config1 |= GPMC_CONFIG1_MUXTYPE(p->mux_add_data); | ||
1207 | if (p->burst_read) | ||
1208 | config1 |= GPMC_CONFIG1_READMULTIPLE_SUPP; | ||
1209 | if (p->burst_write) | ||
1210 | config1 |= GPMC_CONFIG1_WRITEMULTIPLE_SUPP; | ||
1211 | if (p->burst_read || p->burst_write) { | ||
1212 | config1 |= GPMC_CONFIG1_PAGE_LEN(p->burst_len >> 3); | ||
1213 | config1 |= p->burst_wrap ? GPMC_CONFIG1_WRAPBURST_SUPP : 0; | ||
1214 | } | ||
1215 | |||
1216 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1); | ||
1217 | |||
1218 | return 0; | ||
1219 | } | ||
1220 | |||
1128 | #ifdef CONFIG_OF | 1221 | #ifdef CONFIG_OF |
1129 | static struct of_device_id gpmc_dt_ids[] = { | 1222 | static struct of_device_id gpmc_dt_ids[] = { |
1130 | { .compatible = "ti,omap2420-gpmc" }, | 1223 | { .compatible = "ti,omap2420-gpmc" }, |
@@ -1136,70 +1229,110 @@ static struct of_device_id gpmc_dt_ids[] = { | |||
1136 | }; | 1229 | }; |
1137 | MODULE_DEVICE_TABLE(of, gpmc_dt_ids); | 1230 | MODULE_DEVICE_TABLE(of, gpmc_dt_ids); |
1138 | 1231 | ||
1232 | /** | ||
1233 | * gpmc_read_settings_dt - read gpmc settings from device-tree | ||
1234 | * @np: pointer to device-tree node for a gpmc child device | ||
1235 | * @p: pointer to gpmc settings structure | ||
1236 | * | ||
1237 | * Reads the GPMC settings for a GPMC child device from device-tree and | ||
1238 | * stores them in the GPMC settings structure passed. The GPMC settings | ||
1239 | * structure is initialised to zero by this function and so any | ||
1240 | * previously stored settings will be cleared. | ||
1241 | */ | ||
1242 | void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p) | ||
1243 | { | ||
1244 | memset(p, 0, sizeof(struct gpmc_settings)); | ||
1245 | |||
1246 | p->sync_read = of_property_read_bool(np, "gpmc,sync-read"); | ||
1247 | p->sync_write = of_property_read_bool(np, "gpmc,sync-write"); | ||
1248 | p->device_nand = of_property_read_bool(np, "gpmc,device-nand"); | ||
1249 | of_property_read_u32(np, "gpmc,device-width", &p->device_width); | ||
1250 | of_property_read_u32(np, "gpmc,mux-add-data", &p->mux_add_data); | ||
1251 | |||
1252 | if (!of_property_read_u32(np, "gpmc,burst-length", &p->burst_len)) { | ||
1253 | p->burst_wrap = of_property_read_bool(np, "gpmc,burst-wrap"); | ||
1254 | p->burst_read = of_property_read_bool(np, "gpmc,burst-read"); | ||
1255 | p->burst_write = of_property_read_bool(np, "gpmc,burst-write"); | ||
1256 | if (!p->burst_read && !p->burst_write) | ||
1257 | pr_warn("%s: page/burst-length set but not used!\n", | ||
1258 | __func__); | ||
1259 | } | ||
1260 | |||
1261 | if (!of_property_read_u32(np, "gpmc,wait-pin", &p->wait_pin)) { | ||
1262 | p->wait_on_read = of_property_read_bool(np, | ||
1263 | "gpmc,wait-on-read"); | ||
1264 | p->wait_on_write = of_property_read_bool(np, | ||
1265 | "gpmc,wait-on-write"); | ||
1266 | if (!p->wait_on_read && !p->wait_on_write) | ||
1267 | pr_warn("%s: read/write wait monitoring not enabled!\n", | ||
1268 | __func__); | ||
1269 | } | ||
1270 | } | ||
1271 | |||
1139 | static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, | 1272 | static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, |
1140 | struct gpmc_timings *gpmc_t) | 1273 | struct gpmc_timings *gpmc_t) |
1141 | { | 1274 | { |
1142 | u32 val; | 1275 | struct gpmc_bool_timings *p; |
1276 | |||
1277 | if (!np || !gpmc_t) | ||
1278 | return; | ||
1143 | 1279 | ||
1144 | memset(gpmc_t, 0, sizeof(*gpmc_t)); | 1280 | memset(gpmc_t, 0, sizeof(*gpmc_t)); |
1145 | 1281 | ||
1146 | /* minimum clock period for syncronous mode */ | 1282 | /* minimum clock period for syncronous mode */ |
1147 | if (!of_property_read_u32(np, "gpmc,sync-clk", &val)) | 1283 | of_property_read_u32(np, "gpmc,sync-clk-ps", &gpmc_t->sync_clk); |
1148 | gpmc_t->sync_clk = val; | ||
1149 | 1284 | ||
1150 | /* chip select timtings */ | 1285 | /* chip select timtings */ |
1151 | if (!of_property_read_u32(np, "gpmc,cs-on", &val)) | 1286 | of_property_read_u32(np, "gpmc,cs-on-ns", &gpmc_t->cs_on); |
1152 | gpmc_t->cs_on = val; | 1287 | of_property_read_u32(np, "gpmc,cs-rd-off-ns", &gpmc_t->cs_rd_off); |
1153 | 1288 | of_property_read_u32(np, "gpmc,cs-wr-off-ns", &gpmc_t->cs_wr_off); | |
1154 | if (!of_property_read_u32(np, "gpmc,cs-rd-off", &val)) | ||
1155 | gpmc_t->cs_rd_off = val; | ||
1156 | |||
1157 | if (!of_property_read_u32(np, "gpmc,cs-wr-off", &val)) | ||
1158 | gpmc_t->cs_wr_off = val; | ||
1159 | 1289 | ||
1160 | /* ADV signal timings */ | 1290 | /* ADV signal timings */ |
1161 | if (!of_property_read_u32(np, "gpmc,adv-on", &val)) | 1291 | of_property_read_u32(np, "gpmc,adv-on-ns", &gpmc_t->adv_on); |
1162 | gpmc_t->adv_on = val; | 1292 | of_property_read_u32(np, "gpmc,adv-rd-off-ns", &gpmc_t->adv_rd_off); |
1163 | 1293 | of_property_read_u32(np, "gpmc,adv-wr-off-ns", &gpmc_t->adv_wr_off); | |
1164 | if (!of_property_read_u32(np, "gpmc,adv-rd-off", &val)) | ||
1165 | gpmc_t->adv_rd_off = val; | ||
1166 | |||
1167 | if (!of_property_read_u32(np, "gpmc,adv-wr-off", &val)) | ||
1168 | gpmc_t->adv_wr_off = val; | ||
1169 | 1294 | ||
1170 | /* WE signal timings */ | 1295 | /* WE signal timings */ |
1171 | if (!of_property_read_u32(np, "gpmc,we-on", &val)) | 1296 | of_property_read_u32(np, "gpmc,we-on-ns", &gpmc_t->we_on); |
1172 | gpmc_t->we_on = val; | 1297 | of_property_read_u32(np, "gpmc,we-off-ns", &gpmc_t->we_off); |
1173 | |||
1174 | if (!of_property_read_u32(np, "gpmc,we-off", &val)) | ||
1175 | gpmc_t->we_off = val; | ||
1176 | 1298 | ||
1177 | /* OE signal timings */ | 1299 | /* OE signal timings */ |
1178 | if (!of_property_read_u32(np, "gpmc,oe-on", &val)) | 1300 | of_property_read_u32(np, "gpmc,oe-on-ns", &gpmc_t->oe_on); |
1179 | gpmc_t->oe_on = val; | 1301 | of_property_read_u32(np, "gpmc,oe-off-ns", &gpmc_t->oe_off); |
1180 | |||
1181 | if (!of_property_read_u32(np, "gpmc,oe-off", &val)) | ||
1182 | gpmc_t->oe_off = val; | ||
1183 | 1302 | ||
1184 | /* access and cycle timings */ | 1303 | /* access and cycle timings */ |
1185 | if (!of_property_read_u32(np, "gpmc,page-burst-access", &val)) | 1304 | of_property_read_u32(np, "gpmc,page-burst-access-ns", |
1186 | gpmc_t->page_burst_access = val; | 1305 | &gpmc_t->page_burst_access); |
1187 | 1306 | of_property_read_u32(np, "gpmc,access-ns", &gpmc_t->access); | |
1188 | if (!of_property_read_u32(np, "gpmc,access", &val)) | 1307 | of_property_read_u32(np, "gpmc,rd-cycle-ns", &gpmc_t->rd_cycle); |
1189 | gpmc_t->access = val; | 1308 | of_property_read_u32(np, "gpmc,wr-cycle-ns", &gpmc_t->wr_cycle); |
1190 | 1309 | of_property_read_u32(np, "gpmc,bus-turnaround-ns", | |
1191 | if (!of_property_read_u32(np, "gpmc,rd-cycle", &val)) | 1310 | &gpmc_t->bus_turnaround); |
1192 | gpmc_t->rd_cycle = val; | 1311 | of_property_read_u32(np, "gpmc,cycle2cycle-delay-ns", |
1193 | 1312 | &gpmc_t->cycle2cycle_delay); | |
1194 | if (!of_property_read_u32(np, "gpmc,wr-cycle", &val)) | 1313 | of_property_read_u32(np, "gpmc,wait-monitoring-ns", |
1195 | gpmc_t->wr_cycle = val; | 1314 | &gpmc_t->wait_monitoring); |
1196 | 1315 | of_property_read_u32(np, "gpmc,clk-activation-ns", | |
1197 | /* only for OMAP3430 */ | 1316 | &gpmc_t->clk_activation); |
1198 | if (!of_property_read_u32(np, "gpmc,wr-access", &val)) | 1317 | |
1199 | gpmc_t->wr_access = val; | 1318 | /* only applicable to OMAP3+ */ |
1200 | 1319 | of_property_read_u32(np, "gpmc,wr-access-ns", &gpmc_t->wr_access); | |
1201 | if (!of_property_read_u32(np, "gpmc,wr-data-mux-bus", &val)) | 1320 | of_property_read_u32(np, "gpmc,wr-data-mux-bus-ns", |
1202 | gpmc_t->wr_data_mux_bus = val; | 1321 | &gpmc_t->wr_data_mux_bus); |
1322 | |||
1323 | /* bool timing parameters */ | ||
1324 | p = &gpmc_t->bool_timings; | ||
1325 | |||
1326 | p->cycle2cyclediffcsen = | ||
1327 | of_property_read_bool(np, "gpmc,cycle2cycle-diffcsen"); | ||
1328 | p->cycle2cyclesamecsen = | ||
1329 | of_property_read_bool(np, "gpmc,cycle2cycle-samecsen"); | ||
1330 | p->we_extra_delay = of_property_read_bool(np, "gpmc,we-extra-delay"); | ||
1331 | p->oe_extra_delay = of_property_read_bool(np, "gpmc,oe-extra-delay"); | ||
1332 | p->adv_extra_delay = of_property_read_bool(np, "gpmc,adv-extra-delay"); | ||
1333 | p->cs_extra_delay = of_property_read_bool(np, "gpmc,cs-extra-delay"); | ||
1334 | p->time_para_granularity = | ||
1335 | of_property_read_bool(np, "gpmc,time-para-granularity"); | ||
1203 | } | 1336 | } |
1204 | 1337 | ||
1205 | #ifdef CONFIG_MTD_NAND | 1338 | #ifdef CONFIG_MTD_NAND |
@@ -1295,6 +1428,81 @@ static int gpmc_probe_onenand_child(struct platform_device *pdev, | |||
1295 | } | 1428 | } |
1296 | #endif | 1429 | #endif |
1297 | 1430 | ||
1431 | /** | ||
1432 | * gpmc_probe_generic_child - configures the gpmc for a child device | ||
1433 | * @pdev: pointer to gpmc platform device | ||
1434 | * @child: pointer to device-tree node for child device | ||
1435 | * | ||
1436 | * Allocates and configures a GPMC chip-select for a child device. | ||
1437 | * Returns 0 on success and appropriate negative error code on failure. | ||
1438 | */ | ||
1439 | static int gpmc_probe_generic_child(struct platform_device *pdev, | ||
1440 | struct device_node *child) | ||
1441 | { | ||
1442 | struct gpmc_settings gpmc_s; | ||
1443 | struct gpmc_timings gpmc_t; | ||
1444 | struct resource res; | ||
1445 | unsigned long base; | ||
1446 | int ret, cs; | ||
1447 | |||
1448 | if (of_property_read_u32(child, "reg", &cs) < 0) { | ||
1449 | dev_err(&pdev->dev, "%s has no 'reg' property\n", | ||
1450 | child->full_name); | ||
1451 | return -ENODEV; | ||
1452 | } | ||
1453 | |||
1454 | if (of_address_to_resource(child, 0, &res) < 0) { | ||
1455 | dev_err(&pdev->dev, "%s has malformed 'reg' property\n", | ||
1456 | child->full_name); | ||
1457 | return -ENODEV; | ||
1458 | } | ||
1459 | |||
1460 | ret = gpmc_cs_request(cs, resource_size(&res), &base); | ||
1461 | if (ret < 0) { | ||
1462 | dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs); | ||
1463 | return ret; | ||
1464 | } | ||
1465 | |||
1466 | /* | ||
1467 | * FIXME: gpmc_cs_request() will map the CS to an arbitary | ||
1468 | * location in the gpmc address space. When booting with | ||
1469 | * device-tree we want the NOR flash to be mapped to the | ||
1470 | * location specified in the device-tree blob. So remap the | ||
1471 | * CS to this location. Once DT migration is complete should | ||
1472 | * just make gpmc_cs_request() map a specific address. | ||
1473 | */ | ||
1474 | ret = gpmc_cs_remap(cs, res.start); | ||
1475 | if (ret < 0) { | ||
1476 | dev_err(&pdev->dev, "cannot remap GPMC CS %d to 0x%x\n", | ||
1477 | cs, res.start); | ||
1478 | goto err; | ||
1479 | } | ||
1480 | |||
1481 | gpmc_read_settings_dt(child, &gpmc_s); | ||
1482 | |||
1483 | ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width); | ||
1484 | if (ret < 0) | ||
1485 | goto err; | ||
1486 | |||
1487 | ret = gpmc_cs_program_settings(cs, &gpmc_s); | ||
1488 | if (ret < 0) | ||
1489 | goto err; | ||
1490 | |||
1491 | gpmc_read_timings_dt(child, &gpmc_t); | ||
1492 | gpmc_cs_set_timings(cs, &gpmc_t); | ||
1493 | |||
1494 | if (of_platform_device_create(child, NULL, &pdev->dev)) | ||
1495 | return 0; | ||
1496 | |||
1497 | dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name); | ||
1498 | ret = -ENODEV; | ||
1499 | |||
1500 | err: | ||
1501 | gpmc_cs_free(cs); | ||
1502 | |||
1503 | return ret; | ||
1504 | } | ||
1505 | |||
1298 | static int gpmc_probe_dt(struct platform_device *pdev) | 1506 | static int gpmc_probe_dt(struct platform_device *pdev) |
1299 | { | 1507 | { |
1300 | int ret; | 1508 | int ret; |
@@ -1305,6 +1513,13 @@ static int gpmc_probe_dt(struct platform_device *pdev) | |||
1305 | if (!of_id) | 1513 | if (!of_id) |
1306 | return 0; | 1514 | return 0; |
1307 | 1515 | ||
1516 | ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins", | ||
1517 | &gpmc_nr_waitpins); | ||
1518 | if (ret < 0) { | ||
1519 | pr_err("%s: number of wait pins not found!\n", __func__); | ||
1520 | return ret; | ||
1521 | } | ||
1522 | |||
1308 | for_each_node_by_name(child, "nand") { | 1523 | for_each_node_by_name(child, "nand") { |
1309 | ret = gpmc_probe_nand_child(pdev, child); | 1524 | ret = gpmc_probe_nand_child(pdev, child); |
1310 | if (ret < 0) { | 1525 | if (ret < 0) { |
@@ -1320,6 +1535,23 @@ static int gpmc_probe_dt(struct platform_device *pdev) | |||
1320 | return ret; | 1535 | return ret; |
1321 | } | 1536 | } |
1322 | } | 1537 | } |
1538 | |||
1539 | for_each_node_by_name(child, "nor") { | ||
1540 | ret = gpmc_probe_generic_child(pdev, child); | ||
1541 | if (ret < 0) { | ||
1542 | of_node_put(child); | ||
1543 | return ret; | ||
1544 | } | ||
1545 | } | ||
1546 | |||
1547 | for_each_node_by_name(child, "ethernet") { | ||
1548 | ret = gpmc_probe_generic_child(pdev, child); | ||
1549 | if (ret < 0) { | ||
1550 | of_node_put(child); | ||
1551 | return ret; | ||
1552 | } | ||
1553 | } | ||
1554 | |||
1323 | return 0; | 1555 | return 0; |
1324 | } | 1556 | } |
1325 | #else | 1557 | #else |
@@ -1364,25 +1596,37 @@ static int gpmc_probe(struct platform_device *pdev) | |||
1364 | gpmc_dev = &pdev->dev; | 1596 | gpmc_dev = &pdev->dev; |
1365 | 1597 | ||
1366 | l = gpmc_read_reg(GPMC_REVISION); | 1598 | l = gpmc_read_reg(GPMC_REVISION); |
1599 | |||
1600 | /* | ||
1601 | * FIXME: Once device-tree migration is complete the below flags | ||
1602 | * should be populated based upon the device-tree compatible | ||
1603 | * string. For now just use the IP revision. OMAP3+ devices have | ||
1604 | * the wr_access and wr_data_mux_bus register fields. OMAP4+ | ||
1605 | * devices support the addr-addr-data multiplex protocol. | ||
1606 | * | ||
1607 | * GPMC IP revisions: | ||
1608 | * - OMAP24xx = 2.0 | ||
1609 | * - OMAP3xxx = 5.0 | ||
1610 | * - OMAP44xx/54xx/AM335x = 6.0 | ||
1611 | */ | ||
1367 | if (GPMC_REVISION_MAJOR(l) > 0x4) | 1612 | if (GPMC_REVISION_MAJOR(l) > 0x4) |
1368 | gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS; | 1613 | gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS; |
1614 | if (GPMC_REVISION_MAJOR(l) > 0x5) | ||
1615 | gpmc_capability |= GPMC_HAS_MUX_AAD; | ||
1369 | dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l), | 1616 | dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l), |
1370 | GPMC_REVISION_MINOR(l)); | 1617 | GPMC_REVISION_MINOR(l)); |
1371 | 1618 | ||
1372 | rc = gpmc_mem_init(); | 1619 | gpmc_mem_init(); |
1373 | if (IS_ERR_VALUE(rc)) { | ||
1374 | clk_disable_unprepare(gpmc_l3_clk); | ||
1375 | clk_put(gpmc_l3_clk); | ||
1376 | dev_err(gpmc_dev, "failed to reserve memory\n"); | ||
1377 | return rc; | ||
1378 | } | ||
1379 | 1620 | ||
1380 | if (IS_ERR_VALUE(gpmc_setup_irq())) | 1621 | if (gpmc_setup_irq() < 0) |
1381 | dev_warn(gpmc_dev, "gpmc_setup_irq failed\n"); | 1622 | dev_warn(gpmc_dev, "gpmc_setup_irq failed\n"); |
1382 | 1623 | ||
1383 | /* Now the GPMC is initialised, unreserve the chip-selects */ | 1624 | /* Now the GPMC is initialised, unreserve the chip-selects */ |
1384 | gpmc_cs_map = 0; | 1625 | gpmc_cs_map = 0; |
1385 | 1626 | ||
1627 | if (!pdev->dev.of_node) | ||
1628 | gpmc_nr_waitpins = GPMC_NR_WAITPINS; | ||
1629 | |||
1386 | rc = gpmc_probe_dt(pdev); | 1630 | rc = gpmc_probe_dt(pdev); |
1387 | if (rc < 0) { | 1631 | if (rc < 0) { |
1388 | clk_disable_unprepare(gpmc_l3_clk); | 1632 | clk_disable_unprepare(gpmc_l3_clk); |
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h index fe0a844d5007..707f6d58edd5 100644 --- a/arch/arm/mach-omap2/gpmc.h +++ b/arch/arm/mach-omap2/gpmc.h | |||
@@ -58,7 +58,7 @@ | |||
58 | #define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1) | 58 | #define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1) |
59 | #define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10) | 59 | #define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10) |
60 | #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) | 60 | #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) |
61 | #define GPMC_CONFIG1_MUXADDDATA (1 << 9) | 61 | #define GPMC_CONFIG1_MUXTYPE(val) ((val & 3) << 8) |
62 | #define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4) | 62 | #define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4) |
63 | #define GPMC_CONFIG1_FCLK_DIV(val) (val & 3) | 63 | #define GPMC_CONFIG1_FCLK_DIV(val) (val & 3) |
64 | #define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1)) | 64 | #define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1)) |
@@ -73,6 +73,13 @@ | |||
73 | #define GPMC_IRQ_FIFOEVENTENABLE 0x01 | 73 | #define GPMC_IRQ_FIFOEVENTENABLE 0x01 |
74 | #define GPMC_IRQ_COUNT_EVENT 0x02 | 74 | #define GPMC_IRQ_COUNT_EVENT 0x02 |
75 | 75 | ||
76 | #define GPMC_BURST_4 4 /* 4 word burst */ | ||
77 | #define GPMC_BURST_8 8 /* 8 word burst */ | ||
78 | #define GPMC_BURST_16 16 /* 16 word burst */ | ||
79 | #define GPMC_DEVWIDTH_8BIT 1 /* 8-bit device width */ | ||
80 | #define GPMC_DEVWIDTH_16BIT 2 /* 16-bit device width */ | ||
81 | #define GPMC_MUX_AAD 1 /* Addr-Addr-Data multiplex */ | ||
82 | #define GPMC_MUX_AD 2 /* Addr-Data multiplex */ | ||
76 | 83 | ||
77 | /* bool type time settings */ | 84 | /* bool type time settings */ |
78 | struct gpmc_bool_timings { | 85 | struct gpmc_bool_timings { |
@@ -178,10 +185,6 @@ struct gpmc_device_timings { | |||
178 | u8 cyc_wpl; /* write deassertion time in cycles */ | 185 | u8 cyc_wpl; /* write deassertion time in cycles */ |
179 | u32 cyc_iaa; /* initial access time in cycles */ | 186 | u32 cyc_iaa; /* initial access time in cycles */ |
180 | 187 | ||
181 | bool mux; /* address & data muxed */ | ||
182 | bool sync_write;/* synchronous write */ | ||
183 | bool sync_read; /* synchronous read */ | ||
184 | |||
185 | /* extra delays */ | 188 | /* extra delays */ |
186 | bool ce_xdelay; | 189 | bool ce_xdelay; |
187 | bool avd_xdelay; | 190 | bool avd_xdelay; |
@@ -189,28 +192,40 @@ struct gpmc_device_timings { | |||
189 | bool we_xdelay; | 192 | bool we_xdelay; |
190 | }; | 193 | }; |
191 | 194 | ||
195 | struct gpmc_settings { | ||
196 | bool burst_wrap; /* enables wrap bursting */ | ||
197 | bool burst_read; /* enables read page/burst mode */ | ||
198 | bool burst_write; /* enables write page/burst mode */ | ||
199 | bool device_nand; /* device is NAND */ | ||
200 | bool sync_read; /* enables synchronous reads */ | ||
201 | bool sync_write; /* enables synchronous writes */ | ||
202 | bool wait_on_read; /* monitor wait on reads */ | ||
203 | bool wait_on_write; /* monitor wait on writes */ | ||
204 | u32 burst_len; /* page/burst length */ | ||
205 | u32 device_width; /* device bus width (8 or 16 bit) */ | ||
206 | u32 mux_add_data; /* multiplex address & data */ | ||
207 | u32 wait_pin; /* wait-pin to be used */ | ||
208 | }; | ||
209 | |||
192 | extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t, | 210 | extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t, |
193 | struct gpmc_device_timings *dev_t); | 211 | struct gpmc_settings *gpmc_s, |
212 | struct gpmc_device_timings *dev_t); | ||
194 | 213 | ||
195 | extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); | 214 | extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); |
196 | extern int gpmc_get_client_irq(unsigned irq_config); | 215 | extern int gpmc_get_client_irq(unsigned irq_config); |
197 | 216 | ||
198 | extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns); | ||
199 | extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps); | ||
200 | extern unsigned int gpmc_ticks_to_ns(unsigned int ticks); | 217 | extern unsigned int gpmc_ticks_to_ns(unsigned int ticks); |
201 | extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns); | ||
202 | extern unsigned long gpmc_get_fclk_period(void); | ||
203 | 218 | ||
204 | extern void gpmc_cs_write_reg(int cs, int idx, u32 val); | 219 | extern void gpmc_cs_write_reg(int cs, int idx, u32 val); |
205 | extern u32 gpmc_cs_read_reg(int cs, int idx); | ||
206 | extern int gpmc_calc_divider(unsigned int sync_clk); | 220 | extern int gpmc_calc_divider(unsigned int sync_clk); |
207 | extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t); | 221 | extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t); |
222 | extern int gpmc_cs_program_settings(int cs, struct gpmc_settings *p); | ||
208 | extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base); | 223 | extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base); |
209 | extern void gpmc_cs_free(int cs); | 224 | extern void gpmc_cs_free(int cs); |
210 | extern int gpmc_cs_set_reserved(int cs, int reserved); | ||
211 | extern int gpmc_cs_reserved(int cs); | ||
212 | extern void omap3_gpmc_save_context(void); | 225 | extern void omap3_gpmc_save_context(void); |
213 | extern void omap3_gpmc_restore_context(void); | 226 | extern void omap3_gpmc_restore_context(void); |
214 | extern int gpmc_cs_configure(int cs, int cmd, int wval); | 227 | extern int gpmc_configure(int cmd, int wval); |
228 | extern void gpmc_read_settings_dt(struct device_node *np, | ||
229 | struct gpmc_settings *p); | ||
215 | 230 | ||
216 | #endif | 231 | #endif |
diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index 381be7ac0c17..eeea4fa28fbc 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c | |||
@@ -131,7 +131,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev) | |||
131 | int oh_cnt, i, ret = 0; | 131 | int oh_cnt, i, ret = 0; |
132 | 132 | ||
133 | oh_cnt = of_property_count_strings(node, "ti,hwmods"); | 133 | oh_cnt = of_property_count_strings(node, "ti,hwmods"); |
134 | if (!oh_cnt || IS_ERR_VALUE(oh_cnt)) { | 134 | if (oh_cnt <= 0) { |
135 | dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n"); | 135 | dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n"); |
136 | return -ENODEV; | 136 | return -ENODEV; |
137 | } | 137 | } |
@@ -815,20 +815,17 @@ struct device *omap_device_get_by_hwmod_name(const char *oh_name) | |||
815 | } | 815 | } |
816 | 816 | ||
817 | oh = omap_hwmod_lookup(oh_name); | 817 | oh = omap_hwmod_lookup(oh_name); |
818 | if (IS_ERR_OR_NULL(oh)) { | 818 | if (!oh) { |
819 | WARN(1, "%s: no hwmod for %s\n", __func__, | 819 | WARN(1, "%s: no hwmod for %s\n", __func__, |
820 | oh_name); | 820 | oh_name); |
821 | return ERR_PTR(oh ? PTR_ERR(oh) : -ENODEV); | 821 | return ERR_PTR(-ENODEV); |
822 | } | 822 | } |
823 | if (IS_ERR_OR_NULL(oh->od)) { | 823 | if (!oh->od) { |
824 | WARN(1, "%s: no omap_device for %s\n", __func__, | 824 | WARN(1, "%s: no omap_device for %s\n", __func__, |
825 | oh_name); | 825 | oh_name); |
826 | return ERR_PTR(oh->od ? PTR_ERR(oh->od) : -ENODEV); | 826 | return ERR_PTR(-ENODEV); |
827 | } | 827 | } |
828 | 828 | ||
829 | if (IS_ERR_OR_NULL(oh->od->pdev)) | ||
830 | return ERR_PTR(oh->od->pdev ? PTR_ERR(oh->od->pdev) : -ENODEV); | ||
831 | |||
832 | return &oh->od->pdev->dev; | 829 | return &oh->od->pdev->dev; |
833 | } | 830 | } |
834 | 831 | ||
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 5f33c2da6999..3f50f680372e 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -1662,7 +1662,7 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name) | |||
1662 | return -ENOSYS; | 1662 | return -ENOSYS; |
1663 | 1663 | ||
1664 | ret = _lookup_hardreset(oh, name, &ohri); | 1664 | ret = _lookup_hardreset(oh, name, &ohri); |
1665 | if (IS_ERR_VALUE(ret)) | 1665 | if (ret < 0) |
1666 | return ret; | 1666 | return ret; |
1667 | 1667 | ||
1668 | if (oh->clkdm) { | 1668 | if (oh->clkdm) { |
@@ -2412,7 +2412,7 @@ static int __init _init(struct omap_hwmod *oh, void *data) | |||
2412 | _init_mpu_rt_base(oh, NULL); | 2412 | _init_mpu_rt_base(oh, NULL); |
2413 | 2413 | ||
2414 | r = _init_clocks(oh, NULL); | 2414 | r = _init_clocks(oh, NULL); |
2415 | if (IS_ERR_VALUE(r)) { | 2415 | if (r < 0) { |
2416 | WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name); | 2416 | WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name); |
2417 | return -EINVAL; | 2417 | return -EINVAL; |
2418 | } | 2418 | } |
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 1edd000a8143..0b339861d751 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c | |||
@@ -217,7 +217,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir) | |||
217 | return 0; | 217 | return 0; |
218 | 218 | ||
219 | d = debugfs_create_dir(pwrdm->name, (struct dentry *)dir); | 219 | d = debugfs_create_dir(pwrdm->name, (struct dentry *)dir); |
220 | if (!(IS_ERR_OR_NULL(d))) | 220 | if (d) |
221 | (void) debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d, | 221 | (void) debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d, |
222 | (void *)pwrdm, &pwrdm_suspend_fops); | 222 | (void *)pwrdm, &pwrdm_suspend_fops); |
223 | 223 | ||
@@ -261,8 +261,8 @@ static int __init pm_dbg_init(void) | |||
261 | return 0; | 261 | return 0; |
262 | 262 | ||
263 | d = debugfs_create_dir("pm_debug", NULL); | 263 | d = debugfs_create_dir("pm_debug", NULL); |
264 | if (IS_ERR_OR_NULL(d)) | 264 | if (!d) |
265 | return PTR_ERR(d); | 265 | return -EINVAL; |
266 | 266 | ||
267 | (void) debugfs_create_file("count", S_IRUGO, | 267 | (void) debugfs_create_file("count", S_IRUGO, |
268 | d, (void *)DEBUG_FILE_COUNTERS, &debug_fops); | 268 | d, (void *)DEBUG_FILE_COUNTERS, &debug_fops); |
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 89cad4a605dd..86babd740d41 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c | |||
@@ -1180,7 +1180,7 @@ bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm) | |||
1180 | { | 1180 | { |
1181 | int i; | 1181 | int i; |
1182 | 1182 | ||
1183 | if (IS_ERR_OR_NULL(pwrdm)) { | 1183 | if (!pwrdm) { |
1184 | pr_debug("powerdomain: %s: invalid powerdomain pointer\n", | 1184 | pr_debug("powerdomain: %s: invalid powerdomain pointer\n", |
1185 | __func__); | 1185 | __func__); |
1186 | return 1; | 1186 | return 1; |
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index d00d89c93f1c..fdf1c039062c 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <asm/smp_twd.h> | 46 | #include <asm/smp_twd.h> |
47 | #include <asm/sched_clock.h> | 47 | #include <asm/sched_clock.h> |
48 | 48 | ||
49 | #include <asm/arch_timer.h> | ||
50 | #include "omap_hwmod.h" | 49 | #include "omap_hwmod.h" |
51 | #include "omap_device.h" | 50 | #include "omap_device.h" |
52 | #include <plat/counter-32k.h> | 51 | #include <plat/counter-32k.h> |
@@ -57,16 +56,6 @@ | |||
57 | #include "common.h" | 56 | #include "common.h" |
58 | #include "powerdomain.h" | 57 | #include "powerdomain.h" |
59 | 58 | ||
60 | /* Parent clocks, eventually these will come from the clock framework */ | ||
61 | |||
62 | #define OMAP2_MPU_SOURCE "sys_ck" | ||
63 | #define OMAP3_MPU_SOURCE OMAP2_MPU_SOURCE | ||
64 | #define OMAP4_MPU_SOURCE "sys_clkin_ck" | ||
65 | #define OMAP5_MPU_SOURCE "sys_clkin" | ||
66 | #define OMAP2_32K_SOURCE "func_32k_ck" | ||
67 | #define OMAP3_32K_SOURCE "omap_32k_fck" | ||
68 | #define OMAP4_32K_SOURCE "sys_32k_ck" | ||
69 | |||
70 | #define REALTIME_COUNTER_BASE 0x48243200 | 59 | #define REALTIME_COUNTER_BASE 0x48243200 |
71 | #define INCREMENTER_NUMERATOR_OFFSET 0x10 | 60 | #define INCREMENTER_NUMERATOR_OFFSET 0x10 |
72 | #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14 | 61 | #define INCREMENTER_DENUMERATOR_RELOAD_OFFSET 0x14 |
@@ -130,7 +119,6 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode, | |||
130 | } | 119 | } |
131 | 120 | ||
132 | static struct clock_event_device clockevent_gpt = { | 121 | static struct clock_event_device clockevent_gpt = { |
133 | .name = "gp_timer", | ||
134 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 122 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
135 | .rating = 300, | 123 | .rating = 300, |
136 | .set_next_event = omap2_gp_timer_set_next_event, | 124 | .set_next_event = omap2_gp_timer_set_next_event, |
@@ -171,6 +159,12 @@ static struct device_node * __init omap_get_timer_dt(struct of_device_id *match, | |||
171 | if (property && !of_get_property(np, property, NULL)) | 159 | if (property && !of_get_property(np, property, NULL)) |
172 | continue; | 160 | continue; |
173 | 161 | ||
162 | if (!property && (of_get_property(np, "ti,timer-alwon", NULL) || | ||
163 | of_get_property(np, "ti,timer-dsp", NULL) || | ||
164 | of_get_property(np, "ti,timer-pwm", NULL) || | ||
165 | of_get_property(np, "ti,timer-secure", NULL))) | ||
166 | continue; | ||
167 | |||
174 | of_add_property(np, &device_disabled); | 168 | of_add_property(np, &device_disabled); |
175 | return np; | 169 | return np; |
176 | } | 170 | } |
@@ -215,16 +209,17 @@ static u32 __init omap_dm_timer_get_errata(void) | |||
215 | } | 209 | } |
216 | 210 | ||
217 | static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, | 211 | static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, |
218 | int gptimer_id, | 212 | const char *fck_source, |
219 | const char *fck_source, | 213 | const char *property, |
220 | const char *property, | 214 | const char **timer_name, |
221 | int posted) | 215 | int posted) |
222 | { | 216 | { |
223 | char name[10]; /* 10 = sizeof("gptXX_Xck0") */ | 217 | char name[10]; /* 10 = sizeof("gptXX_Xck0") */ |
224 | const char *oh_name; | 218 | const char *oh_name; |
225 | struct device_node *np; | 219 | struct device_node *np; |
226 | struct omap_hwmod *oh; | 220 | struct omap_hwmod *oh; |
227 | struct resource irq, mem; | 221 | struct resource irq, mem; |
222 | struct clk *src; | ||
228 | int r = 0; | 223 | int r = 0; |
229 | 224 | ||
230 | if (of_have_populated_dt()) { | 225 | if (of_have_populated_dt()) { |
@@ -244,10 +239,10 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, | |||
244 | 239 | ||
245 | of_node_put(np); | 240 | of_node_put(np); |
246 | } else { | 241 | } else { |
247 | if (omap_dm_timer_reserve_systimer(gptimer_id)) | 242 | if (omap_dm_timer_reserve_systimer(timer->id)) |
248 | return -ENODEV; | 243 | return -ENODEV; |
249 | 244 | ||
250 | sprintf(name, "timer%d", gptimer_id); | 245 | sprintf(name, "timer%d", timer->id); |
251 | oh_name = name; | 246 | oh_name = name; |
252 | } | 247 | } |
253 | 248 | ||
@@ -255,6 +250,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, | |||
255 | if (!oh) | 250 | if (!oh) |
256 | return -ENODEV; | 251 | return -ENODEV; |
257 | 252 | ||
253 | *timer_name = oh->name; | ||
254 | |||
258 | if (!of_have_populated_dt()) { | 255 | if (!of_have_populated_dt()) { |
259 | r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, | 256 | r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, |
260 | &irq); | 257 | &irq); |
@@ -277,24 +274,24 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, | |||
277 | /* After the dmtimer is using hwmod these clocks won't be needed */ | 274 | /* After the dmtimer is using hwmod these clocks won't be needed */ |
278 | timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); | 275 | timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); |
279 | if (IS_ERR(timer->fclk)) | 276 | if (IS_ERR(timer->fclk)) |
280 | return -ENODEV; | 277 | return PTR_ERR(timer->fclk); |
281 | 278 | ||
282 | /* FIXME: Need to remove hard-coded test on timer ID */ | 279 | src = clk_get(NULL, fck_source); |
283 | if (gptimer_id != 12) { | 280 | if (IS_ERR(src)) |
284 | struct clk *src; | 281 | return PTR_ERR(src); |
285 | 282 | ||
286 | src = clk_get(NULL, fck_source); | 283 | if (clk_get_parent(timer->fclk) != src) { |
287 | if (IS_ERR(src)) { | 284 | r = clk_set_parent(timer->fclk, src); |
288 | r = -EINVAL; | 285 | if (r < 0) { |
289 | } else { | 286 | pr_warn("%s: %s cannot set source\n", __func__, |
290 | r = clk_set_parent(timer->fclk, src); | 287 | oh->name); |
291 | if (IS_ERR_VALUE(r)) | ||
292 | pr_warn("%s: %s cannot set source\n", | ||
293 | __func__, oh->name); | ||
294 | clk_put(src); | 288 | clk_put(src); |
289 | return r; | ||
295 | } | 290 | } |
296 | } | 291 | } |
297 | 292 | ||
293 | clk_put(src); | ||
294 | |||
298 | omap_hwmod_setup_one(oh_name); | 295 | omap_hwmod_setup_one(oh_name); |
299 | omap_hwmod_enable(oh); | 296 | omap_hwmod_enable(oh); |
300 | __omap_dm_timer_init_regs(timer); | 297 | __omap_dm_timer_init_regs(timer); |
@@ -318,6 +315,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, | |||
318 | { | 315 | { |
319 | int res; | 316 | int res; |
320 | 317 | ||
318 | clkev.id = gptimer_id; | ||
321 | clkev.errata = omap_dm_timer_get_errata(); | 319 | clkev.errata = omap_dm_timer_get_errata(); |
322 | 320 | ||
323 | /* | 321 | /* |
@@ -327,8 +325,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, | |||
327 | */ | 325 | */ |
328 | __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767); | 326 | __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767); |
329 | 327 | ||
330 | res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property, | 328 | res = omap_dm_timer_init_one(&clkev, fck_source, property, |
331 | OMAP_TIMER_POSTED); | 329 | &clockevent_gpt.name, OMAP_TIMER_POSTED); |
332 | BUG_ON(res); | 330 | BUG_ON(res); |
333 | 331 | ||
334 | omap2_gp_timer_irq.dev_id = &clkev; | 332 | omap2_gp_timer_irq.dev_id = &clkev; |
@@ -342,8 +340,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, | |||
342 | 3, /* Timer internal resynch latency */ | 340 | 3, /* Timer internal resynch latency */ |
343 | 0xffffffff); | 341 | 0xffffffff); |
344 | 342 | ||
345 | pr_info("OMAP clockevent source: GPTIMER%d at %lu Hz\n", | 343 | pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name, |
346 | gptimer_id, clkev.rate); | 344 | clkev.rate); |
347 | } | 345 | } |
348 | 346 | ||
349 | /* Clocksource code */ | 347 | /* Clocksource code */ |
@@ -360,7 +358,6 @@ static cycle_t clocksource_read_cycles(struct clocksource *cs) | |||
360 | } | 358 | } |
361 | 359 | ||
362 | static struct clocksource clocksource_gpt = { | 360 | static struct clocksource clocksource_gpt = { |
363 | .name = "gp_timer", | ||
364 | .rating = 300, | 361 | .rating = 300, |
365 | .read = clocksource_read_cycles, | 362 | .read = clocksource_read_cycles, |
366 | .mask = CLOCKSOURCE_MASK(32), | 363 | .mask = CLOCKSOURCE_MASK(32), |
@@ -443,13 +440,16 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void) | |||
443 | } | 440 | } |
444 | 441 | ||
445 | static void __init omap2_gptimer_clocksource_init(int gptimer_id, | 442 | static void __init omap2_gptimer_clocksource_init(int gptimer_id, |
446 | const char *fck_source) | 443 | const char *fck_source, |
444 | const char *property) | ||
447 | { | 445 | { |
448 | int res; | 446 | int res; |
449 | 447 | ||
448 | clksrc.id = gptimer_id; | ||
450 | clksrc.errata = omap_dm_timer_get_errata(); | 449 | clksrc.errata = omap_dm_timer_get_errata(); |
451 | 450 | ||
452 | res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL, | 451 | res = omap_dm_timer_init_one(&clksrc, fck_source, property, |
452 | &clocksource_gpt.name, | ||
453 | OMAP_TIMER_NONPOSTED); | 453 | OMAP_TIMER_NONPOSTED); |
454 | BUG_ON(res); | 454 | BUG_ON(res); |
455 | 455 | ||
@@ -462,8 +462,8 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id, | |||
462 | pr_err("Could not register clocksource %s\n", | 462 | pr_err("Could not register clocksource %s\n", |
463 | clocksource_gpt.name); | 463 | clocksource_gpt.name); |
464 | else | 464 | else |
465 | pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n", | 465 | pr_info("OMAP clocksource: %s at %lu Hz\n", |
466 | gptimer_id, clksrc.rate); | 466 | clocksource_gpt.name, clksrc.rate); |
467 | } | 467 | } |
468 | 468 | ||
469 | #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER | 469 | #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER |
@@ -488,7 +488,7 @@ static void __init realtime_counter_init(void) | |||
488 | pr_err("%s: ioremap failed\n", __func__); | 488 | pr_err("%s: ioremap failed\n", __func__); |
489 | return; | 489 | return; |
490 | } | 490 | } |
491 | sys_clk = clk_get(NULL, OMAP5_MPU_SOURCE); | 491 | sys_clk = clk_get(NULL, "sys_clkin"); |
492 | if (IS_ERR(sys_clk)) { | 492 | if (IS_ERR(sys_clk)) { |
493 | pr_err("%s: failed to get system clock handle\n", __func__); | 493 | pr_err("%s: failed to get system clock handle\n", __func__); |
494 | iounmap(base); | 494 | iounmap(base); |
@@ -545,18 +545,19 @@ static inline void __init realtime_counter_init(void) | |||
545 | #endif | 545 | #endif |
546 | 546 | ||
547 | #define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ | 547 | #define OMAP_SYS_GP_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ |
548 | clksrc_nr, clksrc_src) \ | 548 | clksrc_nr, clksrc_src, clksrc_prop) \ |
549 | void __init omap##name##_gptimer_timer_init(void) \ | 549 | void __init omap##name##_gptimer_timer_init(void) \ |
550 | { \ | 550 | { \ |
551 | if (omap_clk_init) \ | 551 | if (omap_clk_init) \ |
552 | omap_clk_init(); \ | 552 | omap_clk_init(); \ |
553 | omap_dmtimer_init(); \ | 553 | omap_dmtimer_init(); \ |
554 | omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ | 554 | omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ |
555 | omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src); \ | 555 | omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \ |
556 | clksrc_prop); \ | ||
556 | } | 557 | } |
557 | 558 | ||
558 | #define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ | 559 | #define OMAP_SYS_32K_TIMER_INIT(name, clkev_nr, clkev_src, clkev_prop, \ |
559 | clksrc_nr, clksrc_src) \ | 560 | clksrc_nr, clksrc_src, clksrc_prop) \ |
560 | void __init omap##name##_sync32k_timer_init(void) \ | 561 | void __init omap##name##_sync32k_timer_init(void) \ |
561 | { \ | 562 | { \ |
562 | if (omap_clk_init) \ | 563 | if (omap_clk_init) \ |
@@ -565,33 +566,35 @@ void __init omap##name##_sync32k_timer_init(void) \ | |||
565 | omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ | 566 | omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ |
566 | /* Enable the use of clocksource="gp_timer" kernel parameter */ \ | 567 | /* Enable the use of clocksource="gp_timer" kernel parameter */ \ |
567 | if (use_gptimer_clksrc) \ | 568 | if (use_gptimer_clksrc) \ |
568 | omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src);\ | 569 | omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src, \ |
570 | clksrc_prop); \ | ||
569 | else \ | 571 | else \ |
570 | omap2_sync32k_clocksource_init(); \ | 572 | omap2_sync32k_clocksource_init(); \ |
571 | } | 573 | } |
572 | 574 | ||
573 | #ifdef CONFIG_ARCH_OMAP2 | 575 | #ifdef CONFIG_ARCH_OMAP2 |
574 | OMAP_SYS_32K_TIMER_INIT(2, 1, OMAP2_32K_SOURCE, "ti,timer-alwon", | 576 | OMAP_SYS_32K_TIMER_INIT(2, 1, "timer_32k_ck", "ti,timer-alwon", |
575 | 2, OMAP2_MPU_SOURCE); | 577 | 2, "timer_sys_ck", NULL); |
576 | #endif /* CONFIG_ARCH_OMAP2 */ | 578 | #endif /* CONFIG_ARCH_OMAP2 */ |
577 | 579 | ||
578 | #ifdef CONFIG_ARCH_OMAP3 | 580 | #ifdef CONFIG_ARCH_OMAP3 |
579 | OMAP_SYS_32K_TIMER_INIT(3, 1, OMAP3_32K_SOURCE, "ti,timer-alwon", | 581 | OMAP_SYS_32K_TIMER_INIT(3, 1, "timer_32k_ck", "ti,timer-alwon", |
580 | 2, OMAP3_MPU_SOURCE); | 582 | 2, "timer_sys_ck", NULL); |
581 | OMAP_SYS_32K_TIMER_INIT(3_secure, 12, OMAP3_32K_SOURCE, "ti,timer-secure", | 583 | OMAP_SYS_32K_TIMER_INIT(3_secure, 12, "secure_32k_fck", "ti,timer-secure", |
582 | 2, OMAP3_MPU_SOURCE); | 584 | 2, "timer_sys_ck", NULL); |
583 | OMAP_SYS_GP_TIMER_INIT(3_gp, 1, OMAP3_MPU_SOURCE, "ti,timer-alwon", | ||
584 | 2, OMAP3_MPU_SOURCE); | ||
585 | #endif /* CONFIG_ARCH_OMAP3 */ | 585 | #endif /* CONFIG_ARCH_OMAP3 */ |
586 | 586 | ||
587 | #ifdef CONFIG_SOC_AM33XX | 587 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) |
588 | OMAP_SYS_GP_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, "ti,timer-alwon", | 588 | OMAP_SYS_GP_TIMER_INIT(3, 2, "timer_sys_ck", NULL, |
589 | 2, OMAP4_MPU_SOURCE); | 589 | 1, "timer_sys_ck", "ti,timer-alwon"); |
590 | #endif /* CONFIG_SOC_AM33XX */ | 590 | #endif |
591 | |||
592 | #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) | ||
593 | static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon", | ||
594 | 2, "sys_clkin_ck", NULL); | ||
595 | #endif | ||
591 | 596 | ||
592 | #ifdef CONFIG_ARCH_OMAP4 | 597 | #ifdef CONFIG_ARCH_OMAP4 |
593 | OMAP_SYS_32K_TIMER_INIT(4, 1, OMAP4_32K_SOURCE, "ti,timer-alwon", | ||
594 | 2, OMAP4_MPU_SOURCE); | ||
595 | #ifdef CONFIG_LOCAL_TIMERS | 598 | #ifdef CONFIG_LOCAL_TIMERS |
596 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29); | 599 | static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29); |
597 | void __init omap4_local_timer_init(void) | 600 | void __init omap4_local_timer_init(void) |
@@ -602,7 +605,7 @@ void __init omap4_local_timer_init(void) | |||
602 | int err; | 605 | int err; |
603 | 606 | ||
604 | if (of_have_populated_dt()) { | 607 | if (of_have_populated_dt()) { |
605 | twd_local_timer_of_register(); | 608 | clocksource_of_init(); |
606 | return; | 609 | return; |
607 | } | 610 | } |
608 | 611 | ||
@@ -620,18 +623,12 @@ void __init omap4_local_timer_init(void) | |||
620 | #endif /* CONFIG_ARCH_OMAP4 */ | 623 | #endif /* CONFIG_ARCH_OMAP4 */ |
621 | 624 | ||
622 | #ifdef CONFIG_SOC_OMAP5 | 625 | #ifdef CONFIG_SOC_OMAP5 |
623 | OMAP_SYS_32K_TIMER_INIT(5, 1, OMAP4_32K_SOURCE, "ti,timer-alwon", | ||
624 | 2, OMAP5_MPU_SOURCE); | ||
625 | void __init omap5_realtime_timer_init(void) | 626 | void __init omap5_realtime_timer_init(void) |
626 | { | 627 | { |
627 | int err; | 628 | omap4_sync32k_timer_init(); |
628 | |||
629 | omap5_sync32k_timer_init(); | ||
630 | realtime_counter_init(); | 629 | realtime_counter_init(); |
631 | 630 | ||
632 | err = arch_timer_of_register(); | 631 | clocksource_of_init(); |
633 | if (err) | ||
634 | pr_err("%s: arch_timer_register failed %d\n", __func__, err); | ||
635 | } | 632 | } |
636 | #endif /* CONFIG_SOC_OMAP5 */ | 633 | #endif /* CONFIG_SOC_OMAP5 */ |
637 | 634 | ||
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c index 5706bdccf45e..aa27d7f5cbb7 100644 --- a/arch/arm/mach-omap2/usb-host.c +++ b/arch/arm/mach-omap2/usb-host.c | |||
@@ -22,8 +22,12 @@ | |||
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/dma-mapping.h> | 24 | #include <linux/dma-mapping.h> |
25 | 25 | #include <linux/regulator/machine.h> | |
26 | #include <asm/io.h> | 26 | #include <linux/regulator/fixed.h> |
27 | #include <linux/string.h> | ||
28 | #include <linux/io.h> | ||
29 | #include <linux/gpio.h> | ||
30 | #include <linux/usb/phy.h> | ||
27 | 31 | ||
28 | #include "soc.h" | 32 | #include "soc.h" |
29 | #include "omap_device.h" | 33 | #include "omap_device.h" |
@@ -526,3 +530,155 @@ void __init usbhs_init(struct usbhs_omap_platform_data *pdata) | |||
526 | } | 530 | } |
527 | 531 | ||
528 | #endif | 532 | #endif |
533 | |||
534 | /* Template for PHY regulators */ | ||
535 | static struct fixed_voltage_config hsusb_reg_config = { | ||
536 | /* .supply_name filled later */ | ||
537 | .microvolts = 3300000, | ||
538 | .gpio = -1, /* updated later */ | ||
539 | .startup_delay = 70000, /* 70msec */ | ||
540 | .enable_high = 1, /* updated later */ | ||
541 | .enabled_at_boot = 0, /* keep in RESET */ | ||
542 | /* .init_data filled later */ | ||
543 | }; | ||
544 | |||
545 | static const char *nop_name = "nop_usb_xceiv"; /* NOP PHY driver */ | ||
546 | static const char *reg_name = "reg-fixed-voltage"; /* Regulator driver */ | ||
547 | |||
548 | /** | ||
549 | * usbhs_add_regulator - Add a gpio based fixed voltage regulator device | ||
550 | * @name: name for the regulator | ||
551 | * @dev_id: device id of the device this regulator supplies power to | ||
552 | * @dev_supply: supply name that the device expects | ||
553 | * @gpio: GPIO number | ||
554 | * @polarity: 1 - Active high, 0 - Active low | ||
555 | */ | ||
556 | static int usbhs_add_regulator(char *name, char *dev_id, char *dev_supply, | ||
557 | int gpio, int polarity) | ||
558 | { | ||
559 | struct regulator_consumer_supply *supplies; | ||
560 | struct regulator_init_data *reg_data; | ||
561 | struct fixed_voltage_config *config; | ||
562 | struct platform_device *pdev; | ||
563 | int ret; | ||
564 | |||
565 | supplies = kzalloc(sizeof(*supplies), GFP_KERNEL); | ||
566 | if (!supplies) | ||
567 | return -ENOMEM; | ||
568 | |||
569 | supplies->supply = dev_supply; | ||
570 | supplies->dev_name = dev_id; | ||
571 | |||
572 | reg_data = kzalloc(sizeof(*reg_data), GFP_KERNEL); | ||
573 | if (!reg_data) | ||
574 | return -ENOMEM; | ||
575 | |||
576 | reg_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS; | ||
577 | reg_data->consumer_supplies = supplies; | ||
578 | reg_data->num_consumer_supplies = 1; | ||
579 | |||
580 | config = kmemdup(&hsusb_reg_config, sizeof(hsusb_reg_config), | ||
581 | GFP_KERNEL); | ||
582 | if (!config) | ||
583 | return -ENOMEM; | ||
584 | |||
585 | config->supply_name = name; | ||
586 | config->gpio = gpio; | ||
587 | config->enable_high = polarity; | ||
588 | config->init_data = reg_data; | ||
589 | |||
590 | /* create a regulator device */ | ||
591 | pdev = kzalloc(sizeof(*pdev), GFP_KERNEL); | ||
592 | if (!pdev) | ||
593 | return -ENOMEM; | ||
594 | |||
595 | pdev->id = PLATFORM_DEVID_AUTO; | ||
596 | pdev->name = reg_name; | ||
597 | pdev->dev.platform_data = config; | ||
598 | |||
599 | ret = platform_device_register(pdev); | ||
600 | if (ret) | ||
601 | pr_err("%s: Failed registering regulator %s for %s\n", | ||
602 | __func__, name, dev_id); | ||
603 | |||
604 | return ret; | ||
605 | } | ||
606 | |||
607 | int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys) | ||
608 | { | ||
609 | char *rail_name; | ||
610 | int i, len; | ||
611 | struct platform_device *pdev; | ||
612 | char *phy_id; | ||
613 | |||
614 | /* the phy_id will be something like "nop_usb_xceiv.1" */ | ||
615 | len = strlen(nop_name) + 3; /* 3 -> ".1" and NULL terminator */ | ||
616 | |||
617 | for (i = 0; i < num_phys; i++) { | ||
618 | |||
619 | if (!phy->port) { | ||
620 | pr_err("%s: Invalid port 0. Must start from 1\n", | ||
621 | __func__); | ||
622 | continue; | ||
623 | } | ||
624 | |||
625 | /* do we need a NOP PHY device ? */ | ||
626 | if (!gpio_is_valid(phy->reset_gpio) && | ||
627 | !gpio_is_valid(phy->vcc_gpio)) | ||
628 | continue; | ||
629 | |||
630 | /* create a NOP PHY device */ | ||
631 | pdev = kzalloc(sizeof(*pdev), GFP_KERNEL); | ||
632 | if (!pdev) | ||
633 | return -ENOMEM; | ||
634 | |||
635 | pdev->id = phy->port; | ||
636 | pdev->name = nop_name; | ||
637 | pdev->dev.platform_data = phy->platform_data; | ||
638 | |||
639 | phy_id = kmalloc(len, GFP_KERNEL); | ||
640 | if (!phy_id) | ||
641 | return -ENOMEM; | ||
642 | |||
643 | scnprintf(phy_id, len, "nop_usb_xceiv.%d\n", | ||
644 | pdev->id); | ||
645 | |||
646 | if (platform_device_register(pdev)) { | ||
647 | pr_err("%s: Failed to register device %s\n", | ||
648 | __func__, phy_id); | ||
649 | continue; | ||
650 | } | ||
651 | |||
652 | usb_bind_phy("ehci-omap.0", phy->port - 1, phy_id); | ||
653 | |||
654 | /* Do we need RESET regulator ? */ | ||
655 | if (gpio_is_valid(phy->reset_gpio)) { | ||
656 | |||
657 | rail_name = kmalloc(13, GFP_KERNEL); | ||
658 | if (!rail_name) | ||
659 | return -ENOMEM; | ||
660 | |||
661 | scnprintf(rail_name, 13, "hsusb%d_reset", phy->port); | ||
662 | |||
663 | usbhs_add_regulator(rail_name, phy_id, "reset", | ||
664 | phy->reset_gpio, 1); | ||
665 | } | ||
666 | |||
667 | /* Do we need VCC regulator ? */ | ||
668 | if (gpio_is_valid(phy->vcc_gpio)) { | ||
669 | |||
670 | rail_name = kmalloc(13, GFP_KERNEL); | ||
671 | if (!rail_name) | ||
672 | return -ENOMEM; | ||
673 | |||
674 | scnprintf(rail_name, 13, "hsusb%d_vcc", phy->port); | ||
675 | |||
676 | usbhs_add_regulator(rail_name, phy_id, "vcc", | ||
677 | phy->vcc_gpio, phy->vcc_polarity); | ||
678 | } | ||
679 | |||
680 | phy++; | ||
681 | } | ||
682 | |||
683 | return 0; | ||
684 | } | ||
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c index c5a3c6f9504e..e832bc7b8e2d 100644 --- a/arch/arm/mach-omap2/usb-tusb6010.c +++ b/arch/arm/mach-omap2/usb-tusb6010.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/err.h> | ||
11 | #include <linux/string.h> | 12 | #include <linux/string.h> |
12 | #include <linux/types.h> | 13 | #include <linux/types.h> |
13 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
@@ -26,6 +27,24 @@ | |||
26 | static u8 async_cs, sync_cs; | 27 | static u8 async_cs, sync_cs; |
27 | static unsigned refclk_psec; | 28 | static unsigned refclk_psec; |
28 | 29 | ||
30 | static struct gpmc_settings tusb_async = { | ||
31 | .wait_on_read = true, | ||
32 | .wait_on_write = true, | ||
33 | .device_width = GPMC_DEVWIDTH_16BIT, | ||
34 | .mux_add_data = GPMC_MUX_AD, | ||
35 | }; | ||
36 | |||
37 | static struct gpmc_settings tusb_sync = { | ||
38 | .burst_read = true, | ||
39 | .burst_write = true, | ||
40 | .sync_read = true, | ||
41 | .sync_write = true, | ||
42 | .wait_on_read = true, | ||
43 | .wait_on_write = true, | ||
44 | .burst_len = GPMC_BURST_16, | ||
45 | .device_width = GPMC_DEVWIDTH_16BIT, | ||
46 | .mux_add_data = GPMC_MUX_AD, | ||
47 | }; | ||
29 | 48 | ||
30 | /* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */ | 49 | /* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */ |
31 | 50 | ||
@@ -37,8 +56,6 @@ static int tusb_set_async_mode(unsigned sysclk_ps) | |||
37 | 56 | ||
38 | memset(&dev_t, 0, sizeof(dev_t)); | 57 | memset(&dev_t, 0, sizeof(dev_t)); |
39 | 58 | ||
40 | dev_t.mux = true; | ||
41 | |||
42 | dev_t.t_ceasu = 8 * 1000; | 59 | dev_t.t_ceasu = 8 * 1000; |
43 | dev_t.t_avdasu = t_acsnh_advnh - 7000; | 60 | dev_t.t_avdasu = t_acsnh_advnh - 7000; |
44 | dev_t.t_ce_avd = 1000; | 61 | dev_t.t_ce_avd = 1000; |
@@ -52,7 +69,7 @@ static int tusb_set_async_mode(unsigned sysclk_ps) | |||
52 | dev_t.t_wpl = 300; | 69 | dev_t.t_wpl = 300; |
53 | dev_t.cyc_aavdh_we = 1; | 70 | dev_t.cyc_aavdh_we = 1; |
54 | 71 | ||
55 | gpmc_calc_timings(&t, &dev_t); | 72 | gpmc_calc_timings(&t, &tusb_async, &dev_t); |
56 | 73 | ||
57 | return gpmc_cs_set_timings(async_cs, &t); | 74 | return gpmc_cs_set_timings(async_cs, &t); |
58 | } | 75 | } |
@@ -65,10 +82,6 @@ static int tusb_set_sync_mode(unsigned sysclk_ps) | |||
65 | 82 | ||
66 | memset(&dev_t, 0, sizeof(dev_t)); | 83 | memset(&dev_t, 0, sizeof(dev_t)); |
67 | 84 | ||
68 | dev_t.mux = true; | ||
69 | dev_t.sync_read = true; | ||
70 | dev_t.sync_write = true; | ||
71 | |||
72 | dev_t.clk = 11100; | 85 | dev_t.clk = 11100; |
73 | dev_t.t_bacc = 1000; | 86 | dev_t.t_bacc = 1000; |
74 | dev_t.t_ces = 1000; | 87 | dev_t.t_ces = 1000; |
@@ -84,7 +97,7 @@ static int tusb_set_sync_mode(unsigned sysclk_ps) | |||
84 | dev_t.cyc_wpl = 6; | 97 | dev_t.cyc_wpl = 6; |
85 | dev_t.t_ce_rdyz = 7000; | 98 | dev_t.t_ce_rdyz = 7000; |
86 | 99 | ||
87 | gpmc_calc_timings(&t, &dev_t); | 100 | gpmc_calc_timings(&t, &tusb_sync, &dev_t); |
88 | 101 | ||
89 | return gpmc_cs_set_timings(sync_cs, &t); | 102 | return gpmc_cs_set_timings(sync_cs, &t); |
90 | } | 103 | } |
@@ -165,18 +178,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, | |||
165 | return status; | 178 | return status; |
166 | } | 179 | } |
167 | tusb_resources[0].end = tusb_resources[0].start + 0x9ff; | 180 | tusb_resources[0].end = tusb_resources[0].start + 0x9ff; |
181 | tusb_async.wait_pin = waitpin; | ||
168 | async_cs = async; | 182 | async_cs = async; |
169 | gpmc_cs_write_reg(async, GPMC_CS_CONFIG1, | ||
170 | GPMC_CONFIG1_PAGE_LEN(2) | ||
171 | | GPMC_CONFIG1_WAIT_READ_MON | ||
172 | | GPMC_CONFIG1_WAIT_WRITE_MON | ||
173 | | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin) | ||
174 | | GPMC_CONFIG1_READTYPE_ASYNC | ||
175 | | GPMC_CONFIG1_WRITETYPE_ASYNC | ||
176 | | GPMC_CONFIG1_DEVICESIZE_16 | ||
177 | | GPMC_CONFIG1_DEVICETYPE_NOR | ||
178 | | GPMC_CONFIG1_MUXADDDATA); | ||
179 | 183 | ||
184 | status = gpmc_cs_program_settings(async_cs, &tusb_async); | ||
185 | if (status < 0) | ||
186 | return status; | ||
180 | 187 | ||
181 | /* SYNC region, primarily for DMA */ | 188 | /* SYNC region, primarily for DMA */ |
182 | status = gpmc_cs_request(sync, SZ_16M, (unsigned long *) | 189 | status = gpmc_cs_request(sync, SZ_16M, (unsigned long *) |
@@ -186,21 +193,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, | |||
186 | return status; | 193 | return status; |
187 | } | 194 | } |
188 | tusb_resources[1].end = tusb_resources[1].start + 0x9ff; | 195 | tusb_resources[1].end = tusb_resources[1].start + 0x9ff; |
196 | tusb_sync.wait_pin = waitpin; | ||
189 | sync_cs = sync; | 197 | sync_cs = sync; |
190 | gpmc_cs_write_reg(sync, GPMC_CS_CONFIG1, | 198 | |
191 | GPMC_CONFIG1_READMULTIPLE_SUPP | 199 | status = gpmc_cs_program_settings(sync_cs, &tusb_sync); |
192 | | GPMC_CONFIG1_READTYPE_SYNC | 200 | if (status < 0) |
193 | | GPMC_CONFIG1_WRITEMULTIPLE_SUPP | 201 | return status; |
194 | | GPMC_CONFIG1_WRITETYPE_SYNC | ||
195 | | GPMC_CONFIG1_PAGE_LEN(2) | ||
196 | | GPMC_CONFIG1_WAIT_READ_MON | ||
197 | | GPMC_CONFIG1_WAIT_WRITE_MON | ||
198 | | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin) | ||
199 | | GPMC_CONFIG1_DEVICESIZE_16 | ||
200 | | GPMC_CONFIG1_DEVICETYPE_NOR | ||
201 | | GPMC_CONFIG1_MUXADDDATA | ||
202 | /* fclk divider gets set later */ | ||
203 | ); | ||
204 | 202 | ||
205 | /* IRQ */ | 203 | /* IRQ */ |
206 | status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq"); | 204 | status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq"); |
diff --git a/arch/arm/mach-omap2/usb.h b/arch/arm/mach-omap2/usb.h index 3319f5cf47a3..e7261ebcf7b0 100644 --- a/arch/arm/mach-omap2/usb.h +++ b/arch/arm/mach-omap2/usb.h | |||
@@ -53,8 +53,17 @@ | |||
53 | #define USBPHY_OTGSESSEND_EN (1 << 20) | 53 | #define USBPHY_OTGSESSEND_EN (1 << 20) |
54 | #define USBPHY_DATA_POLARITY (1 << 23) | 54 | #define USBPHY_DATA_POLARITY (1 << 23) |
55 | 55 | ||
56 | struct usbhs_phy_data { | ||
57 | int port; /* 1 indexed port number */ | ||
58 | int reset_gpio; | ||
59 | int vcc_gpio; | ||
60 | bool vcc_polarity; /* 1 active high, 0 active low */ | ||
61 | void *platform_data; | ||
62 | }; | ||
63 | |||
56 | extern void usb_musb_init(struct omap_musb_board_data *board_data); | 64 | extern void usb_musb_init(struct omap_musb_board_data *board_data); |
57 | extern void usbhs_init(struct usbhs_omap_platform_data *pdata); | 65 | extern void usbhs_init(struct usbhs_omap_platform_data *pdata); |
66 | extern int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys); | ||
58 | 67 | ||
59 | extern void am35x_musb_reset(void); | 68 | extern void am35x_musb_reset(void); |
60 | extern void am35x_musb_phy_power(u8 on); | 69 | extern void am35x_musb_phy_power(u8 on); |