aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-pci.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-pci.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-pci.c')
-rw-r--r--drivers/usb/host/ehci-pci.c15
1 files changed, 4 insertions, 11 deletions
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index d120059bbbf..d43d176161a 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -287,23 +287,15 @@ static int ehci_pci_suspend(struct usb_hcd *hcd)
287 msleep(10); 287 msleep(10);
288 288
289 /* Root hub was already suspended. Disable irq emission and 289 /* Root hub was already suspended. Disable irq emission and
290 * mark HW unaccessible, bail out if RH has been resumed. Use 290 * mark HW unaccessible. The PM and USB cores make sure that
291 * the spinlock to properly synchronize with possible pending 291 * the root hub is either suspended or stopped.
292 * RH suspend or resume activity.
293 *
294 * This is still racy as hcd->state is manipulated outside of
295 * any locks =P But that will be a different fix.
296 */ 292 */
297 spin_lock_irqsave (&ehci->lock, flags); 293 spin_lock_irqsave (&ehci->lock, flags);
298 if (hcd->state != HC_STATE_SUSPENDED) { 294 ehci_prepare_ports_for_controller_suspend(ehci);
299 rc = -EINVAL;
300 goto bail;
301 }
302 ehci_writel(ehci, 0, &ehci->regs->intr_enable); 295 ehci_writel(ehci, 0, &ehci->regs->intr_enable);
303 (void)ehci_readl(ehci, &ehci->regs->intr_enable); 296 (void)ehci_readl(ehci, &ehci->regs->intr_enable);
304 297
305 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 298 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
306 bail:
307 spin_unlock_irqrestore (&ehci->lock, flags); 299 spin_unlock_irqrestore (&ehci->lock, flags);
308 300
309 // could save FLADJ in case of Vaux power loss 301 // could save FLADJ in case of Vaux power loss
@@ -333,6 +325,7 @@ static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated)
333 !hibernated) { 325 !hibernated) {
334 int mask = INTR_MASK; 326 int mask = INTR_MASK;
335 327
328 ehci_prepare_ports_for_controller_resume(ehci);
336 if (!hcd->self.root_hub->do_remote_wakeup) 329 if (!hcd->self.root_hub->do_remote_wakeup)
337 mask &= ~STS_PCD; 330 mask &= ~STS_PCD;
338 ehci_writel(ehci, mask, &ehci->regs->intr_enable); 331 ehci_writel(ehci, mask, &ehci->regs->intr_enable);