Re: [PATCH V3] xhci: Reset TI USB controller on xhci shutdown

From: Wen Xiong

Date: Wed Oct 28 2026 - 16:54:54 EST



I tried to make this code a bit more "proper", by moving the
pci_reset_function_locked() call to xhci-pci.c from xhci.c.

I found that when I actually run this, I get a warning from PCI:

unlocked secondary bus reset via: __pci_reset_function_locked


Hi Michal,

How about we add check TI/failling usb controller in xhci_halt and xhci_pci_shutdown?

Thanks,
Wendy
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index a8889081ae82..af6ca5447f22 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -950,6 +950,10 @@ static void xhci_pci_shutdown(struct usb_hcd *hcd)
/* Yet another workaround for spurious wakeups at shutdown with HSW */
if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
pci_set_power_state(pdev, PCI_D3hot);
+
+ /* TI XHCI controllers do not come back after kexec without this hack */
+ if (xhci->quirks & XHCI_HALT_FAIL_TO_RESET)
+ pci_reset_function_locked(pdev);
}
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.cW
index a9e47e178c28..67108692a354 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -120,6 +120,8 @@ void xhci_quiesce(struct xhci_hcd *xhci)
*/
int xhci_halt(struct xhci_hcd *xhci)
{
+ struct usb_hcd *hcd = xhci_to_hcd(xhci);
+ struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
int ret;

xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Halt the HC");
@@ -130,6 +132,11 @@ int xhci_halt(struct xhci_hcd *xhci)
if (ret) {
if (!(xhci->xhc_state & XHCI_STATE_DYING))
xhci_warn(xhci, "Host halt failed, %d\n", ret);
+
+ if (pdev->vendor == PCI_VENDOR_ID_TI &&
+ pdev->device == 0x8241)
+ xhci->quirks |= XHCI_HALT_FAIL_TO_RESET;
+
return ret;
}