--- /dev/null
+From c7713e736526d8c9f6f87716fb90562a8ffaff2c Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Fri, 16 Mar 2012 13:19:35 -0700
+Subject: xhci: Fix register save/restore order.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit c7713e736526d8c9f6f87716fb90562a8ffaff2c upstream.
+
+The xHCI 1.0 spec errata released on June 13, 2011, changes the ordering
+that the xHCI registers are saved and restored in. It moves the
+interrupt pending (IMAN) and interrupt control (IMOD) registers to be
+saved and restored last. I believe that's because the host controller
+may attempt to fetch the event ring table when interrupts are
+re-enabled. Therefore we need to restore the event ring registers
+before we re-enable interrupts.
+
+This should be backported to kernels as old as 2.6.37, that contain the
+commit 5535b1d5f8885695c6ded783c692e3c0d0eda8ca "USB: xHCI: PCI power
+management implementation"
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Tested-by: Elric Fu <elricfu1@gmail.com>
+Cc: Andiry Xu <andiry.xu@amd.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
+@@ -664,11 +664,11 @@ static void xhci_save_registers(struct x
+ xhci->s3.dev_nt = xhci_readl(xhci, &xhci->op_regs->dev_notification);
+ xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr);
+ xhci->s3.config_reg = xhci_readl(xhci, &xhci->op_regs->config_reg);
+- xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending);
+- xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control);
+ xhci->s3.erst_size = xhci_readl(xhci, &xhci->ir_set->erst_size);
+ xhci->s3.erst_base = xhci_read_64(xhci, &xhci->ir_set->erst_base);
+ xhci->s3.erst_dequeue = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
++ xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending);
++ xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control);
+ }
+
+ static void xhci_restore_registers(struct xhci_hcd *xhci)
+@@ -677,11 +677,11 @@ static void xhci_restore_registers(struc
+ xhci_writel(xhci, xhci->s3.dev_nt, &xhci->op_regs->dev_notification);
+ xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr);
+ xhci_writel(xhci, xhci->s3.config_reg, &xhci->op_regs->config_reg);
+- xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending);
+- xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control);
+ xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size);
+ xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base);
+ xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue);
++ xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending);
++ xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control);
+ }
+
+ static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci)