|
@@ -367,6 +367,13 @@ static int check_root_hub_suspended(struct device *dev)
|
|
|
dev_warn(dev, "Root hub is not suspended\n");
|
|
|
return -EBUSY;
|
|
|
}
|
|
|
+ if (hcd->shared_hcd) {
|
|
|
+ hcd = hcd->shared_hcd;
|
|
|
+ if (HCD_RH_RUNNING(hcd)) {
|
|
|
+ dev_warn(dev, "Secondary root hub is not suspended\n");
|
|
|
+ return -EBUSY;
|
|
|
+ }
|
|
|
+ }
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -391,11 +398,16 @@ static int suspend_common(struct device *dev, bool do_wakeup)
|
|
|
*/
|
|
|
if (do_wakeup && HCD_WAKEUP_PENDING(hcd))
|
|
|
return -EBUSY;
|
|
|
+ if (do_wakeup && hcd->shared_hcd &&
|
|
|
+ HCD_WAKEUP_PENDING(hcd->shared_hcd))
|
|
|
+ return -EBUSY;
|
|
|
retval = hcd->driver->pci_suspend(hcd, do_wakeup);
|
|
|
suspend_report_result(hcd->driver->pci_suspend, retval);
|
|
|
|
|
|
/* Check again in case wakeup raced with pci_suspend */
|
|
|
- if (retval == 0 && do_wakeup && HCD_WAKEUP_PENDING(hcd)) {
|
|
|
+ if ((retval == 0 && do_wakeup && HCD_WAKEUP_PENDING(hcd)) ||
|
|
|
+ (retval == 0 && do_wakeup && hcd->shared_hcd &&
|
|
|
+ HCD_WAKEUP_PENDING(hcd->shared_hcd))) {
|
|
|
if (hcd->driver->pci_resume)
|
|
|
hcd->driver->pci_resume(hcd, false);
|
|
|
retval = -EBUSY;
|
|
@@ -426,7 +438,9 @@ static int resume_common(struct device *dev, int event)
|
|
|
struct usb_hcd *hcd = pci_get_drvdata(pci_dev);
|
|
|
int retval;
|
|
|
|
|
|
- if (HCD_RH_RUNNING(hcd)) {
|
|
|
+ if (HCD_RH_RUNNING(hcd) ||
|
|
|
+ (hcd->shared_hcd &&
|
|
|
+ HCD_RH_RUNNING(hcd->shared_hcd))) {
|
|
|
dev_dbg(dev, "can't resume, not suspended!\n");
|
|
|
return 0;
|
|
|
}
|
|
@@ -440,6 +454,8 @@ static int resume_common(struct device *dev, int event)
|
|
|
pci_set_master(pci_dev);
|
|
|
|
|
|
clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
|
|
|
+ if (hcd->shared_hcd)
|
|
|
+ clear_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags);
|
|
|
|
|
|
if (hcd->driver->pci_resume && !HCD_DEAD(hcd)) {
|
|
|
if (event != PM_EVENT_AUTO_RESUME)
|
|
@@ -449,6 +465,8 @@ static int resume_common(struct device *dev, int event)
|
|
|
event == PM_EVENT_RESTORE);
|
|
|
if (retval) {
|
|
|
dev_err(dev, "PCI post-resume error %d!\n", retval);
|
|
|
+ if (hcd->shared_hcd)
|
|
|
+ usb_hc_died(hcd->shared_hcd);
|
|
|
usb_hc_died(hcd);
|
|
|
}
|
|
|
}
|
|
@@ -474,8 +492,9 @@ static int hcd_pci_suspend_noirq(struct device *dev)
|
|
|
|
|
|
pci_save_state(pci_dev);
|
|
|
|
|
|
- /* If the root hub is dead rather than suspended,
|
|
|
- * disallow remote wakeup.
|
|
|
+ /* If the root hub is dead rather than suspended, disallow remote
|
|
|
+ * wakeup. usb_hc_died() should ensure that both hosts are marked as
|
|
|
+ * dying, so we only need to check the primary roothub.
|
|
|
*/
|
|
|
if (HCD_DEAD(hcd))
|
|
|
device_set_wakeup_enable(dev, 0);
|