[PATCH] irqchip/renesas-rzg2l: Fix loss of interrupt

From: Biju

Date: Thu Aug 13 2026 - 12:48:51 EST


From: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>

Read modify write on rzg2l_clear_{tint,irq}_int() is causing loss of
interrupts when multiple interrupts are triggered, for example with:

gpioset -c gpiochip0 355=0 353=0 328=0 352=0

The ISCR/TSCR status registers are write-1-to-clear per bit, so any
bit written as 0 is left unchanged by hardware. The current code
reads the register, clears only the handled bit in software, and
writes back the whole value. If another interrupt's status bit gets
set between the read and the write, that set bit is written back as
1, clearing an interrupt that hasn't been serviced yet, so it gets
lost.

Fix this by writing back only the bit being cleared (all other bits
as 0) instead of read-modify-writing the whole register, so that
concurrently-set status bits for other interrupts are left intact.

Fixes: 3fed09559cd8 ("irqchip: Add RZ/G2L IA55 Interrupt Controller driver")
Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
---
drivers/irqchip/irq-renesas-rzg2l.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index f6b2e69a2f4e..b3774f82855a 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -161,7 +161,7 @@ static void rzg2l_clear_irq_int(struct rzg2l_irqc_priv *priv, unsigned int hwirq
* falling/rising-edge.
*/
if ((iscr & bit) && (iitsr & IITSR_IITSEL_MASK(hw_irq))) {
- writel_relaxed(iscr & ~bit, priv->base + ISCR);
+ writel_relaxed(~bit, priv->base + ISCR);
/*
* Enforce that the posted write is flushed to prevent that the
* just handled interrupt is raised again.
@@ -177,7 +177,7 @@ static void rzg2l_clear_tint_int(struct rzg2l_irqc_priv *priv, unsigned int hwir

reg = readl_relaxed(priv->base + TSCR);
if (reg & bit) {
- writel_relaxed(reg & ~bit, priv->base + TSCR);
+ writel_relaxed(~bit, priv->base + TSCR);
/*
* Enforce that the posted write is flushed to prevent that the
* just handled interrupt is raised again.
--
2.43.0