diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c index fb4bbe490862..439198b1b835 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -263,9 +263,10 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) /* Slave was requested, restart state machine. */ if (irq_status & ASPEED_I2CD_INTR_SLAVE_MATCH) { - if (irq_status & ASPEED_I2CD_INTR_TX_NAK && - bus->slave_state == ASPEED_I2C_SLAVE_READ_PROCESSED) { - irq_handled |= ASPEED_I2CD_INTR_TX_NAK; + if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP && + bus->slave_state == ASPEED_I2C_SLAVE_WRITE_RECEIVED) { + irq_handled |= ASPEED_I2CD_INTR_NORMAL_STOP; + irq_status &= ~ASPEED_I2CD_INTR_NORMAL_STOP; i2c_slave_event(slave, I2C_SLAVE_STOP, &value); } irq_handled |= ASPEED_I2CD_INTR_SLAVE_MATCH; @@ -346,12 +347,6 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) break; } - if (irq_handled != irq_status) - dev_err(bus->dev, - "irq handled != irq. expected %x, but was %x\n", - irq_status, irq_handled); - writel(irq_handled, bus->base + ASPEED_I2C_INTR_STS_REG); - return irq_handled; } #endif /* CONFIG_I2C_SLAVE */ @@ -427,11 +422,6 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) u8 recv_byte; int ret; - irq_status = readl(bus->base + ASPEED_I2C_INTR_STS_REG); - /* Ack all interrupt bits. */ - writel(irq_status, bus->base + ASPEED_I2C_INTR_STS_REG); - readl(bus->base + ASPEED_I2C_INTR_STS_REG); - if (irq_status & ASPEED_I2CD_INTR_BUS_RECOVER_DONE) { bus->master_state = ASPEED_I2C_MASTER_INACTIVE; irq_handled |= ASPEED_I2CD_INTR_BUS_RECOVER_DONE; @@ -616,10 +606,6 @@ static u32 aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus, u32 irq_status) bus->master_xfer_result = bus->msgs_index + 1; complete(&bus->cmd_complete); out_no_complete: - if (irq_status != irq_handled) - dev_err(bus->dev, - "irq handled != irq. expected 0x%08x, but was 0x%08x\n", - irq_status, irq_handled); return irq_handled; } @@ -630,6 +616,10 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id) spin_lock(&bus->lock); irq_received = readl(bus->base + ASPEED_I2C_INTR_STS_REG); + /* 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_received &= ASPEED_I2CD_INTR_RECV_MASK; irq_remaining = irq_received; @@ -672,6 +662,12 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id) "irq handled != irq. expected 0x%08x, but was 0x%08x\n", irq_received, irq_handled); + /* Ack 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; }