aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2011-12-27 17:05:29 -0500
committerArnd Bergmann <arnd@arndb.de>2011-12-27 17:05:29 -0500
commit9f9f265b0bd407233cfbc61acd64b90ff1da7ba4 (patch)
tree3ede3c805a85cf3a097cb25abb8caaf050ac42dc
parent07b98403ee67838bbaded43bd687875b9d7f74e0 (diff)
parentc0ee8cd68ff337fc2a8020f485f7943df4aa9445 (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.c26
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c10
-rw-r--r--arch/arm/mach-omap2/usb-host.c100
-rw-r--r--arch/arm/plat-omap/include/plat/usb.h3
-rw-r--r--drivers/mfd/omap-usb-host.c755
-rw-r--r--drivers/usb/host/ehci-omap.c17
-rw-r--r--drivers/usb/host/ohci-omap3.c18
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"
38static 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
65static 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
72static struct usbhs_omap_platform_data usbhs_data; 41static struct usbhs_omap_platform_data usbhs_data;
73static struct ehci_hcd_omap_platform_data ehci_data; 42static struct ehci_hcd_omap_platform_data ehci_data;
74static struct ohci_hcd_omap_platform_data ohci_data; 43static struct ohci_hcd_omap_platform_data ohci_data;
75 44
45static 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
509void __init usbhs_init(const struct usbhs_omap_board_data *pdata) 486void __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
562init_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
101extern void usbhs_init(const struct usbhs_omap_board_data *pdata); 101extern void usbhs_init(const struct usbhs_omap_board_data *pdata);
102 102
103extern int omap_usbhs_enable(struct device *dev);
104extern void omap_usbhs_disable(struct device *dev);
105
106extern int omap4430_phy_power(struct device *dev, int ID, int on); 103extern int omap4430_phy_power(struct device *dev, int ID, int on);
107extern int omap4430_phy_set_clk(struct device *dev, int on); 104extern int omap4430_phy_set_clk(struct device *dev, int on);
108extern int omap4430_phy_init(struct device *dev); 105extern 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
149struct usbhs_hcd_omap { 150struct 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 */
327static 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
493err_alloc:
494 iounmap(omap->tll_base);
495
496err_tll:
497 iounmap(omap->uhh_base);
498
499err_init_60m_fclk:
500 clk_put(omap->init_60m_fclk);
501
502err_usbtll_p2_fck:
503 clk_put(omap->usbtll_p2_fck);
504
505err_usbhost_p2_fck:
506 clk_put(omap->usbhost_p2_fck);
507
508err_usbtll_p1_fck:
509 clk_put(omap->usbtll_p1_fck);
510
511err_usbhost_p1_fck:
512 clk_put(omap->usbhost_p1_fck);
513
514err_xclk60mhsp2_ck:
515 clk_put(omap->xclk60mhsp2_ck);
516
517err_utmi_p2_fck:
518 clk_put(omap->utmi_p2_fck);
519
520err_xclk60mhsp1_ck:
521 clk_put(omap->xclk60mhsp1_ck);
522
523err_utmi_p1_fck:
524 clk_put(omap->utmi_p1_fck);
525
526err_usbtll_ick:
527 clk_put(omap->usbtll_ick);
528
529err_usbtll_fck:
530 clk_put(omap->usbtll_fck);
531
532err_usbhost_fs_fck:
533 clk_put(omap->usbhost_fs_fck);
534
535err_usbhost_hs_fck:
536 clk_put(omap->usbhost_hs_fck);
537
538err_usbhost_ick:
539 clk_put(omap->usbhost_ick);
540
541err_end:
542 kfree(omap);
543
544end_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 */
554static 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
585static bool is_ohci_port(enum usbhs_omap_port_mode pmode) 318static 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
692static int usbhs_enable(struct device *dev) 425static 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
459static 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
493static 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
916end_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
621static 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
921err_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
939static 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 */
641static 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
1026end_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
1030int 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
818err_alloc:
819 iounmap(omap->tll_base);
820
821err_tll:
822 iounmap(omap->uhh_base);
823
824err_init_60m_fclk:
825 clk_put(omap->init_60m_fclk);
826
827err_usbtll_p2_fck:
828 clk_put(omap->usbtll_p2_fck);
829
830err_usbhost_p2_fck:
831 clk_put(omap->usbhost_p2_fck);
832
833err_usbtll_p1_fck:
834 clk_put(omap->usbtll_p1_fck);
835
836err_usbhost_p1_fck:
837 clk_put(omap->usbhost_p1_fck);
838
839err_xclk60mhsp2_ck:
840 clk_put(omap->xclk60mhsp2_ck);
841
842err_utmi_p2_fck:
843 clk_put(omap->utmi_p2_fck);
844
845err_xclk60mhsp1_ck:
846 clk_put(omap->xclk60mhsp1_ck);
847
848err_utmi_p1_fck:
849 clk_put(omap->utmi_p1_fck);
850
851err_end:
852 clk_put(omap->ehci_logic_fck);
853 pm_runtime_disable(dev);
854 kfree(omap);
855
856end_probe:
857 return ret;
1033} 858}
1034EXPORT_SYMBOL_GPL(omap_usbhs_enable);
1035 859
1036void 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 */
866static 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}
1040EXPORT_SYMBOL_GPL(omap_usbhs_disable); 888
889static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
890 .runtime_suspend = usbhs_runtime_suspend,
891 .runtime_resume = usbhs_runtime_resume,
892};
1041 893
1042static struct platform_driver usbhs_omap_driver = { 894static 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
242err_add_hcd: 240err_add_hcd:
243 omap_usbhs_disable(dev);
244
245err_enable:
246 disable_put_regulator(pdata); 241 disable_put_regulator(pdata);
247 usb_put_hcd(hcd); 242 pm_runtime_put_sync(dev);
248 243
249err_io: 244err_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
191err_add_hcd: 189err_add_hcd:
192 omap_usbhs_disable(dev); 190 pm_runtime_put_sync(dev);
193
194err_end:
195 usb_put_hcd(hcd); 191 usb_put_hcd(hcd);
196 192
197err_io: 193err_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