|
@@ -968,6 +968,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
|
|
|
unsigned int delay = XHCI_MAX_HALT_USEC;
|
|
|
struct usb_hcd *hcd = xhci_to_hcd(xhci);
|
|
|
u32 command;
|
|
|
+ u32 res;
|
|
|
|
|
|
if (!hcd->state)
|
|
|
return 0;
|
|
@@ -1021,11 +1022,28 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
|
|
|
command = readl(&xhci->op_regs->command);
|
|
|
command |= CMD_CSS;
|
|
|
writel(command, &xhci->op_regs->command);
|
|
|
+ xhci->broken_suspend = 0;
|
|
|
if (xhci_handshake(&xhci->op_regs->status,
|
|
|
STS_SAVE, 0, 10 * 1000)) {
|
|
|
- xhci_warn(xhci, "WARN: xHC save state timeout\n");
|
|
|
- spin_unlock_irq(&xhci->lock);
|
|
|
- return -ETIMEDOUT;
|
|
|
+ /*
|
|
|
+ * AMD SNPS xHC 3.0 occasionally does not clear the
|
|
|
+ * SSS bit of USBSTS and when driver tries to poll
|
|
|
+ * to see if the xHC clears BIT(8) which never happens
|
|
|
+ * and driver assumes that controller is not responding
|
|
|
+ * and times out. To workaround this, its good to check
|
|
|
+ * if SRE and HCE bits are not set (as per xhci
|
|
|
+ * Section 5.4.2) and bypass the timeout.
|
|
|
+ */
|
|
|
+ res = readl(&xhci->op_regs->status);
|
|
|
+ if ((xhci->quirks & XHCI_SNPS_BROKEN_SUSPEND) &&
|
|
|
+ (((res & STS_SRE) == 0) &&
|
|
|
+ ((res & STS_HCE) == 0))) {
|
|
|
+ xhci->broken_suspend = 1;
|
|
|
+ } else {
|
|
|
+ xhci_warn(xhci, "WARN: xHC save state timeout\n");
|
|
|
+ spin_unlock_irq(&xhci->lock);
|
|
|
+ return -ETIMEDOUT;
|
|
|
+ }
|
|
|
}
|
|
|
spin_unlock_irq(&xhci->lock);
|
|
|
|
|
@@ -1078,7 +1096,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
|
|
set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
|
|
|
|
|
|
spin_lock_irq(&xhci->lock);
|
|
|
- if (xhci->quirks & XHCI_RESET_ON_RESUME)
|
|
|
+ if ((xhci->quirks & XHCI_RESET_ON_RESUME) || xhci->broken_suspend)
|
|
|
hibernated = true;
|
|
|
|
|
|
if (!hibernated) {
|