diff options
author | Anand Gadiyar <gadiyar@ti.com> | 2010-11-21 12:53:42 -0500 |
---|---|---|
committer | Anand Gadiyar <gadiyar@ti.com> | 2010-11-30 16:05:49 -0500 |
commit | 4792a15bf0f388838c3e16636f961c99bc2f3572 (patch) | |
tree | 6007fd08b6008a98798027781b6a7bbec4ae5838 /drivers/usb/host | |
parent | 1ed85659a29287bda958a9429461f4a1b0a033be (diff) |
usb: ehci-omap: Add OMAP4 support
Update the ehci-omap glue layer to support the controller in the
OMAP4. Major differences from OMAP3 is that the OMAP4 has per-port
clocking, and supports ULPI output clocking mode. The old input
clocking mode is not supported.
Also, there are only 2 externally available ports as against 3
in the OMAP3. The third port is internally tied off and should
not be used.
Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
Signed-off-by: Anand Gadiyar <gadiyar@ti.com>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/ehci-omap.c | 254 |
1 files changed, 212 insertions, 42 deletions
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index dd9d5c1d9a8f..0374eb47f09b 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
@@ -1,11 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * ehci-omap.c - driver for USBHOST on OMAP 34xx processor | 2 | * ehci-omap.c - driver for USBHOST on OMAP3/4 processors |
3 | * | 3 | * |
4 | * Bus Glue for OMAP34xx USBHOST 3 port EHCI controller | 4 | * Bus Glue for the EHCI controllers in OMAP3/4 |
5 | * Tested on OMAP3430 ES2.0 SDP | 5 | * Tested on several OMAP3 boards, and OMAP4 Pandaboard |
6 | * | 6 | * |
7 | * Copyright (C) 2007-2008 Texas Instruments, Inc. | 7 | * Copyright (C) 2007-2010 Texas Instruments, Inc. |
8 | * Author: Vikram Pandita <vikram.pandita@ti.com> | 8 | * Author: Vikram Pandita <vikram.pandita@ti.com> |
9 | * Author: Anand Gadiyar <gadiyar@ti.com> | ||
9 | * | 10 | * |
10 | * Copyright (C) 2009 Nokia Corporation | 11 | * Copyright (C) 2009 Nokia Corporation |
11 | * Contact: Felipe Balbi <felipe.balbi@nokia.com> | 12 | * Contact: Felipe Balbi <felipe.balbi@nokia.com> |
@@ -26,11 +27,14 @@ | |||
26 | * along with this program; if not, write to the Free Software | 27 | * along with this program; if not, write to the Free Software |
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 28 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
28 | * | 29 | * |
29 | * TODO (last updated Feb 12, 2010): | 30 | * TODO (last updated Nov 21, 2010): |
30 | * - add kernel-doc | 31 | * - add kernel-doc |
31 | * - enable AUTOIDLE | 32 | * - enable AUTOIDLE |
32 | * - add suspend/resume | 33 | * - add suspend/resume |
33 | * - move workarounds to board-files | 34 | * - move workarounds to board-files |
35 | * - factor out code common to OHCI | ||
36 | * - add HSIC and TLL support | ||
37 | * - convert to use hwmod and runtime PM | ||
34 | */ | 38 | */ |
35 | 39 | ||
36 | #include <linux/platform_device.h> | 40 | #include <linux/platform_device.h> |
@@ -114,6 +118,23 @@ | |||
114 | #define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9) | 118 | #define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9) |
115 | #define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10) | 119 | #define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10) |
116 | 120 | ||
121 | /* OMAP4-specific defines */ | ||
122 | #define OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR (3 << 2) | ||
123 | #define OMAP4_UHH_SYSCONFIG_NOIDLE (1 << 2) | ||
124 | |||
125 | #define OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR (3 << 4) | ||
126 | #define OMAP4_UHH_SYSCONFIG_NOSTDBY (1 << 4) | ||
127 | #define OMAP4_UHH_SYSCONFIG_SOFTRESET (1 << 0) | ||
128 | |||
129 | #define OMAP4_P1_MODE_CLEAR (3 << 16) | ||
130 | #define OMAP4_P1_MODE_TLL (1 << 16) | ||
131 | #define OMAP4_P1_MODE_HSIC (3 << 16) | ||
132 | #define OMAP4_P2_MODE_CLEAR (3 << 18) | ||
133 | #define OMAP4_P2_MODE_TLL (1 << 18) | ||
134 | #define OMAP4_P2_MODE_HSIC (3 << 18) | ||
135 | |||
136 | #define OMAP_REV2_TLL_CHANNEL_COUNT 2 | ||
137 | |||
117 | #define OMAP_UHH_DEBUG_CSR (0x44) | 138 | #define OMAP_UHH_DEBUG_CSR (0x44) |
118 | 139 | ||
119 | /* EHCI Register Set */ | 140 | /* EHCI Register Set */ |
@@ -127,8 +148,16 @@ | |||
127 | #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 | 148 | #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 |
128 | #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 | 149 | #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 |
129 | 150 | ||
151 | /* Values of UHH_REVISION - Note: these are not given in the TRM */ | ||
152 | #define OMAP_EHCI_REV1 0x00000010 /* OMAP3 */ | ||
153 | #define OMAP_EHCI_REV2 0x50700100 /* OMAP4 */ | ||
154 | |||
155 | #define is_omap_ehci_rev1(x) (x->omap_ehci_rev == OMAP_EHCI_REV1) | ||
156 | #define is_omap_ehci_rev2(x) (x->omap_ehci_rev == OMAP_EHCI_REV2) | ||
157 | |||
130 | #define is_ehci_phy_mode(x) (x == EHCI_HCD_OMAP_MODE_PHY) | 158 | #define is_ehci_phy_mode(x) (x == EHCI_HCD_OMAP_MODE_PHY) |
131 | #define is_ehci_tll_mode(x) (x == EHCI_HCD_OMAP_MODE_TLL) | 159 | #define is_ehci_tll_mode(x) (x == EHCI_HCD_OMAP_MODE_TLL) |
160 | #define is_ehci_hsic_mode(x) (x == EHCI_HCD_OMAP_MODE_HSIC) | ||
132 | 161 | ||
133 | /*-------------------------------------------------------------------------*/ | 162 | /*-------------------------------------------------------------------------*/ |
134 | 163 | ||
@@ -163,6 +192,10 @@ struct ehci_hcd_omap { | |||
163 | struct clk *usbhost_fs_fck; | 192 | struct clk *usbhost_fs_fck; |
164 | struct clk *usbtll_fck; | 193 | struct clk *usbtll_fck; |
165 | struct clk *usbtll_ick; | 194 | struct clk *usbtll_ick; |
195 | struct clk *xclk60mhsp1_ck; | ||
196 | struct clk *xclk60mhsp2_ck; | ||
197 | struct clk *utmi_p1_fck; | ||
198 | struct clk *utmi_p2_fck; | ||
166 | 199 | ||
167 | /* FIXME the following two workarounds are | 200 | /* FIXME the following two workarounds are |
168 | * board specific not silicon-specific so these | 201 | * board specific not silicon-specific so these |
@@ -179,6 +212,9 @@ struct ehci_hcd_omap { | |||
179 | /* phy reset workaround */ | 212 | /* phy reset workaround */ |
180 | int phy_reset; | 213 | int phy_reset; |
181 | 214 | ||
215 | /* IP revision */ | ||
216 | u32 omap_ehci_rev; | ||
217 | |||
182 | /* desired phy_mode: TLL, PHY */ | 218 | /* desired phy_mode: TLL, PHY */ |
183 | enum ehci_hcd_omap_mode port_mode[OMAP3_HS_USB_PORTS]; | 219 | enum ehci_hcd_omap_mode port_mode[OMAP3_HS_USB_PORTS]; |
184 | 220 | ||
@@ -337,6 +373,80 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
337 | } | 373 | } |
338 | clk_enable(omap->usbtll_ick); | 374 | clk_enable(omap->usbtll_ick); |
339 | 375 | ||
376 | omap->omap_ehci_rev = ehci_omap_readl(omap->uhh_base, | ||
377 | OMAP_UHH_REVISION); | ||
378 | dev_dbg(omap->dev, "OMAP UHH_REVISION 0x%x\n", | ||
379 | omap->omap_ehci_rev); | ||
380 | |||
381 | /* | ||
382 | * Enable per-port clocks as needed (newer controllers only). | ||
383 | * - External ULPI clock for PHY mode | ||
384 | * - Internal clocks for TLL and HSIC modes (TODO) | ||
385 | */ | ||
386 | if (is_omap_ehci_rev2(omap)) { | ||
387 | switch (omap->port_mode[0]) { | ||
388 | case EHCI_HCD_OMAP_MODE_PHY: | ||
389 | omap->xclk60mhsp1_ck = clk_get(omap->dev, | ||
390 | "xclk60mhsp1_ck"); | ||
391 | if (IS_ERR(omap->xclk60mhsp1_ck)) { | ||
392 | ret = PTR_ERR(omap->xclk60mhsp1_ck); | ||
393 | dev_err(omap->dev, | ||
394 | "Unable to get Port1 ULPI clock\n"); | ||
395 | } | ||
396 | |||
397 | omap->utmi_p1_fck = clk_get(omap->dev, | ||
398 | "utmi_p1_gfclk"); | ||
399 | if (IS_ERR(omap->utmi_p1_fck)) { | ||
400 | ret = PTR_ERR(omap->utmi_p1_fck); | ||
401 | dev_err(omap->dev, | ||
402 | "Unable to get utmi_p1_fck\n"); | ||
403 | } | ||
404 | |||
405 | ret = clk_set_parent(omap->utmi_p1_fck, | ||
406 | omap->xclk60mhsp1_ck); | ||
407 | if (ret != 0) { | ||
408 | dev_err(omap->dev, | ||
409 | "Unable to set P1 f-clock\n"); | ||
410 | } | ||
411 | break; | ||
412 | case EHCI_HCD_OMAP_MODE_TLL: | ||
413 | /* TODO */ | ||
414 | default: | ||
415 | break; | ||
416 | } | ||
417 | switch (omap->port_mode[1]) { | ||
418 | case EHCI_HCD_OMAP_MODE_PHY: | ||
419 | omap->xclk60mhsp2_ck = clk_get(omap->dev, | ||
420 | "xclk60mhsp2_ck"); | ||
421 | if (IS_ERR(omap->xclk60mhsp2_ck)) { | ||
422 | ret = PTR_ERR(omap->xclk60mhsp2_ck); | ||
423 | dev_err(omap->dev, | ||
424 | "Unable to get Port2 ULPI clock\n"); | ||
425 | } | ||
426 | |||
427 | omap->utmi_p2_fck = clk_get(omap->dev, | ||
428 | "utmi_p2_gfclk"); | ||
429 | if (IS_ERR(omap->utmi_p2_fck)) { | ||
430 | ret = PTR_ERR(omap->utmi_p2_fck); | ||
431 | dev_err(omap->dev, | ||
432 | "Unable to get utmi_p2_fck\n"); | ||
433 | } | ||
434 | |||
435 | ret = clk_set_parent(omap->utmi_p2_fck, | ||
436 | omap->xclk60mhsp2_ck); | ||
437 | if (ret != 0) { | ||
438 | dev_err(omap->dev, | ||
439 | "Unable to set P2 f-clock\n"); | ||
440 | } | ||
441 | break; | ||
442 | case EHCI_HCD_OMAP_MODE_TLL: | ||
443 | /* TODO */ | ||
444 | default: | ||
445 | break; | ||
446 | } | ||
447 | } | ||
448 | |||
449 | |||
340 | /* perform TLL soft reset, and wait until reset is complete */ | 450 | /* perform TLL soft reset, and wait until reset is complete */ |
341 | ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, | 451 | ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, |
342 | OMAP_USBTLL_SYSCONFIG_SOFTRESET); | 452 | OMAP_USBTLL_SYSCONFIG_SOFTRESET); |
@@ -364,12 +474,20 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
364 | 474 | ||
365 | /* Put UHH in NoIdle/NoStandby mode */ | 475 | /* Put UHH in NoIdle/NoStandby mode */ |
366 | reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); | 476 | reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); |
367 | reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP | 477 | if (is_omap_ehci_rev1(omap)) { |
368 | | OMAP_UHH_SYSCONFIG_SIDLEMODE | 478 | reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP |
369 | | OMAP_UHH_SYSCONFIG_CACTIVITY | 479 | | OMAP_UHH_SYSCONFIG_SIDLEMODE |
370 | | OMAP_UHH_SYSCONFIG_MIDLEMODE); | 480 | | OMAP_UHH_SYSCONFIG_CACTIVITY |
371 | reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; | 481 | | OMAP_UHH_SYSCONFIG_MIDLEMODE); |
482 | reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; | ||
483 | |||
372 | 484 | ||
485 | } else if (is_omap_ehci_rev2(omap)) { | ||
486 | reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR; | ||
487 | reg |= OMAP4_UHH_SYSCONFIG_NOIDLE; | ||
488 | reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR; | ||
489 | reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY; | ||
490 | } | ||
373 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); | 491 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); |
374 | 492 | ||
375 | reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); | 493 | reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); |
@@ -380,40 +498,56 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
380 | | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); | 498 | | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); |
381 | reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; | 499 | reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; |
382 | 500 | ||
383 | if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN) | 501 | if (is_omap_ehci_rev1(omap)) { |
384 | reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; | 502 | if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN) |
385 | if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN) | 503 | reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; |
386 | reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; | 504 | if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN) |
387 | if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN) | 505 | reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; |
388 | reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; | 506 | if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN) |
389 | 507 | reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; | |
390 | /* Bypass the TLL module for PHY mode operation */ | 508 | |
391 | if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) { | 509 | /* Bypass the TLL module for PHY mode operation */ |
392 | dev_dbg(omap->dev, "OMAP3 ES version <= ES2.1\n"); | 510 | if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) { |
393 | if (is_ehci_phy_mode(omap->port_mode[0]) || | 511 | dev_dbg(omap->dev, "OMAP3 ES version <= ES2.1\n"); |
394 | is_ehci_phy_mode(omap->port_mode[1]) || | 512 | if (is_ehci_phy_mode(omap->port_mode[0]) || |
395 | is_ehci_phy_mode(omap->port_mode[2])) | 513 | is_ehci_phy_mode(omap->port_mode[1]) || |
396 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; | 514 | is_ehci_phy_mode(omap->port_mode[2])) |
397 | else | 515 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; |
398 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; | 516 | else |
399 | } else { | 517 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; |
400 | dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n"); | 518 | } else { |
401 | if (is_ehci_phy_mode(omap->port_mode[0])) | 519 | dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n"); |
402 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; | 520 | if (is_ehci_phy_mode(omap->port_mode[0])) |
403 | else if (is_ehci_tll_mode(omap->port_mode[0])) | 521 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; |
404 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; | 522 | else if (is_ehci_tll_mode(omap->port_mode[0])) |
405 | 523 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; | |
406 | if (is_ehci_phy_mode(omap->port_mode[1])) | 524 | |
407 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; | 525 | if (is_ehci_phy_mode(omap->port_mode[1])) |
408 | else if (is_ehci_tll_mode(omap->port_mode[1])) | 526 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; |
409 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; | 527 | else if (is_ehci_tll_mode(omap->port_mode[1])) |
410 | 528 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; | |
411 | if (is_ehci_phy_mode(omap->port_mode[2])) | 529 | |
412 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; | 530 | if (is_ehci_phy_mode(omap->port_mode[2])) |
413 | else if (is_ehci_tll_mode(omap->port_mode[2])) | 531 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; |
414 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; | 532 | else if (is_ehci_tll_mode(omap->port_mode[2])) |
533 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; | ||
534 | } | ||
535 | } else if (is_omap_ehci_rev2(omap)) { | ||
536 | /* Clear port mode fields for PHY mode*/ | ||
537 | reg &= ~OMAP4_P1_MODE_CLEAR; | ||
538 | reg &= ~OMAP4_P2_MODE_CLEAR; | ||
539 | |||
540 | if (is_ehci_tll_mode(omap->port_mode[0])) | ||
541 | reg |= OMAP4_P1_MODE_TLL; | ||
542 | else if (is_ehci_hsic_mode(omap->port_mode[0])) | ||
543 | reg |= OMAP4_P1_MODE_HSIC; | ||
415 | 544 | ||
545 | if (is_ehci_tll_mode(omap->port_mode[1])) | ||
546 | reg |= OMAP4_P2_MODE_TLL; | ||
547 | else if (is_ehci_hsic_mode(omap->port_mode[1])) | ||
548 | reg |= OMAP4_P2_MODE_HSIC; | ||
416 | } | 549 | } |
550 | |||
417 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); | 551 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); |
418 | dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg); | 552 | dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg); |
419 | 553 | ||
@@ -468,6 +602,14 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
468 | return 0; | 602 | return 0; |
469 | 603 | ||
470 | err_sys_status: | 604 | err_sys_status: |
605 | clk_disable(omap->utmi_p2_fck); | ||
606 | clk_put(omap->utmi_p2_fck); | ||
607 | clk_disable(omap->xclk60mhsp2_ck); | ||
608 | clk_put(omap->xclk60mhsp2_ck); | ||
609 | clk_disable(omap->utmi_p1_fck); | ||
610 | clk_put(omap->utmi_p1_fck); | ||
611 | clk_disable(omap->xclk60mhsp1_ck); | ||
612 | clk_put(omap->xclk60mhsp1_ck); | ||
471 | clk_disable(omap->usbtll_ick); | 613 | clk_disable(omap->usbtll_ick); |
472 | clk_put(omap->usbtll_ick); | 614 | clk_put(omap->usbtll_ick); |
473 | 615 | ||
@@ -507,6 +649,8 @@ static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
507 | 649 | ||
508 | /* Reset OMAP modules for insmod/rmmod to work */ | 650 | /* Reset OMAP modules for insmod/rmmod to work */ |
509 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, | 651 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, |
652 | is_omap_ehci_rev2(omap) ? | ||
653 | OMAP4_UHH_SYSCONFIG_SOFTRESET : | ||
510 | OMAP_UHH_SYSCONFIG_SOFTRESET); | 654 | OMAP_UHH_SYSCONFIG_SOFTRESET); |
511 | while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) | 655 | while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) |
512 | & (1 << 0))) { | 656 | & (1 << 0))) { |
@@ -572,6 +716,32 @@ static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
572 | omap->usbtll_ick = NULL; | 716 | omap->usbtll_ick = NULL; |
573 | } | 717 | } |
574 | 718 | ||
719 | if (is_omap_ehci_rev2(omap)) { | ||
720 | if (omap->xclk60mhsp1_ck != NULL) { | ||
721 | clk_disable(omap->xclk60mhsp1_ck); | ||
722 | clk_put(omap->xclk60mhsp1_ck); | ||
723 | omap->xclk60mhsp1_ck = NULL; | ||
724 | } | ||
725 | |||
726 | if (omap->utmi_p1_fck != NULL) { | ||
727 | clk_disable(omap->utmi_p1_fck); | ||
728 | clk_put(omap->utmi_p1_fck); | ||
729 | omap->utmi_p1_fck = NULL; | ||
730 | } | ||
731 | |||
732 | if (omap->xclk60mhsp2_ck != NULL) { | ||
733 | clk_disable(omap->xclk60mhsp2_ck); | ||
734 | clk_put(omap->xclk60mhsp2_ck); | ||
735 | omap->xclk60mhsp2_ck = NULL; | ||
736 | } | ||
737 | |||
738 | if (omap->utmi_p2_fck != NULL) { | ||
739 | clk_disable(omap->utmi_p2_fck); | ||
740 | clk_put(omap->utmi_p2_fck); | ||
741 | omap->utmi_p2_fck = NULL; | ||
742 | } | ||
743 | } | ||
744 | |||
575 | if (omap->phy_reset) { | 745 | if (omap->phy_reset) { |
576 | if (gpio_is_valid(omap->reset_gpio_port[0])) | 746 | if (gpio_is_valid(omap->reset_gpio_port[0])) |
577 | gpio_free(omap->reset_gpio_port[0]); | 747 | gpio_free(omap->reset_gpio_port[0]); |