diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2010-05-12 18:21:35 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-05-20 16:21:45 -0400 |
commit | 16032c4f5b291af541e9114a09ea20ff5a0dc474 (patch) | |
tree | 8f7a6b98859220410bdde08671039ec888635ffe /drivers/usb/host/ehci-pci.c | |
parent | eab80de01cb398419ef3305f35abcb367c647c8b (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.c | 15 |
1 files changed, 4 insertions, 11 deletions
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index d120059bbbf7..d43d176161aa 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); |