Skip to content

Commit dce0919

Browse files
bijudasKAGA-KOKO
authored andcommitted
irqchip/renesas-rzg2l: Do not set TIEN and TINT source at the same time
As per the hardware team, TIEN and TINT source should not set at the same time due to a possible hardware race leading to spurious IRQ. Currently on some scenarios hardware settings for TINT detection is not in sync with TINT source as the enable/disable overrides source setting value leading to hardware inconsistent state. For eg: consider the case GPIOINT0 is used as TINT interrupt and configuring GPIOINT5 as edge type. During rzg2l_irq_set_type(), TINT source for GPIOINT5 is set. On disable(), clearing of the entire bytes of TINT source selection for GPIOINT5 is same as GPIOINT0 with TIEN disabled. Apart from this during enable(), the setting of GPIOINT5 with TIEN results in spurious IRQ as due to a HW race, it is possible that IP can use the TIEN with previous source value (GPIOINT0). So, just update TIEN during enable/disable as TINT source is already set during rzg2l_irq_set_type(). This will make the consistent hardware settings for detection method tied with TINT source and allows to simplify the code. Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
1 parent 853a603 commit dce0919

File tree

1 file changed

+2
-3
lines changed

1 file changed

+2
-3
lines changed

drivers/irqchip/irq-renesas-rzg2l.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ static void rzg2l_irqc_irq_disable(struct irq_data *d)
151151

152152
raw_spin_lock(&priv->lock);
153153
reg = readl_relaxed(priv->base + TSSR(tssr_index));
154-
reg &= ~(TSSEL_MASK << TSSEL_SHIFT(tssr_offset));
154+
reg &= ~(TIEN << TSSEL_SHIFT(tssr_offset));
155155
writel_relaxed(reg, priv->base + TSSR(tssr_index));
156156
raw_spin_unlock(&priv->lock);
157157
}
@@ -163,7 +163,6 @@ static void rzg2l_irqc_irq_enable(struct irq_data *d)
163163
unsigned int hw_irq = irqd_to_hwirq(d);
164164

165165
if (hw_irq >= IRQC_TINT_START && hw_irq < IRQC_NUM_IRQ) {
166-
unsigned long tint = (uintptr_t)irq_data_get_irq_chip_data(d);
167166
struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
168167
u32 offset = hw_irq - IRQC_TINT_START;
169168
u32 tssr_offset = TSSR_OFFSET(offset);
@@ -172,7 +171,7 @@ static void rzg2l_irqc_irq_enable(struct irq_data *d)
172171

173172
raw_spin_lock(&priv->lock);
174173
reg = readl_relaxed(priv->base + TSSR(tssr_index));
175-
reg |= (TIEN | tint) << TSSEL_SHIFT(tssr_offset);
174+
reg |= TIEN << TSSEL_SHIFT(tssr_offset);
176175
writel_relaxed(reg, priv->base + TSSR(tssr_index));
177176
raw_spin_unlock(&priv->lock);
178177
}

0 commit comments

Comments
 (0)