[PATCH 6.19 235/311] mei: me: reduce the scope on unexpected reset

Greg Kroah-Hartman
2026-04-08T18:59:53Z

From: Alexander Usyskin <alexander.usyskin@intel.com>

commit 8c27b1bce059a11a8d3c8682984e13866f0714af upstream.

After commit 2cedb296988c ("mei: me: trigger link reset if hw ready is unexpected")
some devices started to show long resume times (5-7 seconds).
This happens as mei falsely detects unready hardware,
starts parallel link reset flow and triggers link reset timeouts
in the resume callback.

Address it by performing detection of unready hardware only
when driver is in the MEI_DEV_ENABLED state instead of blacklisting
states as done in the original patch.
This eliminates active waitqueue check as in MEI_DEV_ENABLED state
there will be no active waitqueue.

Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
Reported-by: Todd Brandt <todd.e.brandt@linux.intel.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221023
Tested-by: Todd Brandt <todd.e.brandt@linux.intel.com>
Fixes: 2cedb296988c ("mei: me: trigger link reset if hw ready is unexpected")
Cc: stable <stable@kernel.org>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Link: https://patch.msgid.link/20260330083830.536056-1-alexander.usyskin@intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/misc/mei/hw-me.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)

--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -1337,19 +1337,13 @@ irqreturn_t mei_me_irq_thread_handler(in
/* check if we need to start the dev */
if (!mei_host_is_ready(dev)) {
if (mei_hw_is_ready(dev)) {
- /* synchronized by dev mutex */
- if (waitqueue_active(&dev->wait_hw_ready)) {
- dev_dbg(&dev->dev, "we need to start the dev.\n");
- dev->recvd_hw_ready = true;
- wake_up(&dev->wait_hw_ready);
- } else if (dev->dev_state != MEI_DEV_UNINITIALIZED &&
- dev->dev_state != MEI_DEV_POWERING_DOWN &&
- dev->dev_state != MEI_DEV_POWER_DOWN) {
+ if (dev->dev_state == MEI_DEV_ENABLED) {
dev_dbg(&dev->dev, "Force link reset.\n");
schedule_work(&dev->reset_work);
} else {
- dev_dbg(&dev->dev, "Ignore this interrupt in state = %d\n",
- dev->dev_state);
+ dev_dbg(&dev->dev, "we need to start the dev.\n");
+ dev->recvd_hw_ready = true;
+ wake_up(&dev->wait_hw_ready);
}
} else {
dev_dbg(&dev->dev, "Spurious Interrupt\n");