aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/busses/i2c-designware-core.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c
index db20a2841b75..3de549436992 100644
--- a/drivers/i2c/busses/i2c-designware-core.c
+++ b/drivers/i2c/busses/i2c-designware-core.c
@@ -583,11 +583,21 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
583 ret = wait_for_completion_timeout(&dev->cmd_complete, HZ); 583 ret = wait_for_completion_timeout(&dev->cmd_complete, HZ);
584 if (ret == 0) { 584 if (ret == 0) {
585 dev_err(dev->dev, "controller timed out\n"); 585 dev_err(dev->dev, "controller timed out\n");
586 /* i2c_dw_init implicitly disables the adapter */
586 i2c_dw_init(dev); 587 i2c_dw_init(dev);
587 ret = -ETIMEDOUT; 588 ret = -ETIMEDOUT;
588 goto done; 589 goto done;
589 } 590 }
590 591
592 /*
593 * We must disable the adapter before unlocking the &dev->lock mutex
594 * below. Otherwise the hardware might continue generating interrupts
595 * which in turn causes a race condition with the following transfer.
596 * Needs some more investigation if the additional interrupts are
597 * a hardware bug or this driver doesn't handle them correctly yet.
598 */
599 __i2c_dw_enable(dev, false);
600
591 if (dev->msg_err) { 601 if (dev->msg_err) {
592 ret = dev->msg_err; 602 ret = dev->msg_err;
593 goto done; 603 goto done;
@@ -595,8 +605,6 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
595 605
596 /* no error */ 606 /* no error */
597 if (likely(!dev->cmd_err)) { 607 if (likely(!dev->cmd_err)) {
598 /* Disable the adapter */
599 __i2c_dw_enable(dev, false);
600 ret = num; 608 ret = num;
601 goto done; 609 goto done;
602 } 610 }