forked from Minki/linux
i2c: imx: Check for I2SR_IAL after every byte
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>
This commit is contained in:
parent
384a9565f7
commit
1de67a3dee
@ -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__);
|
dev_dbg(&i2c_imx->adapter.dev, "<%s> Timeout\n", __func__);
|
||||||
return -ETIMEDOUT;
|
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__);
|
dev_dbg(&i2c_imx->adapter.dev, "<%s> TRX complete\n", __func__);
|
||||||
i2c_imx->i2csr = 0;
|
i2c_imx->i2csr = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user