|
@@ -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;
|
|
|
}
|
|
|
|