| From 622eb783fe6ff4c1baa47db16c3a5db97f9e6e50 Mon Sep 17 00:00:00 2001 |
| From: Andiry Xu <andiry.xu@gmail.com> |
| Date: Wed, 13 Jun 2012 10:51:57 +0800 |
| Subject: xHCI: Increase the timeout for controller save/restore state operation |
| |
| From: Andiry Xu <andiry.xu@gmail.com> |
| |
| commit 622eb783fe6ff4c1baa47db16c3a5db97f9e6e50 upstream. |
| |
| When system software decides to power down the xHC with the intent of |
| resuming operation at a later time, it will ask xHC to save the internal |
| state and restore it when resume to correctly recover from a power event. |
| Two bits are used to enable this operation: Save State and Restore State. |
| |
| xHCI spec 4.23.2 says software should "Set the Controller Save/Restore |
| State flag in the USBCMD register and wait for the Save/Restore State |
| Status flag in the USBSTS register to transition to '0'". However, it does |
| not define how long software should wait for the SSS/RSS bit to transition |
| to 0. |
| |
| Currently the timeout is set to 1ms. There is bug report |
| (https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1002697) |
| indicates that the timeout is too short for ASMedia ASM1042 host controller |
| to save/restore the state successfully. Increase the timeout to 10ms helps to |
| resolve the issue. |
| |
| This patch should be backported to stable kernels as old as 2.6.37, that |
| contain the commit 5535b1d5f8885695c6ded783c692e3c0d0eda8ca "USB: xHCI: |
| PCI power management implementation" |
| |
| Signed-off-by: Andiry Xu <andiry.xu@gmail.com> |
| Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> |
| Cc: Ming Lei <ming.lei@canonical.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/usb/host/xhci.c | 8 ++++---- |
| 1 file changed, 4 insertions(+), 4 deletions(-) |
| |
| --- a/drivers/usb/host/xhci.c |
| +++ b/drivers/usb/host/xhci.c |
| @@ -795,8 +795,8 @@ int xhci_suspend(struct xhci_hcd *xhci) |
| command = xhci_readl(xhci, &xhci->op_regs->command); |
| command |= CMD_CSS; |
| xhci_writel(xhci, command, &xhci->op_regs->command); |
| - if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10*100)) { |
| - xhci_warn(xhci, "WARN: xHC CMD_CSS timeout\n"); |
| + if (handshake(xhci, &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; |
| } |
| @@ -848,8 +848,8 @@ int xhci_resume(struct xhci_hcd *xhci, b |
| command |= CMD_CRS; |
| xhci_writel(xhci, command, &xhci->op_regs->command); |
| if (handshake(xhci, &xhci->op_regs->status, |
| - STS_RESTORE, 0, 10*100)) { |
| - xhci_dbg(xhci, "WARN: xHC CMD_CSS timeout\n"); |
| + STS_RESTORE, 0, 10 * 1000)) { |
| + xhci_warn(xhci, "WARN: xHC restore state timeout\n"); |
| spin_unlock_irq(&xhci->lock); |
| return -ETIMEDOUT; |
| } |