diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c index 8de0da0e6dfc..4cd79888804b 100644 --- a/drivers/usb/host/uhci-pci.c +++ b/drivers/usb/host/uhci-pci.c @@ -162,6 +162,8 @@ static void uhci_shutdown(struct pci_dev *pdev) #ifdef CONFIG_PM +static int uhci_pci_resume(struct usb_hcd *hcd, bool hibernated); + static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); @@ -174,12 +176,6 @@ static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) if (!HCD_HW_ACCESSIBLE(hcd) || uhci->dead) goto done_okay; /* Already suspended or dead */ - if (uhci->rh_state > UHCI_RH_SUSPENDED) { - dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n"); - rc = -EBUSY; - goto done; - } - /* All PCI host controllers are required to disable IRQ generation * at the source, so we must turn off PIRQ. */ @@ -195,8 +191,15 @@ static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) done_okay: clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); -done: spin_unlock_irq(&uhci->lock); + + synchronize_irq(hcd->irq); + + /* Check for race with a wakeup request */ + if (do_wakeup && HCD_WAKEUP_PENDING(hcd)) { + uhci_pci_resume(hcd, false); + rc = -EBUSY; + } return rc; }