diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2026-05-04 21:59:36 -0700 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2026-06-11 22:39:27 -0700 |
| commit | b6ca982afd0e8fbcbb340092d3c6d3b4a217686c (patch) | |
| tree | 1824e087881992f2ec11e1667cd99e662252b7c7 /drivers/input | |
| parent | a55a683a8e2bddb5467baab3e597a93022d4ee05 (diff) | |
Input: rmi4 - iterative IRQ handler
The current IRQ handler uses recursion to drain the attention FIFO,
which can lead to stack overflow on deep queues. Convert it to a
loop.
Fixes: b908d3cd812a ("Input: synaptics-rmi4 - allow to add attention data")
Cc: stable@vger.kernel.org
Assisted-by: Gemini:gemini-3.1-pro
Link: https://patch.msgid.link/20260505045952.1570713-6-dmitry.torokhov@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
| -rw-r--r-- | drivers/input/rmi4/rmi_driver.c | 32 |
1 files changed, 16 insertions, 16 deletions
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c index 3dc7ab61c269..5eda11bcb59c 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c @@ -198,24 +198,24 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id) struct rmi4_attn_data attn_data = {0}; int ret, count; - count = kfifo_get(&drvdata->attn_fifo, &attn_data); - if (count) { - *(drvdata->irq_status) = attn_data.irq_status; - drvdata->attn_data = attn_data; - } - - ret = rmi_process_interrupt_requests(rmi_dev); - if (ret) - rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev, - "Failed to process interrupt request: %d\n", ret); + do { + count = kfifo_get(&drvdata->attn_fifo, &attn_data); + if (count) { + *drvdata->irq_status = attn_data.irq_status; + drvdata->attn_data = attn_data; + } - if (count) { - kfree(attn_data.data); - drvdata->attn_data.data = NULL; - } + ret = rmi_process_interrupt_requests(rmi_dev); + if (ret) + rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev, + "Failed to process interrupt request: %d\n", + ret); - if (!kfifo_is_empty(&drvdata->attn_fifo)) - return rmi_irq_fn(irq, dev_id); + if (count) { + kfree(attn_data.data); + drvdata->attn_data.data = NULL; + } + } while (!kfifo_is_empty(&drvdata->attn_fifo)); return IRQ_HANDLED; } |
