diff options
author | Jason Wessel <jason.wessel@windriver.com> | 2009-08-20 16:39:55 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-23 09:46:38 -0400 |
commit | aab2d4086a1876fcff282aa36e2d4a92aa9935c9 (patch) | |
tree | 3b1bb3d934bec91c44eaf61aadb6c624eb8dd9b3 /drivers/usb/early | |
parent | 8d053c79f22462f55c02c8083580730b922cf7b4 (diff) |
USB: ehci-dbgp: errata for EHCI debug controller initialization
On some EHCI usb debug controllers, the EHCI debug device will fail to
be seen after a port reset, after a warm reset. Two options exist to
get the device to initialize correctly.
Option 1 is to unplug and plug in the device.
Option 2 is to use the EHCI port test to get the usb debug device to
start talking again. At that point the debug controller port reset
will succeed.
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
CC: dbrownell@users.sourceforge.net
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/early')
-rw-r--r-- | drivers/usb/early/ehci-dbgp.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index b88cb65b64e0..f0a41c647bef 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c | |||
@@ -478,10 +478,13 @@ int dbgp_external_startup(void) | |||
478 | int devnum; | 478 | int devnum; |
479 | struct usb_debug_descriptor dbgp_desc; | 479 | struct usb_debug_descriptor dbgp_desc; |
480 | int ret; | 480 | int ret; |
481 | u32 ctrl, portsc; | 481 | u32 ctrl, portsc, cmd; |
482 | int dbg_port = dbgp_phys_port; | 482 | int dbg_port = dbgp_phys_port; |
483 | int tries = 3; | 483 | int tries = 3; |
484 | int reset_port_tries = 1; | ||
485 | int try_hard_once = 1; | ||
484 | 486 | ||
487 | try_port_reset_again: | ||
485 | ret = dbgp_ehci_startup(); | 488 | ret = dbgp_ehci_startup(); |
486 | if (ret) | 489 | if (ret) |
487 | return ret; | 490 | return ret; |
@@ -490,6 +493,24 @@ int dbgp_external_startup(void) | |||
490 | ret = ehci_wait_for_port(dbg_port); | 493 | ret = ehci_wait_for_port(dbg_port); |
491 | if (ret < 0) { | 494 | if (ret < 0) { |
492 | portsc = readl(&ehci_regs->port_status[dbg_port - 1]); | 495 | portsc = readl(&ehci_regs->port_status[dbg_port - 1]); |
496 | if (!(portsc & PORT_CONNECT) && try_hard_once) { | ||
497 | /* Last ditch effort to try to force enable | ||
498 | * the debug device by using the packet test | ||
499 | * ehci command to try and wake it up. */ | ||
500 | try_hard_once = 0; | ||
501 | cmd = readl(&ehci_regs->command); | ||
502 | cmd &= ~CMD_RUN; | ||
503 | writel(cmd, &ehci_regs->command); | ||
504 | portsc = readl(&ehci_regs->port_status[dbg_port - 1]); | ||
505 | portsc |= PORT_TEST_PKT; | ||
506 | writel(portsc, &ehci_regs->port_status[dbg_port - 1]); | ||
507 | dbgp_ehci_status("Trying to force debug port online"); | ||
508 | mdelay(50); | ||
509 | dbgp_ehci_controller_reset(); | ||
510 | goto try_port_reset_again; | ||
511 | } else if (reset_port_tries--) { | ||
512 | goto try_port_reset_again; | ||
513 | } | ||
493 | dbgp_printk("No device found in debug port\n"); | 514 | dbgp_printk("No device found in debug port\n"); |
494 | return -EIO; | 515 | return -EIO; |
495 | } | 516 | } |