summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorRajmohan Mani <rajmohan.mani@intel.com>2015-11-18 08:48:20 (GMT)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-11-18 17:24:41 (GMT)
commita5964396190d0c40dd549c23848c282fffa5d1f2 (patch)
tree2a97d0c81cdc1ecef5ebfbb1838bae55343c13cb /drivers/usb
parent53de980796e0b7463dfaa81edc41b272f07b1f17 (diff)
downloadlinux-a5964396190d0c40dd549c23848c282fffa5d1f2.tar.xz
xhci: Workaround to get Intel xHCI reset working more reliably
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> Cc: stable <stable@vger.kernel.org> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-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 6e7dc6f..dfa44d3 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)