Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

irqchip/renesas-rzv2h: Prevent TINT spurious interrupt during resume

A glitch in the edge detection circuit can cause a spurious interrupt. The
hardware manual recommends clearing the status flag after setting the
ICU_TSSRk register as a countermeasure.

Currently, a spurious interrupt is generated on the resume path of s2idle
for the PMIC RTC TINT interrupt due to a glitch related to unnecessary
enabling/disabling of the TINT enable bit.

Fix this issue by not setting TSSR(TINT Source) and TITSR(TINT Detection
Method Selection) registers if the values are the same as those set
in these registers.

Fixes: 0d7605e75ac2 ("irqchip: Add RZ/V2H(P) Interrupt Control Unit (ICU) driver")
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260113125315.359967-2-biju.das.jz@bp.renesas.com

authored by

Biju Das and committed by
Thomas Gleixner
cd4a3ced f2edf797

+8 -1
+8 -1
drivers/irqchip/irq-renesas-rzv2h.c
··· 328 328 u32 titsr, titsr_k, titsel_n, tien; 329 329 struct rzv2h_icu_priv *priv; 330 330 u32 tssr, tssr_k, tssel_n; 331 + u32 titsr_cur, tssr_cur; 331 332 unsigned int hwirq; 332 333 u32 tint, sense; 333 334 int tint_nr; ··· 377 376 guard(raw_spinlock)(&priv->lock); 378 377 379 378 tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(tssr_k)); 379 + titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(titsr_k)); 380 + 381 + tssr_cur = field_get(ICU_TSSR_TSSEL_MASK(tssel_n, priv->info->field_width), tssr); 382 + titsr_cur = field_get(ICU_TITSR_TITSEL_MASK(titsel_n), titsr); 383 + if (tssr_cur == tint && titsr_cur == sense) 384 + return 0; 385 + 380 386 tssr &= ~(ICU_TSSR_TSSEL_MASK(tssel_n, priv->info->field_width) | tien); 381 387 tssr |= ICU_TSSR_TSSEL_PREP(tint, tssel_n, priv->info->field_width); 382 388 383 389 writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k)); 384 390 385 - titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(titsr_k)); 386 391 titsr &= ~ICU_TITSR_TITSEL_MASK(titsel_n); 387 392 titsr |= ICU_TITSR_TITSEL_PREP(sense, titsel_n); 388 393