diff mbox series

I2C: cdns: Fix broken retry mechanism on arbitration lost.

Message ID 20230526145616.55719-1-andrea.merello@iit.it
State Accepted
Commit 419ddf944cbf376e3c1d5b8571e82d89056bebfa
Delegated to: Heiko Schocher
Headers show
Series I2C: cdns: Fix broken retry mechanism on arbitration lost. | expand

Commit Message

Andrea Merello May 26, 2023, 2:56 p.m. UTC
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>
---
 drivers/i2c/i2c-cdns.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

--
2.17.1

Comments

Heiko Schocher June 5, 2023, 7:36 a.m. UTC | #1
Hello Andrea,

On 26.05.23 16:56, Andrea Merello wrote:
> 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>
> ---
>  drivers/i2c/i2c-cdns.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)

Applied to u-boot-i2c.git master

Thanks!

bye,
Heiko
diff mbox series

Patch

diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c
index 1a89207206..935b2ac637 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;