diff options
author | Arnd Bergmann <arnd@arndb.de> | 2011-12-27 17:05:29 -0500 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2011-12-27 17:05:29 -0500 |
commit | 9f9f265b0bd407233cfbc61acd64b90ff1da7ba4 (patch) | |
tree | 3ede3c805a85cf3a097cb25abb8caaf050ac42dc | |
parent | 07b98403ee67838bbaded43bd687875b9d7f74e0 (diff) | |
parent | c0ee8cd68ff337fc2a8020f485f7943df4aa9445 (diff) |
Merge branch 'omap/ehci' into next/drivers
* omap/ehci:
MFD: OMAP: USB: Runtime PM support
ARM: OMAP: USBHOST: Replace usbhs core driver APIs by Runtime pm APIs
ARM: OMAP: USB: device name change for the clk names of usbhs
ARM: OMAP: USB: register hwmods of usbhs
-rw-r--r-- | arch/arm/mach-omap2/clock3xxx_data.c | 26 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock44xx_data.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-omap2/usb-host.c | 100 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/usb.h | 3 | ||||
-rw-r--r-- | drivers/mfd/omap-usb-host.c | 755 | ||||
-rw-r--r-- | drivers/usb/host/ehci-omap.c | 17 | ||||
-rw-r--r-- | drivers/usb/host/ohci-omap3.c | 18 |
7 files changed, 369 insertions, 560 deletions
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 4e1b1a2f0537..9d59451446d9 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c | |||
@@ -3297,7 +3297,7 @@ static struct omap_clk omap3xxx_clks[] = { | |||
3297 | CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3297 | CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3298 | CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3298 | CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3299 | CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3299 | CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3300 | CLK("usbhs-omap.0", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3300 | CLK("usbhs_omap", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3301 | CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX), | 3301 | CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX), |
3302 | CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX), | 3302 | CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX), |
3303 | CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX), | 3303 | CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX), |
@@ -3333,7 +3333,7 @@ static struct omap_clk omap3xxx_clks[] = { | |||
3333 | CLK(NULL, "pka_ick", &pka_ick, CK_34XX | CK_36XX), | 3333 | CLK(NULL, "pka_ick", &pka_ick, CK_34XX | CK_36XX), |
3334 | CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX), | 3334 | CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX), |
3335 | CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3335 | CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3336 | CLK("usbhs-omap.0", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3336 | CLK("usbhs_omap", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3337 | CLK("omap_hsmmc.2", "ick", &mmchs3_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3337 | CLK("omap_hsmmc.2", "ick", &mmchs3_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3338 | CLK(NULL, "icr_ick", &icr_ick, CK_34XX | CK_36XX), | 3338 | CLK(NULL, "icr_ick", &icr_ick, CK_34XX | CK_36XX), |
3339 | CLK("omap-aes", "ick", &aes2_ick, CK_34XX | CK_36XX), | 3339 | CLK("omap-aes", "ick", &aes2_ick, CK_34XX | CK_36XX), |
@@ -3379,20 +3379,18 @@ static struct omap_clk omap3xxx_clks[] = { | |||
3379 | CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX), | 3379 | CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX), |
3380 | CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX), | 3380 | CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX), |
3381 | CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3381 | CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3382 | CLK("usbhs-omap.0", "hs_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | ||
3383 | CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3382 | CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3384 | CLK("usbhs-omap.0", "fs_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | ||
3385 | CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3383 | CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3386 | CLK("usbhs-omap.0", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3384 | CLK("usbhs_omap", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3387 | CLK("usbhs-omap.0", "utmi_p1_gfclk", &dummy_ck, CK_3XXX), | 3385 | CLK("usbhs_omap", "utmi_p1_gfclk", &dummy_ck, CK_3XXX), |
3388 | CLK("usbhs-omap.0", "utmi_p2_gfclk", &dummy_ck, CK_3XXX), | 3386 | CLK("usbhs_omap", "utmi_p2_gfclk", &dummy_ck, CK_3XXX), |
3389 | CLK("usbhs-omap.0", "xclk60mhsp1_ck", &dummy_ck, CK_3XXX), | 3387 | CLK("usbhs_omap", "xclk60mhsp1_ck", &dummy_ck, CK_3XXX), |
3390 | CLK("usbhs-omap.0", "xclk60mhsp2_ck", &dummy_ck, CK_3XXX), | 3388 | CLK("usbhs_omap", "xclk60mhsp2_ck", &dummy_ck, CK_3XXX), |
3391 | CLK("usbhs-omap.0", "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX), | 3389 | CLK("usbhs_omap", "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX), |
3392 | CLK("usbhs-omap.0", "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX), | 3390 | CLK("usbhs_omap", "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX), |
3393 | CLK("usbhs-omap.0", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX), | 3391 | CLK("usbhs_omap", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX), |
3394 | CLK("usbhs-omap.0", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX), | 3392 | CLK("usbhs_omap", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX), |
3395 | CLK("usbhs-omap.0", "init_60m_fclk", &dummy_ck, CK_3XXX), | 3393 | CLK("usbhs_omap", "init_60m_fclk", &dummy_ck, CK_3XXX), |
3396 | CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2PLUS | CK_36XX), | 3394 | CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2PLUS | CK_36XX), |
3397 | CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX), | 3395 | CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX), |
3398 | CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX), | 3396 | CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX), |
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index 0798a802497a..c8a1b2740778 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c | |||
@@ -3295,7 +3295,7 @@ static struct omap_clk omap44xx_clks[] = { | |||
3295 | CLK(NULL, "uart2_fck", &uart2_fck, CK_443X), | 3295 | CLK(NULL, "uart2_fck", &uart2_fck, CK_443X), |
3296 | CLK(NULL, "uart3_fck", &uart3_fck, CK_443X), | 3296 | CLK(NULL, "uart3_fck", &uart3_fck, CK_443X), |
3297 | CLK(NULL, "uart4_fck", &uart4_fck, CK_443X), | 3297 | CLK(NULL, "uart4_fck", &uart4_fck, CK_443X), |
3298 | CLK("usbhs-omap.0", "fs_fck", &usb_host_fs_fck, CK_443X), | 3298 | CLK("usbhs_omap", "fs_fck", &usb_host_fs_fck, CK_443X), |
3299 | CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X), | 3299 | CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X), |
3300 | CLK(NULL, "usb_host_hs_utmi_p1_clk", &usb_host_hs_utmi_p1_clk, CK_443X), | 3300 | CLK(NULL, "usb_host_hs_utmi_p1_clk", &usb_host_hs_utmi_p1_clk, CK_443X), |
3301 | CLK(NULL, "utmi_p2_gfclk", &utmi_p2_gfclk, CK_443X), | 3301 | CLK(NULL, "utmi_p2_gfclk", &utmi_p2_gfclk, CK_443X), |
@@ -3306,7 +3306,7 @@ static struct omap_clk omap44xx_clks[] = { | |||
3306 | CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_443X), | 3306 | CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_443X), |
3307 | CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X), | 3307 | CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X), |
3308 | CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X), | 3308 | CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X), |
3309 | CLK("usbhs-omap.0", "hs_fck", &usb_host_hs_fck, CK_443X), | 3309 | CLK("usbhs_omap", "hs_fck", &usb_host_hs_fck, CK_443X), |
3310 | CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_443X), | 3310 | CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_443X), |
3311 | CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_443X), | 3311 | CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_443X), |
3312 | CLK("musb-omap2430", "ick", &usb_otg_hs_ick, CK_443X), | 3312 | CLK("musb-omap2430", "ick", &usb_otg_hs_ick, CK_443X), |
@@ -3314,7 +3314,7 @@ static struct omap_clk omap44xx_clks[] = { | |||
3314 | CLK(NULL, "usb_tll_hs_usb_ch2_clk", &usb_tll_hs_usb_ch2_clk, CK_443X), | 3314 | CLK(NULL, "usb_tll_hs_usb_ch2_clk", &usb_tll_hs_usb_ch2_clk, CK_443X), |
3315 | CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_443X), | 3315 | CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_443X), |
3316 | CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_443X), | 3316 | CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_443X), |
3317 | CLK("usbhs-omap.0", "usbtll_ick", &usb_tll_hs_ick, CK_443X), | 3317 | CLK("usbhs_omap", "usbtll_ick", &usb_tll_hs_ick, CK_443X), |
3318 | CLK(NULL, "usim_ck", &usim_ck, CK_443X), | 3318 | CLK(NULL, "usim_ck", &usim_ck, CK_443X), |
3319 | CLK(NULL, "usim_fclk", &usim_fclk, CK_443X), | 3319 | CLK(NULL, "usim_fclk", &usim_fclk, CK_443X), |
3320 | CLK(NULL, "usim_fck", &usim_fck, CK_443X), | 3320 | CLK(NULL, "usim_fck", &usim_fck, CK_443X), |
@@ -3374,8 +3374,8 @@ static struct omap_clk omap44xx_clks[] = { | |||
3374 | CLK(NULL, "uart2_ick", &dummy_ck, CK_443X), | 3374 | CLK(NULL, "uart2_ick", &dummy_ck, CK_443X), |
3375 | CLK(NULL, "uart3_ick", &dummy_ck, CK_443X), | 3375 | CLK(NULL, "uart3_ick", &dummy_ck, CK_443X), |
3376 | CLK(NULL, "uart4_ick", &dummy_ck, CK_443X), | 3376 | CLK(NULL, "uart4_ick", &dummy_ck, CK_443X), |
3377 | CLK("usbhs-omap.0", "usbhost_ick", &dummy_ck, CK_443X), | 3377 | CLK("usbhs_omap", "usbhost_ick", &dummy_ck, CK_443X), |
3378 | CLK("usbhs-omap.0", "usbtll_fck", &dummy_ck, CK_443X), | 3378 | CLK("usbhs_omap", "usbtll_fck", &dummy_ck, CK_443X), |
3379 | CLK("omap_wdt", "ick", &dummy_ck, CK_443X), | 3379 | CLK("omap_wdt", "ick", &dummy_ck, CK_443X), |
3380 | CLK("omap_timer.1", "32k_ck", &sys_32k_ck, CK_443X), | 3380 | CLK("omap_timer.1", "32k_ck", &sys_32k_ck, CK_443X), |
3381 | CLK("omap_timer.2", "32k_ck", &sys_32k_ck, CK_443X), | 3381 | CLK("omap_timer.2", "32k_ck", &sys_32k_ck, CK_443X), |
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c index 89ae29847c59..771dc781b746 100644 --- a/arch/arm/mach-omap2/usb-host.c +++ b/arch/arm/mach-omap2/usb-host.c | |||
@@ -28,51 +28,28 @@ | |||
28 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
29 | #include <mach/irqs.h> | 29 | #include <mach/irqs.h> |
30 | #include <plat/usb.h> | 30 | #include <plat/usb.h> |
31 | #include <plat/omap_device.h> | ||
31 | 32 | ||
32 | #include "mux.h" | 33 | #include "mux.h" |
33 | 34 | ||
34 | #ifdef CONFIG_MFD_OMAP_USB_HOST | 35 | #ifdef CONFIG_MFD_OMAP_USB_HOST |
35 | 36 | ||
36 | #define OMAP_USBHS_DEVICE "usbhs-omap" | 37 | #define OMAP_USBHS_DEVICE "usbhs_omap" |
37 | 38 | #define USBHS_UHH_HWMODNAME "usb_host_hs" | |
38 | static struct resource usbhs_resources[] = { | 39 | #define USBHS_TLL_HWMODNAME "usb_tll_hs" |
39 | { | ||
40 | .name = "uhh", | ||
41 | .flags = IORESOURCE_MEM, | ||
42 | }, | ||
43 | { | ||
44 | .name = "tll", | ||
45 | .flags = IORESOURCE_MEM, | ||
46 | }, | ||
47 | { | ||
48 | .name = "ehci", | ||
49 | .flags = IORESOURCE_MEM, | ||
50 | }, | ||
51 | { | ||
52 | .name = "ehci-irq", | ||
53 | .flags = IORESOURCE_IRQ, | ||
54 | }, | ||
55 | { | ||
56 | .name = "ohci", | ||
57 | .flags = IORESOURCE_MEM, | ||
58 | }, | ||
59 | { | ||
60 | .name = "ohci-irq", | ||
61 | .flags = IORESOURCE_IRQ, | ||
62 | } | ||
63 | }; | ||
64 | |||
65 | static struct platform_device usbhs_device = { | ||
66 | .name = OMAP_USBHS_DEVICE, | ||
67 | .id = 0, | ||
68 | .num_resources = ARRAY_SIZE(usbhs_resources), | ||
69 | .resource = usbhs_resources, | ||
70 | }; | ||
71 | 40 | ||
72 | static struct usbhs_omap_platform_data usbhs_data; | 41 | static struct usbhs_omap_platform_data usbhs_data; |
73 | static struct ehci_hcd_omap_platform_data ehci_data; | 42 | static struct ehci_hcd_omap_platform_data ehci_data; |
74 | static struct ohci_hcd_omap_platform_data ohci_data; | 43 | static struct ohci_hcd_omap_platform_data ohci_data; |
75 | 44 | ||
45 | static struct omap_device_pm_latency omap_uhhtll_latency[] = { | ||
46 | { | ||
47 | .deactivate_func = omap_device_idle_hwmods, | ||
48 | .activate_func = omap_device_enable_hwmods, | ||
49 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
50 | }, | ||
51 | }; | ||
52 | |||
76 | /* MUX settings for EHCI pins */ | 53 | /* MUX settings for EHCI pins */ |
77 | /* | 54 | /* |
78 | * setup_ehci_io_mux - initialize IO pad mux for USBHOST | 55 | * setup_ehci_io_mux - initialize IO pad mux for USBHOST |
@@ -508,7 +485,10 @@ static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) | |||
508 | 485 | ||
509 | void __init usbhs_init(const struct usbhs_omap_board_data *pdata) | 486 | void __init usbhs_init(const struct usbhs_omap_board_data *pdata) |
510 | { | 487 | { |
511 | int i; | 488 | struct omap_hwmod *oh[2]; |
489 | struct omap_device *od; | ||
490 | int bus_id = -1; | ||
491 | int i; | ||
512 | 492 | ||
513 | for (i = 0; i < OMAP3_HS_USB_PORTS; i++) { | 493 | for (i = 0; i < OMAP3_HS_USB_PORTS; i++) { |
514 | usbhs_data.port_mode[i] = pdata->port_mode[i]; | 494 | usbhs_data.port_mode[i] = pdata->port_mode[i]; |
@@ -523,44 +503,34 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata) | |||
523 | usbhs_data.ohci_data = &ohci_data; | 503 | usbhs_data.ohci_data = &ohci_data; |
524 | 504 | ||
525 | if (cpu_is_omap34xx()) { | 505 | if (cpu_is_omap34xx()) { |
526 | usbhs_resources[0].start = OMAP34XX_UHH_CONFIG_BASE; | ||
527 | usbhs_resources[0].end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1; | ||
528 | usbhs_resources[1].start = OMAP34XX_USBTLL_BASE; | ||
529 | usbhs_resources[1].end = OMAP34XX_USBTLL_BASE + SZ_4K - 1; | ||
530 | usbhs_resources[2].start = OMAP34XX_EHCI_BASE; | ||
531 | usbhs_resources[2].end = OMAP34XX_EHCI_BASE + SZ_1K - 1; | ||
532 | usbhs_resources[3].start = INT_34XX_EHCI_IRQ; | ||
533 | usbhs_resources[4].start = OMAP34XX_OHCI_BASE; | ||
534 | usbhs_resources[4].end = OMAP34XX_OHCI_BASE + SZ_1K - 1; | ||
535 | usbhs_resources[5].start = INT_34XX_OHCI_IRQ; | ||
536 | setup_ehci_io_mux(pdata->port_mode); | 506 | setup_ehci_io_mux(pdata->port_mode); |
537 | setup_ohci_io_mux(pdata->port_mode); | 507 | setup_ohci_io_mux(pdata->port_mode); |
538 | } else if (cpu_is_omap44xx()) { | 508 | } else if (cpu_is_omap44xx()) { |
539 | usbhs_resources[0].start = OMAP44XX_UHH_CONFIG_BASE; | ||
540 | usbhs_resources[0].end = OMAP44XX_UHH_CONFIG_BASE + SZ_1K - 1; | ||
541 | usbhs_resources[1].start = OMAP44XX_USBTLL_BASE; | ||
542 | usbhs_resources[1].end = OMAP44XX_USBTLL_BASE + SZ_4K - 1; | ||
543 | usbhs_resources[2].start = OMAP44XX_HSUSB_EHCI_BASE; | ||
544 | usbhs_resources[2].end = OMAP44XX_HSUSB_EHCI_BASE + SZ_1K - 1; | ||
545 | usbhs_resources[3].start = OMAP44XX_IRQ_EHCI; | ||
546 | usbhs_resources[4].start = OMAP44XX_HSUSB_OHCI_BASE; | ||
547 | usbhs_resources[4].end = OMAP44XX_HSUSB_OHCI_BASE + SZ_1K - 1; | ||
548 | usbhs_resources[5].start = OMAP44XX_IRQ_OHCI; | ||
549 | setup_4430ehci_io_mux(pdata->port_mode); | 509 | setup_4430ehci_io_mux(pdata->port_mode); |
550 | setup_4430ohci_io_mux(pdata->port_mode); | 510 | setup_4430ohci_io_mux(pdata->port_mode); |
551 | } | 511 | } |
552 | 512 | ||
553 | if (platform_device_add_data(&usbhs_device, | 513 | oh[0] = omap_hwmod_lookup(USBHS_UHH_HWMODNAME); |
554 | &usbhs_data, sizeof(usbhs_data)) < 0) { | 514 | if (!oh[0]) { |
555 | printk(KERN_ERR "USBHS platform_device_add_data failed\n"); | 515 | pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME); |
556 | goto init_end; | 516 | return; |
557 | } | 517 | } |
558 | 518 | ||
559 | if (platform_device_register(&usbhs_device) < 0) | 519 | oh[1] = omap_hwmod_lookup(USBHS_TLL_HWMODNAME); |
560 | printk(KERN_ERR "USBHS platform_device_register failed\n"); | 520 | if (!oh[1]) { |
521 | pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME); | ||
522 | return; | ||
523 | } | ||
561 | 524 | ||
562 | init_end: | 525 | od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2, |
563 | return; | 526 | (void *)&usbhs_data, sizeof(usbhs_data), |
527 | omap_uhhtll_latency, | ||
528 | ARRAY_SIZE(omap_uhhtll_latency), false); | ||
529 | if (IS_ERR(od)) { | ||
530 | pr_err("Could not build hwmod devices %s,%s\n", | ||
531 | USBHS_UHH_HWMODNAME, USBHS_TLL_HWMODNAME); | ||
532 | return; | ||
533 | } | ||
564 | } | 534 | } |
565 | 535 | ||
566 | #else | 536 | #else |
@@ -570,5 +540,3 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata) | |||
570 | } | 540 | } |
571 | 541 | ||
572 | #endif | 542 | #endif |
573 | |||
574 | |||
diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index 17d3c939775c..2b66dc266bcf 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h | |||
@@ -100,9 +100,6 @@ extern void usb_musb_init(struct omap_musb_board_data *board_data); | |||
100 | 100 | ||
101 | extern void usbhs_init(const struct usbhs_omap_board_data *pdata); | 101 | extern void usbhs_init(const struct usbhs_omap_board_data *pdata); |
102 | 102 | ||
103 | extern int omap_usbhs_enable(struct device *dev); | ||
104 | extern void omap_usbhs_disable(struct device *dev); | ||
105 | |||
106 | extern int omap4430_phy_power(struct device *dev, int ID, int on); | 103 | extern int omap4430_phy_power(struct device *dev, int ID, int on); |
107 | extern int omap4430_phy_set_clk(struct device *dev, int on); | 104 | extern int omap4430_phy_set_clk(struct device *dev, int on); |
108 | extern int omap4430_phy_init(struct device *dev); | 105 | extern int omap4430_phy_init(struct device *dev); |
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 86e14583a082..3f565ef3e149 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c | |||
@@ -27,8 +27,9 @@ | |||
27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
29 | #include <plat/usb.h> | 29 | #include <plat/usb.h> |
30 | #include <linux/pm_runtime.h> | ||
30 | 31 | ||
31 | #define USBHS_DRIVER_NAME "usbhs-omap" | 32 | #define USBHS_DRIVER_NAME "usbhs_omap" |
32 | #define OMAP_EHCI_DEVICE "ehci-omap" | 33 | #define OMAP_EHCI_DEVICE "ehci-omap" |
33 | #define OMAP_OHCI_DEVICE "ohci-omap3" | 34 | #define OMAP_OHCI_DEVICE "ohci-omap3" |
34 | 35 | ||
@@ -147,9 +148,6 @@ | |||
147 | 148 | ||
148 | 149 | ||
149 | struct usbhs_hcd_omap { | 150 | struct usbhs_hcd_omap { |
150 | struct clk *usbhost_ick; | ||
151 | struct clk *usbhost_hs_fck; | ||
152 | struct clk *usbhost_fs_fck; | ||
153 | struct clk *xclk60mhsp1_ck; | 151 | struct clk *xclk60mhsp1_ck; |
154 | struct clk *xclk60mhsp2_ck; | 152 | struct clk *xclk60mhsp2_ck; |
155 | struct clk *utmi_p1_fck; | 153 | struct clk *utmi_p1_fck; |
@@ -159,8 +157,7 @@ struct usbhs_hcd_omap { | |||
159 | struct clk *usbhost_p2_fck; | 157 | struct clk *usbhost_p2_fck; |
160 | struct clk *usbtll_p2_fck; | 158 | struct clk *usbtll_p2_fck; |
161 | struct clk *init_60m_fclk; | 159 | struct clk *init_60m_fclk; |
162 | struct clk *usbtll_fck; | 160 | struct clk *ehci_logic_fck; |
163 | struct clk *usbtll_ick; | ||
164 | 161 | ||
165 | void __iomem *uhh_base; | 162 | void __iomem *uhh_base; |
166 | void __iomem *tll_base; | 163 | void __iomem *tll_base; |
@@ -169,7 +166,6 @@ struct usbhs_hcd_omap { | |||
169 | 166 | ||
170 | u32 usbhs_rev; | 167 | u32 usbhs_rev; |
171 | spinlock_t lock; | 168 | spinlock_t lock; |
172 | int count; | ||
173 | }; | 169 | }; |
174 | /*-------------------------------------------------------------------------*/ | 170 | /*-------------------------------------------------------------------------*/ |
175 | 171 | ||
@@ -319,269 +315,6 @@ err_end: | |||
319 | return ret; | 315 | return ret; |
320 | } | 316 | } |
321 | 317 | ||
322 | /** | ||
323 | * usbhs_omap_probe - initialize TI-based HCDs | ||
324 | * | ||
325 | * Allocates basic resources for this USB host controller. | ||
326 | */ | ||
327 | static int __devinit usbhs_omap_probe(struct platform_device *pdev) | ||
328 | { | ||
329 | struct device *dev = &pdev->dev; | ||
330 | struct usbhs_omap_platform_data *pdata = dev->platform_data; | ||
331 | struct usbhs_hcd_omap *omap; | ||
332 | struct resource *res; | ||
333 | int ret = 0; | ||
334 | int i; | ||
335 | |||
336 | if (!pdata) { | ||
337 | dev_err(dev, "Missing platform data\n"); | ||
338 | ret = -ENOMEM; | ||
339 | goto end_probe; | ||
340 | } | ||
341 | |||
342 | omap = kzalloc(sizeof(*omap), GFP_KERNEL); | ||
343 | if (!omap) { | ||
344 | dev_err(dev, "Memory allocation failed\n"); | ||
345 | ret = -ENOMEM; | ||
346 | goto end_probe; | ||
347 | } | ||
348 | |||
349 | spin_lock_init(&omap->lock); | ||
350 | |||
351 | for (i = 0; i < OMAP3_HS_USB_PORTS; i++) | ||
352 | omap->platdata.port_mode[i] = pdata->port_mode[i]; | ||
353 | |||
354 | omap->platdata.ehci_data = pdata->ehci_data; | ||
355 | omap->platdata.ohci_data = pdata->ohci_data; | ||
356 | |||
357 | omap->usbhost_ick = clk_get(dev, "usbhost_ick"); | ||
358 | if (IS_ERR(omap->usbhost_ick)) { | ||
359 | ret = PTR_ERR(omap->usbhost_ick); | ||
360 | dev_err(dev, "usbhost_ick failed error:%d\n", ret); | ||
361 | goto err_end; | ||
362 | } | ||
363 | |||
364 | omap->usbhost_hs_fck = clk_get(dev, "hs_fck"); | ||
365 | if (IS_ERR(omap->usbhost_hs_fck)) { | ||
366 | ret = PTR_ERR(omap->usbhost_hs_fck); | ||
367 | dev_err(dev, "usbhost_hs_fck failed error:%d\n", ret); | ||
368 | goto err_usbhost_ick; | ||
369 | } | ||
370 | |||
371 | omap->usbhost_fs_fck = clk_get(dev, "fs_fck"); | ||
372 | if (IS_ERR(omap->usbhost_fs_fck)) { | ||
373 | ret = PTR_ERR(omap->usbhost_fs_fck); | ||
374 | dev_err(dev, "usbhost_fs_fck failed error:%d\n", ret); | ||
375 | goto err_usbhost_hs_fck; | ||
376 | } | ||
377 | |||
378 | omap->usbtll_fck = clk_get(dev, "usbtll_fck"); | ||
379 | if (IS_ERR(omap->usbtll_fck)) { | ||
380 | ret = PTR_ERR(omap->usbtll_fck); | ||
381 | dev_err(dev, "usbtll_fck failed error:%d\n", ret); | ||
382 | goto err_usbhost_fs_fck; | ||
383 | } | ||
384 | |||
385 | omap->usbtll_ick = clk_get(dev, "usbtll_ick"); | ||
386 | if (IS_ERR(omap->usbtll_ick)) { | ||
387 | ret = PTR_ERR(omap->usbtll_ick); | ||
388 | dev_err(dev, "usbtll_ick failed error:%d\n", ret); | ||
389 | goto err_usbtll_fck; | ||
390 | } | ||
391 | |||
392 | omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); | ||
393 | if (IS_ERR(omap->utmi_p1_fck)) { | ||
394 | ret = PTR_ERR(omap->utmi_p1_fck); | ||
395 | dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); | ||
396 | goto err_usbtll_ick; | ||
397 | } | ||
398 | |||
399 | omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); | ||
400 | if (IS_ERR(omap->xclk60mhsp1_ck)) { | ||
401 | ret = PTR_ERR(omap->xclk60mhsp1_ck); | ||
402 | dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); | ||
403 | goto err_utmi_p1_fck; | ||
404 | } | ||
405 | |||
406 | omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk"); | ||
407 | if (IS_ERR(omap->utmi_p2_fck)) { | ||
408 | ret = PTR_ERR(omap->utmi_p2_fck); | ||
409 | dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); | ||
410 | goto err_xclk60mhsp1_ck; | ||
411 | } | ||
412 | |||
413 | omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); | ||
414 | if (IS_ERR(omap->xclk60mhsp2_ck)) { | ||
415 | ret = PTR_ERR(omap->xclk60mhsp2_ck); | ||
416 | dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); | ||
417 | goto err_utmi_p2_fck; | ||
418 | } | ||
419 | |||
420 | omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk"); | ||
421 | if (IS_ERR(omap->usbhost_p1_fck)) { | ||
422 | ret = PTR_ERR(omap->usbhost_p1_fck); | ||
423 | dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret); | ||
424 | goto err_xclk60mhsp2_ck; | ||
425 | } | ||
426 | |||
427 | omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk"); | ||
428 | if (IS_ERR(omap->usbtll_p1_fck)) { | ||
429 | ret = PTR_ERR(omap->usbtll_p1_fck); | ||
430 | dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret); | ||
431 | goto err_usbhost_p1_fck; | ||
432 | } | ||
433 | |||
434 | omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk"); | ||
435 | if (IS_ERR(omap->usbhost_p2_fck)) { | ||
436 | ret = PTR_ERR(omap->usbhost_p2_fck); | ||
437 | dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret); | ||
438 | goto err_usbtll_p1_fck; | ||
439 | } | ||
440 | |||
441 | omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk"); | ||
442 | if (IS_ERR(omap->usbtll_p2_fck)) { | ||
443 | ret = PTR_ERR(omap->usbtll_p2_fck); | ||
444 | dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret); | ||
445 | goto err_usbhost_p2_fck; | ||
446 | } | ||
447 | |||
448 | omap->init_60m_fclk = clk_get(dev, "init_60m_fclk"); | ||
449 | if (IS_ERR(omap->init_60m_fclk)) { | ||
450 | ret = PTR_ERR(omap->init_60m_fclk); | ||
451 | dev_err(dev, "init_60m_fclk failed error:%d\n", ret); | ||
452 | goto err_usbtll_p2_fck; | ||
453 | } | ||
454 | |||
455 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh"); | ||
456 | if (!res) { | ||
457 | dev_err(dev, "UHH EHCI get resource failed\n"); | ||
458 | ret = -ENODEV; | ||
459 | goto err_init_60m_fclk; | ||
460 | } | ||
461 | |||
462 | omap->uhh_base = ioremap(res->start, resource_size(res)); | ||
463 | if (!omap->uhh_base) { | ||
464 | dev_err(dev, "UHH ioremap failed\n"); | ||
465 | ret = -ENOMEM; | ||
466 | goto err_init_60m_fclk; | ||
467 | } | ||
468 | |||
469 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll"); | ||
470 | if (!res) { | ||
471 | dev_err(dev, "UHH EHCI get resource failed\n"); | ||
472 | ret = -ENODEV; | ||
473 | goto err_tll; | ||
474 | } | ||
475 | |||
476 | omap->tll_base = ioremap(res->start, resource_size(res)); | ||
477 | if (!omap->tll_base) { | ||
478 | dev_err(dev, "TLL ioremap failed\n"); | ||
479 | ret = -ENOMEM; | ||
480 | goto err_tll; | ||
481 | } | ||
482 | |||
483 | platform_set_drvdata(pdev, omap); | ||
484 | |||
485 | ret = omap_usbhs_alloc_children(pdev); | ||
486 | if (ret) { | ||
487 | dev_err(dev, "omap_usbhs_alloc_children failed\n"); | ||
488 | goto err_alloc; | ||
489 | } | ||
490 | |||
491 | goto end_probe; | ||
492 | |||
493 | err_alloc: | ||
494 | iounmap(omap->tll_base); | ||
495 | |||
496 | err_tll: | ||
497 | iounmap(omap->uhh_base); | ||
498 | |||
499 | err_init_60m_fclk: | ||
500 | clk_put(omap->init_60m_fclk); | ||
501 | |||
502 | err_usbtll_p2_fck: | ||
503 | clk_put(omap->usbtll_p2_fck); | ||
504 | |||
505 | err_usbhost_p2_fck: | ||
506 | clk_put(omap->usbhost_p2_fck); | ||
507 | |||
508 | err_usbtll_p1_fck: | ||
509 | clk_put(omap->usbtll_p1_fck); | ||
510 | |||
511 | err_usbhost_p1_fck: | ||
512 | clk_put(omap->usbhost_p1_fck); | ||
513 | |||
514 | err_xclk60mhsp2_ck: | ||
515 | clk_put(omap->xclk60mhsp2_ck); | ||
516 | |||
517 | err_utmi_p2_fck: | ||
518 | clk_put(omap->utmi_p2_fck); | ||
519 | |||
520 | err_xclk60mhsp1_ck: | ||
521 | clk_put(omap->xclk60mhsp1_ck); | ||
522 | |||
523 | err_utmi_p1_fck: | ||
524 | clk_put(omap->utmi_p1_fck); | ||
525 | |||
526 | err_usbtll_ick: | ||
527 | clk_put(omap->usbtll_ick); | ||
528 | |||
529 | err_usbtll_fck: | ||
530 | clk_put(omap->usbtll_fck); | ||
531 | |||
532 | err_usbhost_fs_fck: | ||
533 | clk_put(omap->usbhost_fs_fck); | ||
534 | |||
535 | err_usbhost_hs_fck: | ||
536 | clk_put(omap->usbhost_hs_fck); | ||
537 | |||
538 | err_usbhost_ick: | ||
539 | clk_put(omap->usbhost_ick); | ||
540 | |||
541 | err_end: | ||
542 | kfree(omap); | ||
543 | |||
544 | end_probe: | ||
545 | return ret; | ||
546 | } | ||
547 | |||
548 | /** | ||
549 | * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs | ||
550 | * @pdev: USB Host Controller being removed | ||
551 | * | ||
552 | * Reverses the effect of usbhs_omap_probe(). | ||
553 | */ | ||
554 | static int __devexit usbhs_omap_remove(struct platform_device *pdev) | ||
555 | { | ||
556 | struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); | ||
557 | |||
558 | if (omap->count != 0) { | ||
559 | dev_err(&pdev->dev, | ||
560 | "Either EHCI or OHCI is still using usbhs core\n"); | ||
561 | return -EBUSY; | ||
562 | } | ||
563 | |||
564 | iounmap(omap->tll_base); | ||
565 | iounmap(omap->uhh_base); | ||
566 | clk_put(omap->init_60m_fclk); | ||
567 | clk_put(omap->usbtll_p2_fck); | ||
568 | clk_put(omap->usbhost_p2_fck); | ||
569 | clk_put(omap->usbtll_p1_fck); | ||
570 | clk_put(omap->usbhost_p1_fck); | ||
571 | clk_put(omap->xclk60mhsp2_ck); | ||
572 | clk_put(omap->utmi_p2_fck); | ||
573 | clk_put(omap->xclk60mhsp1_ck); | ||
574 | clk_put(omap->utmi_p1_fck); | ||
575 | clk_put(omap->usbtll_ick); | ||
576 | clk_put(omap->usbtll_fck); | ||
577 | clk_put(omap->usbhost_fs_fck); | ||
578 | clk_put(omap->usbhost_hs_fck); | ||
579 | clk_put(omap->usbhost_ick); | ||
580 | kfree(omap); | ||
581 | |||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | static bool is_ohci_port(enum usbhs_omap_port_mode pmode) | 318 | static bool is_ohci_port(enum usbhs_omap_port_mode pmode) |
586 | { | 319 | { |
587 | switch (pmode) { | 320 | switch (pmode) { |
@@ -689,30 +422,85 @@ static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count) | |||
689 | } | 422 | } |
690 | } | 423 | } |
691 | 424 | ||
692 | static int usbhs_enable(struct device *dev) | 425 | static int usbhs_runtime_resume(struct device *dev) |
693 | { | 426 | { |
694 | struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); | 427 | struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); |
695 | struct usbhs_omap_platform_data *pdata = &omap->platdata; | 428 | struct usbhs_omap_platform_data *pdata = &omap->platdata; |
696 | unsigned long flags = 0; | 429 | unsigned long flags; |
697 | int ret = 0; | 430 | |
698 | unsigned long timeout; | 431 | dev_dbg(dev, "usbhs_runtime_resume\n"); |
699 | unsigned reg; | ||
700 | 432 | ||
701 | dev_dbg(dev, "starting TI HSUSB Controller\n"); | ||
702 | if (!pdata) { | 433 | if (!pdata) { |
703 | dev_dbg(dev, "missing platform_data\n"); | 434 | dev_dbg(dev, "missing platform_data\n"); |
704 | return -ENODEV; | 435 | return -ENODEV; |
705 | } | 436 | } |
706 | 437 | ||
707 | spin_lock_irqsave(&omap->lock, flags); | 438 | spin_lock_irqsave(&omap->lock, flags); |
708 | if (omap->count > 0) | ||
709 | goto end_count; | ||
710 | 439 | ||
711 | clk_enable(omap->usbhost_ick); | 440 | if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck)) |
712 | clk_enable(omap->usbhost_hs_fck); | 441 | clk_enable(omap->ehci_logic_fck); |
713 | clk_enable(omap->usbhost_fs_fck); | 442 | |
714 | clk_enable(omap->usbtll_fck); | 443 | if (is_ehci_tll_mode(pdata->port_mode[0])) { |
715 | clk_enable(omap->usbtll_ick); | 444 | clk_enable(omap->usbhost_p1_fck); |
445 | clk_enable(omap->usbtll_p1_fck); | ||
446 | } | ||
447 | if (is_ehci_tll_mode(pdata->port_mode[1])) { | ||
448 | clk_enable(omap->usbhost_p2_fck); | ||
449 | clk_enable(omap->usbtll_p2_fck); | ||
450 | } | ||
451 | clk_enable(omap->utmi_p1_fck); | ||
452 | clk_enable(omap->utmi_p2_fck); | ||
453 | |||
454 | spin_unlock_irqrestore(&omap->lock, flags); | ||
455 | |||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | static int usbhs_runtime_suspend(struct device *dev) | ||
460 | { | ||
461 | struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); | ||
462 | struct usbhs_omap_platform_data *pdata = &omap->platdata; | ||
463 | unsigned long flags; | ||
464 | |||
465 | dev_dbg(dev, "usbhs_runtime_suspend\n"); | ||
466 | |||
467 | if (!pdata) { | ||
468 | dev_dbg(dev, "missing platform_data\n"); | ||
469 | return -ENODEV; | ||
470 | } | ||
471 | |||
472 | spin_lock_irqsave(&omap->lock, flags); | ||
473 | |||
474 | if (is_ehci_tll_mode(pdata->port_mode[0])) { | ||
475 | clk_disable(omap->usbhost_p1_fck); | ||
476 | clk_disable(omap->usbtll_p1_fck); | ||
477 | } | ||
478 | if (is_ehci_tll_mode(pdata->port_mode[1])) { | ||
479 | clk_disable(omap->usbhost_p2_fck); | ||
480 | clk_disable(omap->usbtll_p2_fck); | ||
481 | } | ||
482 | clk_disable(omap->utmi_p2_fck); | ||
483 | clk_disable(omap->utmi_p1_fck); | ||
484 | |||
485 | if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck)) | ||
486 | clk_disable(omap->ehci_logic_fck); | ||
487 | |||
488 | spin_unlock_irqrestore(&omap->lock, flags); | ||
489 | |||
490 | return 0; | ||
491 | } | ||
492 | |||
493 | static void omap_usbhs_init(struct device *dev) | ||
494 | { | ||
495 | struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); | ||
496 | struct usbhs_omap_platform_data *pdata = &omap->platdata; | ||
497 | unsigned long flags; | ||
498 | unsigned reg; | ||
499 | |||
500 | dev_dbg(dev, "starting TI HSUSB Controller\n"); | ||
501 | |||
502 | pm_runtime_get_sync(dev); | ||
503 | spin_lock_irqsave(&omap->lock, flags); | ||
716 | 504 | ||
717 | if (pdata->ehci_data->phy_reset) { | 505 | if (pdata->ehci_data->phy_reset) { |
718 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) { | 506 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) { |
@@ -736,50 +524,6 @@ static int usbhs_enable(struct device *dev) | |||
736 | omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); | 524 | omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); |
737 | dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); | 525 | dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); |
738 | 526 | ||
739 | /* perform TLL soft reset, and wait until reset is complete */ | ||
740 | usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, | ||
741 | OMAP_USBTLL_SYSCONFIG_SOFTRESET); | ||
742 | |||
743 | /* Wait for TLL reset to complete */ | ||
744 | timeout = jiffies + msecs_to_jiffies(1000); | ||
745 | while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS) | ||
746 | & OMAP_USBTLL_SYSSTATUS_RESETDONE)) { | ||
747 | cpu_relax(); | ||
748 | |||
749 | if (time_after(jiffies, timeout)) { | ||
750 | dev_dbg(dev, "operation timed out\n"); | ||
751 | ret = -EINVAL; | ||
752 | goto err_tll; | ||
753 | } | ||
754 | } | ||
755 | |||
756 | dev_dbg(dev, "TLL RESET DONE\n"); | ||
757 | |||
758 | /* (1<<3) = no idle mode only for initial debugging */ | ||
759 | usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, | ||
760 | OMAP_USBTLL_SYSCONFIG_ENAWAKEUP | | ||
761 | OMAP_USBTLL_SYSCONFIG_SIDLEMODE | | ||
762 | OMAP_USBTLL_SYSCONFIG_AUTOIDLE); | ||
763 | |||
764 | /* Put UHH in NoIdle/NoStandby mode */ | ||
765 | reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG); | ||
766 | if (is_omap_usbhs_rev1(omap)) { | ||
767 | reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP | ||
768 | | OMAP_UHH_SYSCONFIG_SIDLEMODE | ||
769 | | OMAP_UHH_SYSCONFIG_CACTIVITY | ||
770 | | OMAP_UHH_SYSCONFIG_MIDLEMODE); | ||
771 | reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; | ||
772 | |||
773 | |||
774 | } else if (is_omap_usbhs_rev2(omap)) { | ||
775 | reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR; | ||
776 | reg |= OMAP4_UHH_SYSCONFIG_NOIDLE; | ||
777 | reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR; | ||
778 | reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY; | ||
779 | } | ||
780 | |||
781 | usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); | ||
782 | |||
783 | reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG); | 527 | reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG); |
784 | /* setup ULPI bypass and burst configurations */ | 528 | /* setup ULPI bypass and burst configurations */ |
785 | reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN | 529 | reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN |
@@ -825,49 +569,6 @@ static int usbhs_enable(struct device *dev) | |||
825 | reg &= ~OMAP4_P1_MODE_CLEAR; | 569 | reg &= ~OMAP4_P1_MODE_CLEAR; |
826 | reg &= ~OMAP4_P2_MODE_CLEAR; | 570 | reg &= ~OMAP4_P2_MODE_CLEAR; |
827 | 571 | ||
828 | if (is_ehci_phy_mode(pdata->port_mode[0])) { | ||
829 | ret = clk_set_parent(omap->utmi_p1_fck, | ||
830 | omap->xclk60mhsp1_ck); | ||
831 | if (ret != 0) { | ||
832 | dev_err(dev, "xclk60mhsp1_ck set parent" | ||
833 | "failed error:%d\n", ret); | ||
834 | goto err_tll; | ||
835 | } | ||
836 | } else if (is_ehci_tll_mode(pdata->port_mode[0])) { | ||
837 | ret = clk_set_parent(omap->utmi_p1_fck, | ||
838 | omap->init_60m_fclk); | ||
839 | if (ret != 0) { | ||
840 | dev_err(dev, "init_60m_fclk set parent" | ||
841 | "failed error:%d\n", ret); | ||
842 | goto err_tll; | ||
843 | } | ||
844 | clk_enable(omap->usbhost_p1_fck); | ||
845 | clk_enable(omap->usbtll_p1_fck); | ||
846 | } | ||
847 | |||
848 | if (is_ehci_phy_mode(pdata->port_mode[1])) { | ||
849 | ret = clk_set_parent(omap->utmi_p2_fck, | ||
850 | omap->xclk60mhsp2_ck); | ||
851 | if (ret != 0) { | ||
852 | dev_err(dev, "xclk60mhsp1_ck set parent" | ||
853 | "failed error:%d\n", ret); | ||
854 | goto err_tll; | ||
855 | } | ||
856 | } else if (is_ehci_tll_mode(pdata->port_mode[1])) { | ||
857 | ret = clk_set_parent(omap->utmi_p2_fck, | ||
858 | omap->init_60m_fclk); | ||
859 | if (ret != 0) { | ||
860 | dev_err(dev, "init_60m_fclk set parent" | ||
861 | "failed error:%d\n", ret); | ||
862 | goto err_tll; | ||
863 | } | ||
864 | clk_enable(omap->usbhost_p2_fck); | ||
865 | clk_enable(omap->usbtll_p2_fck); | ||
866 | } | ||
867 | |||
868 | clk_enable(omap->utmi_p1_fck); | ||
869 | clk_enable(omap->utmi_p2_fck); | ||
870 | |||
871 | if (is_ehci_tll_mode(pdata->port_mode[0]) || | 572 | if (is_ehci_tll_mode(pdata->port_mode[0]) || |
872 | (is_ohci_port(pdata->port_mode[0]))) | 573 | (is_ohci_port(pdata->port_mode[0]))) |
873 | reg |= OMAP4_P1_MODE_TLL; | 574 | reg |= OMAP4_P1_MODE_TLL; |
@@ -913,12 +614,15 @@ static int usbhs_enable(struct device *dev) | |||
913 | (pdata->ehci_data->reset_gpio_port[1], 1); | 614 | (pdata->ehci_data->reset_gpio_port[1], 1); |
914 | } | 615 | } |
915 | 616 | ||
916 | end_count: | ||
917 | omap->count++; | ||
918 | spin_unlock_irqrestore(&omap->lock, flags); | 617 | spin_unlock_irqrestore(&omap->lock, flags); |
919 | return 0; | 618 | pm_runtime_put_sync(dev); |
619 | } | ||
620 | |||
621 | static void omap_usbhs_deinit(struct device *dev) | ||
622 | { | ||
623 | struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); | ||
624 | struct usbhs_omap_platform_data *pdata = &omap->platdata; | ||
920 | 625 | ||
921 | err_tll: | ||
922 | if (pdata->ehci_data->phy_reset) { | 626 | if (pdata->ehci_data->phy_reset) { |
923 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) | 627 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) |
924 | gpio_free(pdata->ehci_data->reset_gpio_port[0]); | 628 | gpio_free(pdata->ehci_data->reset_gpio_port[0]); |
@@ -926,123 +630,272 @@ err_tll: | |||
926 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) | 630 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) |
927 | gpio_free(pdata->ehci_data->reset_gpio_port[1]); | 631 | gpio_free(pdata->ehci_data->reset_gpio_port[1]); |
928 | } | 632 | } |
929 | |||
930 | clk_disable(omap->usbtll_ick); | ||
931 | clk_disable(omap->usbtll_fck); | ||
932 | clk_disable(omap->usbhost_fs_fck); | ||
933 | clk_disable(omap->usbhost_hs_fck); | ||
934 | clk_disable(omap->usbhost_ick); | ||
935 | spin_unlock_irqrestore(&omap->lock, flags); | ||
936 | return ret; | ||
937 | } | 633 | } |
938 | 634 | ||
939 | static void usbhs_disable(struct device *dev) | 635 | |
636 | /** | ||
637 | * usbhs_omap_probe - initialize TI-based HCDs | ||
638 | * | ||
639 | * Allocates basic resources for this USB host controller. | ||
640 | */ | ||
641 | static int __devinit usbhs_omap_probe(struct platform_device *pdev) | ||
940 | { | 642 | { |
941 | struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); | 643 | struct device *dev = &pdev->dev; |
942 | struct usbhs_omap_platform_data *pdata = &omap->platdata; | 644 | struct usbhs_omap_platform_data *pdata = dev->platform_data; |
943 | unsigned long flags = 0; | 645 | struct usbhs_hcd_omap *omap; |
944 | unsigned long timeout; | 646 | struct resource *res; |
647 | int ret = 0; | ||
648 | int i; | ||
945 | 649 | ||
946 | dev_dbg(dev, "stopping TI HSUSB Controller\n"); | 650 | if (!pdata) { |
651 | dev_err(dev, "Missing platform data\n"); | ||
652 | ret = -ENOMEM; | ||
653 | goto end_probe; | ||
654 | } | ||
947 | 655 | ||
948 | spin_lock_irqsave(&omap->lock, flags); | 656 | omap = kzalloc(sizeof(*omap), GFP_KERNEL); |
657 | if (!omap) { | ||
658 | dev_err(dev, "Memory allocation failed\n"); | ||
659 | ret = -ENOMEM; | ||
660 | goto end_probe; | ||
661 | } | ||
949 | 662 | ||
950 | if (omap->count == 0) | 663 | spin_lock_init(&omap->lock); |
951 | goto end_disble; | ||
952 | 664 | ||
953 | omap->count--; | 665 | for (i = 0; i < OMAP3_HS_USB_PORTS; i++) |
666 | omap->platdata.port_mode[i] = pdata->port_mode[i]; | ||
667 | |||
668 | omap->platdata.ehci_data = pdata->ehci_data; | ||
669 | omap->platdata.ohci_data = pdata->ohci_data; | ||
954 | 670 | ||
955 | if (omap->count != 0) | 671 | pm_runtime_enable(dev); |
956 | goto end_disble; | ||
957 | 672 | ||
958 | /* Reset OMAP modules for insmod/rmmod to work */ | ||
959 | usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, | ||
960 | is_omap_usbhs_rev2(omap) ? | ||
961 | OMAP4_UHH_SYSCONFIG_SOFTRESET : | ||
962 | OMAP_UHH_SYSCONFIG_SOFTRESET); | ||
963 | 673 | ||
964 | timeout = jiffies + msecs_to_jiffies(100); | 674 | for (i = 0; i < OMAP3_HS_USB_PORTS; i++) |
965 | while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS) | 675 | if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) || |
966 | & (1 << 0))) { | 676 | is_ehci_hsic_mode(i)) { |
967 | cpu_relax(); | 677 | omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck"); |
678 | if (IS_ERR(omap->ehci_logic_fck)) { | ||
679 | ret = PTR_ERR(omap->ehci_logic_fck); | ||
680 | dev_warn(dev, "ehci_logic_fck failed:%d\n", | ||
681 | ret); | ||
682 | } | ||
683 | break; | ||
684 | } | ||
968 | 685 | ||
969 | if (time_after(jiffies, timeout)) | 686 | omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); |
970 | dev_dbg(dev, "operation timed out\n"); | 687 | if (IS_ERR(omap->utmi_p1_fck)) { |
688 | ret = PTR_ERR(omap->utmi_p1_fck); | ||
689 | dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); | ||
690 | goto err_end; | ||
971 | } | 691 | } |
972 | 692 | ||
973 | while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS) | 693 | omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); |
974 | & (1 << 1))) { | 694 | if (IS_ERR(omap->xclk60mhsp1_ck)) { |
975 | cpu_relax(); | 695 | ret = PTR_ERR(omap->xclk60mhsp1_ck); |
696 | dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); | ||
697 | goto err_utmi_p1_fck; | ||
698 | } | ||
976 | 699 | ||
977 | if (time_after(jiffies, timeout)) | 700 | omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk"); |
978 | dev_dbg(dev, "operation timed out\n"); | 701 | if (IS_ERR(omap->utmi_p2_fck)) { |
702 | ret = PTR_ERR(omap->utmi_p2_fck); | ||
703 | dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); | ||
704 | goto err_xclk60mhsp1_ck; | ||
979 | } | 705 | } |
980 | 706 | ||
981 | while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS) | 707 | omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); |
982 | & (1 << 2))) { | 708 | if (IS_ERR(omap->xclk60mhsp2_ck)) { |
983 | cpu_relax(); | 709 | ret = PTR_ERR(omap->xclk60mhsp2_ck); |
710 | dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); | ||
711 | goto err_utmi_p2_fck; | ||
712 | } | ||
984 | 713 | ||
985 | if (time_after(jiffies, timeout)) | 714 | omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk"); |
986 | dev_dbg(dev, "operation timed out\n"); | 715 | if (IS_ERR(omap->usbhost_p1_fck)) { |
716 | ret = PTR_ERR(omap->usbhost_p1_fck); | ||
717 | dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret); | ||
718 | goto err_xclk60mhsp2_ck; | ||
987 | } | 719 | } |
988 | 720 | ||
989 | usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1)); | 721 | omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk"); |
722 | if (IS_ERR(omap->usbtll_p1_fck)) { | ||
723 | ret = PTR_ERR(omap->usbtll_p1_fck); | ||
724 | dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret); | ||
725 | goto err_usbhost_p1_fck; | ||
726 | } | ||
990 | 727 | ||
991 | while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS) | 728 | omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk"); |
992 | & (1 << 0))) { | 729 | if (IS_ERR(omap->usbhost_p2_fck)) { |
993 | cpu_relax(); | 730 | ret = PTR_ERR(omap->usbhost_p2_fck); |
731 | dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret); | ||
732 | goto err_usbtll_p1_fck; | ||
733 | } | ||
994 | 734 | ||
995 | if (time_after(jiffies, timeout)) | 735 | omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk"); |
996 | dev_dbg(dev, "operation timed out\n"); | 736 | if (IS_ERR(omap->usbtll_p2_fck)) { |
737 | ret = PTR_ERR(omap->usbtll_p2_fck); | ||
738 | dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret); | ||
739 | goto err_usbhost_p2_fck; | ||
997 | } | 740 | } |
998 | 741 | ||
999 | if (is_omap_usbhs_rev2(omap)) { | 742 | omap->init_60m_fclk = clk_get(dev, "init_60m_fclk"); |
1000 | if (is_ehci_tll_mode(pdata->port_mode[0])) | 743 | if (IS_ERR(omap->init_60m_fclk)) { |
1001 | clk_disable(omap->usbtll_p1_fck); | 744 | ret = PTR_ERR(omap->init_60m_fclk); |
1002 | if (is_ehci_tll_mode(pdata->port_mode[1])) | 745 | dev_err(dev, "init_60m_fclk failed error:%d\n", ret); |
1003 | clk_disable(omap->usbtll_p2_fck); | 746 | goto err_usbtll_p2_fck; |
1004 | clk_disable(omap->utmi_p2_fck); | ||
1005 | clk_disable(omap->utmi_p1_fck); | ||
1006 | } | 747 | } |
1007 | 748 | ||
1008 | clk_disable(omap->usbtll_ick); | 749 | if (is_ehci_phy_mode(pdata->port_mode[0])) { |
1009 | clk_disable(omap->usbtll_fck); | 750 | /* for OMAP3 , the clk set paretn fails */ |
1010 | clk_disable(omap->usbhost_fs_fck); | 751 | ret = clk_set_parent(omap->utmi_p1_fck, |
1011 | clk_disable(omap->usbhost_hs_fck); | 752 | omap->xclk60mhsp1_ck); |
1012 | clk_disable(omap->usbhost_ick); | 753 | if (ret != 0) |
754 | dev_err(dev, "xclk60mhsp1_ck set parent" | ||
755 | "failed error:%d\n", ret); | ||
756 | } else if (is_ehci_tll_mode(pdata->port_mode[0])) { | ||
757 | ret = clk_set_parent(omap->utmi_p1_fck, | ||
758 | omap->init_60m_fclk); | ||
759 | if (ret != 0) | ||
760 | dev_err(dev, "init_60m_fclk set parent" | ||
761 | "failed error:%d\n", ret); | ||
762 | } | ||
1013 | 763 | ||
1014 | /* The gpio_free migh sleep; so unlock the spinlock */ | 764 | if (is_ehci_phy_mode(pdata->port_mode[1])) { |
1015 | spin_unlock_irqrestore(&omap->lock, flags); | 765 | ret = clk_set_parent(omap->utmi_p2_fck, |
766 | omap->xclk60mhsp2_ck); | ||
767 | if (ret != 0) | ||
768 | dev_err(dev, "xclk60mhsp2_ck set parent" | ||
769 | "failed error:%d\n", ret); | ||
770 | } else if (is_ehci_tll_mode(pdata->port_mode[1])) { | ||
771 | ret = clk_set_parent(omap->utmi_p2_fck, | ||
772 | omap->init_60m_fclk); | ||
773 | if (ret != 0) | ||
774 | dev_err(dev, "init_60m_fclk set parent" | ||
775 | "failed error:%d\n", ret); | ||
776 | } | ||
1016 | 777 | ||
1017 | if (pdata->ehci_data->phy_reset) { | 778 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh"); |
1018 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) | 779 | if (!res) { |
1019 | gpio_free(pdata->ehci_data->reset_gpio_port[0]); | 780 | dev_err(dev, "UHH EHCI get resource failed\n"); |
781 | ret = -ENODEV; | ||
782 | goto err_init_60m_fclk; | ||
783 | } | ||
1020 | 784 | ||
1021 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) | 785 | omap->uhh_base = ioremap(res->start, resource_size(res)); |
1022 | gpio_free(pdata->ehci_data->reset_gpio_port[1]); | 786 | if (!omap->uhh_base) { |
787 | dev_err(dev, "UHH ioremap failed\n"); | ||
788 | ret = -ENOMEM; | ||
789 | goto err_init_60m_fclk; | ||
1023 | } | 790 | } |
1024 | return; | ||
1025 | 791 | ||
1026 | end_disble: | 792 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll"); |
1027 | spin_unlock_irqrestore(&omap->lock, flags); | 793 | if (!res) { |
1028 | } | 794 | dev_err(dev, "UHH EHCI get resource failed\n"); |
795 | ret = -ENODEV; | ||
796 | goto err_tll; | ||
797 | } | ||
1029 | 798 | ||
1030 | int omap_usbhs_enable(struct device *dev) | 799 | omap->tll_base = ioremap(res->start, resource_size(res)); |
1031 | { | 800 | if (!omap->tll_base) { |
1032 | return usbhs_enable(dev->parent); | 801 | dev_err(dev, "TLL ioremap failed\n"); |
802 | ret = -ENOMEM; | ||
803 | goto err_tll; | ||
804 | } | ||
805 | |||
806 | platform_set_drvdata(pdev, omap); | ||
807 | |||
808 | ret = omap_usbhs_alloc_children(pdev); | ||
809 | if (ret) { | ||
810 | dev_err(dev, "omap_usbhs_alloc_children failed\n"); | ||
811 | goto err_alloc; | ||
812 | } | ||
813 | |||
814 | omap_usbhs_init(dev); | ||
815 | |||
816 | goto end_probe; | ||
817 | |||
818 | err_alloc: | ||
819 | iounmap(omap->tll_base); | ||
820 | |||
821 | err_tll: | ||
822 | iounmap(omap->uhh_base); | ||
823 | |||
824 | err_init_60m_fclk: | ||
825 | clk_put(omap->init_60m_fclk); | ||
826 | |||
827 | err_usbtll_p2_fck: | ||
828 | clk_put(omap->usbtll_p2_fck); | ||
829 | |||
830 | err_usbhost_p2_fck: | ||
831 | clk_put(omap->usbhost_p2_fck); | ||
832 | |||
833 | err_usbtll_p1_fck: | ||
834 | clk_put(omap->usbtll_p1_fck); | ||
835 | |||
836 | err_usbhost_p1_fck: | ||
837 | clk_put(omap->usbhost_p1_fck); | ||
838 | |||
839 | err_xclk60mhsp2_ck: | ||
840 | clk_put(omap->xclk60mhsp2_ck); | ||
841 | |||
842 | err_utmi_p2_fck: | ||
843 | clk_put(omap->utmi_p2_fck); | ||
844 | |||
845 | err_xclk60mhsp1_ck: | ||
846 | clk_put(omap->xclk60mhsp1_ck); | ||
847 | |||
848 | err_utmi_p1_fck: | ||
849 | clk_put(omap->utmi_p1_fck); | ||
850 | |||
851 | err_end: | ||
852 | clk_put(omap->ehci_logic_fck); | ||
853 | pm_runtime_disable(dev); | ||
854 | kfree(omap); | ||
855 | |||
856 | end_probe: | ||
857 | return ret; | ||
1033 | } | 858 | } |
1034 | EXPORT_SYMBOL_GPL(omap_usbhs_enable); | ||
1035 | 859 | ||
1036 | void omap_usbhs_disable(struct device *dev) | 860 | /** |
861 | * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs | ||
862 | * @pdev: USB Host Controller being removed | ||
863 | * | ||
864 | * Reverses the effect of usbhs_omap_probe(). | ||
865 | */ | ||
866 | static int __devexit usbhs_omap_remove(struct platform_device *pdev) | ||
1037 | { | 867 | { |
1038 | usbhs_disable(dev->parent); | 868 | struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); |
869 | |||
870 | omap_usbhs_deinit(&pdev->dev); | ||
871 | iounmap(omap->tll_base); | ||
872 | iounmap(omap->uhh_base); | ||
873 | clk_put(omap->init_60m_fclk); | ||
874 | clk_put(omap->usbtll_p2_fck); | ||
875 | clk_put(omap->usbhost_p2_fck); | ||
876 | clk_put(omap->usbtll_p1_fck); | ||
877 | clk_put(omap->usbhost_p1_fck); | ||
878 | clk_put(omap->xclk60mhsp2_ck); | ||
879 | clk_put(omap->utmi_p2_fck); | ||
880 | clk_put(omap->xclk60mhsp1_ck); | ||
881 | clk_put(omap->utmi_p1_fck); | ||
882 | clk_put(omap->ehci_logic_fck); | ||
883 | pm_runtime_disable(&pdev->dev); | ||
884 | kfree(omap); | ||
885 | |||
886 | return 0; | ||
1039 | } | 887 | } |
1040 | EXPORT_SYMBOL_GPL(omap_usbhs_disable); | 888 | |
889 | static const struct dev_pm_ops usbhsomap_dev_pm_ops = { | ||
890 | .runtime_suspend = usbhs_runtime_suspend, | ||
891 | .runtime_resume = usbhs_runtime_resume, | ||
892 | }; | ||
1041 | 893 | ||
1042 | static struct platform_driver usbhs_omap_driver = { | 894 | static struct platform_driver usbhs_omap_driver = { |
1043 | .driver = { | 895 | .driver = { |
1044 | .name = (char *)usbhs_driver_name, | 896 | .name = (char *)usbhs_driver_name, |
1045 | .owner = THIS_MODULE, | 897 | .owner = THIS_MODULE, |
898 | .pm = &usbhsomap_dev_pm_ops, | ||
1046 | }, | 899 | }, |
1047 | .remove = __exit_p(usbhs_omap_remove), | 900 | .remove = __exit_p(usbhs_omap_remove), |
1048 | }; | 901 | }; |
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index e39b0297bad1..568cefbd63a2 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/usb/ulpi.h> | 41 | #include <linux/usb/ulpi.h> |
42 | #include <plat/usb.h> | 42 | #include <plat/usb.h> |
43 | #include <linux/regulator/consumer.h> | 43 | #include <linux/regulator/consumer.h> |
44 | #include <linux/pm_runtime.h> | ||
44 | 45 | ||
45 | /* EHCI Register Set */ | 46 | /* EHCI Register Set */ |
46 | #define EHCI_INSNREG04 (0xA0) | 47 | #define EHCI_INSNREG04 (0xA0) |
@@ -190,11 +191,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
190 | } | 191 | } |
191 | } | 192 | } |
192 | 193 | ||
193 | ret = omap_usbhs_enable(dev); | 194 | pm_runtime_enable(dev); |
194 | if (ret) { | 195 | pm_runtime_get_sync(dev); |
195 | dev_err(dev, "failed to start usbhs with err %d\n", ret); | ||
196 | goto err_enable; | ||
197 | } | ||
198 | 196 | ||
199 | /* | 197 | /* |
200 | * An undocumented "feature" in the OMAP3 EHCI controller, | 198 | * An undocumented "feature" in the OMAP3 EHCI controller, |
@@ -240,11 +238,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
240 | return 0; | 238 | return 0; |
241 | 239 | ||
242 | err_add_hcd: | 240 | err_add_hcd: |
243 | omap_usbhs_disable(dev); | ||
244 | |||
245 | err_enable: | ||
246 | disable_put_regulator(pdata); | 241 | disable_put_regulator(pdata); |
247 | usb_put_hcd(hcd); | 242 | pm_runtime_put_sync(dev); |
248 | 243 | ||
249 | err_io: | 244 | err_io: |
250 | iounmap(regs); | 245 | iounmap(regs); |
@@ -266,10 +261,12 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) | |||
266 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 261 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
267 | 262 | ||
268 | usb_remove_hcd(hcd); | 263 | usb_remove_hcd(hcd); |
269 | omap_usbhs_disable(dev); | ||
270 | disable_put_regulator(dev->platform_data); | 264 | disable_put_regulator(dev->platform_data); |
271 | iounmap(hcd->regs); | 265 | iounmap(hcd->regs); |
272 | usb_put_hcd(hcd); | 266 | usb_put_hcd(hcd); |
267 | pm_runtime_put_sync(dev); | ||
268 | pm_runtime_disable(dev); | ||
269 | |||
273 | return 0; | 270 | return 0; |
274 | } | 271 | } |
275 | 272 | ||
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c index 516ebc4d6cc2..1b8133b6e451 100644 --- a/drivers/usb/host/ohci-omap3.c +++ b/drivers/usb/host/ohci-omap3.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
33 | #include <plat/usb.h> | 33 | #include <plat/usb.h> |
34 | #include <linux/pm_runtime.h> | ||
34 | 35 | ||
35 | /*-------------------------------------------------------------------------*/ | 36 | /*-------------------------------------------------------------------------*/ |
36 | 37 | ||
@@ -134,7 +135,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev) | |||
134 | int irq; | 135 | int irq; |
135 | 136 | ||
136 | if (usb_disabled()) | 137 | if (usb_disabled()) |
137 | goto err_end; | 138 | return -ENODEV; |
138 | 139 | ||
139 | if (!dev->parent) { | 140 | if (!dev->parent) { |
140 | dev_err(dev, "Missing parent device\n"); | 141 | dev_err(dev, "Missing parent device\n"); |
@@ -172,11 +173,8 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev) | |||
172 | hcd->rsrc_len = resource_size(res); | 173 | hcd->rsrc_len = resource_size(res); |
173 | hcd->regs = regs; | 174 | hcd->regs = regs; |
174 | 175 | ||
175 | ret = omap_usbhs_enable(dev); | 176 | pm_runtime_enable(dev); |
176 | if (ret) { | 177 | pm_runtime_get_sync(dev); |
177 | dev_dbg(dev, "failed to start ohci\n"); | ||
178 | goto err_end; | ||
179 | } | ||
180 | 178 | ||
181 | ohci_hcd_init(hcd_to_ohci(hcd)); | 179 | ohci_hcd_init(hcd_to_ohci(hcd)); |
182 | 180 | ||
@@ -189,9 +187,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev) | |||
189 | return 0; | 187 | return 0; |
190 | 188 | ||
191 | err_add_hcd: | 189 | err_add_hcd: |
192 | omap_usbhs_disable(dev); | 190 | pm_runtime_put_sync(dev); |
193 | |||
194 | err_end: | ||
195 | usb_put_hcd(hcd); | 191 | usb_put_hcd(hcd); |
196 | 192 | ||
197 | err_io: | 193 | err_io: |
@@ -220,9 +216,9 @@ static int __devexit ohci_hcd_omap3_remove(struct platform_device *pdev) | |||
220 | 216 | ||
221 | iounmap(hcd->regs); | 217 | iounmap(hcd->regs); |
222 | usb_remove_hcd(hcd); | 218 | usb_remove_hcd(hcd); |
223 | omap_usbhs_disable(dev); | 219 | pm_runtime_put_sync(dev); |
220 | pm_runtime_disable(dev); | ||
224 | usb_put_hcd(hcd); | 221 | usb_put_hcd(hcd); |
225 | |||
226 | return 0; | 222 | return 0; |
227 | } | 223 | } |
228 | 224 | ||