Browse Source

Udate v5.14 patches

Changes:
 - Include fix for USB/keyboard not working after hibernation. See #617
   for more information.

Links:
 - https://github.com/linux-surface/kernel/commit/a99c1b9bdbe9dd6fc9f41ec16b575c675be30539
Maximilian Luz 3 years ago
parent
commit
df73af5ccc
1 changed files with 70 additions and 0 deletions
  1. 70 0
      patches/5.14/0012-misc-fixes.patch

+ 70 - 0
patches/5.14/0012-misc-fixes.patch

@@ -0,0 +1,70 @@
+From 84b7c183f256bfb411af2aca08e5b3f9e7672e40 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Fri, 29 Oct 2021 15:51:54 +0300
+Subject: [PATCH] xhci: Fix commad ring abort, write all 64 bits to CRCR
+ register.
+
+Turns out some xHC controllers require all 64 bits in the CRCR register
+to be written to execute a command abort.
+
+The lower 32 bits containing the command abort bit is written first.
+In case the command ring stops before we write the upper 32 bits then
+hardware may use these upper bits to set the commnd ring dequeue pointer.
+
+Solve this by making sure the upper 32 bits contain a valid command
+ring dequeue pointer.
+
+The original patch that only wrote the first 32 to stop the ring went
+to stable, so this fix should go there as well.
+
+Fixes: ff0e50d3564f ("xhci: Fix command ring pointer corruption while aborting a command")
+Cc: stable@vger.kernel.org
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Patchset: misc-fixes
+---
+ drivers/usb/host/xhci-ring.c | 21 ++++++++++++++-------
+ 1 file changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 8fedf1bf292b..3dd5929b67f0 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -366,7 +366,9 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci,
+ /* Must be called with xhci->lock held, releases and aquires lock back */
+ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
+ {
+-	u32 temp_32;
++	struct xhci_segment *new_seg	= xhci->cmd_ring->deq_seg;
++	union xhci_trb *new_deq		= xhci->cmd_ring->dequeue;
++	u64 crcr;
+ 	int ret;
+ 
+ 	xhci_dbg(xhci, "Abort command ring\n");
+@@ -375,13 +377,18 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
+ 
+ 	/*
+ 	 * The control bits like command stop, abort are located in lower
+-	 * dword of the command ring control register. Limit the write
+-	 * to the lower dword to avoid corrupting the command ring pointer
+-	 * in case if the command ring is stopped by the time upper dword
+-	 * is written.
++	 * dword of the command ring control register.
++	 * Some controllers require all 64 bits to be written to abort the ring.
++	 * Make sure the upper dword is valid, pointing to the next command,
++	 * avoiding corrupting the command ring pointer in case the command ring
++	 * is stopped by the time the upper dword is written.
+ 	 */
+-	temp_32 = readl(&xhci->op_regs->cmd_ring);
+-	writel(temp_32 | CMD_RING_ABORT, &xhci->op_regs->cmd_ring);
++	next_trb(xhci, NULL, &new_seg, &new_deq);
++	if (trb_is_link(new_deq))
++		next_trb(xhci, NULL, &new_seg, &new_deq);
++
++	crcr = xhci_trb_virt_to_dma(new_seg, new_deq);
++	xhci_write_64(xhci, crcr | CMD_RING_ABORT, &xhci->op_regs->cmd_ring);
+ 
+ 	/* Section 4.6.1.2 of xHCI 1.0 spec says software should also time the
+ 	 * completion of the Command Abort operation. If CRR is not negated in 5
+-- 
+2.33.1
+