From nobody Sat Jun 13 06:03:54 2026 Received: from mail-ed1-f51.google.com (mail-ed1-f51.google.com [209.85.208.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2E195394497 for ; Sat, 9 May 2026 09:12:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778317941; cv=none; b=hs4LKcl0kYhYP1VOxKQm+HNIdl9GA4o9kw3J8xNO/77pbhgL0kqREkrc3Fo+FfI0dqOPr7tUk7zvJUS5CK8GDGpXrhKnZ+UvZDblmAflxrsa2VNAN+3t7ixJbMEyITeR8LwNxwsnZTF4hAhehBXDw9nK0taoLg4I4Xn6RBJ6Ssw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778317941; c=relaxed/simple; bh=kT9wOZIR2Wfh0ZigYUA9rtm7wCF4sP8fJbMh8roHmiE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=d8bMuJgjYfULrrdBxZhl+gPO5qTcB8iazZoGHPMb/roXZTjg5VGd+MXXtJBUB9aLBIRwLlESSQuxWBoqaWBzH1ehG4CjxWvDoACBt9Yudepeky1P9/RukGFNePWUmLS1JVExaBg7GvUM9DnvVrJbx+ILpx9UtjIGJsjaTSuxgXg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=XOFZrX51; arc=none smtp.client-ip=209.85.208.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="XOFZrX51" Received: by mail-ed1-f51.google.com with SMTP id 4fb4d7f45d1cf-678adefbd26so5107450a12.3 for ; Sat, 09 May 2026 02:12:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778317938; x=1778922738; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4imfVsi2VomO9FzKGpPU5riMSUcvWN6BNCMHeP3TKZM=; b=XOFZrX51tARqx+WMuQE+aP+J9SRmLZoSnkM+ra9RUPA8JJBDhw9zHobJBaGSPaXbdU 0zb4UMYDmxdsvV06uFigXEuYTG/uJClDhtWIQeHQUo25z/2HCb3kW2eGdOVOP9WsRilE kIuuz+bxHOii6/H02br6k3MERjB72jP8xbQ3d8VlFLBdA8LTs2tgDheekEU/r4KJPAOf S8t82uTq0/KC2JCPOZWFaIs/JRPq4lYNU7+q/QLYA0Iau7Ah7jGwIIk3EH1cNumTLUlK wpZiAMocKgMOXyHZcfbYFRmDGVtcylEQ/K7Id9GmeO3Dmc0Q6pjmswQmROw2l+rsNJ5F Gx/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778317938; x=1778922738; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=4imfVsi2VomO9FzKGpPU5riMSUcvWN6BNCMHeP3TKZM=; b=fwU+xltysV7GFEJ6+R9nspFyKuWX7LMmGyOQqfwrRKsVXAymjZjFIFXg5KQAynG97s U95jgm2NTEpT/+eyWPy+FFxtbPPDJyUjSI+GP/02VVvmkZggmH6axUudVz7iQzAdJsW5 fpDfmGABkIIUqV83z1IMojUKBEGupaalkmV2r6FdPdBRPRRhafsJozLiW+hAOlw+LOUa xeMMpkSY+DyTsRo8aEviWEVN8p3yiVF8ySAtQNJvUM4Fcp2Sh2o1TaExRdmFGAk04QW9 DsLr38QFzWXp4HvD4co0Cyq8udGQ6xGfMyTr3ZA9hHiFsx4lX2h8UOIPPQE7sqN2rRHt kMMQ== X-Forwarded-Encrypted: i=1; AFNElJ8fiNYU1PnJHTf/2vk+PqWjPuSyPt0Co8YxcTQqLdYKbBsDpk7qZ/ogqdnFfhEB/Rv0no07FG61yEvLXoY=@vger.kernel.org X-Gm-Message-State: AOJu0YwNTXZopDNBYxVarY8cdfb77XBLww82vApvjvZHGZoeU0zqOrSs G//jbYeOF0fVOKwae9c2h0aFl1JspZc4c5hvSx+yxFxwVdeptOcCA7Np X-Gm-Gg: Acq92OGDfANNWxflyqZBJmjcXeQL/vdnr49xQYcfPk43ZAjs0yh6PYQ4Zi2RMdH3AGK OLGhIv0wGOOv/G7icsk7C8Sl5L5XwpZSbmmg3Gheh7lLsIa9ungIEm8EIwuoAtxbRyI6ps+3T2l fetY0V+/II3wCMMnUuX4eIxr9LbtwZxBIRuCjKbkaXjJoN/oV5Sw02DGLG5CAf5mKuso30aeb5D XbnhOTDrZNkCibwaFvRGNGQXzo3DLtOHwE28Afq9RN3dW10yRwRRDjGGY32TwIQ+5mMfK2IdSL+ Z1Y/VEkZP0YAVkHiAe4HJ9WhY6TZKdsYv3/7wMc0gn9Cv4BH2LtRw0CmyXxJt+499kIbNAK8a7M C+mQLy6BHPlVly8rdVX0M3Z3lnNyg/8wUF43zy5DxWpnoAmNNfJLdiLzLyqZpEDz/ggU1fyTDyg N6TY8L/Y82sZgSY4PudnNMM9n7ZPmRa1ZWml0= X-Received: by 2002:a17:907:988:b0:bbe:37ee:8a2b with SMTP id a640c23a62f3a-bcaac454c4dmr348565366b.33.1778317938239; Sat, 09 May 2026 02:12:18 -0700 (PDT) Received: from C-PF5D4647.localdomain ([147.161.248.89]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac3f66cadsm203819866b.42.2026.05.09.02.12.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 09 May 2026 02:12:17 -0700 (PDT) From: Jie Li X-Google-Original-From: Jie Li To: wsa@kernel.org, linusw@kernel.org Cc: linux-i2c@vger.kernel.org, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Jie Li Subject: [PATCH v4 1/2] gpiolib: add gpiod_is_single_ended() helper Date: Sat, 9 May 2026 11:12:07 +0200 Message-ID: <20260509091208.18346-2-jie.i.li@nokia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260509091208.18346-1-jie.i.li@nokia.com> References: <20260509091208.18346-1-jie.i.li@nokia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The direction of a single-ended (open-drain or open-source) GPIO line cannot always be reliably determined by reading hardware registers. In true open-drain implementations, the "high" state is achieved by entering a high-impedance mode, which many hardware controllers report as "input" even if the software intends to use it as an output. This creates issues for consumer drivers (like I2C) that rely on gpiod_get_direction() to decide if a line can be driven. Introduce gpiod_is_single_ended() to allow consumers to check the software configuration (GPIO_FLAG_OPEN_DRAIN/GPIO_FLAG_OPEN_SOURCE) of a descriptor. This provides a robust way to identify lines that are capable of being driven, regardless of their instantaneous hardware state. Signed-off-by: Jie Li Reviewed-by: Linus Walleij --- drivers/gpio/gpiolib.c | 22 ++++++++++++++++++++++ include/linux/gpio/consumer.h | 5 +++++ 2 files changed, 27 insertions(+) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 1e6dce430dca..69743d6deeaf 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -491,6 +491,28 @@ int gpiod_get_direction(struct gpio_desc *desc) } EXPORT_SYMBOL_GPL(gpiod_get_direction); =20 +/** + * gpiod_is_single_ended - check if the GPIO is configured as single-ended + * @desc: the GPIO descriptor to check + * + * Returns true if the GPIO is configured as either Open Drain or Open Sou= rce. + * In these modes, the direction of the line cannot always be reliably + * determined by reading hardware registers, as the "off" state (High-Z) + * is physically indistinguishable from an input state. + */ +bool gpiod_is_single_ended(struct gpio_desc *desc) +{ + if (!desc) + return false; + + if (test_bit(GPIOD_FLAG_OPEN_DRAIN, &desc->flags) || + test_bit(GPIOD_FLAG_OPEN_SOURCE, &desc->flags)) + return true; + + return false; +} +EXPORT_SYMBOL_GPL(gpiod_is_single_ended); + /* * Add a new chip to the global chips list, keeping the list of chips sort= ed * by range(means [base, base + ngpio - 1]) order. diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 3efb5cb1e1d1..8fb27f9aa67f 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -111,6 +111,7 @@ void devm_gpiod_unhinge(struct device *dev, struct gpio= _desc *desc); void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs); =20 int gpiod_get_direction(struct gpio_desc *desc); +bool gpiod_is_single_ended(struct gpio_desc *desc); int gpiod_direction_input(struct gpio_desc *desc); int gpiod_direction_output(struct gpio_desc *desc, int value); int gpiod_direction_output_raw(struct gpio_desc *desc, int value); @@ -337,6 +338,10 @@ static inline int gpiod_get_direction(const struct gpi= o_desc *desc) WARN_ON(desc); return -ENOSYS; } +static inline bool gpiod_is_single_ended(struct gpio_desc *desc) +{ + return false; +} static inline int gpiod_direction_input(struct gpio_desc *desc) { /* GPIO can never have been requested */ --=20 2.43.0 From nobody Sat Jun 13 06:03:54 2026 Received: from mail-ed1-f41.google.com (mail-ed1-f41.google.com [209.85.208.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7D80839A04E for ; Sat, 9 May 2026 09:12:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778317946; cv=none; b=YiUAYrpmGPGc5XkKbWmrEgf8KjtPdK6KSoe/7nXp+4ttZGpLZKQMfundWLL9bGlUNno6x7Xfd48d6w+c7HHH/wdRoxjRMKlVHFspFwgzc+t8A7N1Huju5ZFKhM3c2YhzeyNlKu+6Z9wueqXrf0ULL4N/G+QKI2zeR0RzqiMWvGM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778317946; c=relaxed/simple; bh=ULSxsA99WtOVeyQnnnWwi4Szn0714xC40QbXKSsl18o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rbiPM2zUoru1lCyxhget6Chxf19EGTJdj0MDtWqP1fPj2olgj4OT8d2zGus4eacyJBJMFJEE/c8SUKsA+WrIwcx2zai2rziWfsX0CqoGX/xkwG3UdoUq7KoKlKhMi58pRiPDUZKMiZqF/ev8QU/E3dJJaH8uaBjwTCy+3H9lh3M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=iPitiYVR; arc=none smtp.client-ip=209.85.208.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="iPitiYVR" Received: by mail-ed1-f41.google.com with SMTP id 4fb4d7f45d1cf-67e9b3037dcso3257278a12.0 for ; Sat, 09 May 2026 02:12:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778317942; x=1778922742; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=pk/ryGv+w8weiU5QHQuVNcKF565C/DJ9GpiFb4c/EJM=; b=iPitiYVRebqxAaucnGOFAC/4+/M5h1gtxJo9Zx+fH0B2iq/v2+cLZfs1evCq1i8qS5 yhn7JmpwZoWDPyAta8hueKBtiPDhq36zJrmPZEQ+cPtP5io6WcRZWGJWkubAGUZLK57a Nkn+CgGZQ1xakpHBWsSLCsqAkDOaklXKqbgyT+Mv6nVjWJKQRA45bxPifBGZA1y16u+6 miCOEaAlUtDpF+K+uJ9+ruuMh7xXMe28Q/dK1iQi58vGE9aGZmoM6jeRL4N3O7dvIuj2 4F/NypL3EQ36kIwR8I/30j98lqKUUxlkU+zvz8rLq8NUMDkM6aNc33M139eTR4ila214 lq8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778317942; x=1778922742; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=pk/ryGv+w8weiU5QHQuVNcKF565C/DJ9GpiFb4c/EJM=; b=Eu6bGWMuNuSAOiEFUoRtL055+P5SjChWrnk6GTFxuW2ej09ZpemOq2LPxyVzozsDLY Mv6yuxnr/XrUndtMrKg4mPuNTcPh6CwvJqRSK0yGGsxD7cvfdWJi1tMZdcIhQfmlTzZH PxxqsJzCSTxpFHAx4j2IadxEimvLAsJMltp1o8dWhYcO8DR2/UPhewlI0qiYTWa4F/sE NMkd56ruPIK2PKYneKJ0gZe/LHTsJvWsY7A1wAlYPHAeEIL1wzpBvED+yYBrZ0SyPK3R utuPKOc7e5JvnVnZ+uwIvd1ffJ5dRjrBE3+ewRvSplL7OyvK43EXTzI6sq17Q/Du8sP2 Ms9w== X-Forwarded-Encrypted: i=1; AFNElJ+hirnc0ysW9HT6cy1vHgx38DzI25zJKRtSz7BAotSFeSPutb7a6nFGcIVYYP9QuYpe8f9IRIG0I6GkCgU=@vger.kernel.org X-Gm-Message-State: AOJu0Yz2QK8HGrKA0KvXtdy0fHwpGHuWBcWdwqrCGmx0YNmjSssQjdw9 glYmDugnCs9r/qs+eqAwQeQe7EYGWkoBguOhrJ8YnvnS/T40UKa2O7Us X-Gm-Gg: Acq92OHg/CnBUZhrDfggvqoPsRAA57OtEX8szyqyuAW3f5/cIgw4MDVivzWu9p75W/T P/Hx+qB7XIrbyHsL1xQWqU0/kvA2UdBj+4BmkCLvCppKCwvYJywD1BOOP7Zjqv7dFbbwS0LqD96 bBcF7JNv//7Edb0KRkqEokEzHJYVFtqt6rJOwrBi8D9Pek/BKpU9hLv6EW+t210Vj7kmP+aMPKV 9YRnOW8EoVuUhPokLBAAjiB9P80yqR3iYsmdgr2oxfhaT1iy3VO1OCrN6cUKomBSZ7JDrbHsEZl OEQvv7H2adfzP8W0yW1aeZWiJc+NZ/9wimqgmzz+HREYI7JXb3zuIevYjMvr3xx3ISMxLQmCucn Dk6bbUpN4dyFdMqgLoratViJJsDf+YzciX+30imvFvFo9IALhgEDqUjeNEFf4bH2PzwhbrRvHLt QpEHSEHCeyTqyp//hOQOwFdS9QjlloTN86gpn7rRhRLC7q7A== X-Received: by 2002:a17:907:9346:b0:bc3:b598:7f47 with SMTP id a640c23a62f3a-bcaad226929mr377767166b.42.1778317942195; Sat, 09 May 2026 02:12:22 -0700 (PDT) Received: from C-PF5D4647.localdomain ([147.161.248.89]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bcac3f66cadsm203819866b.42.2026.05.09.02.12.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 09 May 2026 02:12:21 -0700 (PDT) From: Jie Li X-Google-Original-From: Jie Li To: wsa@kernel.org, linusw@kernel.org Cc: linux-i2c@vger.kernel.org, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Jie Li , Wolfram Sang Subject: [PATCH v4 2/2] i2c: core: support recovery for single-ended GPIOs Date: Sat, 9 May 2026 11:12:08 +0200 Message-ID: <20260509091208.18346-3-jie.i.li@nokia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260509091208.18346-1-jie.i.li@nokia.com> References: <20260509091208.18346-1-jie.i.li@nokia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Currently, i2c_init_recovery() only assigns the set_sda/set_scl hooks if gpiod_get_direction() returns GPIO_LINE_DIRECTION_OUT. 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 Reviewed-by: Linus Walleij Acked-by: Wolfram Sang --- drivers/i2c/i2c-core-base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 9c46147e3506..a3c33e804d47 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -445,8 +445,8 @@ static int i2c_init_recovery(struct i2c_adapter *adap) bri->set_scl =3D set_scl_gpio_value; if (bri->sda_gpiod) { bri->get_sda =3D get_sda_gpio_value; - /* FIXME: add proper flag instead of '0' once available */ - if (gpiod_get_direction(bri->sda_gpiod) =3D=3D 0) + if (gpiod_get_direction(bri->sda_gpiod) =3D=3D GPIO_LINE_DIRECTION_OUT = || + gpiod_is_single_ended(bri->sda_gpiod)) bri->set_sda =3D set_sda_gpio_value; } } else if (bri->recover_bus =3D=3D i2c_generic_scl_recovery) { --=20 2.43.0