Make sure the HCD_FLAG_HW_ACCESSIBLE flag is mirrored by both roothubs, since it refers to whether the shared hardware is accessible. Make sure each bus is marked as suspended by setting usb_hcd->state to HC_STATE_SUSPENDED when the PCI host controller is resumed. If the host is resumed, and the power session is not lost, then make sure to set the state of each host controller to what it was before. (NOTE: this code is on an unreachable code path, and I'm waiting on a formal patch from Andiry to fix it.) Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx> --- drivers/usb/host/xhci-pci.c | 3 ++- drivers/usb/host/xhci.c | 24 ++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 69c235f..63bd55b 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -157,7 +157,8 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) struct xhci_hcd *xhci = hcd_to_xhci(hcd); int retval = 0; - if (hcd->state != HC_STATE_SUSPENDED) + if (hcd->state != HC_STATE_SUSPENDED || + hcd->shared_hcd->state != HC_STATE_SUSPENDED) return -EINVAL; retval = xhci_suspend(xhci); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index e3e5eea..0a5d168 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -680,6 +680,7 @@ int xhci_suspend(struct xhci_hcd *xhci) spin_lock_irq(&xhci->lock); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->shared_hcd->flags); /* step 1: stop endpoint */ /* skipped assuming that port suspend has done */ @@ -730,9 +731,12 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) u32 command, temp = 0; struct usb_hcd *hcd = xhci_to_hcd(xhci); struct usb_hcd *secondary_hcd; - int old_state, retval; + int primary_hcd_old_state; + int secondary_hcd_old_state; + int retval; - old_state = hcd->state; + primary_hcd_old_state = hcd->primary_hcd->state; + secondary_hcd_old_state = hcd->primary_hcd->shared_hcd->state; /* Wait a bit if either of the roothubs need to settle from the * transistion into bus suspend. */ @@ -811,10 +815,14 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) xhci_dbg(xhci, "Start the secondary HCD\n"); retval = xhci_run(secondary_hcd); - if (!retval) + if (!retval) { set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + set_bit(HCD_FLAG_HW_ACCESSIBLE, + &hcd->shared_hcd->flags); + } failed_restart: hcd->state = HC_STATE_SUSPENDED; + hcd->shared_hcd->state = HC_STATE_SUSPENDED; return retval; } @@ -835,10 +843,14 @@ failed_restart: */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - if (!hibernated) - hcd->state = old_state; - else + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->shared_hcd->flags); + if (!hibernated) { + hcd->primary_hcd->state = primary_hcd_old_state; + hcd->primary_hcd->shared_hcd->state = secondary_hcd_old_state; + } else { hcd->state = HC_STATE_SUSPENDED; + hcd->shared_hcd->state = HC_STATE_SUSPENDED; + } spin_unlock_irq(&xhci->lock); return 0; -- 1.6.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html