From: Biju Das biju.das.jz@bp.renesas.com
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 IRQ 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") Cc: stable@vger.kernel.org Signed-off-by: Biju Das biju.das.jz@bp.renesas.com --- drivers/irqchip/irq-renesas-rzv2h.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c index 0c44b6109842..9b4565375e83 100644 --- a/drivers/irqchip/irq-renesas-rzv2h.c +++ b/drivers/irqchip/irq-renesas-rzv2h.c @@ -328,6 +328,7 @@ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type) u32 titsr, titsr_k, titsel_n, tien; struct rzv2h_icu_priv *priv; u32 tssr, tssr_k, tssel_n; + u32 titsr_cur, tssr_cur; unsigned int hwirq; u32 tint, sense; int tint_nr; @@ -376,12 +377,18 @@ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type) guard(raw_spinlock)(&priv->lock);
tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(tssr_k)); + titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(titsr_k)); + + tssr_cur = field_get(ICU_TSSR_TSSEL_MASK(tssel_n, priv->info->field_width), tssr); + titsr_cur = field_get(ICU_TITSR_TITSEL_MASK(titsel_n), titsr); + if (tssr_cur == tint && titsr_cur == sense) + return 0; + tssr &= ~(ICU_TSSR_TSSEL_MASK(tssel_n, priv->info->field_width) | tien); tssr |= ICU_TSSR_TSSEL_PREP(tint, tssel_n, priv->info->field_width);
writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k));
- titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(titsr_k)); titsr &= ~ICU_TITSR_TITSEL_MASK(titsel_n); titsr |= ICU_TITSR_TITSEL_PREP(sense, titsel_n);
linux-stable-mirror@lists.linaro.org