|
@@ -120,9 +120,26 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
|
|
|
del_timer_sync(&ehci->watchdog);
|
|
|
del_timer_sync(&ehci->iaa_watchdog);
|
|
|
|
|
|
- port = HCS_N_PORTS (ehci->hcs_params);
|
|
|
spin_lock_irq (&ehci->lock);
|
|
|
|
|
|
+ /* Once the controller is stopped, port resumes that are already
|
|
|
+ * in progress won't complete. Hence if remote wakeup is enabled
|
|
|
+ * for the root hub and any ports are in the middle of a resume or
|
|
|
+ * remote wakeup, we must fail the suspend.
|
|
|
+ */
|
|
|
+ if (hcd->self.root_hub->do_remote_wakeup) {
|
|
|
+ port = HCS_N_PORTS(ehci->hcs_params);
|
|
|
+ while (port--) {
|
|
|
+ if (ehci->reset_done[port] != 0) {
|
|
|
+ spin_unlock_irq(&ehci->lock);
|
|
|
+ ehci_dbg(ehci, "suspend failed because "
|
|
|
+ "port %d is resuming\n",
|
|
|
+ port + 1);
|
|
|
+ return -EBUSY;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/* stop schedules, clean any completed work */
|
|
|
if (HC_IS_RUNNING(hcd->state)) {
|
|
|
ehci_quiesce (ehci);
|
|
@@ -138,6 +155,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
|
|
|
*/
|
|
|
ehci->bus_suspended = 0;
|
|
|
ehci->owned_ports = 0;
|
|
|
+ port = HCS_N_PORTS(ehci->hcs_params);
|
|
|
while (port--) {
|
|
|
u32 __iomem *reg = &ehci->regs->port_status [port];
|
|
|
u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
|