diff options
author | Felipe Balbi <balbi@ti.com> | 2012-09-12 12:58:04 +0200 |
---|---|---|
committer | Wolfram Sang <w.sang@pengutronix.de> | 2012-09-12 15:02:50 +0200 |
commit | 1d7afc95946487945cc7f5019b41255b72224b70 (patch) | |
tree | 001376661d82bfb02dde2cad4e5ddcaa2a6489fc | |
parent | i2c: omap: switch over to do {} while loop (diff) | |
download | linux-1d7afc95946487945cc7f5019b41255b72224b70.tar.xz linux-1d7afc95946487945cc7f5019b41255b72224b70.zip |
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 <balbi@ti.com>
[Ack the stat OMAP_I2C_STAT_AL in case of arbitration lost]
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
-rw-r--r-- | drivers/i2c/busses/i2c-omap.c | 28 |
1 files changed, 16 insertions, 12 deletions
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); |