summaryrefslogtreecommitdiff
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2026-05-04 21:59:36 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2026-06-11 22:39:27 -0700
commitb6ca982afd0e8fbcbb340092d3c6d3b4a217686c (patch)
tree1824e087881992f2ec11e1667cd99e662252b7c7 /drivers/input
parenta55a683a8e2bddb5467baab3e597a93022d4ee05 (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.c32
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;
}