49 lines
1.9 KiB
Diff
49 lines
1.9 KiB
Diff
From af9d38028438d5893403b1bea8bd493186f8d2b7 Mon Sep 17 00:00:00 2001
|
|
From: Niklas Neronin <niklas.neronin@linux.intel.com>
|
|
Date: Tue, 19 Aug 2025 15:58:44 +0300
|
|
Subject: usb: xhci: fix host not responding after suspend and resume
|
|
|
|
Partially revert commit e1db856bd288 ("usb: xhci: remove '0' write to
|
|
write-1-to-clear register") because the patch cleared the Interrupt Pending
|
|
bit during interrupt enabling and disabling. The Interrupt Pending bit
|
|
should only be cleared when the driver has handled the interrupt.
|
|
|
|
Ideally, all interrupts should be handled before disabling the interrupt;
|
|
consequently, no interrupt should be pending when enabling the interrupt.
|
|
For this reason, keep the debug message informing if an interrupt is still
|
|
pending when an interrupt is disabled.
|
|
|
|
Because the Interrupt Pending bit is write-1-to-clear, writing '0' to it
|
|
ensures that the state does not change.
|
|
|
|
Link: https://lore.kernel.org/linux-usb/20250818231103.672ec7ed@foxbook
|
|
Fixes: e1db856bd288 ("usb: xhci: remove '0' write to write-1-to-clear register")
|
|
Closes: https://bbs.archlinux.org/viewtopic.php?id=307641
|
|
cc: stable@vger.kernel.org # 6.16+
|
|
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
|
|
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
|
|
Link: https://lore.kernel.org/r/20250819125844.2042452-3-mathias.nyman@linux.intel.com
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
drivers/usb/host/xhci.c | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
--- a/drivers/usb/host/xhci.c
|
|
+++ b/drivers/usb/host/xhci.c
|
|
@@ -309,6 +309,7 @@ int xhci_enable_interrupter(struct xhci_
|
|
return -EINVAL;
|
|
|
|
iman = readl(&ir->ir_set->iman);
|
|
+ iman &= ~IMAN_IP;
|
|
iman |= IMAN_IE;
|
|
writel(iman, &ir->ir_set->iman);
|
|
|
|
@@ -325,6 +326,7 @@ int xhci_disable_interrupter(struct xhci
|
|
return -EINVAL;
|
|
|
|
iman = readl(&ir->ir_set->iman);
|
|
+ iman &= ~IMAN_IP;
|
|
iman &= ~IMAN_IE;
|
|
writel(iman, &ir->ir_set->iman);
|
|
|