[PATCH] i2c: cdns: Add timeout for RXDV status bit polling
Michal Simek
michal.simek at amd.com
Wed Nov 26 16:12:35 CET 2025
From: Padmarao Begari <padmarao.begari at amd.com>
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 <padmarao.begari at amd.com>
Signed-off-by: Michal Simek <michal.simek at amd.com>
---
drivers/i2c/i2c-cdns.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c
index 3f7cf8533ec7..4e9d4e44899a 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;
--
2.43.0
base-commit: d9f73d26af832e19dfd79a4b7bfcf09c498a4873
branch: debian-sent3
More information about the U-Boot
mailing list