From ba5b9203f55bae1ef3566a84648cad46c6949270 Mon Sep 17 00:00:00 2001 From: Ondrej Jirman Date: Thu, 25 May 2023 14:18:17 +0200 Subject: i2c: rockchip: De-initialize the bus after start bit failure Failure can happen when i2c is used without initializing pinctrl properly, which U-Boot happily allows in SPL. Without this fix, further I2C access would fail, even after proper pinctrl initialization. Signed-off-by: Ondrej Jirman Cc: Heiko Schocher Reviewed-by: Kever Yang Reviewed-by: Heiko Schocher --- drivers/i2c/rk_i2c.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/rk_i2c.c b/drivers/i2c/rk_i2c.c index f8fac45..9927af9 100644 --- a/drivers/i2c/rk_i2c.c +++ b/drivers/i2c/rk_i2c.c @@ -342,7 +342,7 @@ static int rockchip_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) { struct rk_i2c *i2c = dev_get_priv(bus); - int ret; + int ret = 0; debug("i2c_xfer: %d messages\n", nmsgs); for (; nmsgs > 0; nmsgs--, msg++) { @@ -356,14 +356,15 @@ static int rockchip_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, } if (ret) { debug("i2c_write: error sending\n"); - return -EREMOTEIO; + ret = -EREMOTEIO; + break; } } rk_i2c_send_stop_bit(i2c); rk_i2c_disable(i2c); - return 0; + return ret; } int rockchip_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) -- cgit v1.1 From 419ddf944cbf376e3c1d5b8571e82d89056bebfa Mon Sep 17 00:00:00 2001 From: Andrea Merello Date: Fri, 26 May 2023 16:56:16 +0200 Subject: 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 --- drivers/i2c/i2c-cdns.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c index 1a89207..935b2ac 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; -- cgit v1.1