From nobody Sun Feb 8 18:33:03 2026 Received: from mail-ed1-f47.google.com (mail-ed1-f47.google.com [209.85.208.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 27ADE2ED872 for ; Sun, 1 Feb 2026 11:18:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769944701; cv=none; b=Z/t6OhS1h46lUX2EiOQTRxeAO+kritu0PusyI19Kzii3Hq0g79gqBEql6wZXnzZR1H8n+7Nse928rim2Vr18RHetWZNuCWJeG02XJ3FZGA5/cQE0vz3Rqwo0Eic0+LTsKv8R4V0U/ifa32yc8NI+jFWkFb6RlyYHU/YDgR9s2bo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769944701; c=relaxed/simple; bh=nRpH/iLtlWIM8KUrHyohq2XqCM2gV6aIOs+uJYs9+8k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=J2JF/1HcAioJSAKa78xMjvV0cP5IHFXlPCKGqzqXXosJwjPAzLwxxQvf3eXDZ/cbzJougL+4Zx5bcKi2zjS86lpI96PM8QrOKQdAfXxxMrw9dmVn6MeanYoqDy6LRRHyh6EIjqm4QafeHNlCJORxE9oQqcBAqnYTipvRuXXSBJI= 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=A0Uz3/IY; arc=none smtp.client-ip=209.85.208.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="A0Uz3/IY" Received: by mail-ed1-f47.google.com with SMTP id 4fb4d7f45d1cf-65808bb859cso5274145a12.2 for ; Sun, 01 Feb 2026 03:18:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1769944698; x=1770549498; 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=/RzDUpXasUz2gSgQY0FnUVtM7tN13xUWfydJ/oE+LZw=; b=A0Uz3/IY2Nux+nmg/MuAPWM20U1jhVlUS3GUTiQIUdikLB7L3UmkE8Bfd0smX5x/Ky 2wOCm7YZkjBhC/7N1vWOjG/aelNNfILoji9wKFr1kMalQvvmIKF+zHpLW2NSgJJD2Ulq AF1GKLWx8+IHcMNJ9jlih8IWwWzapcYBypIkspkmh0HpLcdfNSMv0XRlm6PrV7LLD06p Db00iVOTpzJI0dPM0b4SxGPGJpIlsG9PQ5GLpjeFWag4L/QEIpI6C1yljgRUoNKjW4ZU HHdAyX4I1cruEDuGMiemQfsWxrQf0267Yro0eaL4Jrn2mlegKISvlGrkQk0AWDyXbjH/ cinw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769944698; x=1770549498; 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=/RzDUpXasUz2gSgQY0FnUVtM7tN13xUWfydJ/oE+LZw=; b=bcA0YRPW5QX8UkjC0HEWeeHqvtfn9zRi586yDtebU0KfYEhoFGFdbPhT6cK8ATKQpF GvdttJCDXWXJc2hnsY5+LzvZUxR6wy+uxBUZ+ViBVBDDn5X92/YGQT54qT4aFpIe/Iy1 i+W7AvJi43hwMQ/x6o5THGAS1UCvn9gaUU2zmQuvca1bXxxKzrCQKXrj371yP6eKZFEq kL/ekcd3Qu6Wgow9XOIwXDulqhqLxnGfTjv02Uvgq6jNJ1Y5FRS99mm3me1d76rGcCn+ kT631/OHMic3kVWhGrt+mPMdujQ7kY2tFPFBUqMlZ6nzk8pBsnmPzAx75awHTeblOh0j 0cUw== X-Forwarded-Encrypted: i=1; AJvYcCW61wyHVCwbxYgd+LUEEfJFHnuf46yEEHHBLwD5irkrvOdB6NoJ9vu7JHznAykXKk3WbCLT4nOAyHe+d1Q=@vger.kernel.org X-Gm-Message-State: AOJu0YzUnlnrq7zV3o1kYg+mUSEPr6XYIEmEK/UqXFqhrxZZ64gXFRnD iwCLL2DYQU8sEbxrqpx+xTR+V9mytwuNhrLYaLgFa1EhakJKDW5q+oo+ X-Gm-Gg: AZuq6aIkg9Zr4VGCAXjc9JM/2HGfK0qTM5TxvAe++nxbVKwF4lP0MWJVeB32GJJb3rg Z3RbwhLVwpEo6ZU8J3ziMibind504FgBtkhqNL1pb809n6um28hc1hcddNBlzQt7PVGDAB1oZn8 HvRjcQ226YO6LX685yMyBUjCyYgK1lXQfcFHmrielWKsPmjYvvDzW/dglGpx66jgVyYFl7/sB9h 1eX8hchzUaNAP6S+h90OWKb0LlyoHbO9u/lED7uElG7T1kboxl6Aa7a92ntzgAXXvjiM9GKjg4S WhA1hNkApvF6Lcdao1KH45CkMUG02UmIt6IUEvqjbKal38IQH6xgam/rj9DPWQ6CTpB1SyMr0RK NauCzZrr4rIVKXLubuUIT2xunLcewFYvMq8Ics1dTW/9AOmwOZIPcLEIRIl8ByjQYz9c3kNT7qf YYQoyMISSM5kvHMNrKK/L55BY= X-Received: by 2002:a17:906:c155:b0:b84:40d3:43e7 with SMTP id a640c23a62f3a-b8dff514fd6mr457167866b.6.1769944698320; Sun, 01 Feb 2026 03:18:18 -0800 (PST) Received: from C-PF5D4647.localdomain ([147.161.249.21]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b8dbf2ed6besm714713066b.60.2026.02.01.03.18.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Feb 2026 03:18:17 -0800 (PST) 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 v3 1/2] gpiolib: add gpiod_is_single_ended() helper Date: Sun, 1 Feb 2026 12:18:11 +0100 Message-ID: <20260201111812.18945-2-jie.i.li@nokia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260201111812.18945-1-jie.i.li@nokia.com> References: <20260201111812.18945-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 1578cf3a8c74..08e6960053f8 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -486,6 +486,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 cafeb7a40ad1..12ef6e07ee1a 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -109,6 +109,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); @@ -335,6 +336,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 Sun Feb 8 18:33:03 2026 Received: from mail-ej1-f41.google.com (mail-ej1-f41.google.com [209.85.218.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 7769C324B1D for ; Sun, 1 Feb 2026 11:18:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769944702; cv=none; b=MJhb8/irNkNTCaWrxZnWGXi3P8qKCT48yr/RzEVARnT2gFgPNePnOKhSwINoj/qwSDYdk9bKqgZKUduPU7dw+IIPBfyZ5qcaG5B5Vm0ivUoFFhTFtMC7PFQOp227TV9asN0HPFjOZeIZxBjOBMYxdkLtalUgB0AEvs6cDTaj/FI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769944702; c=relaxed/simple; bh=DT/AC0f3v8zTwDpTqWISUM92EMD8mREJDDZ5pNdtZYw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=b/QcaM/8t4vMqaT8EWQM3HSMv4bly7BcFSkvwJKi/MGXGx0PdtMJG0AjDAYiYBk2G/FPdze99iMRzL4iR+qddzKURdtKYHDPMRxGojr3B41exjQhScbcurY1+H3aO75kz0HjQIkiQDuseta/qkb+2K+7XcF17rtm4I3Vw3EvTso= 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=lNZPwrFf; arc=none smtp.client-ip=209.85.218.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="lNZPwrFf" Received: by mail-ej1-f41.google.com with SMTP id a640c23a62f3a-b884cb1e717so692485666b.0 for ; Sun, 01 Feb 2026 03:18:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1769944700; x=1770549500; 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=lGn3i/O/y+GdrcNDRMS16OuGNGT+puPLYW3aCy6Bi54=; b=lNZPwrFfUVHJobP8737sLm3ff2MZU/dhdCu+vC14sb67nOdJXNh1rmUzZL4otHpH44 DsT+CKHkQD6hRD6bODQuD2QQ+TXy15OhuTO/EF7pzwHXLjSVTr5Mpa4yDgPf4CHFEVev fMIvu394le0JZPH/9UgCjPDOQF/L69B55aFVyW8IyFiJPMllVgkt313tGlq6vBhm6lUy Pa66ggn2e8ZIQCGNnjiVX9V0Hn23aAlq3t9wTTHvoH0ekLxCtVU7cgC6Uc83b5thu7OX 851g2upf33kOCRRf/xSpOe/Y5VdToKdkp/9s2+GRD3ihjXTLu4Dd+6i6DUCpERo5lzOu yFFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769944700; x=1770549500; 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=lGn3i/O/y+GdrcNDRMS16OuGNGT+puPLYW3aCy6Bi54=; b=xHKlSCAyZTQu1EHKp47par4oSqJPO+x+iTDp9OMFi+IKAurONnWfLkdwAvTW0rJs75 CQdrmLYJqcJbM7cS2TU4YUfCuRpbc49p/lAOJgCioTmCwU8dIg8BebyiKgLqMqU241wk SXk75/dPjiIbgPw10vHzWACgZYcFaFkqf/0LHeXOYcv4Buzp0Qbqxcj3EmpuW4Elipnx spc8jCYTv2zPCgcyQgoXQP4ASGyjHWXG7rEM6UmTgLoFSPrUsmMGVeakQNvL1aROoi9l xhWvliXqDywqtQNxgjdoJ+aiCRc5/OOFFC9ufcrz+bMzKbdAfsFLU683vCRfdRDbla1E 5Wlw== X-Forwarded-Encrypted: i=1; AJvYcCViTfJ19SnMLeLuJGdJDjMjJAYDyKaN4fMrCUXeSRIiPy0w5E7ROR2npwvwWU3wqJesTz7GBQALXSD31tg=@vger.kernel.org X-Gm-Message-State: AOJu0YzMnZmaBFb/9WaxTu+ZszrHngUUNXHS1L0LvuET3OvFH3hB2vmn xHabvl+D24YXsP3cw4/Cc/xMuKtppkFJE3NggqYkku+AaEIiu7MJZSSY X-Gm-Gg: AZuq6aI2u9agpAGigocxNXqugSQu3TDIE5YCjKmjpK12o9B4itU4iIHna0/kB/32uE1 VUPFBddcCRDLK5ViCbiS2FFsnabLZgXZd9npxgcRscCsJ0gWgc1mQ/AUfhJ1TG8VCsaghwXQdb/ 5pISpBXgTZGpa90kTUXxh1FCF9kyAjzixZFPZnj55mQ/U9RSowSq7uwlQ2EYU2BN004O090skIG UgSYyuzOGivB63lmEHh0+mzwPiWFV0AZnMEyKxKI3w4R6d0sdjwqoTAUubKXD/sLVqceJ/Z0fU4 SdKMyp+OQITPr6RrMAK0LclnIUwiARsGrilPGN3xbfvjVu8ESGAgSMo8MJmNBFuMEXPlLfGBLpA P8i4S1HLVQQ5cCJpW996hdoMKKe9muTSOJzLqfs5eB5NykHPn9NaiVG5r58763v45wRTELD9gZt E6mcETBQkqm8S89Z5zYS1P1/s= X-Received: by 2002:a17:907:3f08:b0:b8a:e013:9c5b with SMTP id a640c23a62f3a-b8dff1f35d0mr611231766b.4.1769944699726; Sun, 01 Feb 2026 03:18:19 -0800 (PST) Received: from C-PF5D4647.localdomain ([147.161.249.21]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b8dbf2ed6besm714713066b.60.2026.02.01.03.18.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Feb 2026 03:18:19 -0800 (PST) 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 v3 2/2] i2c: core: support recovery for single-ended GPIOs Date: Sun, 1 Feb 2026 12:18:12 +0100 Message-ID: <20260201111812.18945-3-jie.i.li@nokia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260201111812.18945-1-jie.i.li@nokia.com> References: <20260201111812.18945-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 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 Reviewed-by: Linus Walleij --- 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 =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 0 || + 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