RE: [PATCH] irqchip/renesas-rzg2l: Fix loss of interrupt
From: Biju Das
Date: Thu Aug 13 2026 - 16:00:25 EST
Hi All,
> -----Original Message-----
> From: Biju <biju.das.au@xxxxxxxxx>
> Sent: 13 August 2026 17:48
> Subject: [PATCH] irqchip/renesas-rzg2l: Fix loss of interrupt
>
> 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
Typo here. Write 0 to clear the status bit and any bit written as 1 is ignored.
Hardware manual mentions 1 as "Invalid to write". According to the hardware engineer,
"Invalid to write" means that the write operation is invalid. Even if a '1' is written to the target bit of the TSCR/ISCR, the write is ignored, and the interrupt status remains unchanged.( so, it is "No effect".)
> 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.
back as 0
>
> Fix this by writing back only the bit being cleared (all other bits as 0) instead of read-modify-writing
(all other bits as 1)
I will update the commit description in the next version.
Cheers,
Biju
> 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
>