On 6.9.2019 8.36, Rick Tseng wrote:
NVIDIA 3.1 xHCI card would lose power when moving power state into D3Cold.
Thus we need to wait CNR bit to clear when xhci resmue as xhci init.
Signed-off-by: Rick Tseng <rtseng@xxxxxxxxxx>
---
drivers/usb/host/xhci.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 03d1e55..6c7102c 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1108,6 +1108,15 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
hibernated = true;
if (!hibernated) {
+ /* Some xHC would lose power during suspend, so wait for
+ * controller ready from resume as xHC init.
+ */
+ if (xhci_handshake(&xhci->op_regs->status,
+ STS_CNR, 0, 10 * 1000 * 1000)) {
+ xhci_warn(xhci, "WARN: xHC timeout for CNR clear\n");
+ spin_unlock_irq(&xhci->lock);
+ return -ETIMEDOUT;
+ }
xhci_handshake() can return -ENODEV in case controller is not reachable (still in PCI D3).
Would be better to just show and return what xhci_handshake() returns.
I know there are places where the existing code doesn't do this, but it would be
better to add it for new code
ret = xhci_handshake(CNR bit clear)
if (ret) {
xhci_warn(xhci, "Controller not ready at resume %d\n", ret);
unlock()
return ret
}
-Mathias