On Thu, May 17, 2012 at 7:41 PM, Richard Zhao <richard.zhao@xxxxxxxxxxxxx> wrote: > commit 3d9545cc375d117554a9b35dfddadf9189c62775 > Author: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> > Date: Mon Apr 23 13:54:36 2012 -0400 > > EHCI: maintain the ehci->command value properly > > The ehci-hcd driver is a little haphazard about keeping track of the > state of the USBCMD register. The ehci->command field is supposed to > hold the register's value (apart from a few special bits) at all > times, but it isn't maintained properly. > > This patch (as1543) cleans up the situation. It keeps ehci->command > up-to-date, and uses that value rather than reading the register from > the hardware whenever possible. > > Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> > Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> > > > The above commit causes failure of imx usb host hub detection. This commit may introduce an overriding problem on initial configuration of CMD: initial configuration of CMD is figured out in ehci_init, but is override later in the following ehci_reset, see ehci_setup. So could you please try the below patch to see if it can fix your problem? diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index f644ba9..29a9057 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -318,8 +318,7 @@ static void tdi_reset (struct ehci_hcd *ehci) ehci_writel(ehci, tmp, reg_ptr); } -/* reset a non-running (STS_HALT == 1) controller */ -static int ehci_reset (struct ehci_hcd *ehci) +static int __ehci_reset (struct ehci_hcd *ehci) { int retval; u32 command = ehci_readl(ehci, &ehci->regs->command); @@ -352,12 +351,27 @@ static int ehci_reset (struct ehci_hcd *ehci) if (ehci->debug) dbgp_external_startup(); - ehci->command = ehci_readl(ehci, &ehci->regs->command); ehci->port_c_suspend = ehci->suspended_ports = ehci->resuming_ports = 0; return retval; } +/* ehci hardware init */ +static int ehci_hw_init (struct ehci_hcd *ehci) +{ + return __ehci_reset(ehci); +} + +/* reset a non-running (STS_HALT == 1) controller */ +static int ehci_reset (struct ehci_hcd *ehci) +{ + int val; + val = __ehci_reset(ehci); + ehci->command = ehci_readl(ehci, &ehci->regs->command); + + return val; +} + /* idle the controller (from running) */ static void ehci_quiesce (struct ehci_hcd *ehci) { @@ -836,7 +850,7 @@ static int __maybe_unused ehci_setup (struct usb_hcd *hcd) if (retval) return retval; - ehci_reset(ehci); + ehci_hw_init(ehci); return 0; } Thanks, -- Ming Lei -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html