[PATCH 1/2] i2c: imx: do not carry the interrupt status over to the next transfer
From: Mehmet Fide
Date: Fri Nov 13 2026 - 04:54:43 EST
From: Mehmet Fide <mehmet.fide@xxxxxxxxxxxxxxxxxx>
In DMA mode the interrupt handler stores I2SR in i2c_imx->i2csr and only
i2c_imx_trx_complete() clears it. A DMA transfer that fails returns
without doing so, for example a DMA write whose address is not
acknowledged.
The stale status stays until the next DMA read. There
i2c_imx_prepare_read() calls i2c_imx_trx_complete(), which finds IIF set
and returns before the address byte has been sent, so the read returns
0xff for every byte without an error:
i2ctransfer -a -y 0 w20@0x03 0x00- # unused address, -ETIMEDOUT
i2ctransfer -y 0 w1@0x54 0x00 r32 # 32 times 0xff
i2ctransfer -y 0 w1@0x54 0x00 r32 # correct data
Clear the status when a transfer starts.
Fixes: ce1a78840ff7 ("i2c: imx: add DMA support for freescale i2c driver")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Mehmet Fide <mehmet.fide@xxxxxxxxxxxxxxxxxx>
---
drivers/i2c/busses/i2c-imx.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index ccf08cd63151..1987a0fd8132 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -1657,6 +1657,8 @@ static int i2c_imx_xfer_common(struct i2c_adapter *adapter,
if (result)
return result;
+ i2c_imx->i2csr = 0;
+
/* Start I2C transfer */
result = i2c_imx_start(i2c_imx, atomic);
if (result) {
--
2.56.0