From nobody Sat Jun 13 02:57:02 2026 Received: from mail-lf1-f41.google.com (mail-lf1-f41.google.com [209.85.167.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 B8D6C373BE7 for ; Mon, 11 May 2026 11:37:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778499456; cv=none; b=jMg8II3smMEnL2ykMhyyTJUSHmS3CjaU5HVnTXUaU+YRK85qc4emYNyP47JAf2a3QSuaCrvTaa7FP0/9n7Aqe54CjAJFMicNEx0q2CMidTUUIeneBcdIgqrqcSjlCBChGIYnbx8rnBD3Jls6edRpTUPj3TACxId2EF7ISIdkfCU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778499456; c=relaxed/simple; bh=kT9wOZIR2Wfh0ZigYUA9rtm7wCF4sP8fJbMh8roHmiE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HpUZRgIExEEqLcx7z+FzM+qSuqYvYOxd9Kk+y/ZAUor6RkqT1eZvGuTcTTyY9IyyQkmrBeQ+T0GseqBVXvt7/ZDH76ZnnuEnyMU31iw45SiK2z6efpbnzkb+JdT7w5eauHfNOIHAuc8hKEBZ6ZmU7bY++gYWWRNofjMW0SSUTOs= 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=XWk8x7KV; arc=none smtp.client-ip=209.85.167.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="XWk8x7KV" Received: by mail-lf1-f41.google.com with SMTP id 2adb3069b0e04-5a8c94cefcdso733929e87.0 for ; Mon, 11 May 2026 04:37:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778499453; x=1779104253; 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=XWk8x7KVwgyTZH4FvnHCRysoOgZQKhh3WuGRBclKTwHdSrTqnjT0Tx/GuZ8RvclYqz oAaxNDqiUdSumB+CFa3fTf6DGeV79uF78Vvs+wTaCs3XAhS6GeUIHTuUcgoYtGzxCe0A fxsHXOm5zkRoShoCCb5S+tdawfnKUKsIiS65QHi/gojrx687bQtsNsapvp3E3++94ELo 7i3RiGYAJVzvCVOjXrORsgf/mP9qQ6lZWtwq2O5iF8mAagi8dad8xyD9BT9zJvia1t/7 VlVFtdsFlP3poHCVES7rW0Fy+CRAJsHWvQThlY8BYFE8PdS99URQvbRf8biklbTaL3vT asNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778499453; x=1779104253; 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=ohb1RShers2Lhky1tRCHt4hQY4sgj9GKWjqLes6Hgs9Vsf0wqtaDBu0uDh+su42GUW US4CAxDXyms3xTFK3ikPzf2LF5WvSBike5n6vE6744wJNnuBO9wgp0PwPs0sRk0vgPiJ CORf2dX+I7kU+2IHrPpVTXCH6gcGe3I+F0X+iKG3fqxafMXB2pQuZFfi6oe1L/xAilNO 5crjetzj1wivFYmT8eYJd3O1r5OwqBvFI24yGlPBDaydno0wREANpptL3RW3L1T6xk7F 1tGzS5nWyh8hdSoAxGKbl0cJdHLa7jLVdp3O304fQS03O8TgkVpa67a9WBxmgIzFdDxG v+PA== X-Forwarded-Encrypted: i=1; AFNElJ83I/Pi23kO+Mg9P353LtynLXBTiZLuydtrajU5bK8HF+8qcQ1wwP6fnJREgzzhtUBXU458PLqLrRiHE04=@vger.kernel.org X-Gm-Message-State: AOJu0YxuSmoWGTj0ZuMpwN37QJ30Mhhqibh3Sw1cE8sjDb3p65ayYZH7 gxssEGt1K38J/MmppAflx5YGrtVucUjHsagUQMEOc2ZM9QyV0ZygyBdb X-Gm-Gg: Acq92OHv0QEGaxF+OU8TqIS39GFY9CmPhxHOo/Wwm24n6s4lY/UkhO2Jh2WhMhaOvJS 1kmR249Z4T2tW85+5Lt/02vHxkZp9g9+8JZkhgPdS6/3iGEJDyn8ubEiRfEKu1L6tRapDoMQ2nF HXhdm8ZEbxmPEqVC9X31ozPoYx4Uj5jbqSnCz+MhuoUdpFGTm6NDhZZFIiFzBGtEdJgetoEmxOJ YSrYCrvg6opvIMFtc7sWYnYFVwaLUbDGIiW65vqplgVX1QbdIKgSlBkWJd/Gys1rJoxTR1Z+EYM 3fpYO11EAjQAooqLFeiX1Ls/m9NrUdnLvAXQbrcXjccK4efxFioMEHu3qjQt5z2dNcZeR6mFAyO Igs5tx+Up6/QbLyqbJ7G0iEZeaj5GGJzcwgCksbIFHIa70zTFDo7S61TZYm3N2VKK+QM6DlXcyr 2ESksg9yQKCPYn6Y3yHI8HRxtAvWa3V4a9HYBP6wnNxwBJ8A== X-Received: by 2002:a05:6512:15a7:b0:5a8:8b42:4ea0 with SMTP id 2adb3069b0e04-5a8b6e8f5b6mr2253554e87.18.1778499452463; Mon, 11 May 2026 04:37:32 -0700 (PDT) Received: from C-PF5D4647.localdomain ([147.161.186.80]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5a8a956b1cfsm2593967e87.73.2026.05.11.04.37.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 May 2026 04:37:31 -0700 (PDT) From: Jie Li X-Google-Original-From: Jie Li To: Bartosz Golaszewski , Linus Walleij Cc: Wolfram Sang , Wolfram Sang , linux-gpio@vger.kernel.org, linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org, Jie Li Subject: [PATCH v5 1/2] gpiolib: add gpiod_is_single_ended() helper Date: Mon, 11 May 2026 13:37:25 +0200 Message-ID: <20260511113726.49041-2-jie.i.li@nokia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260511113726.49041-1-jie.i.li@nokia.com> References: <20260511113726.49041-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 02:57:02 2026 Received: from mail-lf1-f47.google.com (mail-lf1-f47.google.com [209.85.167.47]) (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 0D3CD374E62 for ; Mon, 11 May 2026 11:37:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778499457; cv=none; b=SSfejb4L5MuK5A6rELQBKjHH1ReTIdQx34ASLTba/fIgf/t9K9ACPBRkS8IdP9BPe5pMKIQFLw/ZxljxGIY/0PYBSJepXoqpioIgk5qTcUpxyjwAAbuvPpM9J5wr9fL+RxsGojrt16WFkutcSIdJzvRrpzgKXBDUF75/FywiXgI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778499457; c=relaxed/simple; bh=ULSxsA99WtOVeyQnnnWwi4Szn0714xC40QbXKSsl18o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tK8UzRwaJG9VgyhuxTSXKS8RaddjSTwvLZu2+a/uE0TVAXumdkbbrv2OLoxrQY3oc4Zog0/GlPkQ2h7yydtd1qZ7OHm5bSiXEA0hkh5EQGnBnazT/SIZVM+3dhmWuNaSSzWppwZNqiG+oL8eV8mBP0XwrUt4peW6aGm0vVTw5+U= 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=aY4FAfIA; arc=none smtp.client-ip=209.85.167.47 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="aY4FAfIA" Received: by mail-lf1-f47.google.com with SMTP id 2adb3069b0e04-5a40cfab24dso4590351e87.2 for ; Mon, 11 May 2026 04:37:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778499454; x=1779104254; 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=aY4FAfIAP5iGjoRSa+GybgKWTQ07w7xp7My0SKkySC4RGZqFV9+rb0bnnr5ZPMkKkd dwhcwQyeejK8WoP6aKyiS51LuSs0cuZut2OGqK5NS+lMA73B09XDzv/JCakxpN5SRA9a PnAjg7Ew/TNYkynei1bCg2oryDPQK0KRzy/wCR0qDOe3ccfzykDpunWQkfOvFy2MnE1B JG5gc7RzBwYyRQsC4ohhDvWGjoYeApI8xicJL5d7Y/ALL8GIazSDo6m5EpVuIDa4ovNw TeIrwHEypSd4HYN3W0BVexaKnYQoQjTV1VRHHG0AAEuijtBNLWHZsqYnQqGmXu2+3aSA Oa3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778499454; x=1779104254; 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=pgae3K5AZ8nuJXiyxQij9i0yE7ro/qR+4t2p+btzmrGtRMzkwyNM5Xl6jbPRxYP6D5 GHl/d1GbjBmzAIBR18YzHg6vfd2aLER8o3iobpb3fw1fKomOaVC95EFt/NxBaVaO74nX cT3XxPQG9PSI2sYZFKaKfJO/Ac/yYK7j3UMu2DMw4Znk08HV40TLpuEivAVM3mcXfzqH j430v+7KrxFh4YM4fMGmbUl9gjbgY9Q6KF2igifyKUP1s9zZtA3YpY20U36EybhGjAgF 2TWfFTClE8KcumUxpNn6Ohokp3iu0/gCUvlkZnpUnJ2cootMPgHosvgbyrpL4CbcXI9v N/vg== X-Forwarded-Encrypted: i=1; AFNElJ8/z/OodtqiKqb0CJyBJ6M2jqqDie7hPXwd5VR7RX3jR7yEn18m4D+nlMzrESMELCC6SoC1pDCPyYq5rRQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwPaoZ0723m3w6IiWuNAvIdHh+rP2gK4GDOULtqqzopyB6ddg8Z OC73d+/H1r+dgWReuTeO7RsKHORij+XCYWe3Vey0Vz0/cbIJiO52FQxd X-Gm-Gg: Acq92OGk0j3wqy78tSrMcn7Lat8WRMan4sd0FRAi8EWZx4P610v1z1aOWIiQDfIy1NQ Dpxw/fObEPRYCvjdh07XGau4rHDe3nlYsmqR8z4ivG+NjSkqpTukghx3Rugm6PQ904NkYa+m61z q9sV8FAhtctD/Dat4Xbe1BO8myVrzWR+xIWLruXwpGfeLi9RTgtngmfwF9TqPs7o4oUF2cXcuV6 s2HdYGDA8PtdvRUlDp+wGH3QUzgjbQUdPDLfi1bxIG8QgTmDY8E4OdUmvCyaPG7l/hvKT+4qYzO 6iaoNEVIXgI/PumQQte5YmRPBj+g1q3RimqxclYvC8Pc3iwqtfyrAc9jn+kgJu4oMusyDA1QJqF pMddd4uvoH7nFaaaNIR/4PvqiapKarohyBmgOb2xfZlosQRUnI/rHsnpQ7ZiFttjWFk/173PsAn Qnf9XrLEdNWUC8L9jGvJ2AAxVYEoeclCSM2YzLYL4SDfgjxg== X-Received: by 2002:a05:6512:2252:b0:5a4:52d:4abc with SMTP id 2adb3069b0e04-5a8a949f19amr4681273e87.8.1778499453886; Mon, 11 May 2026 04:37:33 -0700 (PDT) Received: from C-PF5D4647.localdomain ([147.161.186.80]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5a8a956b1cfsm2593967e87.73.2026.05.11.04.37.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 May 2026 04:37:33 -0700 (PDT) From: Jie Li X-Google-Original-From: Jie Li To: Bartosz Golaszewski , Linus Walleij Cc: Wolfram Sang , Wolfram Sang , linux-gpio@vger.kernel.org, linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org, Jie Li Subject: [PATCH v5 2/2] i2c: core: support recovery for single-ended GPIOs Date: Mon, 11 May 2026 13:37:26 +0200 Message-ID: <20260511113726.49041-3-jie.i.li@nokia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260511113726.49041-1-jie.i.li@nokia.com> References: <20260511113726.49041-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