summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRajmohan Mani <rajmohan.mani@intel.com>2015-11-18 11:48:20 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-12-09 22:34:43 +0300
commit7588e627c8891e53e86c600d312cef20acef81e5 (patch)
treea1a35c859588a5791d618a431295862342e8008c
parent2be56f43e40a65249132d153b14b8c33cb635d4d (diff)
downloadlinux-7588e627c8891e53e86c600d312cef20acef81e5.tar.xz
xhci: Workaround to get Intel xHCI reset working more reliably
commit a5964396190d0c40dd549c23848c282fffa5d1f2 upstream. Existing Intel xHCI controllers require a delay of 1 mS, after setting the CMD_RESET bit in command register, before accessing any HC registers. This allows the HC to complete the reset operation and be ready for HC register access. Without this delay, the subsequent HC register access, may result in a system hang, very rarely. Verified CherryView / Braswell platforms go through over 5000 warm reboot cycles (which was not possible without this patch), without any xHCI reset hang. Signed-off-by: Rajmohan Mani <rajmohan.mani@intel.com> Tested-by: Joe Lawrence <joe.lawrence@stratus.com> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/host/xhci.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 9957bd96d4bc..385f9f5d6715 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -175,6 +175,16 @@ int xhci_reset(struct xhci_hcd *xhci)
command |= CMD_RESET;
writel(command, &xhci->op_regs->command);
+ /* Existing Intel xHCI controllers require a delay of 1 mS,
+ * after setting the CMD_RESET bit, and before accessing any
+ * HC registers. This allows the HC to complete the
+ * reset operation and be ready for HC register access.
+ * Without this delay, the subsequent HC register access,
+ * may result in a system hang very rarely.
+ */
+ if (xhci->quirks & XHCI_INTEL_HOST)
+ udelay(1000);
+
ret = xhci_handshake(&xhci->op_regs->command,
CMD_RESET, 0, 10 * 1000 * 1000);
if (ret)