diff options
Diffstat (limited to 'drivers/usb/host/ehci-hub.c')
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 2c6571c05f35..c75d9270c752 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -120,9 +120,26 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
120 | del_timer_sync(&ehci->watchdog); | 120 | del_timer_sync(&ehci->watchdog); |
121 | del_timer_sync(&ehci->iaa_watchdog); | 121 | del_timer_sync(&ehci->iaa_watchdog); |
122 | 122 | ||
123 | port = HCS_N_PORTS (ehci->hcs_params); | ||
124 | spin_lock_irq (&ehci->lock); | 123 | spin_lock_irq (&ehci->lock); |
125 | 124 | ||
125 | /* Once the controller is stopped, port resumes that are already | ||
126 | * in progress won't complete. Hence if remote wakeup is enabled | ||
127 | * for the root hub and any ports are in the middle of a resume or | ||
128 | * remote wakeup, we must fail the suspend. | ||
129 | */ | ||
130 | if (hcd->self.root_hub->do_remote_wakeup) { | ||
131 | port = HCS_N_PORTS(ehci->hcs_params); | ||
132 | while (port--) { | ||
133 | if (ehci->reset_done[port] != 0) { | ||
134 | spin_unlock_irq(&ehci->lock); | ||
135 | ehci_dbg(ehci, "suspend failed because " | ||
136 | "port %d is resuming\n", | ||
137 | port + 1); | ||
138 | return -EBUSY; | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | |||
126 | /* stop schedules, clean any completed work */ | 143 | /* stop schedules, clean any completed work */ |
127 | if (HC_IS_RUNNING(hcd->state)) { | 144 | if (HC_IS_RUNNING(hcd->state)) { |
128 | ehci_quiesce (ehci); | 145 | ehci_quiesce (ehci); |
@@ -138,6 +155,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
138 | */ | 155 | */ |
139 | ehci->bus_suspended = 0; | 156 | ehci->bus_suspended = 0; |
140 | ehci->owned_ports = 0; | 157 | ehci->owned_ports = 0; |
158 | port = HCS_N_PORTS(ehci->hcs_params); | ||
141 | while (port--) { | 159 | while (port--) { |
142 | u32 __iomem *reg = &ehci->regs->port_status [port]; | 160 | u32 __iomem *reg = &ehci->regs->port_status [port]; |
143 | u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; | 161 | u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; |