aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-designware.c
diff options
context:
space:
mode:
authorShinya Kuribayashi <shinya.kuribayashi@necel.com>2009-11-06 07:51:36 -0500
committerBen Dooks <ben-linux@fluff.org>2009-12-08 19:19:12 -0500
commit597fe310f16d8246eec856326aa497bfa1b5bfa3 (patch)
treec8093cf8803bfe3793c46edcea965f9583e35e93 /drivers/i2c/busses/i2c-designware.c
parent8f588e40c788e63756ca1028c253f9f663d7d1c5 (diff)
i2c-designware: Skip RX_FULL and TX_EMPTY bits on tx abort errors
Suppose TX_ABRT occurs in the middle of processing i2c_msg msgs[], and a STOP condition has already been generated on the bus. In this case, subsequent i2c_dw_xfer_msg() might initiate a new and unnecessary I2C transaction, which we'd have to avoid. Furthermore, anytime TX_ABRT is set, the contents of tx/rx buffers are flushed, so we don't have to process RX_FULL and TX_EMPTY. Disable interrupts, and skip them. Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi@necel.com> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'drivers/i2c/busses/i2c-designware.c')
-rw-r--r--drivers/i2c/busses/i2c-designware.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-designware.c b/drivers/i2c/busses/i2c-designware.c
index cb83671ff5fc..e6b1e6ece5d7 100644
--- a/drivers/i2c/busses/i2c-designware.c
+++ b/drivers/i2c/busses/i2c-designware.c
@@ -621,6 +621,13 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
621 if (stat & DW_IC_INTR_TX_ABRT) { 621 if (stat & DW_IC_INTR_TX_ABRT) {
622 dev->cmd_err |= DW_IC_ERR_TX_ABRT; 622 dev->cmd_err |= DW_IC_ERR_TX_ABRT;
623 dev->status = STATUS_IDLE; 623 dev->status = STATUS_IDLE;
624
625 /*
626 * Anytime TX_ABRT is set, the contents of the tx/rx
627 * buffers are flushed. Make sure to skip them.
628 */
629 writel(0, dev->base + DW_IC_INTR_MASK);
630 goto tx_aborted;
624 } 631 }
625 632
626 if (stat & DW_IC_INTR_RX_FULL) 633 if (stat & DW_IC_INTR_RX_FULL)
@@ -635,6 +642,7 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
635 * the current transmit status. 642 * the current transmit status.
636 */ 643 */
637 644
645tx_aborted:
638 if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err) 646 if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err)
639 complete(&dev->cmd_complete); 647 complete(&dev->cmd_complete);
640 648