From cb8484d1ba71ca9572ae6c6f97010be7bdd95fb7 Mon Sep 17 00:00:00 2001 From: Tali Perry Date: Fri, 28 Mar 2025 19:32:50 +0000 Subject: [PATCH] i2c: npcm: Add clock toggle recovery [ Upstream commit 38010591a0fc3203f1cee45b01ab358b72dd9ab2 ] During init of the bus, the module checks that the bus is idle. If one of the lines are stuck try to recover them first before failing. Sometimes SDA and SCL are low if improper reset occurs (e.g., reboot). Signed-off-by: Tali Perry Signed-off-by: Mohammed Elbadry Reviewed-by: Mukesh Kumar Savaliya Link: https://lore.kernel.org/r/20250328193252.1570811-1-mohammed.0.elbadry@gmail.com Signed-off-by: Andi Shyti Signed-off-by: Sasha Levin --- drivers/i2c/busses/i2c-npcm7xx.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c index a693ebb64edf..7b6eb2bfb412 100644 --- a/drivers/i2c/busses/i2c-npcm7xx.c +++ b/drivers/i2c/busses/i2c-npcm7xx.c @@ -1969,10 +1969,14 @@ static int npcm_i2c_init_module(struct npcm_i2c *bus, enum i2c_mode mode, /* Check HW is OK: SDA and SCL should be high at this point. */ if ((npcm_i2c_get_SDA(&bus->adap) == 0) || (npcm_i2c_get_SCL(&bus->adap) == 0)) { - dev_err(bus->dev, "I2C%d init fail: lines are low\n", bus->num); - dev_err(bus->dev, "SDA=%d SCL=%d\n", npcm_i2c_get_SDA(&bus->adap), - npcm_i2c_get_SCL(&bus->adap)); - return -ENXIO; + dev_warn(bus->dev, " I2C%d SDA=%d SCL=%d, attempting to recover\n", bus->num, + npcm_i2c_get_SDA(&bus->adap), npcm_i2c_get_SCL(&bus->adap)); + if (npcm_i2c_recovery_tgclk(&bus->adap)) { + dev_err(bus->dev, "I2C%d init fail: SDA=%d SCL=%d\n", + bus->num, npcm_i2c_get_SDA(&bus->adap), + npcm_i2c_get_SCL(&bus->adap)); + return -ENXIO; + } } npcm_i2c_int_enable(bus, true);