|
@@ -583,11 +583,21 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
|
|
|
ret = wait_for_completion_timeout(&dev->cmd_complete, HZ);
|
|
|
if (ret == 0) {
|
|
|
dev_err(dev->dev, "controller timed out\n");
|
|
|
+ /* i2c_dw_init implicitly disables the adapter */
|
|
|
i2c_dw_init(dev);
|
|
|
ret = -ETIMEDOUT;
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * We must disable the adapter before unlocking the &dev->lock mutex
|
|
|
+ * below. Otherwise the hardware might continue generating interrupts
|
|
|
+ * which in turn causes a race condition with the following transfer.
|
|
|
+ * Needs some more investigation if the additional interrupts are
|
|
|
+ * a hardware bug or this driver doesn't handle them correctly yet.
|
|
|
+ */
|
|
|
+ __i2c_dw_enable(dev, false);
|
|
|
+
|
|
|
if (dev->msg_err) {
|
|
|
ret = dev->msg_err;
|
|
|
goto done;
|
|
@@ -595,8 +605,6 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
|
|
|
|
|
|
/* no error */
|
|
|
if (likely(!dev->cmd_err)) {
|
|
|
- /* Disable the adapter */
|
|
|
- __i2c_dw_enable(dev, false);
|
|
|
ret = num;
|
|
|
goto done;
|
|
|
}
|