lkml.org 
[lkml]   [2021]   [Dec]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 32/70] i2c: stm32f7: flush TX FIFO upon transfer errors
    Date
    From: Alain Volmat <alain.volmat@foss.st.com>

    commit 0c21d02ca469574d2082379db52d1a27b99eed0c upstream.

    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 <alain.volmat@foss.st.com>
    Reviewed-by: Pierre-Yves MORDRET <pierre-yves.mordret@foss.st.com>
    Signed-off-by: Wolfram Sang <wsa@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/i2c/busses/i2c-stm32f7.c | 20 +++++++++++++++++++-
    1 file changed, 19 insertions(+), 1 deletion(-)

    --- a/drivers/i2c/busses/i2c-stm32f7.c
    +++ b/drivers/i2c/busses/i2c-stm32f7.c
    @@ -1586,6 +1586,16 @@ static int stm32f7_i2c_xfer(struct i2c_a
    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",
    @@ -1634,8 +1644,16 @@ static int stm32f7_i2c_smbus_xfer(struct
    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);

    \
     
     \ /
      Last update: 2021-12-06 16:40    [W:4.099 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site