While handling an error during transfer (ex: NACK), it could
happen that the driver has already written data into TXDR
before the transfer get stopped.
This commit add TXDR Flush after end of transfer in case of error to
avoid sending a wrong data on any other slave upon next transfer.
Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver")
Signed-off-by: Alain Volmat <[email protected]>
---
drivers/i2c/busses/i2c-stm32f7.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c
index b9b19a2a2ffa..ed977b6f7ab6 100644
--- a/drivers/i2c/busses/i2c-stm32f7.c
+++ b/drivers/i2c/busses/i2c-stm32f7.c
@@ -1696,6 +1696,16 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap,
time_left = wait_for_completion_timeout(&i2c_dev->complete,
i2c_dev->adap.timeout);
ret = f7_msg->result;
+ if (ret) {
+ /*
+ * It is possible that some unsent data have already been
+ * written into TXDR. To avoid sending old data in a
+ * further transfer, flush TXDR in case of any error
+ */
+ writel_relaxed(STM32F7_I2C_ISR_TXE,
+ i2c_dev->base + STM32F7_I2C_ISR);
+ goto pm_free;
+ }
if (!time_left) {
dev_dbg(i2c_dev->dev, "Access to slave 0x%x timed out\n",
@@ -1744,8 +1754,16 @@ static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
timeout = wait_for_completion_timeout(&i2c_dev->complete,
i2c_dev->adap.timeout);
ret = f7_msg->result;
- if (ret)
+ if (ret) {
+ /*
+ * It is possible that some unsent data have already been
+ * written into TXDR. To avoid sending old data in a
+ * further transfer, flush TXDR in case of any error
+ */
+ writel_relaxed(STM32F7_I2C_ISR_TXE,
+ i2c_dev->base + STM32F7_I2C_ISR);
goto pm_free;
+ }
if (!timeout) {
dev_dbg(dev, "Access to slave 0x%x timed out\n", f7_msg->addr);
--
2.25.1
Hi Alain
Reviewed-by: Pierre-Yves MORDRET <[email protected]>
Regards
On 9/20/21 5:21 PM, Alain Volmat wrote:
> While handling an error during transfer (ex: NACK), it could
> happen that the driver has already written data into TXDR
> before the transfer get stopped.
> This commit add TXDR Flush after end of transfer in case of error to
> avoid sending a wrong data on any other slave upon next transfer.
>
> Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver")
>
> Signed-off-by: Alain Volmat <[email protected]>
> ---
> drivers/i2c/busses/i2c-stm32f7.c | 20 +++++++++++++++++++-
> 1 file changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c
> index b9b19a2a2ffa..ed977b6f7ab6 100644
> --- a/drivers/i2c/busses/i2c-stm32f7.c
> +++ b/drivers/i2c/busses/i2c-stm32f7.c
> @@ -1696,6 +1696,16 @@ static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap,
> time_left = wait_for_completion_timeout(&i2c_dev->complete,
> i2c_dev->adap.timeout);
> ret = f7_msg->result;
> + if (ret) {
> + /*
> + * It is possible that some unsent data have already been
> + * written into TXDR. To avoid sending old data in a
> + * further transfer, flush TXDR in case of any error
> + */
> + writel_relaxed(STM32F7_I2C_ISR_TXE,
> + i2c_dev->base + STM32F7_I2C_ISR);
> + goto pm_free;
> + }
>
> if (!time_left) {
> dev_dbg(i2c_dev->dev, "Access to slave 0x%x timed out\n",
> @@ -1744,8 +1754,16 @@ static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
> timeout = wait_for_completion_timeout(&i2c_dev->complete,
> i2c_dev->adap.timeout);
> ret = f7_msg->result;
> - if (ret)
> + if (ret) {
> + /*
> + * It is possible that some unsent data have already been
> + * written into TXDR. To avoid sending old data in a
> + * further transfer, flush TXDR in case of any error
> + */
> + writel_relaxed(STM32F7_I2C_ISR_TXE,
> + i2c_dev->base + STM32F7_I2C_ISR);
> goto pm_free;
> + }
>
> if (!timeout) {
> dev_dbg(dev, "Access to slave 0x%x timed out\n", f7_msg->addr);
>
--
--
~ Py MORDRET
--
On Mon, Sep 20, 2021 at 05:21:29PM +0200, Alain Volmat wrote:
> While handling an error during transfer (ex: NACK), it could
> happen that the driver has already written data into TXDR
> before the transfer get stopped.
> This commit add TXDR Flush after end of transfer in case of error to
> avoid sending a wrong data on any other slave upon next transfer.
>
> Fixes: aeb068c57214 ("i2c: i2c-stm32f7: add driver")
>
> Signed-off-by: Alain Volmat <[email protected]>
Applied to for-current, thanks!