forked from Minki/linux
i2c: aspeed: Avoid i2c interrupt status clear race condition.
In AST2600 there have a slow peripheral bus between CPU and i2c
controller. Therefore GIC i2c interrupt status clear have delay timing,
when CPU issue write clear i2c controller interrupt status. To avoid
this issue, the driver need have read after write clear at i2c ISR.
Fixes: f327c686d3
("i2c: aspeed: added driver for Aspeed I2C")
Signed-off-by: ryan_chen <ryan_chen@aspeedtech.com>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
[wsa: added Fixes tag]
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
This commit is contained in:
parent
ac2b0813fc
commit
c926c87b8e
@ -603,6 +603,7 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
|
||||
/* Ack all interrupts except for Rx done */
|
||||
writel(irq_received & ~ASPEED_I2CD_INTR_RX_DONE,
|
||||
bus->base + ASPEED_I2C_INTR_STS_REG);
|
||||
readl(bus->base + ASPEED_I2C_INTR_STS_REG);
|
||||
irq_remaining = irq_received;
|
||||
|
||||
#if IS_ENABLED(CONFIG_I2C_SLAVE)
|
||||
@ -645,9 +646,11 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id)
|
||||
irq_received, irq_handled);
|
||||
|
||||
/* Ack Rx done */
|
||||
if (irq_received & ASPEED_I2CD_INTR_RX_DONE)
|
||||
if (irq_received & ASPEED_I2CD_INTR_RX_DONE) {
|
||||
writel(ASPEED_I2CD_INTR_RX_DONE,
|
||||
bus->base + ASPEED_I2C_INTR_STS_REG);
|
||||
readl(bus->base + ASPEED_I2C_INTR_STS_REG);
|
||||
}
|
||||
spin_unlock(&bus->lock);
|
||||
return irq_remaining ? IRQ_NONE : IRQ_HANDLED;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user