[PATCH v2 3/7] i2c: npcm: fix consecutive dm_i2c_read/write error

Jim Liu jim.t90615 at gmail.com
Thu Aug 7 07:32:20 CEST 2025


From: Stanley Chu <yschu at nuvoton.com>

When doing a dm_i2c_read followed by a dm_i2c_write, the subsequent
transaction may get npcm_i2c_check_sda error because the module is
still busy in STOP condition in previous dm_i2c_read.
Always check and wait for module to be out of busy before starting
an i2c transaction.

Signed-off-by: Stanley Chu <yschu at nuvoton.com>
Signed-off-by: Jim Liu <JJLIU0 at nuvoton.com>
---
 drivers/i2c/npcm_i2c.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/i2c/npcm_i2c.c b/drivers/i2c/npcm_i2c.c
index c64752e1467..bff0d04f1a5 100644
--- a/drivers/i2c/npcm_i2c.c
+++ b/drivers/i2c/npcm_i2c.c
@@ -34,6 +34,7 @@
 #define SMBCTL3_SDA_LVL		BIT(6)
 
 /* SMBCST */
+#define SMBCST_BUSY		BIT(0)
 #define SMBCST_BB		BIT(1)
 #define SMBCST_TGSCL		BIT(5)
 
@@ -479,11 +480,17 @@ static int npcm_i2c_xfer(struct udevice *dev,
 	struct npcm_i2c_bus *bus = dev_get_priv(dev);
 	struct npcm_i2c_regs *reg = bus->reg;
 	int ret = 0, err = 0;
+	u8 val;
 
 	if (nmsgs < 1 || nmsgs > 2) {
 		printf("%s: commands not support\n", __func__);
 		return -EREMOTEIO;
 	}
+
+	/* Wait for module out of busy */
+	if (readb_poll_timeout(&reg->cst, val, !(val & SMBCST_BUSY), 1000))
+		return -EBUSY;
+
 	/* clear ST register */
 	writeb(0xFF, &reg->st);
 
-- 
2.34.1



More information about the U-Boot mailing list