aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-au1xxx.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2010-05-12 18:21:35 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-20 16:21:45 -0400
commit16032c4f5b291af541e9114a09ea20ff5a0dc474 (patch)
tree8f7a6b98859220410bdde08671039ec888635ffe /drivers/usb/host/ehci-au1xxx.c
parenteab80de01cb398419ef3305f35abcb367c647c8b (diff)
USB: EHCI: fix controller wakeup flag settings during suspend
This patch (as1380) fixes a bug in the wakeup settings for EHCI host controllers. When the controller is suspended, if it isn't enabled for remote wakeup then we have to turn off all the port wakeup flags. Disabling PCI PME# isn't good enough, because some systems (Intel) evidently use alternate wakeup signalling paths. In addition, the patch improves the handling of the Intel Moorestown hardware by performing various power-up and power-down delays just once instead of once for each port (i.e., the delays are moved outside of the port loops). This requires extra code, but the total delay time is reduced. There are also a few additional minor cleanups. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Reported-by: Ondrej Zary <linux@rainbow-software.org> CC: Alek Du <alek.du@intel.com> CC: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ehci-au1xxx.c')
-rw-r--r--drivers/usb/host/ehci-au1xxx.c16
1 files changed, 4 insertions, 12 deletions
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c
index 7a27b7c4ee84..faa61748db70 100644
--- a/drivers/usb/host/ehci-au1xxx.c
+++ b/drivers/usb/host/ehci-au1xxx.c
@@ -224,26 +224,17 @@ static int ehci_hcd_au1xxx_drv_suspend(struct device *dev)
224 msleep(10); 224 msleep(10);
225 225
226 /* Root hub was already suspended. Disable irq emission and 226 /* Root hub was already suspended. Disable irq emission and
227 * mark HW unaccessible, bail out if RH has been resumed. Use 227 * mark HW unaccessible. The PM and USB cores make sure that
228 * the spinlock to properly synchronize with possible pending 228 * the root hub is either suspended or stopped.
229 * RH suspend or resume activity.
230 *
231 * This is still racy as hcd->state is manipulated outside of
232 * any locks =P But that will be a different fix.
233 */ 229 */
234 spin_lock_irqsave(&ehci->lock, flags); 230 spin_lock_irqsave(&ehci->lock, flags);
235 if (hcd->state != HC_STATE_SUSPENDED) { 231 ehci_prepare_ports_for_controller_suspend(ehci);
236 rc = -EINVAL;
237 goto bail;
238 }
239 ehci_writel(ehci, 0, &ehci->regs->intr_enable); 232 ehci_writel(ehci, 0, &ehci->regs->intr_enable);
240 (void)ehci_readl(ehci, &ehci->regs->intr_enable); 233 (void)ehci_readl(ehci, &ehci->regs->intr_enable);
241 234
242 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 235 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
243 236
244 au1xxx_stop_ehc(); 237 au1xxx_stop_ehc();
245
246bail:
247 spin_unlock_irqrestore(&ehci->lock, flags); 238 spin_unlock_irqrestore(&ehci->lock, flags);
248 239
249 // could save FLADJ in case of Vaux power loss 240 // could save FLADJ in case of Vaux power loss
@@ -273,6 +264,7 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
273 if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { 264 if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) {
274 int mask = INTR_MASK; 265 int mask = INTR_MASK;
275 266
267 ehci_prepare_ports_for_controller_resume(ehci);
276 if (!hcd->self.root_hub->do_remote_wakeup) 268 if (!hcd->self.root_hub->do_remote_wakeup)
277 mask &= ~STS_PCD; 269 mask &= ~STS_PCD;
278 ehci_writel(ehci, mask, &ehci->regs->intr_enable); 270 ehci_writel(ehci, mask, &ehci->regs->intr_enable);