From: Padmarao Begari Date: Wed, 26 Nov 2025 15:12:35 +0000 (+0100) Subject: i2c: cdns: Add timeout for RXDV status bit polling X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=38e3f9658ef8c5054999f93d3c5f97cbb485c696;p=thirdparty%2Fu-boot.git i2c: cdns: Add timeout for RXDV status bit polling Add a timeout mechanism when waiting for the RXDV (Receive Data Valid) status bit to be set before reading data from the FIFO. This prevents infinite polling loops that could occur if the hardware doesn't respond as expected. The timeout is set to 1000ms (CDNS_I2C_RXDV_TIMEOUT_MS) and uses the wait_for_bit_le32() function to poll the status register. If the timeout expires, an error code is returned. Signed-off-by: Padmarao Begari Reviewed-by: Heiko Schocher Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/ba53d57c179f3390b32bc6094f3ffb5f4cde931e.1764169953.git.michal.simek@amd.com --- diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c index 3f7cf8533ec..4e9d4e44899 100644 --- a/drivers/i2c/i2c-cdns.c +++ b/drivers/i2c/i2c-cdns.c @@ -85,6 +85,8 @@ struct cdns_i2c_regs { #define CDNS_I2C_ARB_LOST_MAX_RETRIES 10 +#define CDNS_I2C_RXDV_TIMEOUT_MS 1000 + #ifdef DEBUG static void cdns_i2c_debug_status(struct cdns_i2c_regs *cdns_i2c) { @@ -349,6 +351,11 @@ static int cdns_i2c_read_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, hold_quirk = (i2c_bus->quirks & CDNS_I2C_BROKEN_HOLD_BIT) && updatetx; while (recv_count && !is_arbitration_lost(regs)) { + int err = wait_for_bit_le32(®s->status, CDNS_I2C_STATUS_RXDV, + true, CDNS_I2C_RXDV_TIMEOUT_MS, false); + if (err) + return err; + while (readl(®s->status) & CDNS_I2C_STATUS_RXDV) { if (recv_count < i2c_bus->fifo_depth && !i2c_bus->hold_flag) { @@ -452,6 +459,10 @@ static int cdns_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, ret = cdns_i2c_write_data(i2c_bus, msg->addr, msg->buf, msg->len); } + + if (ret == -ETIMEDOUT) + return ret; + if (ret == -EAGAIN) { msg = message; nmsgs = num_msgs;