diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2011-03-07 14:24:07 -0500 |
---|---|---|
committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2011-03-13 21:23:47 -0400 |
commit | b320937972d456db2a46fdcbc6bebc4dcdc9daa4 (patch) | |
tree | a41cfa6897e7b2d6dfd79e43cfb6c77dbd9bf6a7 | |
parent | 65b22f93fde320b34d43e4a3978e1b52b1bcc279 (diff) |
xhci: Fixes for suspend/resume of shared HCDs.
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.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
-rw-r--r-- | drivers/usb/host/xhci-pci.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 6 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 8 |
3 files changed, 13 insertions, 4 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 4a9d55e80f73..ceea9f33491c 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -225,7 +225,8 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) | |||
225 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 225 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
226 | int retval = 0; | 226 | int retval = 0; |
227 | 227 | ||
228 | if (hcd->state != HC_STATE_SUSPENDED) | 228 | if (hcd->state != HC_STATE_SUSPENDED || |
229 | xhci->shared_hcd->state != HC_STATE_SUSPENDED) | ||
229 | return -EINVAL; | 230 | return -EINVAL; |
230 | 231 | ||
231 | retval = xhci_suspend(xhci); | 232 | retval = xhci_suspend(xhci); |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 3bdf30dd8ce6..bd0f2343ef9c 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -2256,10 +2256,12 @@ hw_died: | |||
2256 | irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd) | 2256 | irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd) |
2257 | { | 2257 | { |
2258 | irqreturn_t ret; | 2258 | irqreturn_t ret; |
2259 | struct xhci_hcd *xhci; | ||
2259 | 2260 | ||
2261 | xhci = hcd_to_xhci(hcd); | ||
2260 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | 2262 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); |
2261 | if (hcd->shared_hcd) | 2263 | if (xhci->shared_hcd) |
2262 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); | 2264 | set_bit(HCD_FLAG_SAW_IRQ, &xhci->shared_hcd->flags); |
2263 | 2265 | ||
2264 | ret = xhci_irq(hcd); | 2266 | ret = xhci_irq(hcd); |
2265 | 2267 | ||
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ce024dc7116f..238ebe158b83 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -681,6 +681,7 @@ int xhci_suspend(struct xhci_hcd *xhci) | |||
681 | 681 | ||
682 | spin_lock_irq(&xhci->lock); | 682 | spin_lock_irq(&xhci->lock); |
683 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 683 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
684 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); | ||
684 | /* step 1: stop endpoint */ | 685 | /* step 1: stop endpoint */ |
685 | /* skipped assuming that port suspend has done */ | 686 | /* skipped assuming that port suspend has done */ |
686 | 687 | ||
@@ -811,10 +812,14 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
811 | 812 | ||
812 | xhci_dbg(xhci, "Start the secondary HCD\n"); | 813 | xhci_dbg(xhci, "Start the secondary HCD\n"); |
813 | retval = xhci_run(secondary_hcd); | 814 | retval = xhci_run(secondary_hcd); |
814 | if (!retval) | 815 | if (!retval) { |
815 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 816 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
817 | set_bit(HCD_FLAG_HW_ACCESSIBLE, | ||
818 | &xhci->shared_hcd->flags); | ||
819 | } | ||
816 | failed_restart: | 820 | failed_restart: |
817 | hcd->state = HC_STATE_SUSPENDED; | 821 | hcd->state = HC_STATE_SUSPENDED; |
822 | xhci->shared_hcd->state = HC_STATE_SUSPENDED; | ||
818 | return retval; | 823 | return retval; |
819 | } | 824 | } |
820 | 825 | ||
@@ -835,6 +840,7 @@ failed_restart: | |||
835 | */ | 840 | */ |
836 | 841 | ||
837 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 842 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
843 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); | ||
838 | 844 | ||
839 | spin_unlock_irq(&xhci->lock); | 845 | spin_unlock_irq(&xhci->lock); |
840 | return 0; | 846 | return 0; |