Skip to content

Commit

Permalink
USB: ehci-dbgp: errata for EHCI debug controller initialization
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jason Wessel authored and Greg Kroah-Hartman committed Sep 23, 2009
1 parent 8d053c7 commit aab2d40
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
23 changes: 22 additions & 1 deletion drivers/usb/early/ehci-dbgp.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,10 +478,13 @@ int dbgp_external_startup(void)
int devnum;
struct usb_debug_descriptor dbgp_desc;
int ret;
u32 ctrl, portsc;
u32 ctrl, portsc, cmd;
int dbg_port = dbgp_phys_port;
int tries = 3;
int reset_port_tries = 1;
int try_hard_once = 1;

try_port_reset_again:
ret = dbgp_ehci_startup();
if (ret)
return ret;
Expand All @@ -490,6 +493,24 @@ int dbgp_external_startup(void)
ret = ehci_wait_for_port(dbg_port);
if (ret < 0) {
portsc = readl(&ehci_regs->port_status[dbg_port - 1]);
if (!(portsc & PORT_CONNECT) && try_hard_once) {
/* Last ditch effort to try to force enable
* the debug device by using the packet test
* ehci command to try and wake it up. */
try_hard_once = 0;
cmd = readl(&ehci_regs->command);
cmd &= ~CMD_RUN;
writel(cmd, &ehci_regs->command);
portsc = readl(&ehci_regs->port_status[dbg_port - 1]);
portsc |= PORT_TEST_PKT;
writel(portsc, &ehci_regs->port_status[dbg_port - 1]);
dbgp_ehci_status("Trying to force debug port online");
mdelay(50);
dbgp_ehci_controller_reset();
goto try_port_reset_again;
} else if (reset_port_tries--) {
goto try_port_reset_again;
}
dbgp_printk("No device found in debug port\n");
return -EIO;
}
Expand Down
1 change: 1 addition & 0 deletions include/linux/usb/ehci_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ struct ehci_regs {
#define PORT_WKDISC_E (1<<21) /* wake on disconnect (enable) */
#define PORT_WKCONN_E (1<<20) /* wake on connect (enable) */
/* 19:16 for port testing */
#define PORT_TEST_PKT (0x4<<16) /* Port Test Control - packet test */
#define PORT_LED_OFF (0<<14)
#define PORT_LED_AMBER (1<<14)
#define PORT_LED_GREEN (2<<14)
Expand Down

0 comments on commit aab2d40

Please sign in to comment.