From: Felipe Balbi Date: Wed, 12 Sep 2012 10:58:04 +0000 (+0530) Subject: i2c: omap: ack IRQ in parts X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=1d7afc95946487945cc7f5019b41255b72224b70;p=openwrt%2Fstaging%2Fblogic.git i2c: omap: ack IRQ in parts According to flow diagrams on OMAP TRMs, we should ACK the IRQ as they happen. Signed-off-by: Felipe Balbi [Ack the stat OMAP_I2C_STAT_AL in case of arbitration lost] Signed-off-by: Shubhrajyoti D Signed-off-by: Wolfram Sang --- diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 40451341c479..bac1f11cc64b 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -850,21 +850,19 @@ omap_i2c_isr(int this_irq, void *dev_id) } complete: - /* - * Ack the stat in one go, but [R/X]DR and [R/X]RDY should be - * acked after the data operation is complete. - * Ref: TRM SWPU114Q Figure 18-31 - */ - omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat & - ~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR | - OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); - - if (stat & OMAP_I2C_STAT_NACK) + if (stat & OMAP_I2C_STAT_NACK) { err |= OMAP_I2C_STAT_NACK; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); + omap_i2c_complete_cmd(dev, err); + return IRQ_HANDLED; + } if (stat & OMAP_I2C_STAT_AL) { dev_err(dev->dev, "Arbitration lost\n"); err |= OMAP_I2C_STAT_AL; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL); + omap_i2c_complete_cmd(dev, err); + return IRQ_HANDLED; } /* @@ -941,12 +939,18 @@ complete: if (stat & OMAP_I2C_STAT_ROVR) { dev_err(dev->dev, "Receive overrun\n"); - dev->cmd_err |= OMAP_I2C_STAT_ROVR; + err |= OMAP_I2C_STAT_ROVR; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR); + omap_i2c_complete_cmd(dev, err); + return IRQ_HANDLED; } if (stat & OMAP_I2C_STAT_XUDF) { dev_err(dev->dev, "Transmit underflow\n"); - dev->cmd_err |= OMAP_I2C_STAT_XUDF; + err |= OMAP_I2C_STAT_XUDF; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF); + omap_i2c_complete_cmd(dev, err); + return IRQ_HANDLED; } } while (stat);