[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20260125195123.248798-3-jie.i.li@nokia.com>
Date: Sun, 25 Jan 2026 20:51:23 +0100
From: Jie Li <lj29312931@...il.com>
To: wsa@...nel.org,
linus.walleij@...aro.org
Cc: linux-i2c@...r.kernel.org,
linux-gpio@...r.kernel.org,
linux-kernel@...r.kernel.org,
Jie Li <jie.i.li@...ia.com>
Subject: [PATCH v2 2/2] i2c: core: support recovery for single-ended GPIOs
Currently, i2c_init_recovery() only assigns the set_sda/set_scl
hooks if gpiod_get_direction() returns 0 (output).
This logic fails on certain SoC controllers where open-drain lines
in a high-impedance state are physically reported as inputs. This
leads to a "deadlock" where the I2C core refuses to assign the
recovery hooks because it incorrectly assumes the pins are
input-only, even though they are fully capable of driving the bus
low for recovery.
Update the recovery initialization to use the new
gpiod_is_single_ended() helper. If a GPIO is configured as
open-drain or open-source in the firmware, it is safe to assume
it can be used for bus recovery, even if the current hardware
direction is reported as input.
Signed-off-by: Jie Li <jie.i.li@...ia.com>
---
drivers/i2c/i2c-core-base.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index ae7e9c8b65a6..11bd801418e8 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -446,7 +446,8 @@ static int i2c_init_recovery(struct i2c_adapter *adap)
if (bri->sda_gpiod) {
bri->get_sda = get_sda_gpio_value;
/* FIXME: add proper flag instead of '0' once available */
- if (gpiod_get_direction(bri->sda_gpiod) == 0)
+ if (gpiod_get_direction(bri->sda_gpiod) == 0 ||
+ gpiod_is_single_ended(bri->sda_gpiod))
bri->set_sda = set_sda_gpio_value;
}
} else if (bri->recover_bus == i2c_generic_scl_recovery) {
--
2.43.0
Powered by blists - more mailing lists