[PATCH v2 1/5] Input: applespi - use unified wait queue with timeouts for drain
From: Shih-Yuan Lee <hidden>
Date: 2026-07-20 10:14:48
Also in:
lkml
Subsystem:
input (keyboard, mouse, joystick, touchscreen) drivers, the rest · Maintainers:
Dmitry Torokhov, Linus Torvalds
The driver currently maintains a dedicated wait queue 'drain_complete' specifically to wait for outstanding write requests to complete. Consolidate this with other wait events by renaming it to 'wait_queue' to make resource management cleaner. Furthermore, using wait_event_lock_irq() without a timeout risks blocking the thread indefinitely during driver unbinding (remove) or PM transition phases if the hardware fails to respond or interrupts are missed. Replace wait_event_lock_irq() with wait_event_lock_irq_timeout() in applespi_drain_writes() and applespi_drain_reads() with a 3-second timeout. This ensures the driver can gracefully recover and avoid lockups under unresponsive hardware conditions. Signed-off-by: Shih-Yuan Lee <redacted> --- drivers/input/keyboard/applespi.c | 32 +++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-)
diff --git a/drivers/input/keyboard/applespi.c b/drivers/input/keyboard/applespi.c
index b5ff71cd5a70..64bbeba85ea9 100644
--- a/drivers/input/keyboard/applespi.c
+++ b/drivers/input/keyboard/applespi.c@@ -417,7 +417,7 @@ struct applespi_data { bool suspended; bool drain; - wait_queue_head_t drain_complete; + wait_queue_head_t wait_queue; bool read_active; bool write_active;
@@ -677,7 +677,7 @@ static int applespi_setup_spi(struct applespi_data *applespi) return sts; spin_lock_init(&applespi->cmd_msg_lock); - init_waitqueue_head(&applespi->drain_complete); + init_waitqueue_head(&applespi->wait_queue); return 0; }
@@ -725,7 +725,7 @@ static void applespi_msg_complete(struct applespi_data *applespi, applespi->write_active = false; if (applespi->drain && !applespi->write_active) - wake_up_all(&applespi->drain_complete); + wake_up_all(&applespi->wait_queue); if (is_write_msg) { applespi->cmd_msg_queued = 0;
@@ -1415,7 +1415,7 @@ static void applespi_got_data(struct applespi_data *applespi) applespi->read_active = false; applespi->write_active = false; - wake_up_all(&applespi->drain_complete); + wake_up_all(&applespi->wait_queue); } return;
@@ -1793,21 +1793,33 @@ static int applespi_probe(struct spi_device *spi) static void applespi_drain_writes(struct applespi_data *applespi) { - guard(spinlock_irqsave)(&applespi->cmd_msg_lock); + unsigned long flags; + + spin_lock_irqsave(&applespi->cmd_msg_lock, flags); applespi->drain = true; - wait_event_lock_irq(applespi->drain_complete, !applespi->write_active, - applespi->cmd_msg_lock); + wait_event_lock_irq_timeout(applespi->wait_queue, + !applespi->write_active, + applespi->cmd_msg_lock, + msecs_to_jiffies(3000)); + + spin_unlock_irqrestore(&applespi->cmd_msg_lock, flags); } static void applespi_drain_reads(struct applespi_data *applespi) { - guard(spinlock_irqsave)(&applespi->cmd_msg_lock); + unsigned long flags; + + spin_lock_irqsave(&applespi->cmd_msg_lock, flags); - wait_event_lock_irq(applespi->drain_complete, !applespi->read_active, - applespi->cmd_msg_lock); + wait_event_lock_irq_timeout(applespi->wait_queue, + !applespi->read_active, + applespi->cmd_msg_lock, + msecs_to_jiffies(3000)); applespi->suspended = true; + + spin_unlock_irqrestore(&applespi->cmd_msg_lock, flags); } static void applespi_remove(struct spi_device *spi)
--
2.39.5