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

Biju Das <[email protected]>
Newsgroups org.kernel.vger.linux-renesas-soc,org.kernel.vger.linux-kernel
Message-ID <TY3PR01MB1134658D087DDE1106CA0DF2E86DB2@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Hi All,

> -----Original Message-----
> From: Biju <[email protected]>
> Sent: 13 August 2026 17:48


> Subject: [PATCH] irqchip/renesas-rzg2l: Fix loss of interrupt
> 
> From: Biju Das <[email protected]>
> 
> 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 <[email protected]>
> ---
>  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
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.