| From 191edc5e2e515aab1075a3f0ef23599e80be5f59 Mon Sep 17 00:00:00 2001 |
| From: Kai-Heng Feng <kai.heng.feng@canonical.com> |
| Date: Thu, 8 Mar 2018 17:17:17 +0200 |
| Subject: xhci: Fix front USB ports on ASUS PRIME B350M-A |
| |
| From: Kai-Heng Feng <kai.heng.feng@canonical.com> |
| |
| commit 191edc5e2e515aab1075a3f0ef23599e80be5f59 upstream. |
| |
| When a USB device gets plugged on ASUS PRIME B350M-A's front ports, the |
| xHC stops working: |
| [ 549.114587] xhci_hcd 0000:02:00.0: WARN: xHC CMD_RUN timeout |
| [ 549.114608] suspend_common(): xhci_pci_suspend+0x0/0xc0 returns -110 |
| [ 549.114638] xhci_hcd 0000:02:00.0: can't suspend (hcd_pci_runtime_suspend returned -110) |
| |
| Delay before running xHC command CMD_RUN can workaround the issue. |
| |
| Use a new quirk to make the delay only targets to the affected xHC. |
| |
| Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> |
| Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> |
| Cc: stable <stable@vger.kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/usb/host/xhci-pci.c | 3 +++ |
| drivers/usb/host/xhci.c | 3 +++ |
| drivers/usb/host/xhci.h | 1 + |
| 3 files changed, 7 insertions(+) |
| |
| --- a/drivers/usb/host/xhci-pci.c |
| +++ b/drivers/usb/host/xhci-pci.c |
| @@ -134,6 +134,9 @@ static void xhci_pci_quirks(struct devic |
| if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) |
| xhci->quirks |= XHCI_AMD_PLL_FIX; |
| |
| + if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x43bb) |
| + xhci->quirks |= XHCI_SUSPEND_DELAY; |
| + |
| if (pdev->vendor == PCI_VENDOR_ID_AMD) |
| xhci->quirks |= XHCI_TRUST_TX_LENGTH; |
| |
| --- a/drivers/usb/host/xhci.c |
| +++ b/drivers/usb/host/xhci.c |
| @@ -887,6 +887,9 @@ int xhci_suspend(struct xhci_hcd *xhci, |
| clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); |
| del_timer_sync(&xhci->shared_hcd->rh_timer); |
| |
| + if (xhci->quirks & XHCI_SUSPEND_DELAY) |
| + usleep_range(1000, 1500); |
| + |
| spin_lock_irq(&xhci->lock); |
| clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
| clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); |
| --- a/drivers/usb/host/xhci.h |
| +++ b/drivers/usb/host/xhci.h |
| @@ -1830,6 +1830,7 @@ struct xhci_hcd { |
| #define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26) |
| /* Reserved. It was XHCI_U2_DISABLE_WAKE */ |
| #define XHCI_ASMEDIA_MODIFY_FLOWCONTROL (1 << 28) |
| +#define XHCI_SUSPEND_DELAY (1 << 30) |
| |
| unsigned int num_active_eps; |
| unsigned int limit_active_eps; |