Skip to content

Commit

Permalink
i2c: imx: Check for I2SR_IAL after every byte
Browse files Browse the repository at this point in the history
Arbitration Lost (IAL) can happen after every single byte transfer. If
arbitration is lost, the I2C hardware will autonomously switch from
master mode to slave. If a transfer is not aborted in this state,
consecutive transfers will not be executed by the hardware and will
timeout.

Signed-off-by: Christian Eggers <ceggers@arri.de>
Tested (not extensively) on Vybrid VF500 (Toradex VF50):
Tested-by: Krzysztof Kozlowski <krzk@kernel.org>
Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
Cc: stable@vger.kernel.org
Signed-off-by: Wolfram Sang <wsa@kernel.org>
  • Loading branch information
ceggers-arri authored and wsakernel committed Dec 2, 2020
1 parent 384a956 commit 1de67a3
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions drivers/i2c/busses/i2c-imx.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,16 @@ static int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx, bool atomic)
dev_dbg(&i2c_imx->adapter.dev, "<%s> Timeout\n", __func__);
return -ETIMEDOUT;
}

/* check for arbitration lost */
if (i2c_imx->i2csr & I2SR_IAL) {
dev_dbg(&i2c_imx->adapter.dev, "<%s> Arbitration lost\n", __func__);
i2c_imx_clear_irq(i2c_imx, I2SR_IAL);

i2c_imx->i2csr = 0;
return -EAGAIN;
}

dev_dbg(&i2c_imx->adapter.dev, "<%s> TRX complete\n", __func__);
i2c_imx->i2csr = 0;
return 0;
Expand Down

0 comments on commit 1de67a3

Please sign in to comment.