[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-usb
Subject: [RFC 19/22] xhci: Fix re-init on power loss after resume.
From: Sarah Sharp <sarah.a.sharp () linux ! intel ! com>
Date: 2010-12-30 23:37:24
Message-ID: 05f568e11b378f9f1ffa87fdbbede3d9f14368da.1293748395.git.sarah.a.sharp () linux ! intel ! com
[Download RAW message or body]
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>
---
drivers/usb/host/xhci.c | 23 +++++++++++++++++++----
1 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 7ebf9fb..e3e5eea 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -729,6 +729,7 @@ 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;
old_state = hcd->state;
@@ -790,15 +791,29 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
xhci_dbg(xhci, "xhci_stop completed - status = %x\n",
xhci_readl(xhci, &xhci->op_regs->status));
- xhci_dbg(xhci, "Initialize the HCD\n");
- retval = xhci_init(hcd);
+ /* USB core calls the PCI reinit and start functions twice:
+ * first with the primary HCD, and then with the secondary HCD.
+ * If we don't do the same, the host will never be started.
+ */
+ if (!usb_hcd_is_primary_hcd(hcd))
+ secondary_hcd = hcd;
+ else
+ secondary_hcd = hcd->shared_hcd;
+
+ xhci_dbg(xhci, "Initialize the xhci_hcd\n");
+ retval = xhci_init(hcd->primary_hcd);
if (retval)
return retval;
+ xhci_dbg(xhci, "Start the primary HCD\n");
+ retval = xhci_run(hcd->primary_hcd);
+ if (retval)
+ goto failed_restart;
- xhci_dbg(xhci, "Start the HCD\n");
- retval = xhci_run(hcd);
+ xhci_dbg(xhci, "Start the secondary HCD\n");
+ retval = xhci_run(secondary_hcd);
if (!retval)
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+failed_restart:
hcd->state = HC_STATE_SUSPENDED;
return retval;
}
--
1.6.3.3
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic