blob: 174d33a0be211c1cb89289f4de4b0ce430949f5f [file] [log] [blame]
From c2e1abb35b37a2b46220ea0af7c8d70d8c09edf6 Mon Sep 17 00:00:00 2001
From: Joel Stanley <joel@jms.id.au>
Date: Fri, 7 Apr 2017 17:57:00 +0300
Subject: [PATCH 186/286] xhci: Do not halt the host until both HCD have
disconnected their devices.
We can't halt the host controller immediately when first HCD is removed as
it will cause problems if we have devices attached to the second (primary)
HCD, like a keyboard.
We've been carrying this in our Linux-as-a-bootloader environment for a
little while now. The machines all have the same TI TUSB73x0 part,
and when we kexec the devices don't come back until a system power cycle.
[minor adjustments, code comments and remove HALT check -Mathias]
Signed-off-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit fe190ed0d60260e44f48d8b0b04f26a8c8898a02)
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
drivers/usb/host/xhci.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -692,21 +692,21 @@ void xhci_stop(struct usb_hcd *hcd)
mutex_lock(&xhci->mutex);
- if (!(xhci->xhc_state & XHCI_STATE_HALTED)) {
- spin_lock_irq(&xhci->lock);
-
- xhci->xhc_state |= XHCI_STATE_HALTED;
- xhci->cmd_ring_state = CMD_RING_STATE_STOPPED;
- xhci_halt(xhci);
- xhci_reset(xhci);
- spin_unlock_irq(&xhci->lock);
- }
-
+ /* Only halt host and free memory after both hcds are removed */
if (!usb_hcd_is_primary_hcd(hcd)) {
+ /* usb core will free this hcd shortly, unset pointer */
+ xhci->shared_hcd = NULL;
mutex_unlock(&xhci->mutex);
return;
}
+ spin_lock_irq(&xhci->lock);
+ xhci->xhc_state |= XHCI_STATE_HALTED;
+ xhci->cmd_ring_state = CMD_RING_STATE_STOPPED;
+ xhci_halt(xhci);
+ xhci_reset(xhci);
+ spin_unlock_irq(&xhci->lock);
+
xhci_cleanup_msix(xhci);
/* Deleting Compliance Mode Recovery Timer */