diff options
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.c | 12 |
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 | } |