diff options
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); |