From: Greg Kroah-Hartman Date: Thu, 19 Apr 2012 16:20:36 +0000 (-0700) Subject: 3.3-stable patches X-Git-Tag: v3.2.16~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=583e83520e366c7e4bd9e357d4d99787cbd11504;p=thirdparty%2Fkernel%2Fstable-queue.git 3.3-stable patches added patches: xhci-fix-register-save-restore-order.patch --- diff --git a/queue-3.3/series b/queue-3.3/series index f57f1d2551b..5f5d9d79167 100644 --- a/queue-3.3/series +++ b/queue-3.3/series @@ -57,3 +57,4 @@ memcg-fix-bad-page-state-after-replace_page_cache.patch serial-pl011-clear-pending-interrupts.patch serial-pl011-move-interrupt-clearing.patch fcaps-clear-the-same-personality-flags-as-suid-when-fcaps-are-used.patch +xhci-fix-register-save-restore-order.patch diff --git a/queue-3.3/xhci-fix-register-save-restore-order.patch b/queue-3.3/xhci-fix-register-save-restore-order.patch new file mode 100644 index 00000000000..d4a6ac4b160 --- /dev/null +++ b/queue-3.3/xhci-fix-register-save-restore-order.patch @@ -0,0 +1,60 @@ +From c7713e736526d8c9f6f87716fb90562a8ffaff2c Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Fri, 16 Mar 2012 13:19:35 -0700 +Subject: xhci: Fix register save/restore order. + +From: Sarah Sharp + +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 +Tested-by: Elric Fu +Cc: Andiry Xu +Signed-off-by: Greg Kroah-Hartman + +--- + 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)