aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2010-12-17 15:35:05 -0500
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2011-03-13 21:23:45 -0400
commit65b22f93fde320b34d43e4a3978e1b52b1bcc279 (patch)
tree087312018a0076866f28e056f1481db76cfe2b78 /drivers/usb/host/xhci.c
parentf9de8151877b4f01cc8e124b0e213a6c6c78d970 (diff)
xhci: Fix re-init on power loss after resume.
When a host controller has lost power during a suspend, we must reinitialize it. Now that the xHCI host has two roothubs, xhci_run() and xhci_stop() expect to be called with both usb_hcd structures. Be sure that the re-initialization code in xhci_resume() mirrors the process the USB PCI probe function uses. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r--drivers/usb/host/xhci.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 4549068758f5..ce024dc7116f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -730,6 +730,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
730{ 730{
731 u32 command, temp = 0; 731 u32 command, temp = 0;
732 struct usb_hcd *hcd = xhci_to_hcd(xhci); 732 struct usb_hcd *hcd = xhci_to_hcd(xhci);
733 struct usb_hcd *secondary_hcd;
733 int retval; 734 int retval;
734 735
735 /* Wait a bit if either of the roothubs need to settle from the 736 /* Wait a bit if either of the roothubs need to settle from the
@@ -790,15 +791,29 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
790 xhci_dbg(xhci, "xhci_stop completed - status = %x\n", 791 xhci_dbg(xhci, "xhci_stop completed - status = %x\n",
791 xhci_readl(xhci, &xhci->op_regs->status)); 792 xhci_readl(xhci, &xhci->op_regs->status));
792 793
793 xhci_dbg(xhci, "Initialize the HCD\n"); 794 /* USB core calls the PCI reinit and start functions twice:
794 retval = xhci_init(hcd); 795 * first with the primary HCD, and then with the secondary HCD.
796 * If we don't do the same, the host will never be started.
797 */
798 if (!usb_hcd_is_primary_hcd(hcd))
799 secondary_hcd = hcd;
800 else
801 secondary_hcd = xhci->shared_hcd;
802
803 xhci_dbg(xhci, "Initialize the xhci_hcd\n");
804 retval = xhci_init(hcd->primary_hcd);
795 if (retval) 805 if (retval)
796 return retval; 806 return retval;
807 xhci_dbg(xhci, "Start the primary HCD\n");
808 retval = xhci_run(hcd->primary_hcd);
809 if (retval)
810 goto failed_restart;
797 811
798 xhci_dbg(xhci, "Start the HCD\n"); 812 xhci_dbg(xhci, "Start the secondary HCD\n");
799 retval = xhci_run(hcd); 813 retval = xhci_run(secondary_hcd);
800 if (!retval) 814 if (!retval)
801 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 815 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
816failed_restart:
802 hcd->state = HC_STATE_SUSPENDED; 817 hcd->state = HC_STATE_SUSPENDED;
803 return retval; 818 return retval;
804 } 819 }