aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Merello2023-05-26 16:56:16 +0200
committerHeiko Schocher2023-06-05 06:54:25 +0200
commit419ddf944cbf376e3c1d5b8571e82d89056bebfa (patch)
tree21203eab5efc77d2aa99b2b9cf21a58e7cbd6a7e
parentba5b9203f55bae1ef3566a84648cad46c6949270 (diff)
I2C: cdns: Fix broken retry mechanism on arbitration lost.
In the current implementation, in case of I2C arbitration lost, a retry is attempted; the message counter and pointer are reset to the original values and the I2C xfer process is restart from the beginning. However the message counter and message pointer are respectively decremented and incremented by one before attempting any transfer, causing the 1st transfer not to be actually retried (in case of a single transfer, nothing is actually retried at all). This patch fixes this: in case of retry, the 1st transfer is also retried. Tested on a ZynqMP Kria board, with upstream older u-boot, but the involved file and underlying logic seem basically the same. Signed-off-by: Andrea Merello <andrea.merello@iit.it>
-rw-r--r--drivers/i2c/i2c-cdns.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c
index 1a892072063..935b2ac6377 100644
--- a/drivers/i2c/i2c-cdns.c
+++ b/drivers/i2c/i2c-cdns.c
@@ -444,7 +444,7 @@ static int cdns_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
debug("i2c_xfer: %d messages\n", nmsgs);
for (u8 retry = 0; retry < CDNS_I2C_ARB_LOST_MAX_RETRIES &&
- nmsgs > 0; nmsgs--, msg++) {
+ nmsgs > 0;) {
debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
if (msg->flags & I2C_M_RD) {
ret = cdns_i2c_read_data(i2c_bus, msg->addr, msg->buf,
@@ -461,7 +461,8 @@ static int cdns_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
retry);
continue;
}
-
+ nmsgs--;
+ msg++;
if (ret) {
debug("i2c_write: error sending\n");
return -EREMOTEIO;