linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/10] gpio: improve support for shared GPIOs
@ 2025-11-12 13:55 Bartosz Golaszewski
  2025-11-12 13:55 ` [PATCH v4 01/10] string: provide strends() Bartosz Golaszewski
                   ` (14 more replies)
  0 siblings, 15 replies; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-12 13:55 UTC (permalink / raw)
  To: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Bartosz Golaszewski,
	Catalin Marinas, Will Deacon, Srinivas Kandagatla, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Alexey Klimov,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

Bjorn, Konrad: I should have Cc'ed you on v1 but I just went with what
came out of b4 --auto-to-cc. It only gave me arm-msm. :( Patch 7 from
this series however impacts Qualcomm platforms. It's a runtime dependency
of patches 8 and 9. Would you mind Acking it so that I can take it into
an immutable branch that I'll make available to Mark Brown for him to
take patches 8-10 through the ASoC and regulator trees for v6.19?

Problem statement: GPIOs are implemented as a strictly exclusive
resource in the kernel but there are lots of platforms on which single
pin is shared by multiple devices which don't communicate so need some
way of properly sharing access to a GPIO. What we have now is the
GPIOD_FLAGS_BIT_NONEXCLUSIVE flag which was introduced as a hack and
doesn't do any locking or arbitration of access - it literally just hand
the same GPIO descriptor to all interested users.

The proposed solution is composed of three major parts: the high-level,
shared GPIO proxy driver that arbitrates access to the shared pin and
exposes a regular GPIO chip interface to consumers, a low-level shared
GPIOLIB module that scans firmware nodes and creates auxiliary devices
that attach to the proxy driver and finally a set of core GPIOLIB
changes that plug the former into the GPIO lookup path.

The changes are implemented in a way that allows to seamlessly compile
out any code related to sharing GPIOs for systems that don't need it.

The practical use-case for this are the powerdown GPIOs shared by
speakers on Qualcomm db845c platform, however I have also extensively
tested it using gpio-virtuser on arm64 qemu with various DT
configurations.

I'm Cc'ing some people that may help with reviewing/be interested in
this: OF maintainers (because the main target are OF systems initially),
Mark Brown because most users of GPIOD_FLAGS_BIT_NONEXCLUSIVE live
in audio or regulator drivers and one of the goals of this series is
dropping the hand-crafted GPIO enable counting via struct
regulator_enable_gpio in regulator core), Andy and Mika because I'd like
to also cover ACPI (even though I don't know about any ACPI platform that
would need this at the moment, I think it makes sense to make the
solution complete), Dmitry (same thing but for software nodes), Mani
(because you have a somewhat related use-case for the PERST# signal and
I'd like to hear your input on whether this is something you can use or
maybe it needs a separate, implicit gpio-perst driver similar to what
Krzysztof did for reset-gpios) and Greg (because I mentioned this to you
last week in person and I also use the auxiliary bus for the proxy
devices).

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
Changes in v4:
- Collect tags
- Extend Cc list
- Link to v3: https://lore.kernel.org/r/20251029-gpio-shared-v3-0-71c568acf47c@linaro.org

Changes in v3:
- Make strends() a static inline function
- Use an empty release() callback for auxiliary devices
- Refactor the code for finding the shared descriptors in the GPIOLIB
  shared module, split it into several smaller functions
- Use str_high_low() where applicable
- Use non-atomic bit ops where atomicity is not required
- Link to v2: https://lore.kernel.org/r/20251022-gpio-shared-v2-0-d34aa1fbdf06@linaro.org

Changes in v2:
- Fix a memory leak in error path in gpiolib-shared
- Drop the gpio-wcd934x fix that already went upstream
- Free resources used during scanning by GPIOs that turned out to be
  unique
- Rework the OF property scanning
- Add patches making the regulator subsystem aware of shared GPIOs
  managed by GPIOLIB
- Link to v1: https://lore.kernel.org/r/20250924-gpio-shared-v1-0-775e7efeb1a3@linaro.org

---
Bartosz Golaszewski (10):
      string: provide strends()
      gpiolib: define GPIOD_FLAG_SHARED
      gpiolib: implement low-level, shared GPIO support
      gpio: shared-proxy: implement the shared GPIO proxy driver
      gpiolib: support shared GPIOs in core subsystem code
      gpio: provide gpiod_is_shared()
      arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM
      ASoC: wsa881x: drop GPIOD_FLAGS_BIT_NONEXCLUSIVE flag from GPIO lookup
      ASoC: wsa883x: drop GPIOD_FLAGS_BIT_NONEXCLUSIVE flag from GPIO lookup
      regulator: make the subsystem aware of shared GPIOs

 arch/arm64/Kconfig.platforms     |   1 +
 drivers/gpio/Kconfig             |  17 ++
 drivers/gpio/Makefile            |   2 +
 drivers/gpio/gpio-shared-proxy.c | 333 +++++++++++++++++++++++
 drivers/gpio/gpiolib-shared.c    | 558 +++++++++++++++++++++++++++++++++++++++
 drivers/gpio/gpiolib-shared.h    |  71 +++++
 drivers/gpio/gpiolib.c           |  70 ++++-
 drivers/gpio/gpiolib.h           |   2 +
 drivers/regulator/core.c         |   8 +
 include/linux/gpio/consumer.h    |   9 +
 include/linux/string.h           |  18 ++
 lib/tests/string_kunit.c         |  13 +
 sound/soc/codecs/wsa881x.c       |   3 +-
 sound/soc/codecs/wsa883x.c       |   7 +-
 14 files changed, 1096 insertions(+), 16 deletions(-)
---
base-commit: 96bf1bb63977b67d1a3e4a3645f857bc3fa03f48
change-id: 20250908-gpio-shared-67ec352884b6

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski@linaro.org>


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v4 01/10] string: provide strends()
  2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
@ 2025-11-12 13:55 ` Bartosz Golaszewski
  2025-11-17 20:33   ` Kees Cook
  2025-11-12 13:55 ` [PATCH v4 02/10] gpiolib: define GPIOD_FLAG_SHARED Bartosz Golaszewski
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-12 13:55 UTC (permalink / raw)
  To: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Bartosz Golaszewski,
	Catalin Marinas, Will Deacon, Srinivas Kandagatla, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Alexey Klimov,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Implement a function for checking if a string ends with a different
string and add its kunit test cases.

Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 include/linux/string.h   | 18 ++++++++++++++++++
 lib/tests/string_kunit.c | 13 +++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/include/linux/string.h b/include/linux/string.h
index fdd3442c6bcbd786e177b6e87358e1065a0ffafc..929d05d1247c76eb9011fe34250b487834b2d3c9 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -562,4 +562,22 @@ static inline bool strstarts(const char *str, const char *prefix)
 	return strncmp(str, prefix, strlen(prefix)) == 0;
 }
 
+/**
+ * strends - Check if a string ends with another string.
+ * @str - NULL-terminated string to check against @suffix
+ * @suffix - NULL-terminated string defining the suffix to look for in @str
+ *
+ * Returns:
+ * True if @str ends with @suffix. False in all other cases.
+ */
+static inline bool strends(const char *str, const char *suffix)
+{
+	unsigned int str_len = strlen(str), suffix_len = strlen(suffix);
+
+	if (str_len < suffix_len)
+		return false;
+
+	return !(strcmp(str + str_len - suffix_len, suffix));
+}
+
 #endif /* _LINUX_STRING_H_ */
diff --git a/lib/tests/string_kunit.c b/lib/tests/string_kunit.c
index 0ed7448a26d3aa0fe9e2a6a894d4c49c2c0b86e0..f9a8e557ba7734c9848d58ff986407d8000f52ee 100644
--- a/lib/tests/string_kunit.c
+++ b/lib/tests/string_kunit.c
@@ -602,6 +602,18 @@ static void string_test_memtostr(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, dest[7], '\0');
 }
 
+static void string_test_strends(struct kunit *test)
+{
+	KUNIT_EXPECT_TRUE(test, strends("foo-bar", "bar"));
+	KUNIT_EXPECT_TRUE(test, strends("foo-bar", "-bar"));
+	KUNIT_EXPECT_TRUE(test, strends("foobar", "foobar"));
+	KUNIT_EXPECT_TRUE(test, strends("foobar", ""));
+	KUNIT_EXPECT_FALSE(test, strends("bar", "foobar"));
+	KUNIT_EXPECT_FALSE(test, strends("", "foo"));
+	KUNIT_EXPECT_FALSE(test, strends("foobar", "ba"));
+	KUNIT_EXPECT_TRUE(test, strends("", ""));
+}
+
 static struct kunit_case string_test_cases[] = {
 	KUNIT_CASE(string_test_memset16),
 	KUNIT_CASE(string_test_memset32),
@@ -623,6 +635,7 @@ static struct kunit_case string_test_cases[] = {
 	KUNIT_CASE(string_test_strlcat),
 	KUNIT_CASE(string_test_strtomem),
 	KUNIT_CASE(string_test_memtostr),
+	KUNIT_CASE(string_test_strends),
 	{}
 };
 

-- 
2.51.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 02/10] gpiolib: define GPIOD_FLAG_SHARED
  2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
  2025-11-12 13:55 ` [PATCH v4 01/10] string: provide strends() Bartosz Golaszewski
@ 2025-11-12 13:55 ` Bartosz Golaszewski
  2025-11-12 13:55 ` [PATCH v4 03/10] gpiolib: implement low-level, shared GPIO support Bartosz Golaszewski
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-12 13:55 UTC (permalink / raw)
  To: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Bartosz Golaszewski,
	Catalin Marinas, Will Deacon, Srinivas Kandagatla, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Alexey Klimov,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Define a new GPIO descriptor flag for marking pins that are shared by
multiple consumer. This flag will be used in several places so we need
to do it in advance and separately from other changes.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 drivers/gpio/gpiolib.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 14e6a9807a89da6d7c6594a0a2de5f5032c49e0d..c9de4bb10584206f4888c0f28468762a3680aae6 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -204,6 +204,7 @@ struct gpio_desc {
 #define GPIOD_FLAG_EDGE_FALLING		17 /* GPIO CDEV detects falling edge events */
 #define GPIOD_FLAG_EVENT_CLOCK_REALTIME	18 /* GPIO CDEV reports REALTIME timestamps in events */
 #define GPIOD_FLAG_EVENT_CLOCK_HTE	19 /* GPIO CDEV reports hardware timestamps in events */
+#define GPIOD_FLAG_SHARED		20 /* GPIO is shared by multiple consumers */
 
 	/* Connection label */
 	struct gpio_desc_label __rcu *label;

-- 
2.51.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 03/10] gpiolib: implement low-level, shared GPIO support
  2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
  2025-11-12 13:55 ` [PATCH v4 01/10] string: provide strends() Bartosz Golaszewski
  2025-11-12 13:55 ` [PATCH v4 02/10] gpiolib: define GPIOD_FLAG_SHARED Bartosz Golaszewski
@ 2025-11-12 13:55 ` Bartosz Golaszewski
  2025-11-12 13:55 ` [PATCH v4 04/10] gpio: shared-proxy: implement the shared GPIO proxy driver Bartosz Golaszewski
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-12 13:55 UTC (permalink / raw)
  To: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Bartosz Golaszewski,
	Catalin Marinas, Will Deacon, Srinivas Kandagatla, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Alexey Klimov,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

This module scans the device tree (for now only OF nodes are supported
but care is taken to make other fwnode implementations easy to
integrate) and determines which GPIO lines are shared by multiple users.
It stores that information in memory. When the GPIO chip exposing shared
lines is registered, the shared GPIO descriptors it exposes are marked
as shared and virtual "proxy" devices that mediate access to the shared
lines are created. When a consumer of a shared GPIO looks it up, its
fwnode lookup is redirected to a just-in-time machine lookup that points
to this proxy device.

This code can be compiled out on platforms which don't use shared GPIOs.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 drivers/gpio/Kconfig          |   8 +
 drivers/gpio/Makefile         |   1 +
 drivers/gpio/gpiolib-shared.c | 540 ++++++++++++++++++++++++++++++++++++++++++
 drivers/gpio/gpiolib-shared.h |  71 ++++++
 4 files changed, 620 insertions(+)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ce237398fa00eddad49afe995accae3abbb4b2cb..f90b4d3e77f7cab46525b7adfcf114a21d276678 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -6,6 +6,9 @@
 config GPIOLIB_LEGACY
 	def_bool y
 
+config HAVE_SHARED_GPIOS
+	bool
+
 menuconfig GPIOLIB
 	bool "GPIO Support"
 	help
@@ -42,6 +45,11 @@ config GPIOLIB_IRQCHIP
 	select IRQ_DOMAIN
 	bool
 
+config GPIO_SHARED
+	def_bool y
+	depends on HAVE_SHARED_GPIOS || COMPILE_TEST
+	select AUXILIARY_BUS
+
 config DEBUG_GPIO
 	bool "Debug GPIO calls"
 	depends on DEBUG_KERNEL
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index ee260a0809d36cd07987f04e0ef17b05af764214..48f309c764e3286c23dbe604be933f7180f0b89a 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_GPIO_SYSFS)	+= gpiolib-sysfs.o
 obj-$(CONFIG_GPIO_ACPI)		+= gpiolib-acpi.o
 gpiolib-acpi-y			:= gpiolib-acpi-core.o gpiolib-acpi-quirks.o
 obj-$(CONFIG_GPIOLIB)		+= gpiolib-swnode.o
+obj-$(CONFIG_GPIO_SHARED)	+= gpiolib-shared.o
 
 # Device drivers. Generally keep list sorted alphabetically
 obj-$(CONFIG_GPIO_REGMAP)	+= gpio-regmap.o
diff --git a/drivers/gpio/gpiolib-shared.c b/drivers/gpio/gpiolib-shared.c
new file mode 100644
index 0000000000000000000000000000000000000000..56b9b03cbb6dbcdf095a656fc36ff321770035da
--- /dev/null
+++ b/drivers/gpio/gpiolib-shared.c
@@ -0,0 +1,540 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2025 Linaro Ltd.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/auxiliary_bus.h>
+#include <linux/cleanup.h>
+#include <linux/device.h>
+#include <linux/fwnode.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/machine.h>
+#include <linux/idr.h>
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/lockdep.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/overflow.h>
+#include <linux/printk.h>
+#include <linux/property.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include "gpiolib.h"
+#include "gpiolib-shared.h"
+
+/* Represents a single reference to a GPIO pin. */
+struct gpio_shared_ref {
+	struct list_head list;
+	/* Firmware node associated with this GPIO's consumer. */
+	struct fwnode_handle *fwnode;
+	/* GPIO flags this consumer uses for the request. */
+	enum gpiod_flags flags;
+	char *con_id;
+	int dev_id;
+	struct auxiliary_device adev;
+	struct gpiod_lookup_table *lookup;
+};
+
+/* Represents a single GPIO pin. */
+struct gpio_shared_entry {
+	struct list_head list;
+	/* Firmware node associated with the GPIO controller. */
+	struct fwnode_handle *fwnode;
+	/* Hardware offset of the GPIO within its chip. */
+	unsigned int offset;
+	/* Index in the property value array. */
+	size_t index;
+	struct gpio_shared_desc *shared_desc;
+	struct kref ref;
+	struct list_head refs;
+};
+
+static LIST_HEAD(gpio_shared_list);
+static DEFINE_MUTEX(gpio_shared_lock);
+static DEFINE_IDA(gpio_shared_ida);
+
+static struct gpio_shared_entry *
+gpio_shared_find_entry(struct fwnode_handle *controller_node,
+		       unsigned int offset)
+{
+	struct gpio_shared_entry *entry;
+
+	list_for_each_entry(entry, &gpio_shared_list, list) {
+		if (entry->fwnode == controller_node && entry->offset == offset)
+			return entry;
+	}
+
+	return NULL;
+}
+
+#if IS_ENABLED(CONFIG_OF)
+static int gpio_shared_of_traverse(struct device_node *curr)
+{
+	struct gpio_shared_entry *entry;
+	size_t con_id_len, suffix_len;
+	struct fwnode_handle *fwnode;
+	struct of_phandle_args args;
+	struct property *prop;
+	unsigned int offset;
+	const char *suffix;
+	int ret, count, i;
+
+	for_each_property_of_node(curr, prop) {
+		/*
+		 * The standard name for a GPIO property is "foo-gpios"
+		 * or "foo-gpio". Some bindings also use "gpios" or "gpio".
+		 * There are some legacy device-trees which have a different
+		 * naming convention and for which we have rename quirks in
+		 * place in gpiolib-of.c. I don't think any of them require
+		 * support for shared GPIOs so for now let's just ignore
+		 * them. We can always just export the quirk list and
+		 * iterate over it here.
+		 */
+		if (!strends(prop->name, "-gpios") &&
+		    !strends(prop->name, "-gpio") &&
+		    strcmp(prop->name, "gpios") != 0 &&
+		    strcmp(prop->name, "gpio") != 0)
+			continue;
+
+		count = of_count_phandle_with_args(curr, prop->name,
+						   "#gpio-cells");
+		if (count <= 0)
+			continue;
+
+		for (i = 0; i < count; i++) {
+			struct device_node *np __free(device_node) = NULL;
+
+			ret = of_parse_phandle_with_args(curr, prop->name,
+							 "#gpio-cells", i,
+							 &args);
+			if (ret)
+				continue;
+
+			np = args.np;
+
+			if (!of_property_present(np, "gpio-controller"))
+				continue;
+
+			/*
+			 * We support 1, 2 and 3 cell GPIO bindings in the
+			 * kernel currently. There's only one old MIPS dts that
+			 * has a one-cell binding but there's no associated
+			 * consumer so it may as well be an error. There don't
+			 * seem to be any 3-cell users of non-exclusive GPIOs,
+			 * so we can skip this as well. Let's occupy ourselves
+			 * with the predominant 2-cell binding with the first
+			 * cell indicating the hardware offset of the GPIO and
+			 * the second defining the GPIO flags of the request.
+			 */
+			if (args.args_count != 2)
+				continue;
+
+			fwnode = of_fwnode_handle(args.np);
+			offset = args.args[0];
+
+			entry = gpio_shared_find_entry(fwnode, offset);
+			if (!entry) {
+				entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+				if (!entry)
+					return -ENOMEM;
+
+				entry->fwnode = fwnode_handle_get(fwnode);
+				entry->offset = offset;
+				entry->index = count;
+				INIT_LIST_HEAD(&entry->refs);
+
+				list_add_tail(&entry->list, &gpio_shared_list);
+			}
+
+			struct gpio_shared_ref *ref __free(kfree) =
+					kzalloc(sizeof(*ref), GFP_KERNEL);
+			if (!ref)
+				return -ENOMEM;
+
+			ref->fwnode = fwnode_handle_get(of_fwnode_handle(curr));
+			ref->flags = args.args[1];
+
+			if (strends(prop->name, "gpios"))
+				suffix = "-gpios";
+			else if (strends(prop->name, "gpio"))
+				suffix = "-gpio";
+			else
+				suffix = NULL;
+			if (!suffix)
+				continue;
+
+			/* We only set con_id if there's actually one. */
+			if (strcmp(prop->name, "gpios") && strcmp(prop->name, "gpio")) {
+				ref->con_id = kstrdup(prop->name, GFP_KERNEL);
+				if (!ref->con_id)
+					return -ENOMEM;
+
+				con_id_len = strlen(ref->con_id);
+				suffix_len = strlen(suffix);
+
+				ref->con_id[con_id_len - suffix_len] = '\0';
+			}
+
+			ref->dev_id = ida_alloc(&gpio_shared_ida, GFP_KERNEL);
+			if (ref->dev_id < 0) {
+				kfree(ref->con_id);
+				return -ENOMEM;
+			}
+
+			if (!list_empty(&entry->refs))
+				pr_debug("GPIO %u at %s is shared by multiple firmware nodes\n",
+					 entry->offset, fwnode_get_name(entry->fwnode));
+
+			list_add_tail(&no_free_ptr(ref)->list, &entry->refs);
+		}
+	}
+
+	for_each_child_of_node_scoped(curr, child) {
+		ret = gpio_shared_of_traverse(child);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int gpio_shared_of_scan(void)
+{
+	return gpio_shared_of_traverse(of_root);
+}
+#else
+static int gpio_shared_of_scan(void)
+{
+	return 0;
+}
+#endif /* CONFIG_OF */
+
+static void gpio_shared_adev_release(struct device *dev)
+{
+
+}
+
+static int gpio_shared_make_adev(struct gpio_device *gdev,
+				 struct gpio_shared_ref *ref)
+{
+	struct auxiliary_device *adev = &ref->adev;
+	int ret;
+
+	lockdep_assert_held(&gpio_shared_lock);
+
+	memset(adev, 0, sizeof(*adev));
+
+	adev->id = ref->dev_id;
+	adev->name = "proxy";
+	adev->dev.parent = gdev->dev.parent;
+	adev->dev.release = gpio_shared_adev_release;
+
+	ret = auxiliary_device_init(adev);
+	if (ret)
+		return ret;
+
+	ret = auxiliary_device_add(adev);
+	if (ret) {
+		auxiliary_device_uninit(adev);
+		return ret;
+	}
+
+	pr_debug("Created an auxiliary GPIO proxy %s for GPIO device %s\n",
+		 dev_name(&adev->dev), gpio_device_get_label(gdev));
+
+	return 0;
+}
+
+int gpio_shared_add_proxy_lookup(struct device *consumer, unsigned long lflags)
+{
+	const char *dev_id = dev_name(consumer);
+	struct gpio_shared_entry *entry;
+	struct gpio_shared_ref *ref;
+
+	struct gpiod_lookup_table *lookup __free(kfree) =
+			kzalloc(struct_size(lookup, table, 2), GFP_KERNEL);
+	if (!lookup)
+		return -ENOMEM;
+
+	guard(mutex)(&gpio_shared_lock);
+
+	list_for_each_entry(entry, &gpio_shared_list, list) {
+		list_for_each_entry(ref, &entry->refs, list) {
+			if (!device_match_fwnode(consumer, ref->fwnode))
+				continue;
+
+			/* We've already done that on a previous request. */
+			if (ref->lookup)
+				return 0;
+
+			char *key __free(kfree) =
+				kasprintf(GFP_KERNEL,
+					  KBUILD_MODNAME ".proxy.%u",
+					  ref->adev.id);
+			if (!key)
+				return -ENOMEM;
+
+			pr_debug("Adding machine lookup entry for a shared GPIO for consumer %s, with key '%s' and con_id '%s'\n",
+				 dev_id, key, ref->con_id ?: "none");
+
+			lookup->dev_id = dev_id;
+			lookup->table[0] = GPIO_LOOKUP(no_free_ptr(key), 0,
+						       ref->con_id, lflags);
+
+			gpiod_add_lookup_table(no_free_ptr(lookup));
+
+			return 0;
+		}
+	}
+
+	/* We warn here because this can only happen if the programmer borked. */
+	WARN_ON(1);
+	return -ENOENT;
+}
+
+static void gpio_shared_remove_adev(struct auxiliary_device *adev)
+{
+	lockdep_assert_held(&gpio_shared_lock);
+
+	auxiliary_device_uninit(adev);
+	auxiliary_device_delete(adev);
+}
+
+int gpio_device_setup_shared(struct gpio_device *gdev)
+{
+	struct gpio_shared_entry *entry;
+	struct gpio_shared_ref *ref;
+	unsigned long *flags;
+	int ret;
+
+	guard(mutex)(&gpio_shared_lock);
+
+	list_for_each_entry(entry, &gpio_shared_list, list) {
+		if (!device_match_fwnode(&gdev->dev, entry->fwnode))
+			continue;
+
+		if (list_count_nodes(&entry->refs) <= 1)
+			continue;
+
+		flags = &gdev->descs[entry->offset].flags;
+
+		__set_bit(GPIOD_FLAG_SHARED, flags);
+		/*
+		 * Shared GPIOs are not requested via the normal path. Make
+		 * them inaccessible to anyone even before we register the
+		 * chip.
+		 */
+		__set_bit(GPIOD_FLAG_REQUESTED, flags);
+
+		pr_debug("GPIO %u owned by %s is shared by multiple consumers\n",
+			 entry->offset, gpio_device_get_label(gdev));
+
+		list_for_each_entry(ref, &entry->refs, list) {
+			pr_debug("Setting up a shared GPIO entry for %s\n",
+				 fwnode_get_name(ref->fwnode));
+
+			ret = gpio_shared_make_adev(gdev, ref);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+void gpio_device_teardown_shared(struct gpio_device *gdev)
+{
+	struct gpio_shared_entry *entry;
+	struct gpio_shared_ref *ref;
+
+	guard(mutex)(&gpio_shared_lock);
+
+	list_for_each_entry(entry, &gpio_shared_list, list) {
+		if (!device_match_fwnode(&gdev->dev, entry->fwnode))
+			continue;
+
+		list_for_each_entry(ref, &entry->refs, list) {
+			gpiod_remove_lookup_table(ref->lookup);
+			kfree(ref->lookup->table[0].key);
+			kfree(ref->lookup);
+			ref->lookup = NULL;
+			gpio_shared_remove_adev(&ref->adev);
+		}
+	}
+}
+
+static void gpio_shared_release(struct kref *kref)
+{
+	struct gpio_shared_entry *entry =
+		container_of(kref, struct gpio_shared_entry, ref);
+	struct gpio_shared_desc *shared_desc = entry->shared_desc;
+
+	guard(mutex)(&gpio_shared_lock);
+
+	gpio_device_put(shared_desc->desc->gdev);
+	if (shared_desc->can_sleep)
+		mutex_destroy(&shared_desc->mutex);
+	kfree(shared_desc);
+	entry->shared_desc = NULL;
+}
+
+static void gpiod_shared_put(void *data)
+{
+	struct gpio_shared_entry *entry = data;
+
+	lockdep_assert_not_held(&gpio_shared_lock);
+
+	kref_put(&entry->ref, gpio_shared_release);
+}
+
+static struct gpio_shared_desc *
+gpiod_shared_desc_create(struct gpio_shared_entry *entry)
+{
+	struct gpio_shared_desc *shared_desc;
+	struct gpio_device *gdev;
+
+	shared_desc = kzalloc(sizeof(*shared_desc), GFP_KERNEL);
+	if (!shared_desc)
+		return ERR_PTR(-ENOMEM);
+
+	gdev = gpio_device_find_by_fwnode(entry->fwnode);
+	if (!gdev) {
+		kfree(shared_desc);
+		return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	shared_desc->desc = &gdev->descs[entry->offset];
+	shared_desc->can_sleep = gpiod_cansleep(shared_desc->desc);
+	if (shared_desc->can_sleep)
+		mutex_init(&shared_desc->mutex);
+	else
+		spin_lock_init(&shared_desc->spinlock);
+
+	return shared_desc;
+}
+
+static struct gpio_shared_entry *gpiod_shared_find(struct auxiliary_device *adev)
+{
+	struct gpio_shared_desc *shared_desc;
+	struct gpio_shared_entry *entry;
+	struct gpio_shared_ref *ref;
+
+	guard(mutex)(&gpio_shared_lock);
+
+	list_for_each_entry(entry, &gpio_shared_list, list) {
+		list_for_each_entry(ref, &entry->refs, list) {
+			if (adev != &ref->adev)
+				continue;
+
+			if (entry->shared_desc) {
+				kref_get(&entry->ref);
+				return entry;
+			}
+
+			shared_desc = gpiod_shared_desc_create(entry);
+			if (IS_ERR(shared_desc))
+				return ERR_CAST(shared_desc);
+
+			kref_init(&entry->ref);
+			entry->shared_desc = shared_desc;
+
+			pr_debug("Device %s acquired a reference to the shared GPIO %u owned by %s\n",
+				 dev_name(&adev->dev), gpiod_hwgpio(shared_desc->desc),
+				 gpio_device_get_label(shared_desc->desc->gdev));
+
+
+			return entry;
+		}
+	}
+
+	return ERR_PTR(-ENOENT);
+}
+
+struct gpio_shared_desc *devm_gpiod_shared_get(struct device *dev)
+{
+	struct gpio_shared_entry *entry;
+	int ret;
+
+	entry = gpiod_shared_find(to_auxiliary_dev(dev));
+	if (IS_ERR(entry))
+		return ERR_CAST(entry);
+
+	ret = devm_add_action_or_reset(dev, gpiod_shared_put, entry);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return entry->shared_desc;
+}
+EXPORT_SYMBOL_GPL(devm_gpiod_shared_get);
+
+static void gpio_shared_drop_ref(struct gpio_shared_ref *ref)
+{
+	list_del(&ref->list);
+	kfree(ref->con_id);
+	ida_free(&gpio_shared_ida, ref->dev_id);
+	fwnode_handle_put(ref->fwnode);
+	kfree(ref);
+}
+
+static void gpio_shared_drop_entry(struct gpio_shared_entry *entry)
+{
+	list_del(&entry->list);
+	fwnode_handle_put(entry->fwnode);
+	kfree(entry);
+}
+
+/*
+ * This is only called if gpio_shared_init() fails so it's in fact __init and
+ * not __exit.
+ */
+static void __init gpio_shared_teardown(void)
+{
+	struct gpio_shared_entry *entry, *epos;
+	struct gpio_shared_ref *ref, *rpos;
+
+	list_for_each_entry_safe(entry, epos, &gpio_shared_list, list) {
+		list_for_each_entry_safe(ref, rpos, &entry->refs, list)
+			gpio_shared_drop_ref(ref);
+
+		gpio_shared_drop_entry(entry);
+	}
+}
+
+static void gpio_shared_free_exclusive(void)
+{
+	struct gpio_shared_entry *entry, *epos;
+
+	list_for_each_entry_safe(entry, epos, &gpio_shared_list, list) {
+		if (list_count_nodes(&entry->refs) > 1)
+			continue;
+
+		gpio_shared_drop_ref(list_first_entry(&entry->refs,
+						      struct gpio_shared_ref,
+						      list));
+		gpio_shared_drop_entry(entry);
+	}
+}
+
+static int __init gpio_shared_init(void)
+{
+	int ret;
+
+	/* Right now, we only support OF-based systems. */
+	ret = gpio_shared_of_scan();
+	if (ret) {
+		gpio_shared_teardown();
+		pr_err("Failed to scan OF nodes for shared GPIOs: %d\n", ret);
+		return ret;
+	}
+
+	gpio_shared_free_exclusive();
+
+	pr_debug("Finished scanning firmware nodes for shared GPIOs\n");
+	return 0;
+}
+postcore_initcall(gpio_shared_init);
diff --git a/drivers/gpio/gpiolib-shared.h b/drivers/gpio/gpiolib-shared.h
new file mode 100644
index 0000000000000000000000000000000000000000..667dbdff3585066b7cbe2ebe476725fe7d683d84
--- /dev/null
+++ b/drivers/gpio/gpiolib-shared.h
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __LINUX_GPIO_SHARED_H
+#define __LINUX_GPIO_SHARED_H
+
+#include <linux/cleanup.h>
+#include <linux/lockdep.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+
+struct gpio_device;
+struct gpio_desc;
+struct device;
+
+#if IS_ENABLED(CONFIG_GPIO_SHARED)
+
+int gpio_device_setup_shared(struct gpio_device *gdev);
+void gpio_device_teardown_shared(struct gpio_device *gdev);
+int gpio_shared_add_proxy_lookup(struct device *consumer, unsigned long lflags);
+
+#else
+
+static inline int gpio_device_setup_shared(struct gpio_device *gdev)
+{
+	return 0;
+}
+
+static inline void gpio_device_teardown_shared(struct gpio_device *gdev) { }
+
+static inline int gpio_shared_add_proxy_lookup(struct device *consumer,
+					       unsigned long lflags)
+{
+	return 0;
+}
+
+#endif /* CONFIG_GPIO_SHARED */
+
+struct gpio_shared_desc {
+	struct gpio_desc *desc;
+	bool can_sleep;
+	unsigned long cfg;
+	unsigned int usecnt;
+	unsigned int highcnt;
+	union {
+		struct mutex mutex;
+		spinlock_t spinlock;
+	};
+};
+
+struct gpio_shared_desc *devm_gpiod_shared_get(struct device *dev);
+
+DEFINE_LOCK_GUARD_1(gpio_shared_desc_lock, struct gpio_shared_desc,
+	if (_T->lock->can_sleep)
+		mutex_lock(&_T->lock->mutex);
+	else
+		spin_lock_irqsave(&_T->lock->spinlock, _T->flags),
+	if (_T->lock->can_sleep)
+		mutex_unlock(&_T->lock->mutex);
+	else
+		spin_unlock_irqrestore(&_T->lock->spinlock, _T->flags),
+	unsigned long flags)
+
+static inline void gpio_shared_lockdep_assert(struct gpio_shared_desc *shared_desc)
+{
+	if (shared_desc->can_sleep)
+		lockdep_assert_held(&shared_desc->mutex);
+	else
+		lockdep_assert_held(&shared_desc->spinlock);
+}
+
+#endif /* __LINUX_GPIO_SHARED_H */

-- 
2.51.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 04/10] gpio: shared-proxy: implement the shared GPIO proxy driver
  2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
                   ` (2 preceding siblings ...)
  2025-11-12 13:55 ` [PATCH v4 03/10] gpiolib: implement low-level, shared GPIO support Bartosz Golaszewski
@ 2025-11-12 13:55 ` Bartosz Golaszewski
  2025-11-12 13:55 ` [PATCH v4 05/10] gpiolib: support shared GPIOs in core subsystem code Bartosz Golaszewski
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-12 13:55 UTC (permalink / raw)
  To: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Bartosz Golaszewski,
	Catalin Marinas, Will Deacon, Srinivas Kandagatla, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Alexey Klimov,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Add a virtual GPIO proxy driver which arbitrates access to a single
shared GPIO by multiple users. It works together with the core shared
GPIO support from GPIOLIB and functions by acquiring a reference to a
shared GPIO descriptor exposed by gpiolib-shared and making sure that
the state of the GPIO stays consistent.

In general: if there's only one user at the moment: allow it to do
anything as if this was a normal GPIO (in essence: just propagate calls
to the underlying real hardware driver). If there are more users: don't
allow to change the direction set by the initial user, allow to change
configuration options but warn about possible conflicts and finally:
treat the output-high value as a reference counted, logical "GPIO
enabled" setting, meaning: the GPIO value is set to high when the first
user requests it to be high and back to low once the last user stops
"voting" for high.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 drivers/gpio/Kconfig             |   9 ++
 drivers/gpio/Makefile            |   1 +
 drivers/gpio/gpio-shared-proxy.c | 333 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 343 insertions(+)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index f90b4d3e77f7cab46525b7adfcf114a21d276678..f910c20f0d5d7771f7f8f3d52ced7bce413d24f1 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -2025,6 +2025,15 @@ config GPIO_SIM
 	  This enables the GPIO simulator - a configfs-based GPIO testing
 	  driver.
 
+config GPIO_SHARED_PROXY
+	tristate "Proxy driver for non-exclusive GPIOs"
+	default m
+	depends on GPIO_SHARED || COMPILE_TEST
+	select AUXILIARY_BUS
+	help
+	  This enables the GPIO shared proxy driver - an abstraction layer
+	  for GPIO pins that are shared by multiple devices.
+
 endmenu
 
 menu "GPIO Debugging utilities"
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 48f309c764e3286c23dbe604be933f7180f0b89a..2421a8fd3733e0b06c2581262aaa9cd629f66c7d 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -161,6 +161,7 @@ obj-$(CONFIG_ARCH_SA1100)		+= gpio-sa1100.o
 obj-$(CONFIG_GPIO_SAMA5D2_PIOBU)	+= gpio-sama5d2-piobu.o
 obj-$(CONFIG_GPIO_SCH311X)		+= gpio-sch311x.o
 obj-$(CONFIG_GPIO_SCH)			+= gpio-sch.o
+obj-$(CONFIG_GPIO_SHARED_PROXY)		+= gpio-shared-proxy.o
 obj-$(CONFIG_GPIO_SIFIVE)		+= gpio-sifive.o
 obj-$(CONFIG_GPIO_SIM)			+= gpio-sim.o
 obj-$(CONFIG_GPIO_SIOX)			+= gpio-siox.o
diff --git a/drivers/gpio/gpio-shared-proxy.c b/drivers/gpio/gpio-shared-proxy.c
new file mode 100644
index 0000000000000000000000000000000000000000..3ef2c40ed15229074052eda93b6ee56f0a2bfb72
--- /dev/null
+++ b/drivers/gpio/gpio-shared-proxy.c
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2025 Linaro Ltd.
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/cleanup.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/driver.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/string_choices.h>
+#include <linux/types.h>
+
+#include "gpiolib-shared.h"
+
+struct gpio_shared_proxy_data {
+	struct gpio_chip gc;
+	struct gpio_shared_desc *shared_desc;
+	struct device *dev;
+	bool voted_high;
+};
+
+static int
+gpio_shared_proxy_set_unlocked(struct gpio_shared_proxy_data *proxy,
+			       int (*set_func)(struct gpio_desc *desc, int value),
+			       int value)
+{
+	struct gpio_shared_desc *shared_desc = proxy->shared_desc;
+	struct gpio_desc *desc = shared_desc->desc;
+	int ret = 0;
+
+	gpio_shared_lockdep_assert(shared_desc);
+
+	if (value) {
+	       /* User wants to set value to high. */
+		if (proxy->voted_high)
+			/* Already voted for high, nothing to do. */
+			goto out;
+
+		/* Haven't voted for high yet. */
+		if (!shared_desc->highcnt) {
+			/*
+			 * Current value is low, need to actually set value
+			 * to high.
+			 */
+			ret = set_func(desc, 1);
+			if (ret)
+				goto out;
+		}
+
+		shared_desc->highcnt++;
+		proxy->voted_high = true;
+
+		goto out;
+	}
+
+	/* Desired value is low. */
+	if (!proxy->voted_high)
+		/* We didn't vote for high, nothing to do. */
+		goto out;
+
+	/* We previously voted for high. */
+	if (shared_desc->highcnt == 1) {
+		/* This is the last remaining vote for high, set value  to low. */
+		ret = set_func(desc, 0);
+		if (ret)
+			goto out;
+	}
+
+	shared_desc->highcnt--;
+	proxy->voted_high = false;
+
+out:
+	if (shared_desc->highcnt)
+		dev_dbg(proxy->dev,
+			"Voted for value '%s', effective value is 'high', number of votes for 'high': %u\n",
+			str_high_low(value), shared_desc->highcnt);
+	else
+		dev_dbg(proxy->dev, "Voted for value 'low', effective value is 'low'\n");
+
+	return ret;
+}
+
+static int gpio_shared_proxy_request(struct gpio_chip *gc, unsigned int offset)
+{
+	struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
+	struct gpio_shared_desc *shared_desc = proxy->shared_desc;
+
+	guard(gpio_shared_desc_lock)(shared_desc);
+
+	proxy->shared_desc->usecnt++;
+
+	dev_dbg(proxy->dev, "Shared GPIO requested, number of users: %u\n",
+		proxy->shared_desc->usecnt);
+
+	return 0;
+}
+
+static void gpio_shared_proxy_free(struct gpio_chip *gc, unsigned int offset)
+{
+	struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
+	struct gpio_shared_desc *shared_desc = proxy->shared_desc;
+
+	guard(gpio_shared_desc_lock)(shared_desc);
+
+	proxy->shared_desc->usecnt--;
+
+	dev_dbg(proxy->dev, "Shared GPIO freed, number of users: %u\n",
+		proxy->shared_desc->usecnt);
+}
+
+static int gpio_shared_proxy_set_config(struct gpio_chip *gc,
+					unsigned int offset, unsigned long cfg)
+{
+	struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
+	struct gpio_shared_desc *shared_desc = proxy->shared_desc;
+	struct gpio_desc *desc = shared_desc->desc;
+	int ret;
+
+	guard(gpio_shared_desc_lock)(shared_desc);
+
+	if (shared_desc->usecnt > 1) {
+		if (shared_desc->cfg != cfg) {
+			dev_dbg(proxy->dev,
+				"Shared GPIO's configuration already set, accepting changes but users may conflict!!\n");
+		} else {
+			dev_dbg(proxy->dev, "Equal config requested, nothing to do\n");
+			return 0;
+		}
+	}
+
+	ret = gpiod_set_config(desc, cfg);
+	if (ret && ret != -ENOTSUPP)
+		return ret;
+
+	shared_desc->cfg = cfg;
+	return 0;
+}
+
+static int gpio_shared_proxy_direction_input(struct gpio_chip *gc,
+					     unsigned int offset)
+{
+	struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
+	struct gpio_shared_desc *shared_desc = proxy->shared_desc;
+	struct gpio_desc *desc = shared_desc->desc;
+	int dir;
+
+	guard(gpio_shared_desc_lock)(shared_desc);
+
+	if (shared_desc->usecnt == 1) {
+		dev_dbg(proxy->dev,
+			"Only one user of this shared GPIO, allowing to set direction to input\n");
+
+		return gpiod_direction_input(desc);
+	}
+
+	dir = gpiod_get_direction(desc);
+	if (dir < 0)
+		return dir;
+
+	if (dir == GPIO_LINE_DIRECTION_OUT) {
+		dev_dbg(proxy->dev,
+			"Shared GPIO's direction already set to output, refusing to change\n");
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int gpio_shared_proxy_direction_output(struct gpio_chip *gc,
+					      unsigned int offset, int value)
+{
+	struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
+	struct gpio_shared_desc *shared_desc = proxy->shared_desc;
+	struct gpio_desc *desc = shared_desc->desc;
+	int ret, dir;
+
+	guard(gpio_shared_desc_lock)(shared_desc);
+
+	if (shared_desc->usecnt == 1) {
+		dev_dbg(proxy->dev,
+			"Only one user of this shared GPIO, allowing to set direction to output with value '%s'\n",
+			str_high_low(value));
+
+		ret = gpiod_direction_output(desc, value);
+		if (ret)
+			return ret;
+
+		if (value) {
+			proxy->voted_high = true;
+			shared_desc->highcnt = 1;
+		} else {
+			proxy->voted_high = false;
+			shared_desc->highcnt = 0;
+		}
+
+		return 0;
+	}
+
+	dir = gpiod_get_direction(desc);
+	if (dir < 0)
+		return dir;
+
+	if (dir == GPIO_LINE_DIRECTION_IN) {
+		dev_dbg(proxy->dev,
+			"Shared GPIO's direction already set to input, refusing to change\n");
+		return -EPERM;
+	}
+
+	return gpio_shared_proxy_set_unlocked(proxy, gpiod_direction_output, value);
+}
+
+static int gpio_shared_proxy_get(struct gpio_chip *gc, unsigned int offset)
+{
+	struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
+
+	return gpiod_get_value(proxy->shared_desc->desc);
+}
+
+static int gpio_shared_proxy_get_cansleep(struct gpio_chip *gc,
+					  unsigned int offset)
+{
+	struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
+
+	return gpiod_get_value_cansleep(proxy->shared_desc->desc);
+}
+
+static int gpio_shared_proxy_do_set(struct gpio_shared_proxy_data *proxy,
+				    int (*set_func)(struct gpio_desc *desc, int value),
+				    int value)
+{
+	guard(gpio_shared_desc_lock)(proxy->shared_desc);
+
+	return gpio_shared_proxy_set_unlocked(proxy, set_func, value);
+}
+
+static int gpio_shared_proxy_set(struct gpio_chip *gc, unsigned int offset,
+				 int value)
+{
+	struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
+
+	return gpio_shared_proxy_do_set(proxy, gpiod_set_value, value);
+}
+
+static int gpio_shared_proxy_set_cansleep(struct gpio_chip *gc,
+					  unsigned int offset, int value)
+{
+	struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
+
+	return gpio_shared_proxy_do_set(proxy, gpiod_set_value_cansleep, value);
+}
+
+static int gpio_shared_proxy_get_direction(struct gpio_chip *gc,
+					   unsigned int offset)
+{
+	struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
+
+	return gpiod_get_direction(proxy->shared_desc->desc);
+}
+
+static int gpio_shared_proxy_to_irq(struct gpio_chip *gc, unsigned int offset)
+{
+	struct gpio_shared_proxy_data *proxy = gpiochip_get_data(gc);
+
+	return gpiod_to_irq(proxy->shared_desc->desc);
+}
+
+static int gpio_shared_proxy_probe(struct auxiliary_device *adev,
+				   const struct auxiliary_device_id *id)
+{
+	struct gpio_shared_proxy_data *proxy;
+	struct gpio_shared_desc *shared_desc;
+	struct device *dev = &adev->dev;
+	struct gpio_chip *gc;
+
+	shared_desc = devm_gpiod_shared_get(dev);
+	if (IS_ERR(shared_desc))
+		return PTR_ERR(shared_desc);
+
+	proxy = devm_kzalloc(dev, sizeof(*proxy), GFP_KERNEL);
+	if (!proxy)
+		return -ENOMEM;
+
+	proxy->shared_desc = shared_desc;
+	proxy->dev = dev;
+
+	gc = &proxy->gc;
+	gc->base = -1;
+	gc->ngpio = 1;
+	gc->label = dev_name(dev);
+	gc->parent = dev;
+	gc->owner = THIS_MODULE;
+	gc->can_sleep = shared_desc->can_sleep;
+
+	gc->request = gpio_shared_proxy_request;
+	gc->free = gpio_shared_proxy_free;
+	gc->set_config = gpio_shared_proxy_set_config;
+	gc->direction_input = gpio_shared_proxy_direction_input;
+	gc->direction_output = gpio_shared_proxy_direction_output;
+	if (gc->can_sleep) {
+		gc->set = gpio_shared_proxy_set_cansleep;
+		gc->get = gpio_shared_proxy_get_cansleep;
+	} else {
+		gc->set = gpio_shared_proxy_set;
+		gc->get = gpio_shared_proxy_get;
+	}
+	gc->get_direction = gpio_shared_proxy_get_direction;
+	gc->to_irq = gpio_shared_proxy_to_irq;
+
+	return devm_gpiochip_add_data(dev, &proxy->gc, proxy);
+}
+
+static const struct auxiliary_device_id gpio_shared_proxy_id_table[] = {
+	{ .name = "gpiolib_shared.proxy" },
+	{},
+};
+MODULE_DEVICE_TABLE(auxiliary, gpio_shared_proxy_id_table);
+
+static struct auxiliary_driver gpio_shared_proxy_driver = {
+	.driver = {
+		.name = "gpio-shared-proxy",
+	},
+	.probe = gpio_shared_proxy_probe,
+	.id_table = gpio_shared_proxy_id_table,
+};
+module_auxiliary_driver(gpio_shared_proxy_driver);
+
+MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski@linaro.org>");
+MODULE_DESCRIPTION("Shared GPIO mux driver.");
+MODULE_LICENSE("GPL");

-- 
2.51.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 05/10] gpiolib: support shared GPIOs in core subsystem code
  2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
                   ` (3 preceding siblings ...)
  2025-11-12 13:55 ` [PATCH v4 04/10] gpio: shared-proxy: implement the shared GPIO proxy driver Bartosz Golaszewski
@ 2025-11-12 13:55 ` Bartosz Golaszewski
  2025-11-12 13:55 ` [PATCH v4 06/10] gpio: provide gpiod_is_shared() Bartosz Golaszewski
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-12 13:55 UTC (permalink / raw)
  To: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Bartosz Golaszewski,
	Catalin Marinas, Will Deacon, Srinivas Kandagatla, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Alexey Klimov,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

As the final step in adding official support for shared GPIOs, enable
the previously added elements in core GPIO subsystem code. Set-up shared
GPIOs when adding a GPIO chip, tear it down on removal and check if a
GPIO descriptor looked up during the firmware-node stage is shared and
fall-back to machine lookup in this case.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 drivers/gpio/gpiolib.c | 50 +++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 41 insertions(+), 9 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 3659acc600d9622d5d2baeb055ac083556f344a9..c59fe05c838e073b4bc99c4a7667cb1ff40c26b4 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -37,6 +37,7 @@
 #include "gpiolib-acpi.h"
 #include "gpiolib-cdev.h"
 #include "gpiolib-of.h"
+#include "gpiolib-shared.h"
 #include "gpiolib-swnode.h"
 #include "gpiolib-sysfs.h"
 #include "gpiolib.h"
@@ -1213,6 +1214,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
 	if (ret)
 		goto err_remove_irqchip_mask;
 
+	ret = gpio_device_setup_shared(gdev);
+	if (ret)
+		goto err_remove_irqchip;
+
 	/*
 	 * By first adding the chardev, and then adding the device,
 	 * we get a device node entry in sysfs under
@@ -1224,10 +1229,13 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
 	if (gpiolib_initialized) {
 		ret = gpiochip_setup_dev(gdev);
 		if (ret)
-			goto err_remove_irqchip;
+			goto err_teardown_shared;
 	}
+
 	return 0;
 
+err_teardown_shared:
+	gpio_device_teardown_shared(gdev);
 err_remove_irqchip:
 	gpiochip_irqchip_remove(gc);
 err_remove_irqchip_mask:
@@ -1296,6 +1304,7 @@ void gpiochip_remove(struct gpio_chip *gc)
 	/* Numb the device, cancelling all outstanding operations */
 	rcu_assign_pointer(gdev->chip, NULL);
 	synchronize_srcu(&gdev->srcu);
+	gpio_device_teardown_shared(gdev);
 	gpiochip_irqchip_remove(gc);
 	acpi_gpiochip_remove(gc);
 	of_gpiochip_remove(gc);
@@ -4659,11 +4668,29 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer,
 	scoped_guard(srcu, &gpio_devices_srcu) {
 		desc = gpiod_fwnode_lookup(fwnode, consumer, con_id, idx,
 					   &flags, &lookupflags);
+		if (!IS_ERR_OR_NULL(desc) &&
+		    test_bit(GPIOD_FLAG_SHARED, &desc->flags)) {
+			/*
+			 * We're dealing with a GPIO shared by multiple
+			 * consumers. This is the moment to add the machine
+			 * lookup table for the proxy device as previously
+			 * we only knew the consumer's fwnode.
+			 */
+			ret = gpio_shared_add_proxy_lookup(consumer, lookupflags);
+			if (ret)
+				return ERR_PTR(ret);
+
+			/* Trigger platform lookup for shared GPIO proxy. */
+			desc = ERR_PTR(-ENOENT);
+			/* Trigger it even for fwnode-only gpiod_get(). */
+			platform_lookup_allowed = true;
+		}
+
 		if (gpiod_not_found(desc) && platform_lookup_allowed) {
 			/*
 			 * Either we are not using DT or ACPI, or their lookup
-			 * did not return a result. In that case, use platform
-			 * lookup as a fallback.
+			 * did not return a result or this is a shared GPIO. In
+			 * that case, use platform lookup as a fallback.
 			 */
 			dev_dbg(consumer,
 				"using lookup tables for GPIO lookup\n");
@@ -4686,14 +4713,19 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer,
 			return ERR_PTR(ret);
 
 		/*
-		 * This happens when there are several consumers for
-		 * the same GPIO line: we just return here without
-		 * further initialization. It is a bit of a hack.
-		 * This is necessary to support fixed regulators.
+		 * This happens when there are several consumers for the same
+		 * GPIO line: we just return here without further
+		 * initialization. It's a hack introduced long ago to support
+		 * fixed regulators. We now have a better solution with
+		 * automated scanning where affected platforms just need to
+		 * select the provided Kconfig option.
 		 *
-		 * FIXME: Make this more sane and safe.
+		 * FIXME: Remove the GPIOD_FLAGS_BIT_NONEXCLUSIVE flag after
+		 * making sure all platforms use the new mechanism.
 		 */
-		dev_info(consumer, "nonexclusive access to GPIO for %s\n", name);
+		dev_info(consumer,
+			 "nonexclusive access to GPIO for %s, consider updating your code to using gpio-shared-proxy\n",
+			 name);
 		return desc;
 	}
 

-- 
2.51.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 06/10] gpio: provide gpiod_is_shared()
  2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
                   ` (4 preceding siblings ...)
  2025-11-12 13:55 ` [PATCH v4 05/10] gpiolib: support shared GPIOs in core subsystem code Bartosz Golaszewski
@ 2025-11-12 13:55 ` Bartosz Golaszewski
  2025-11-12 13:55 ` [PATCH v4 07/10] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM Bartosz Golaszewski
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-12 13:55 UTC (permalink / raw)
  To: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Bartosz Golaszewski,
	Catalin Marinas, Will Deacon, Srinivas Kandagatla, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Alexey Klimov,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Provide an interface allowing consumers to check if a GPIO descriptor
represents a GPIO that can potentially be shared by multiple consumers
at the same time. This is exposed to allow subsystems that already
work around the limitations of the current non-exclusive GPIO handling
in some ways, to gradually convert to relying on the new shared GPIO
feature of GPIOLIB.

Extend the gpiolib-shared module to mark the GPIO shared proxy
descriptors with a flag checked by the new interface.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 drivers/gpio/gpiolib-shared.c | 18 ++++++++++++++++++
 drivers/gpio/gpiolib.c        | 20 ++++++++++++++++++++
 drivers/gpio/gpiolib.h        |  1 +
 include/linux/gpio/consumer.h |  9 +++++++++
 4 files changed, 48 insertions(+)

diff --git a/drivers/gpio/gpiolib-shared.c b/drivers/gpio/gpiolib-shared.c
index 56b9b03cbb6dbcdf095a656fc36ff321770035da..c22eaf05eef23a7f5f111708c3db9412c4c30231 100644
--- a/drivers/gpio/gpiolib-shared.c
+++ b/drivers/gpio/gpiolib-shared.c
@@ -314,6 +314,24 @@ int gpio_device_setup_shared(struct gpio_device *gdev)
 
 	guard(mutex)(&gpio_shared_lock);
 
+	list_for_each_entry(entry, &gpio_shared_list, list) {
+		list_for_each_entry(ref, &entry->refs, list) {
+			if (gdev->dev.parent == &ref->adev.dev) {
+				/*
+				 * This is a shared GPIO proxy. Mark its
+				 * descriptor as such and return here.
+				 */
+				__set_bit(GPIOD_FLAG_SHARED_PROXY,
+					  &gdev->descs[0].flags);
+				return 0;
+			}
+		}
+	}
+
+	/*
+	 * This is not a shared GPIO proxy but it still may be the device
+	 * exposing shared pins. Find them and create the proxy devices.
+	 */
 	list_for_each_entry(entry, &gpio_shared_list, list) {
 		if (!device_match_fwnode(&gdev->dev, entry->fwnode))
 			continue;
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index c59fe05c838e073b4bc99c4a7667cb1ff40c26b4..91e0c384f34ae5c0ed61ccd3a978685d4f72e867 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -3997,6 +3997,26 @@ int gpiod_set_consumer_name(struct gpio_desc *desc, const char *name)
 }
 EXPORT_SYMBOL_GPL(gpiod_set_consumer_name);
 
+/**
+ * gpiod_is_shared() - check if this GPIO can be shared by multiple consumers
+ * @desc: GPIO to inspect
+ *
+ * Returns:
+ * True if this GPIO can be shared by multiple consumers at once. False if it's
+ * a regular, exclusive GPIO.
+ *
+ * Note:
+ * This function returning true does not mean that this GPIO is currently being
+ * shared. It means the GPIO core has registered the fact that the firmware
+ * configuration indicates that it can be shared by multiple consumers and is
+ * in charge of arbitrating the access.
+ */
+bool gpiod_is_shared(const struct gpio_desc *desc)
+{
+	return test_bit(GPIOD_FLAG_SHARED_PROXY, &desc->flags);
+}
+EXPORT_SYMBOL_GPL(gpiod_is_shared);
+
 /**
  * gpiod_to_irq() - return the IRQ corresponding to a GPIO
  * @desc: gpio whose IRQ will be returned (already requested)
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index c9de4bb10584206f4888c0f28468762a3680aae6..77f6f2936dc263a67b31a38799a841128a57603a 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -205,6 +205,7 @@ struct gpio_desc {
 #define GPIOD_FLAG_EVENT_CLOCK_REALTIME	18 /* GPIO CDEV reports REALTIME timestamps in events */
 #define GPIOD_FLAG_EVENT_CLOCK_HTE	19 /* GPIO CDEV reports hardware timestamps in events */
 #define GPIOD_FLAG_SHARED		20 /* GPIO is shared by multiple consumers */
+#define GPIOD_FLAG_SHARED_PROXY		21 /* GPIO is a virtual proxy to a physically shared pin. */
 
 	/* Connection label */
 	struct gpio_desc_label __rcu *label;
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index 994d46874d560416175c9099e18180237839bd4c..cafeb7a40ad1c25aeb7deaf598410d5f2f004a82 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -167,6 +167,8 @@ int gpiod_cansleep(const struct gpio_desc *desc);
 int gpiod_to_irq(const struct gpio_desc *desc);
 int gpiod_set_consumer_name(struct gpio_desc *desc, const char *name);
 
+bool gpiod_is_shared(const struct gpio_desc *desc);
+
 /* Convert between the old gpio_ and new gpiod_ interfaces */
 struct gpio_desc *gpio_to_desc(unsigned gpio);
 int desc_to_gpio(const struct gpio_desc *desc);
@@ -522,6 +524,13 @@ static inline int gpiod_set_consumer_name(struct gpio_desc *desc,
 	return -EINVAL;
 }
 
+static inline bool gpiod_is_shared(const struct gpio_desc *desc)
+{
+	/* GPIO can never have been requested */
+	WARN_ON(desc);
+	return false;
+}
+
 static inline struct gpio_desc *gpio_to_desc(unsigned gpio)
 {
 	return NULL;

-- 
2.51.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 07/10] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM
  2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
                   ` (5 preceding siblings ...)
  2025-11-12 13:55 ` [PATCH v4 06/10] gpio: provide gpiod_is_shared() Bartosz Golaszewski
@ 2025-11-12 13:55 ` Bartosz Golaszewski
  2025-11-13  8:51   ` Arnd Bergmann
                     ` (2 more replies)
  2025-11-12 13:55 ` [PATCH v4 08/10] ASoC: wsa881x: drop GPIOD_FLAGS_BIT_NONEXCLUSIVE flag from GPIO lookup Bartosz Golaszewski
                   ` (7 subsequent siblings)
  14 siblings, 3 replies; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-12 13:55 UTC (permalink / raw)
  To: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Bartosz Golaszewski,
	Catalin Marinas, Will Deacon, Srinivas Kandagatla, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Alexey Klimov,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Some qualcomm platforms use shared GPIOs. Enable support for them by
selecting the Kconfig switch provided by GPIOLIB.

Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 arch/arm64/Kconfig.platforms | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 13173795c43d4f28e2d47acc700f80a165d44671..3dbff0261f0add0516d8cb3fd0f29e277af94f20 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -316,6 +316,7 @@ config ARCH_QCOM
 	select GPIOLIB
 	select PINCTRL
 	select HAVE_PWRCTRL if PCI
+	select HAVE_SHARED_GPIOS
 	help
 	  This enables support for the ARMv8 based Qualcomm chipsets.
 

-- 
2.51.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 08/10] ASoC: wsa881x: drop GPIOD_FLAGS_BIT_NONEXCLUSIVE flag from GPIO lookup
  2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
                   ` (6 preceding siblings ...)
  2025-11-12 13:55 ` [PATCH v4 07/10] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM Bartosz Golaszewski
@ 2025-11-12 13:55 ` Bartosz Golaszewski
  2025-11-12 13:55 ` [PATCH v4 09/10] ASoC: wsa883x: " Bartosz Golaszewski
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-12 13:55 UTC (permalink / raw)
  To: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Bartosz Golaszewski,
	Catalin Marinas, Will Deacon, Srinivas Kandagatla, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Alexey Klimov,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

This driver is only used on Qualcomm platforms which now select
HAVE_SHARED_GPIOS so this flag can be dropped.

Reviewed-and-tested-by: Alexey Klimov <alexey.klimov@linaro.org> # RB3
Acked-by: Mark Brown <broonie@kernel.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 sound/soc/codecs/wsa881x.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c
index e249de7f91d91f8c7f1e7020086cc65c71e64c5e..d7aca6567c2de1ec36e9f36aa82463bdbf3be27e 100644
--- a/sound/soc/codecs/wsa881x.c
+++ b/sound/soc/codecs/wsa881x.c
@@ -1112,8 +1112,7 @@ static int wsa881x_probe(struct sdw_slave *pdev,
 	if (!wsa881x)
 		return -ENOMEM;
 
-	wsa881x->sd_n = devm_gpiod_get_optional(dev, "powerdown",
-						GPIOD_FLAGS_BIT_NONEXCLUSIVE);
+	wsa881x->sd_n = devm_gpiod_get_optional(dev, "powerdown", 0);
 	if (IS_ERR(wsa881x->sd_n))
 		return dev_err_probe(dev, PTR_ERR(wsa881x->sd_n),
 				     "Shutdown Control GPIO not found\n");

-- 
2.51.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 09/10] ASoC: wsa883x: drop GPIOD_FLAGS_BIT_NONEXCLUSIVE flag from GPIO lookup
  2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
                   ` (7 preceding siblings ...)
  2025-11-12 13:55 ` [PATCH v4 08/10] ASoC: wsa881x: drop GPIOD_FLAGS_BIT_NONEXCLUSIVE flag from GPIO lookup Bartosz Golaszewski
@ 2025-11-12 13:55 ` Bartosz Golaszewski
  2025-11-12 13:55 ` [PATCH v4 10/10] regulator: make the subsystem aware of shared GPIOs Bartosz Golaszewski
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-12 13:55 UTC (permalink / raw)
  To: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Bartosz Golaszewski,
	Catalin Marinas, Will Deacon, Srinivas Kandagatla, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Alexey Klimov,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

This driver is only used on Qualcomm platforms which now select
HAVE_SHARED_GPIOS so this flag can be dropped.

Acked-by: Mark Brown <broonie@kernel.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 sound/soc/codecs/wsa883x.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c
index 96dd66c4b88dea34f1f24bed4d5ab66d3e2249ae..c3046e260cb958296a41b78b545f1ac7f377a968 100644
--- a/sound/soc/codecs/wsa883x.c
+++ b/sound/soc/codecs/wsa883x.c
@@ -1572,13 +1572,10 @@ static int wsa883x_get_reset(struct device *dev, struct wsa883x_priv *wsa883x)
 	if (IS_ERR(wsa883x->sd_reset))
 		return dev_err_probe(dev, PTR_ERR(wsa883x->sd_reset),
 				     "Failed to get reset\n");
-	/*
-	 * if sd_reset: NULL, so use the backwards compatible way for powerdown-gpios,
-	 * which does not handle sharing GPIO properly.
-	 */
+
+	 /* if sd_reset: NULL, so use the backwards compatible way for powerdown-gpios */
 	if (!wsa883x->sd_reset) {
 		wsa883x->sd_n = devm_gpiod_get_optional(dev, "powerdown",
-							GPIOD_FLAGS_BIT_NONEXCLUSIVE |
 							GPIOD_OUT_HIGH);
 		if (IS_ERR(wsa883x->sd_n))
 			return dev_err_probe(dev, PTR_ERR(wsa883x->sd_n),

-- 
2.51.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 10/10] regulator: make the subsystem aware of shared GPIOs
  2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
                   ` (8 preceding siblings ...)
  2025-11-12 13:55 ` [PATCH v4 09/10] ASoC: wsa883x: " Bartosz Golaszewski
@ 2025-11-12 13:55 ` Bartosz Golaszewski
  2025-11-17  9:20 ` (subset) [PATCH v4 00/10] gpio: improve support for " Bartosz Golaszewski
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-12 13:55 UTC (permalink / raw)
  To: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Bartosz Golaszewski,
	Catalin Marinas, Will Deacon, Srinivas Kandagatla, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Alexey Klimov,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

GPIOLIB is now aware of shared GPIOs and - for platforms where access to
such pins is managed internally - we don't need to keep track of the
enable count.

Once all users in the kernel switch to using the new mechanism, we'll be
able to drop the internal counting of users from the regulator code.

Acked-by: Mark Brown <broonie@kernel.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 drivers/regulator/core.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 2eab56df042e6b05abf0989f425dc161c7b0e66d..53b2b2d3746f9f2419234912d49bd8b4f21a893d 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2742,6 +2742,13 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev,
 
 	mutex_lock(&regulator_list_mutex);
 
+	if (gpiod_is_shared(gpiod))
+		/*
+		 * The sharing of this GPIO pin is managed internally by
+		 * GPIOLIB. We don't need to keep track of its enable count.
+		 */
+		goto skip_compare;
+
 	list_for_each_entry(pin, &regulator_ena_gpio_list, list) {
 		if (gpiod_is_equal(pin->gpiod, gpiod)) {
 			rdev_dbg(rdev, "GPIO is already used\n");
@@ -2754,6 +2761,7 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev,
 		return -ENOMEM;
 	}
 
+skip_compare:
 	pin = new_pin;
 	new_pin = NULL;
 

-- 
2.51.0


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 07/10] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM
  2025-11-12 13:55 ` [PATCH v4 07/10] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM Bartosz Golaszewski
@ 2025-11-13  8:51   ` Arnd Bergmann
  2025-11-14 19:40   ` Bjorn Andersson
  2025-11-18 14:06   ` Mark Brown
  2 siblings, 0 replies; 35+ messages in thread
From: Arnd Bergmann @ 2025-11-13  8:51 UTC (permalink / raw)
  To: Bartosz Golaszewski, Kees Cook, Mika Westerberg, Dmitry Torokhov,
	Andrew Morton, Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio
  Cc: linux-hardening, linux-kernel, open list:GPIO SUBSYSTEM,
	linux-arm-kernel, linux-sound, linux-arm-msm, Bartosz Golaszewski

On Wed, Nov 12, 2025, at 14:55, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>
> Some qualcomm platforms use shared GPIOs. Enable support for them by
> selecting the Kconfig switch provided by GPIOLIB.
>
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Acked-by: Arnd Bergmann <arnd@arndb.de>

Please take this through the gpio and asoc trees for simplicity.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 07/10] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM
  2025-11-12 13:55 ` [PATCH v4 07/10] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM Bartosz Golaszewski
  2025-11-13  8:51   ` Arnd Bergmann
@ 2025-11-14 19:40   ` Bjorn Andersson
  2025-11-18 14:06   ` Mark Brown
  2 siblings, 0 replies; 35+ messages in thread
From: Bjorn Andersson @ 2025-11-14 19:40 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Konrad Dybcio, linux-hardening,
	linux-kernel, linux-gpio, linux-arm-kernel, linux-sound,
	linux-arm-msm, Bartosz Golaszewski

On Wed, Nov 12, 2025 at 02:55:36PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> Some qualcomm platforms use shared GPIOs. Enable support for them by
> selecting the Kconfig switch provided by GPIOLIB.
> 
> Acked-by: Linus Walleij <linus.walleij@linaro.org>

Acked-by: Bjorn Andersson <andersson@kernel.org>

Regards,
Bjorn

> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> ---
>  arch/arm64/Kconfig.platforms | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
> index 13173795c43d4f28e2d47acc700f80a165d44671..3dbff0261f0add0516d8cb3fd0f29e277af94f20 100644
> --- a/arch/arm64/Kconfig.platforms
> +++ b/arch/arm64/Kconfig.platforms
> @@ -316,6 +316,7 @@ config ARCH_QCOM
>  	select GPIOLIB
>  	select PINCTRL
>  	select HAVE_PWRCTRL if PCI
> +	select HAVE_SHARED_GPIOS
>  	help
>  	  This enables support for the ARMv8 based Qualcomm chipsets.
>  
> 
> -- 
> 2.51.0
> 

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: (subset) [PATCH v4 00/10] gpio: improve support for shared GPIOs
  2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
                   ` (9 preceding siblings ...)
  2025-11-12 13:55 ` [PATCH v4 10/10] regulator: make the subsystem aware of shared GPIOs Bartosz Golaszewski
@ 2025-11-17  9:20 ` Bartosz Golaszewski
  2025-11-18 11:15 ` Geert Uytterhoeven
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-17  9:20 UTC (permalink / raw)
  To: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	Bartosz Golaszewski
  Cc: Bartosz Golaszewski, linux-hardening, linux-kernel, linux-gpio,
	linux-arm-kernel, linux-sound, linux-arm-msm

From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>


On Wed, 12 Nov 2025 14:55:29 +0100, Bartosz Golaszewski wrote:
> Bjorn, Konrad: I should have Cc'ed you on v1 but I just went with what
> came out of b4 --auto-to-cc. It only gave me arm-msm. :( Patch 7 from
> this series however impacts Qualcomm platforms. It's a runtime dependency
> of patches 8 and 9. Would you mind Acking it so that I can take it into
> an immutable branch that I'll make available to Mark Brown for him to
> take patches 8-10 through the ASoC and regulator trees for v6.19?
> 
> [...]

Applied, thanks!

[01/10] string: provide strends()
        https://git.kernel.org/brgl/linux/c/197b3f3c70d61ff1c7ca24f66d567e06fe8ed3d9
[02/10] gpiolib: define GPIOD_FLAG_SHARED
        https://git.kernel.org/brgl/linux/c/d4340ff75eaa083f261e16d49f13191236bfad06
[03/10] gpiolib: implement low-level, shared GPIO support
        https://git.kernel.org/brgl/linux/c/a060b8c511abb0997381b397e52149a5e3e5259a
[04/10] gpio: shared-proxy: implement the shared GPIO proxy driver
        https://git.kernel.org/brgl/linux/c/e992d54c6f970b382ffeacd7c88f68b94a3c6caf
[05/10] gpiolib: support shared GPIOs in core subsystem code
        https://git.kernel.org/brgl/linux/c/1e4f6db614a310cc34d07ffbf031c76ea9581bcf
[06/10] gpio: provide gpiod_is_shared()
        https://git.kernel.org/brgl/linux/c/eb374f764a7012eda28019266a6d9191670c4fa5
[07/10] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM
        https://git.kernel.org/brgl/linux/c/e511d484cbe44fe48a1b9f621f6a947c72503f9e

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 01/10] string: provide strends()
  2025-11-12 13:55 ` [PATCH v4 01/10] string: provide strends() Bartosz Golaszewski
@ 2025-11-17 20:33   ` Kees Cook
  2025-11-18  9:47     ` Bartosz Golaszewski
  0 siblings, 1 reply; 35+ messages in thread
From: Kees Cook @ 2025-11-17 20:33 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Mika Westerberg, Dmitry Torokhov, Andrew Morton, Linus Walleij,
	Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, Greg Kroah-Hartman,
	Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

On Wed, Nov 12, 2025 at 02:55:30PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> Implement a function for checking if a string ends with a different
> string and add its kunit test cases.
> 
> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> ---
>  include/linux/string.h   | 18 ++++++++++++++++++
>  lib/tests/string_kunit.c | 13 +++++++++++++
>  2 files changed, 31 insertions(+)
> 
> diff --git a/include/linux/string.h b/include/linux/string.h
> index fdd3442c6bcbd786e177b6e87358e1065a0ffafc..929d05d1247c76eb9011fe34250b487834b2d3c9 100644
> --- a/include/linux/string.h
> +++ b/include/linux/string.h
> @@ -562,4 +562,22 @@ static inline bool strstarts(const char *str, const char *prefix)
>  	return strncmp(str, prefix, strlen(prefix)) == 0;
>  }
>  
> +/**
> + * strends - Check if a string ends with another string.
> + * @str - NULL-terminated string to check against @suffix
> + * @suffix - NULL-terminated string defining the suffix to look for in @str
> + *
> + * Returns:
> + * True if @str ends with @suffix. False in all other cases.

Maybe added "empty strings never match"?

> + */
> +static inline bool strends(const char *str, const char *suffix)

These are required to be non-NULL, so we might want to consider marking
them as such with the "nonnull" attribute. We don't use it much in Linux
yet, but I do see a few places.

e.g.:

static inline bool __attribute__((nonnull(1,2)))
strends(const char *str, const char *suffix)

> +{
> +	unsigned int str_len = strlen(str), suffix_len = strlen(suffix);
> +
> +	if (str_len < suffix_len)
> +		return false;
> +
> +	return !(strcmp(str + str_len - suffix_len, suffix));
> +}

We should probably add it to strlen and strcmp as well. :)

> +
>  #endif /* _LINUX_STRING_H_ */
> diff --git a/lib/tests/string_kunit.c b/lib/tests/string_kunit.c
> index 0ed7448a26d3aa0fe9e2a6a894d4c49c2c0b86e0..f9a8e557ba7734c9848d58ff986407d8000f52ee 100644
> --- a/lib/tests/string_kunit.c
> +++ b/lib/tests/string_kunit.c
> @@ -602,6 +602,18 @@ static void string_test_memtostr(struct kunit *test)
>  	KUNIT_EXPECT_EQ(test, dest[7], '\0');
>  }
>  
> +static void string_test_strends(struct kunit *test)
> +{
> +	KUNIT_EXPECT_TRUE(test, strends("foo-bar", "bar"));
> +	KUNIT_EXPECT_TRUE(test, strends("foo-bar", "-bar"));
> +	KUNIT_EXPECT_TRUE(test, strends("foobar", "foobar"));
> +	KUNIT_EXPECT_TRUE(test, strends("foobar", ""));
> +	KUNIT_EXPECT_FALSE(test, strends("bar", "foobar"));
> +	KUNIT_EXPECT_FALSE(test, strends("", "foo"));
> +	KUNIT_EXPECT_FALSE(test, strends("foobar", "ba"));
> +	KUNIT_EXPECT_TRUE(test, strends("", ""));
> +}

Thanks for adding tests! :)

> +
>  static struct kunit_case string_test_cases[] = {
>  	KUNIT_CASE(string_test_memset16),
>  	KUNIT_CASE(string_test_memset32),
> @@ -623,6 +635,7 @@ static struct kunit_case string_test_cases[] = {
>  	KUNIT_CASE(string_test_strlcat),
>  	KUNIT_CASE(string_test_strtomem),
>  	KUNIT_CASE(string_test_memtostr),
> +	KUNIT_CASE(string_test_strends),
>  	{}
>  };
>  
> 
> -- 
> 2.51.0
> 

Reviewed-by: Kees Cook <kees@kernel.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 01/10] string: provide strends()
  2025-11-17 20:33   ` Kees Cook
@ 2025-11-18  9:47     ` Bartosz Golaszewski
  2025-11-18 10:13       ` Andy Shevchenko
  0 siblings, 1 reply; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-18  9:47 UTC (permalink / raw)
  To: Kees Cook
  Cc: Mika Westerberg, Dmitry Torokhov, Andrew Morton, Linus Walleij,
	Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, Greg Kroah-Hartman,
	Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

On Mon, Nov 17, 2025 at 9:33 PM Kees Cook <kees@kernel.org> wrote:
>
> On Wed, Nov 12, 2025 at 02:55:30PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> >
> > Implement a function for checking if a string ends with a different
> > string and add its kunit test cases.
> >
> > Acked-by: Linus Walleij <linus.walleij@linaro.org>
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> > ---

Hi Kees!

Thanks for the review. I already queued this for v6.19, so let me
address the issues in a follow-up.

> >  include/linux/string.h   | 18 ++++++++++++++++++
> >  lib/tests/string_kunit.c | 13 +++++++++++++
> >  2 files changed, 31 insertions(+)
> >
> > diff --git a/include/linux/string.h b/include/linux/string.h
> > index fdd3442c6bcbd786e177b6e87358e1065a0ffafc..929d05d1247c76eb9011fe34250b487834b2d3c9 100644
> > --- a/include/linux/string.h
> > +++ b/include/linux/string.h
> > @@ -562,4 +562,22 @@ static inline bool strstarts(const char *str, const char *prefix)
> >       return strncmp(str, prefix, strlen(prefix)) == 0;
> >  }
> >
> > +/**
> > + * strends - Check if a string ends with another string.
> > + * @str - NULL-terminated string to check against @suffix
> > + * @suffix - NULL-terminated string defining the suffix to look for in @str
> > + *
> > + * Returns:
> > + * True if @str ends with @suffix. False in all other cases.
>
> Maybe added "empty strings never match"?
>

But they do, please see the test.

> > + */
> > +static inline bool strends(const char *str, const char *suffix)
>
> These are required to be non-NULL, so we might want to consider marking
> them as such with the "nonnull" attribute. We don't use it much in Linux
> yet, but I do see a few places.
>
> e.g.:
>
> static inline bool __attribute__((nonnull(1,2)))
> strends(const char *str, const char *suffix)
>

Ok.

> > +{
> > +     unsigned int str_len = strlen(str), suffix_len = strlen(suffix);
> > +
> > +     if (str_len < suffix_len)
> > +             return false;
> > +
> > +     return !(strcmp(str + str_len - suffix_len, suffix));
> > +}
>
> We should probably add it to strlen and strcmp as well. :)
>

Sure but that's outside of the scope of this.

Bart

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 01/10] string: provide strends()
  2025-11-18  9:47     ` Bartosz Golaszewski
@ 2025-11-18 10:13       ` Andy Shevchenko
  0 siblings, 0 replies; 35+ messages in thread
From: Andy Shevchenko @ 2025-11-18 10:13 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

On Tue, Nov 18, 2025 at 11:47 AM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> On Mon, Nov 17, 2025 at 9:33 PM Kees Cook <kees@kernel.org> wrote:
> > On Wed, Nov 12, 2025 at 02:55:30PM +0100, Bartosz Golaszewski wrote:

...

> > > + * True if @str ends with @suffix. False in all other cases.
> >
> > Maybe added "empty strings never match"?
>
> But they do, please see the test.

I also think that "" == "" (on the same page as Bart). Why should we
make it different?

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 00/10] gpio: improve support for shared GPIOs
  2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
                   ` (10 preceding siblings ...)
  2025-11-17  9:20 ` (subset) [PATCH v4 00/10] gpio: improve support for " Bartosz Golaszewski
@ 2025-11-18 11:15 ` Geert Uytterhoeven
  2025-11-18 11:55   ` Bartosz Golaszewski
  2025-11-18 23:23   ` Linus Walleij
  2025-11-20 10:39 ` (subset) " Mark Brown
                   ` (2 subsequent siblings)
  14 siblings, 2 replies; 35+ messages in thread
From: Geert Uytterhoeven @ 2025-11-18 11:15 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski, Linux-Renesas

Hi Bartosz,

On Wed, 12 Nov 2025 at 15:05, Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> Bjorn, Konrad: I should have Cc'ed you on v1 but I just went with what
> came out of b4 --auto-to-cc. It only gave me arm-msm. :( Patch 7 from
> this series however impacts Qualcomm platforms. It's a runtime dependency
> of patches 8 and 9. Would you mind Acking it so that I can take it into
> an immutable branch that I'll make available to Mark Brown for him to
> take patches 8-10 through the ASoC and regulator trees for v6.19?
>
> Problem statement: GPIOs are implemented as a strictly exclusive
> resource in the kernel but there are lots of platforms on which single
> pin is shared by multiple devices which don't communicate so need some
> way of properly sharing access to a GPIO. What we have now is the
> GPIOD_FLAGS_BIT_NONEXCLUSIVE flag which was introduced as a hack and
> doesn't do any locking or arbitration of access - it literally just hand
> the same GPIO descriptor to all interested users.
>
> The proposed solution is composed of three major parts: the high-level,
> shared GPIO proxy driver that arbitrates access to the shared pin and
> exposes a regular GPIO chip interface to consumers, a low-level shared
> GPIOLIB module that scans firmware nodes and creates auxiliary devices
> that attach to the proxy driver and finally a set of core GPIOLIB
> changes that plug the former into the GPIO lookup path.
>
> The changes are implemented in a way that allows to seamlessly compile
> out any code related to sharing GPIOs for systems that don't need it.
>
> The practical use-case for this are the powerdown GPIOs shared by
> speakers on Qualcomm db845c platform, however I have also extensively
> tested it using gpio-virtuser on arm64 qemu with various DT
> configurations.

Thanks for your series, part of which is now present linux-next.
IIUIC, this requires the direction of the GPIO to be fixed?

We have a long-standing use-case on various Renesas R-Car Gen3 boards
(e.g. Salvator-X(S) and ULCB[1]), where GPIOs are shared by LEDs and
key switches.  Basically, the GPIO is connected to:
  1. A key switch connecting to GND when closed, with pull-up.
  2. The gate of an N-channel MOSFET, turning on an LED when driven
     high.

Hence:
  - In output mode, the LED can be controlled freely,
  - In input mode, the LED is on, unless the key is pressed,
  - Hence the switch state can only be read when the LED is turned on.
If you have any idea how to handle this, feel free to reply ;-)

Thanks!

[1] https://www.renesas.com/en/document/sch/r-car-starterkit-schematic
    (needs a (free) account) Page 15 aka schematic 12.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 00/10] gpio: improve support for shared GPIOs
  2025-11-18 11:15 ` Geert Uytterhoeven
@ 2025-11-18 11:55   ` Bartosz Golaszewski
  2025-11-18 12:55     ` Geert Uytterhoeven
  2025-11-18 23:23   ` Linus Walleij
  1 sibling, 1 reply; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-18 11:55 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski, Linux-Renesas

On Tue, Nov 18, 2025 at 12:16 PM Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
>
> Hi Bartosz,
>
> On Wed, 12 Nov 2025 at 15:05, Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> > Bjorn, Konrad: I should have Cc'ed you on v1 but I just went with what
> > came out of b4 --auto-to-cc. It only gave me arm-msm. :( Patch 7 from
> > this series however impacts Qualcomm platforms. It's a runtime dependency
> > of patches 8 and 9. Would you mind Acking it so that I can take it into
> > an immutable branch that I'll make available to Mark Brown for him to
> > take patches 8-10 through the ASoC and regulator trees for v6.19?
> >
> > Problem statement: GPIOs are implemented as a strictly exclusive
> > resource in the kernel but there are lots of platforms on which single
> > pin is shared by multiple devices which don't communicate so need some
> > way of properly sharing access to a GPIO. What we have now is the
> > GPIOD_FLAGS_BIT_NONEXCLUSIVE flag which was introduced as a hack and
> > doesn't do any locking or arbitration of access - it literally just hand
> > the same GPIO descriptor to all interested users.
> >
> > The proposed solution is composed of three major parts: the high-level,
> > shared GPIO proxy driver that arbitrates access to the shared pin and
> > exposes a regular GPIO chip interface to consumers, a low-level shared
> > GPIOLIB module that scans firmware nodes and creates auxiliary devices
> > that attach to the proxy driver and finally a set of core GPIOLIB
> > changes that plug the former into the GPIO lookup path.
> >
> > The changes are implemented in a way that allows to seamlessly compile
> > out any code related to sharing GPIOs for systems that don't need it.
> >
> > The practical use-case for this are the powerdown GPIOs shared by
> > speakers on Qualcomm db845c platform, however I have also extensively
> > tested it using gpio-virtuser on arm64 qemu with various DT
> > configurations.
>
> Thanks for your series, part of which is now present linux-next.
> IIUIC, this requires the direction of the GPIO to be fixed?
>
> We have a long-standing use-case on various Renesas R-Car Gen3 boards
> (e.g. Salvator-X(S) and ULCB[1]), where GPIOs are shared by LEDs and
> key switches.  Basically, the GPIO is connected to:
>   1. A key switch connecting to GND when closed, with pull-up.
>   2. The gate of an N-channel MOSFET, turning on an LED when driven
>      high.
>
> Hence:
>   - In output mode, the LED can be controlled freely,
>   - In input mode, the LED is on, unless the key is pressed,
>   - Hence the switch state can only be read when the LED is turned on.
> If you have any idea how to handle this, feel free to reply ;-)
>
> Thanks!
>

How is this done currently? Even without this series and using the
GPIOD_FLAGS_BIT_NONEXCLUSIVE, the descriptor has a well-defined
direction so it's not possible for two drivers to request it as input
and output simultaneously. The second requester will override the
previous settings.

Bart

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 00/10] gpio: improve support for shared GPIOs
  2025-11-18 11:55   ` Bartosz Golaszewski
@ 2025-11-18 12:55     ` Geert Uytterhoeven
  2025-11-18 13:21       ` Bartosz Golaszewski
  0 siblings, 1 reply; 35+ messages in thread
From: Geert Uytterhoeven @ 2025-11-18 12:55 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski, Linux-Renesas

Hi Bartosz,

On Tue, 18 Nov 2025 at 12:55, Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> On Tue, Nov 18, 2025 at 12:16 PM Geert Uytterhoeven
> <geert@linux-m68k.org> wrote:
> > On Wed, 12 Nov 2025 at 15:05, Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> > > Bjorn, Konrad: I should have Cc'ed you on v1 but I just went with what
> > > came out of b4 --auto-to-cc. It only gave me arm-msm. :( Patch 7 from
> > > this series however impacts Qualcomm platforms. It's a runtime dependency
> > > of patches 8 and 9. Would you mind Acking it so that I can take it into
> > > an immutable branch that I'll make available to Mark Brown for him to
> > > take patches 8-10 through the ASoC and regulator trees for v6.19?
> > >
> > > Problem statement: GPIOs are implemented as a strictly exclusive
> > > resource in the kernel but there are lots of platforms on which single
> > > pin is shared by multiple devices which don't communicate so need some
> > > way of properly sharing access to a GPIO. What we have now is the
> > > GPIOD_FLAGS_BIT_NONEXCLUSIVE flag which was introduced as a hack and
> > > doesn't do any locking or arbitration of access - it literally just hand
> > > the same GPIO descriptor to all interested users.
> > >
> > > The proposed solution is composed of three major parts: the high-level,
> > > shared GPIO proxy driver that arbitrates access to the shared pin and
> > > exposes a regular GPIO chip interface to consumers, a low-level shared
> > > GPIOLIB module that scans firmware nodes and creates auxiliary devices
> > > that attach to the proxy driver and finally a set of core GPIOLIB
> > > changes that plug the former into the GPIO lookup path.
> > >
> > > The changes are implemented in a way that allows to seamlessly compile
> > > out any code related to sharing GPIOs for systems that don't need it.
> > >
> > > The practical use-case for this are the powerdown GPIOs shared by
> > > speakers on Qualcomm db845c platform, however I have also extensively
> > > tested it using gpio-virtuser on arm64 qemu with various DT
> > > configurations.
> >
> > Thanks for your series, part of which is now present linux-next.
> > IIUIC, this requires the direction of the GPIO to be fixed?
> >
> > We have a long-standing use-case on various Renesas R-Car Gen3 boards
> > (e.g. Salvator-X(S) and ULCB[1]), where GPIOs are shared by LEDs and
> > key switches.  Basically, the GPIO is connected to:
> >   1. A key switch connecting to GND when closed, with pull-up.
> >   2. The gate of an N-channel MOSFET, turning on an LED when driven
> >      high.
> >
> > Hence:
> >   - In output mode, the LED can be controlled freely,
> >   - In input mode, the LED is on, unless the key is pressed,
> >   - Hence the switch state can only be read when the LED is turned on.
> > If you have any idea how to handle this, feel free to reply ;-)
>
> How is this done currently? Even without this series and using the
> GPIOD_FLAGS_BIT_NONEXCLUSIVE, the descriptor has a well-defined
> direction so it's not possible for two drivers to request it as input
> and output simultaneously. The second requester will override the
> previous settings.

We do not handle it yet:
  - arch/arm64/boot/dts/renesas/salvator-common.dtsi describes only
    the keys (key-[a-c]),
  - arch/arm64/boot/dts/renesas/ulcb.dtsi describes the first key
    (key-1), and the others as LEDs (led[56]).

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 00/10] gpio: improve support for shared GPIOs
  2025-11-18 12:55     ` Geert Uytterhoeven
@ 2025-11-18 13:21       ` Bartosz Golaszewski
  0 siblings, 0 replies; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-18 13:21 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski, Linux-Renesas

On Tue, Nov 18, 2025 at 1:56 PM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>
> > >
> > > Thanks for your series, part of which is now present linux-next.
> > > IIUIC, this requires the direction of the GPIO to be fixed?
> > >
> > > We have a long-standing use-case on various Renesas R-Car Gen3 boards
> > > (e.g. Salvator-X(S) and ULCB[1]), where GPIOs are shared by LEDs and
> > > key switches.  Basically, the GPIO is connected to:
> > >   1. A key switch connecting to GND when closed, with pull-up.
> > >   2. The gate of an N-channel MOSFET, turning on an LED when driven
> > >      high.
> > >
> > > Hence:
> > >   - In output mode, the LED can be controlled freely,
> > >   - In input mode, the LED is on, unless the key is pressed,
> > >   - Hence the switch state can only be read when the LED is turned on.
> > > If you have any idea how to handle this, feel free to reply ;-)
> >
> > How is this done currently? Even without this series and using the
> > GPIOD_FLAGS_BIT_NONEXCLUSIVE, the descriptor has a well-defined
> > direction so it's not possible for two drivers to request it as input
> > and output simultaneously. The second requester will override the
> > previous settings.
>
> We do not handle it yet:
>   - arch/arm64/boot/dts/renesas/salvator-common.dtsi describes only
>     the keys (key-[a-c]),
>   - arch/arm64/boot/dts/renesas/ulcb.dtsi describes the first key
>     (key-1), and the others as LEDs (led[56]).
>

I see. This series cannot possibly address this. Off the top of my
head: I would create an auxiliary device binding to a dedicated driver
that would be a consumer of this pin and register a LED and an input
key. By default it would set the direction to input and if the user
decided to configure the LED, it would change direction to output.

Obviously, there would be a DR quirk to handle as we already have this
described in DT as gpio-keys on salvator.

Bartosz

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 07/10] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM
  2025-11-12 13:55 ` [PATCH v4 07/10] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM Bartosz Golaszewski
  2025-11-13  8:51   ` Arnd Bergmann
  2025-11-14 19:40   ` Bjorn Andersson
@ 2025-11-18 14:06   ` Mark Brown
  2025-11-18 14:13     ` Bartosz Golaszewski
  2 siblings, 1 reply; 35+ messages in thread
From: Mark Brown @ 2025-11-18 14:06 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Alexey Klimov, Bjorn Andersson, Konrad Dybcio, linux-hardening,
	linux-kernel, linux-gpio, linux-arm-kernel, linux-sound,
	linux-arm-msm, Bartosz Golaszewski, Aishwarya.TCV

[-- Attachment #1: Type: text/plain, Size: 27163 bytes --]

On Wed, Nov 12, 2025 at 02:55:36PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> 
> Some qualcomm platforms use shared GPIOs. Enable support for them by
> selecting the Kconfig switch provided by GPIOLIB.

This is causing boot failures for me in -next on the ARM FVP with
defconfig, the select affects all platforms not just the Qualcomm ones.
We get:

[    0.137360] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000058

...

[    0.140979] Call trace:
[    0.141037]  gpio_shared_of_traverse+0x48/0x480 (P)
[    0.141187]  gpio_shared_init+0x28/0x14c
[    0.141314]  do_one_initcall+0x60/0x1d4
[    0.141446]  kernel_init_freeable+0x24c/0x2c8
[    0.141607]  kernel_init+0x20/0x140

Full log:

   https://lava.sirena.org.uk/scheduler/job/2101484#L692

Bisect log:

# bad: [187dac290bfd0741b9d7d5490af825c33fd9baa4] Add linux-next specific files for 20251118
# good: [17bfd0eea14a5f4217041fc57d85c965b07c02a8] Merge branch 'for-linux-next-fixes' of https://gitlab.freedesktop.org/drm/misc/kernel.git
# good: [118eb2cb97b8fc0d515bb0449495959247db58f0] spi: bcm63xx: drop wrong casts in probe()
# good: [059f545832be85d29ac9ccc416a16f647aa78485] spi: add support for microchip "soft" spi controller
# good: [6402ddf3027d8975f135cf2b2014d6bbeb2d3436] MAINTAINERS: refer to trivial-codec.yaml in relevant sections
# good: [4e00135b2dd1d7924a58bffa551b6ceb3bd836f2] spi: spi-cadence: supports transmission with bits_per_word of 16 and 32
# good: [e65b871c9b5af9265aefc5b8cd34993586d93aab] ASoC: codecs: pm4125: Remove irq_chip on component unbind
# good: [8d63e85c5b50f1dbfa0ccb214bd91fe5d7e2e860] firmware: cs_dsp: fix kernel-doc warnings in a header file
# good: [8ff3dcb0e8a8bf6c41f23ed4aa62d066d3948a10] ASoC: codecs: lpass-rx-macro: add SM6115 compatible
# good: [123cd174a3782307787268adf45f22de4d290128] ASoC: Intel: atom: Replace strcpy() with strscpy()
# good: [4d6e2211aeb932e096f673c88475016b1cc0f8ab] ASoC: Intel: boards: fix HDMI playback lookup when HDMI-In capture used
# good: [1d562ba0aa7df81335bf96c02be77efe8d5bab87] spi: dt-bindings: nuvoton,npcm-pspi: Convert to DT schema
# good: [b3a5302484033331af37569f7277d00131694b57] ASoC: Intel: sof_rt5682: Add quirk override support
# good: [873bc94689d832878befbcadc10b6ad5bb4e0027] ASoC: Intel: sof_sdw: add codec speaker support for the SKU
# good: [32172cf3cb543a04c41a1677c97a38e60cad05b6] ASoC: cs35l56: Allow restoring factory calibration through ALSA control
# good: [772ada50282b0c80343c8989147db816961f571d] ASoC: cs35l56: Alter error codes for calibration routine
# good: [6985defd1d832f1dd9d1977a6a2cc2cef7632704] regmap: sdw-mbq: Reorder regmap_mbq_context struct for better packing
# good: [fb1ebb10468da414d57153ddebaab29c38ef1a78] regulator: core: disable supply if enabling main regulator fails
# good: [6951be397ca8b8b167c9f99b5a11c541148c38cb] ASoC: codecs: pm4125: remove duplicate code
# good: [4e92abd0a11b91af3742197a9ca962c3c00d0948] spi: imx: add i.MX51 ECSPI target mode support
# good: [2089f086303b773e181567fd8d5df3038bd85937] regulator: mt6363: Remove unneeded semicolon
# good: [abc9a349b87ac0fd3ba8787ca00971b59c2e1257] spi: fsl-qspi: support the SpacemiT K1 SoC
# good: [55d03b5b5bdd04daf9a35ce49db18d8bb488dffb] spi: imx: remove CLK calculation and check for target mode
# good: [1b0f3f9ee41ee2bdd206667f85ea2aa36dfe6e69] ASoC: SDCA: support Q7.8 volume format
# good: [6bd1ad97eb790570c167d4de4ca59fbc9c33722a] regulator: pf9453: Fix kernel doc for mux_poll()
# good: [3c36965df80801344850388592e95033eceea05b] regulator: Add support for MediaTek MT6363 SPMI PMIC Regulators
# good: [655079ac8a7721ac215a0596e3f33b740e01144a] ASoC: qcom: q6asm: Use guard() for spin locks
# good: [2f538ef9f6f7c3d700c68536f21447dfc598f8c8] spi: aspeed: Use devm_iounmap() to unmap devm_ioremap() memory
# good: [aa897ffc396b48cc39eee133b6b43175d0df9eb5] ASoC: dt-bindings: ti,pcm1862: convert to dtschema
# good: [380fd29d57abe6679d87ec56babe65ddc5873a37] spi: tegra210-quad: Check hardware status on timeout
# good: [af9c8092d84244ca54ffb590435735f788e7a170] regmap: i3c: Use ARRAY_SIZE()
# good: [c4e68959af66df525d71db619ffe44af9178bb22] ASoC: dt-bindings: ti,tas2781: Add TAS5822 support
# good: [2ecc8c089802e033d2e5204d21a9f467e2517df9] regulator: pf9453: remove unused I2C_LT register
# good: [84194c66aaf78fed150edb217b9f341518b1cba2] ASoC: codecs: aw88261: pass pointer directly instead of passing the address
# good: [252abf2d07d33b1c70a59ba1c9395ba42bbd793e] regulator: Small cleanup in of_get_regulation_constraints()
# good: [ed5d499b5c9cc11dd3edae1a7a55db7dfa4f1bdc] regcache: maple: Split ->populate() from ->init()
# good: [e73b743bfe8a6ff4e05b5657d3f7586a17ac3ba0] ASoC: soc-core: check ops & auto_selectable_formats in snd_soc_dai_get_fmt() to prevent dereference error
# good: [6ef8e042cdcaabe3e3c68592ba8bfbaee2fa10a3] ASoC: codec: wm8400: replace printk() calls with dev_*() device aware logging
# good: [ecd0de438c1f0ee86cf8f6d5047965a2a181444b] spi: tle62x0: Add newline to sysfs attribute output
# good: [f1dfbc1b5cf8650ae9a0d543e5f5335fc0f478ce] ASoC: max98090/91: fixing the stream index
# good: [8fdb030fe283c84fd8d378c97ad0f32d6cdec6ce] ASoC: qcom: sc7280: make use of common helpers
# good: [20bcda681f8597e86070a4b3b12d1e4f541865d3] ASoC: codecs: va-macro: fix revision checking
# good: [cf6bf51b53252284bafc7377a4d8dbf10f048b4d] ASoC: cs4271: Add support for the external mclk
# good: [28039efa4d8e8bbf98b066133a906bd4e307d496] MAINTAINERS: remove obsolete file entry in DIALOG SEMICONDUCTOR DRIVERS
# good: [e062bdfdd6adbb2dee7751d054c1d8df63ddb8b8] regmap: warn users about uninitialized flat cache
# good: [f034c16a4663eaf3198dc18b201ba50533fb5b81] ASoC: spacemit: add failure check for spacemit_i2s_init_dai()
# good: [66fecfa91deb536a12ddf3d878a99590d7900277] ASoC: spacemit: use `depends on` instead of `select`
# good: [4a5ac6cd05a7e54f1585d7779464d6ed6272c134] ASoC: sun4i-spdif: Support SPDIF output on A523 family
# good: [ef042df96d0e1089764f39ede61bc8f140a4be00] ASoC: SDCA: Add HID button IRQ
# good: [4795375d8aa072e9aacb0b278e6203c6ca41816a] ASoC: cs-amp-lib-test: Add test cases for cs_amp_set_efi_calibration_data()
# good: [4c33cef58965eb655a0ac8e243aa323581ec025f] regulator: pca9450: link regulator inputs to supply groups
# good: [e973dfe9259095fb509ab12658c68d46f0e439d7] ASoC: qcom: sm8250: add qrb2210-sndcard compatible string
# good: [e7434adf0c53a84d548226304cdb41c8818da1cb] ASoC: cs530x: Add SPI bus support for cs530x parts
# good: [d29479abaded34b2b1dab2e17efe96a65eba3d61] ASoC: renesas: fsi: Constify struct fsi_stream_handler
# good: [77a58ba7c64ccca20616aa03599766ccb0d1a330] spi: spi-mem: Trace exec_op
# good: [01313661b248c5ba586acae09bff57077dbec0a5] regulator: Let raspberrypi drivers depend on ARM
# good: [c17fa4cbc546c431ccf13e9354d5d9c1cd247b7c] ASoC: sdw_utils: add name_prefix for rt1321 part id
# good: [310bf433c01f78e0756fd5056a43118a2f77318c] ASoC: max98090/91: fixing a space
# good: [fd5ef3d69f8975bad16c437a337b5cb04c8217a2] spi: spi-qpic-snand: make qcom_spi_ecc_engine_ops_pipelined const
# good: [d054cc3a2ccfb19484f3b54d69b6e416832dc8f4] regulator: rpmh-regulator: Add RPMH regulator support for PMR735D
# good: [2528c15f314ece50218d1273654f630d74109583] ASoC: max98090/91: adding DAPM routing for digital output for max98091
# good: [638bae3fb225a708dc67db613af62f6d14c4eff4] ASoC: max98090/91: added DAPM widget for digital output for max98091
# good: [ecba655bf54a661ffe078856cd8dbc898270e4b5] ASoC: fsl_aud2htx: add IEC958_SUBFRAME_LE format in supported list
# good: [7e1906643a7374529af74b013bba35e4fa4e6ffc] ASoC: codecs: va-macro: Clean up on error path in probe()
# good: [d742ebcfe524dc54023f7c520d2ed2e4b7203c19] ASoC: soc.h: remove snd_soc_kcontrol_component()
# good: [fce217449075d59b29052b8cdac567f0f3e22641] ASoC: spacemit: add i2s support for K1 SoC
# good: [6658472a3e2de08197acfe099ba71ee0e2505ecf] ASoC: amd: amd_sdw: Propagate the PCI subsystem Vendor and Device IDs
# good: [0cc08c8130ac8f74419f99fe707dc193b7f79d86] spi: aspeed: Fix an IS_ERR() vs NULL bug in probe()
# good: [0743acf746a81e0460a56fd5ff847d97fa7eb370] spi: airoha: buffer must be 0xff-ed before writing
# good: [d77daa49085b067137d0adbe3263f75a7ee13a1b] spi: aspeed: fix spelling mistake "triming" -> "trimming"
# good: [1e570e77392f43a3cdab2849d1f81535f8a033e2] ASoC: mxs-saif: support usage with simple-audio-card
# good: [15afe57a874eaf104bfbb61ec598fa31627f7b19] ASoC: dt-bindings: qcom: Add Kaanapali LPASS macro codecs
# good: [fb25114cd760c13cf177d9ac37837fafcc9657b5] regulator: sy7636a: add gpios and input regulator
# good: [65efe5404d151767653c7b7dd39bd2e7ad532c2d] regulator: rpmh-regulator: Add RPMH regulator support for Glymur
# good: [6621b0f118d500092f5f3d72ddddb22aeeb3c3a0] ASoC: codecs: rt5670: use SOC_VALUE_ENUM_SINGLE_DECL for DAC2 L/R MX-1B
# good: [433e294c3c5b5d2020085a0e36c1cb47b694690a] regulator: core: forward undervoltage events downstream by default
# good: [0b0eb7702a9fa410755e86124b4b7cd36e7d1cb4] ASoC: replace use of system_wq with system_dfl_wq
# good: [7e7e2c6e2a1cb250f8d03bb99eed01f6d982d5dd] ASoC: sof-function-topology-lib: escalate the log when missing function topoplogy
# good: [64d87ccfae3326a9561fe41dc6073064a083e0df] spi: aspeed: Only map necessary address window region
# good: [4d410ba9aa275e7990a270f63ce436990ace1bea] dt-bindings: sound: Update ADMAIF bindings for tegra264
# good: [b83fb1b14c06bdd765903ac852ba20a14e24f227] spi: offload: Add offset parameter
# good: [9797329220a2c6622411eb9ecf6a35b24ce09d04] ASoC: sof-function-topology-lib: escalate the log when missing function topoplogy
# good: [fe8cc44dd173cde5788ab4e3730ac61f3d316d9c] spi: dw: add target mode support
# good: [6277a486a7faaa6c87f4bf1d59a2de233a093248] regulator: dt-bindings: Convert Dialog DA9211 Regulators to DT schema
# good: [5e537031f322d55315cd384398b726a9a0748d47] ASoC: codecs: Fix the error of excessive semicolons
# good: [4412ab501677606436e5c49e41151a1e6eac7ac0] spi: dt-bindings: spi-qpic-snand: Add IPQ5332 compatible
git bisect start '187dac290bfd0741b9d7d5490af825c33fd9baa4' '17bfd0eea14a5f4217041fc57d85c965b07c02a8' '118eb2cb97b8fc0d515bb0449495959247db58f0' '059f545832be85d29ac9ccc416a16f647aa78485' '6402ddf3027d8975f135cf2b2014d6bbeb2d3436' '4e00135b2dd1d7924a58bffa551b6ceb3bd836f2' 'e65b871c9b5af9265aefc5b8cd34993586d93aab' '8d63e85c5b50f1dbfa0ccb214bd91fe5d7e2e860' '8ff3dcb0e8a8bf6c41f23ed4aa62d066d3948a10' '123cd174a3782307787268adf45f22de4d290128' '4d6e2211aeb932e096f673c88475016b1cc0f8ab' '1d562ba0aa7df81335bf96c02be77efe8d5bab87' 'b3a5302484033331af37569f7277d00131694b57' '873bc94689d832878befbcadc10b6ad5bb4e0027' '32172cf3cb543a04c41a1677c97a38e60cad05b6' '772ada50282b0c80343c8989147db816961f571d' '6985defd1d832f1dd9d1977a6a2cc2cef7632704' 'fb1ebb10468da414d57153ddebaab29c38ef1a78' '6951be397ca8b8b167c9f99b5a11c541148c38cb' '4e92abd0a11b91af3742197a9ca962c3c00d0948' '2089f086303b773e181567fd8d5df3038bd85937' 'abc9a349b87ac0fd3ba8787ca00971b59c2e1257' '55d03b5b5bdd04daf9a35ce49db18d8bb488dffb' '1b0f3f9ee41ee2bdd206667f85ea2aa36dfe6e69' '6bd1ad97eb790570c167d4de4ca59fbc9c33722a' '3c36965df80801344850388592e95033eceea05b' '655079ac8a7721ac215a0596e3f33b740e01144a' '2f538ef9f6f7c3d700c68536f21447dfc598f8c8' 'aa897ffc396b48cc39eee133b6b43175d0df9eb5' '380fd29d57abe6679d87ec56babe65ddc5873a37' 'af9c8092d84244ca54ffb590435735f788e7a170' 'c4e68959af66df525d71db619ffe44af9178bb22' '2ecc8c089802e033d2e5204d21a9f467e2517df9' '84194c66aaf78fed150edb217b9f341518b1cba2' '252abf2d07d33b1c70a59ba1c9395ba42bbd793e' 'ed5d499b5c9cc11dd3edae1a7a55db7dfa4f1bdc' 'e73b743bfe8a6ff4e05b5657d3f7586a17ac3ba0' '6ef8e042cdcaabe3e3c68592ba8bfbaee2fa10a3' 'ecd0de438c1f0ee86cf8f6d5047965a2a181444b' 'f1dfbc1b5cf8650ae9a0d543e5f5335fc0f478ce' '8fdb030fe283c84fd8d378c97ad0f32d6cdec6ce' '20bcda681f8597e86070a4b3b12d1e4f541865d3' 'cf6bf51b53252284bafc7377a4d8dbf10f048b4d' '28039efa4d8e8bbf98b066133a906bd4e307d496' 'e062bdfdd6adbb2dee7751d054c1d8df63ddb8b8' 'f034c16a4663eaf3198dc18b201ba50533fb5b81' '66fecfa91deb536a12ddf3d878a99590d7900277' '4a5ac6cd05a7e54f1585d7779464d6ed6272c134' 'ef042df96d0e1089764f39ede61bc8f140a4be00' '4795375d8aa072e9aacb0b278e6203c6ca41816a' '4c33cef58965eb655a0ac8e243aa323581ec025f' 'e973dfe9259095fb509ab12658c68d46f0e439d7' 'e7434adf0c53a84d548226304cdb41c8818da1cb' 'd29479abaded34b2b1dab2e17efe96a65eba3d61' '77a58ba7c64ccca20616aa03599766ccb0d1a330' '01313661b248c5ba586acae09bff57077dbec0a5' 'c17fa4cbc546c431ccf13e9354d5d9c1cd247b7c' '310bf433c01f78e0756fd5056a43118a2f77318c' 'fd5ef3d69f8975bad16c437a337b5cb04c8217a2' 'd054cc3a2ccfb19484f3b54d69b6e416832dc8f4' '2528c15f314ece50218d1273654f630d74109583' '638bae3fb225a708dc67db613af62f6d14c4eff4' 'ecba655bf54a661ffe078856cd8dbc898270e4b5' '7e1906643a7374529af74b013bba35e4fa4e6ffc' 'd742ebcfe524dc54023f7c520d2ed2e4b7203c19' 'fce217449075d59b29052b8cdac567f0f3e22641' '6658472a3e2de08197acfe099ba71ee0e2505ecf' '0cc08c8130ac8f74419f99fe707dc193b7f79d86' '0743acf746a81e0460a56fd5ff847d97fa7eb370' 'd77daa49085b067137d0adbe3263f75a7ee13a1b' '1e570e77392f43a3cdab2849d1f81535f8a033e2' '15afe57a874eaf104bfbb61ec598fa31627f7b19' 'fb25114cd760c13cf177d9ac37837fafcc9657b5' '65efe5404d151767653c7b7dd39bd2e7ad532c2d' '6621b0f118d500092f5f3d72ddddb22aeeb3c3a0' '433e294c3c5b5d2020085a0e36c1cb47b694690a' '0b0eb7702a9fa410755e86124b4b7cd36e7d1cb4' '7e7e2c6e2a1cb250f8d03bb99eed01f6d982d5dd' '64d87ccfae3326a9561fe41dc6073064a083e0df' '4d410ba9aa275e7990a270f63ce436990ace1bea' 'b83fb1b14c06bdd765903ac852ba20a14e24f227' '9797329220a2c6622411eb9ecf6a35b24ce09d04' 'fe8cc44dd173cde5788ab4e3730ac61f3d316d9c' '6277a486a7faaa6c87f4bf1d59a2de233a093248' '5e537031f322d55315cd384398b726a9a0748d47' '4412ab501677606436e5c49e41151a1e6eac7ac0'
# test job: [118eb2cb97b8fc0d515bb0449495959247db58f0] https://lava.sirena.org.uk/scheduler/job/2092429
# test job: [059f545832be85d29ac9ccc416a16f647aa78485] https://lava.sirena.org.uk/scheduler/job/2086705
# test job: [6402ddf3027d8975f135cf2b2014d6bbeb2d3436] https://lava.sirena.org.uk/scheduler/job/2086607
# test job: [4e00135b2dd1d7924a58bffa551b6ceb3bd836f2] https://lava.sirena.org.uk/scheduler/job/2082519
# test job: [e65b871c9b5af9265aefc5b8cd34993586d93aab] https://lava.sirena.org.uk/scheduler/job/2083021
# test job: [8d63e85c5b50f1dbfa0ccb214bd91fe5d7e2e860] https://lava.sirena.org.uk/scheduler/job/2082629
# test job: [8ff3dcb0e8a8bf6c41f23ed4aa62d066d3948a10] https://lava.sirena.org.uk/scheduler/job/2083070
# test job: [123cd174a3782307787268adf45f22de4d290128] https://lava.sirena.org.uk/scheduler/job/2078932
# test job: [4d6e2211aeb932e096f673c88475016b1cc0f8ab] https://lava.sirena.org.uk/scheduler/job/2078021
# test job: [1d562ba0aa7df81335bf96c02be77efe8d5bab87] https://lava.sirena.org.uk/scheduler/job/2078357
# test job: [b3a5302484033331af37569f7277d00131694b57] https://lava.sirena.org.uk/scheduler/job/2074567
# test job: [873bc94689d832878befbcadc10b6ad5bb4e0027] https://lava.sirena.org.uk/scheduler/job/2074808
# test job: [32172cf3cb543a04c41a1677c97a38e60cad05b6] https://lava.sirena.org.uk/scheduler/job/2075068
# test job: [772ada50282b0c80343c8989147db816961f571d] https://lava.sirena.org.uk/scheduler/job/2069222
# test job: [6985defd1d832f1dd9d1977a6a2cc2cef7632704] https://lava.sirena.org.uk/scheduler/job/2059088
# test job: [fb1ebb10468da414d57153ddebaab29c38ef1a78] https://lava.sirena.org.uk/scheduler/job/2059751
# test job: [6951be397ca8b8b167c9f99b5a11c541148c38cb] https://lava.sirena.org.uk/scheduler/job/2055789
# test job: [4e92abd0a11b91af3742197a9ca962c3c00d0948] https://lava.sirena.org.uk/scheduler/job/2055834
# test job: [2089f086303b773e181567fd8d5df3038bd85937] https://lava.sirena.org.uk/scheduler/job/2058076
# test job: [abc9a349b87ac0fd3ba8787ca00971b59c2e1257] https://lava.sirena.org.uk/scheduler/job/2054550
# test job: [55d03b5b5bdd04daf9a35ce49db18d8bb488dffb] https://lava.sirena.org.uk/scheduler/job/2053870
# test job: [1b0f3f9ee41ee2bdd206667f85ea2aa36dfe6e69] https://lava.sirena.org.uk/scheduler/job/2053622
# test job: [6bd1ad97eb790570c167d4de4ca59fbc9c33722a] https://lava.sirena.org.uk/scheduler/job/2053461
# test job: [3c36965df80801344850388592e95033eceea05b] https://lava.sirena.org.uk/scheduler/job/2049487
# test job: [655079ac8a7721ac215a0596e3f33b740e01144a] https://lava.sirena.org.uk/scheduler/job/2049673
# test job: [2f538ef9f6f7c3d700c68536f21447dfc598f8c8] https://lava.sirena.org.uk/scheduler/job/2048609
# test job: [aa897ffc396b48cc39eee133b6b43175d0df9eb5] https://lava.sirena.org.uk/scheduler/job/2048708
# test job: [380fd29d57abe6679d87ec56babe65ddc5873a37] https://lava.sirena.org.uk/scheduler/job/2044538
# test job: [af9c8092d84244ca54ffb590435735f788e7a170] https://lava.sirena.org.uk/scheduler/job/2043755
# test job: [c4e68959af66df525d71db619ffe44af9178bb22] https://lava.sirena.org.uk/scheduler/job/2044079
# test job: [2ecc8c089802e033d2e5204d21a9f467e2517df9] https://lava.sirena.org.uk/scheduler/job/2038469
# test job: [84194c66aaf78fed150edb217b9f341518b1cba2] https://lava.sirena.org.uk/scheduler/job/2038350
# test job: [252abf2d07d33b1c70a59ba1c9395ba42bbd793e] https://lava.sirena.org.uk/scheduler/job/2038498
# test job: [ed5d499b5c9cc11dd3edae1a7a55db7dfa4f1bdc] https://lava.sirena.org.uk/scheduler/job/2028996
# test job: [e73b743bfe8a6ff4e05b5657d3f7586a17ac3ba0] https://lava.sirena.org.uk/scheduler/job/2026389
# test job: [6ef8e042cdcaabe3e3c68592ba8bfbaee2fa10a3] https://lava.sirena.org.uk/scheduler/job/2025846
# test job: [ecd0de438c1f0ee86cf8f6d5047965a2a181444b] https://lava.sirena.org.uk/scheduler/job/2026091
# test job: [f1dfbc1b5cf8650ae9a0d543e5f5335fc0f478ce] https://lava.sirena.org.uk/scheduler/job/2025507
# test job: [8fdb030fe283c84fd8d378c97ad0f32d6cdec6ce] https://lava.sirena.org.uk/scheduler/job/2021419
# test job: [20bcda681f8597e86070a4b3b12d1e4f541865d3] https://lava.sirena.org.uk/scheduler/job/2022919
# test job: [cf6bf51b53252284bafc7377a4d8dbf10f048b4d] https://lava.sirena.org.uk/scheduler/job/2022940
# test job: [28039efa4d8e8bbf98b066133a906bd4e307d496] https://lava.sirena.org.uk/scheduler/job/2020277
# test job: [e062bdfdd6adbb2dee7751d054c1d8df63ddb8b8] https://lava.sirena.org.uk/scheduler/job/2020136
# test job: [f034c16a4663eaf3198dc18b201ba50533fb5b81] https://lava.sirena.org.uk/scheduler/job/2015402
# test job: [66fecfa91deb536a12ddf3d878a99590d7900277] https://lava.sirena.org.uk/scheduler/job/2015319
# test job: [4a5ac6cd05a7e54f1585d7779464d6ed6272c134] https://lava.sirena.org.uk/scheduler/job/2011242
# test job: [ef042df96d0e1089764f39ede61bc8f140a4be00] https://lava.sirena.org.uk/scheduler/job/2010188
# test job: [4795375d8aa072e9aacb0b278e6203c6ca41816a] https://lava.sirena.org.uk/scheduler/job/2009710
# test job: [4c33cef58965eb655a0ac8e243aa323581ec025f] https://lava.sirena.org.uk/scheduler/job/2009389
# test job: [e973dfe9259095fb509ab12658c68d46f0e439d7] https://lava.sirena.org.uk/scheduler/job/2008156
# test job: [e7434adf0c53a84d548226304cdb41c8818da1cb] https://lava.sirena.org.uk/scheduler/job/2007781
# test job: [d29479abaded34b2b1dab2e17efe96a65eba3d61] https://lava.sirena.org.uk/scheduler/job/2008399
# test job: [77a58ba7c64ccca20616aa03599766ccb0d1a330] https://lava.sirena.org.uk/scheduler/job/2007312
# test job: [01313661b248c5ba586acae09bff57077dbec0a5] https://lava.sirena.org.uk/scheduler/job/2008756
# test job: [c17fa4cbc546c431ccf13e9354d5d9c1cd247b7c] https://lava.sirena.org.uk/scheduler/job/2000025
# test job: [310bf433c01f78e0756fd5056a43118a2f77318c] https://lava.sirena.org.uk/scheduler/job/1995997
# test job: [fd5ef3d69f8975bad16c437a337b5cb04c8217a2] https://lava.sirena.org.uk/scheduler/job/1996106
# test job: [d054cc3a2ccfb19484f3b54d69b6e416832dc8f4] https://lava.sirena.org.uk/scheduler/job/1995702
# test job: [2528c15f314ece50218d1273654f630d74109583] https://lava.sirena.org.uk/scheduler/job/1997627
# test job: [638bae3fb225a708dc67db613af62f6d14c4eff4] https://lava.sirena.org.uk/scheduler/job/1991837
# test job: [ecba655bf54a661ffe078856cd8dbc898270e4b5] https://lava.sirena.org.uk/scheduler/job/1985161
# test job: [7e1906643a7374529af74b013bba35e4fa4e6ffc] https://lava.sirena.org.uk/scheduler/job/1978626
# test job: [d742ebcfe524dc54023f7c520d2ed2e4b7203c19] https://lava.sirena.org.uk/scheduler/job/1975991
# test job: [fce217449075d59b29052b8cdac567f0f3e22641] https://lava.sirena.org.uk/scheduler/job/1975648
# test job: [6658472a3e2de08197acfe099ba71ee0e2505ecf] https://lava.sirena.org.uk/scheduler/job/1973468
# test job: [0cc08c8130ac8f74419f99fe707dc193b7f79d86] https://lava.sirena.org.uk/scheduler/job/1965716
# test job: [0743acf746a81e0460a56fd5ff847d97fa7eb370] https://lava.sirena.org.uk/scheduler/job/1964817
# test job: [d77daa49085b067137d0adbe3263f75a7ee13a1b] https://lava.sirena.org.uk/scheduler/job/1962810
# test job: [1e570e77392f43a3cdab2849d1f81535f8a033e2] https://lava.sirena.org.uk/scheduler/job/1962218
# test job: [15afe57a874eaf104bfbb61ec598fa31627f7b19] https://lava.sirena.org.uk/scheduler/job/1962933
# test job: [fb25114cd760c13cf177d9ac37837fafcc9657b5] https://lava.sirena.org.uk/scheduler/job/1960135
# test job: [65efe5404d151767653c7b7dd39bd2e7ad532c2d] https://lava.sirena.org.uk/scheduler/job/1959967
# test job: [6621b0f118d500092f5f3d72ddddb22aeeb3c3a0] https://lava.sirena.org.uk/scheduler/job/1959721
# test job: [433e294c3c5b5d2020085a0e36c1cb47b694690a] https://lava.sirena.org.uk/scheduler/job/1957324
# test job: [0b0eb7702a9fa410755e86124b4b7cd36e7d1cb4] https://lava.sirena.org.uk/scheduler/job/1957396
# test job: [7e7e2c6e2a1cb250f8d03bb99eed01f6d982d5dd] https://lava.sirena.org.uk/scheduler/job/1954253
# test job: [64d87ccfae3326a9561fe41dc6073064a083e0df] https://lava.sirena.org.uk/scheduler/job/1947205
# test job: [4d410ba9aa275e7990a270f63ce436990ace1bea] https://lava.sirena.org.uk/scheduler/job/1947743
# test job: [b83fb1b14c06bdd765903ac852ba20a14e24f227] https://lava.sirena.org.uk/scheduler/job/1946813
# test job: [9797329220a2c6622411eb9ecf6a35b24ce09d04] https://lava.sirena.org.uk/scheduler/job/1947377
# test job: [fe8cc44dd173cde5788ab4e3730ac61f3d316d9c] https://lava.sirena.org.uk/scheduler/job/1946013
# test job: [6277a486a7faaa6c87f4bf1d59a2de233a093248] https://lava.sirena.org.uk/scheduler/job/1947015
# test job: [5e537031f322d55315cd384398b726a9a0748d47] https://lava.sirena.org.uk/scheduler/job/1946667
# test job: [4412ab501677606436e5c49e41151a1e6eac7ac0] https://lava.sirena.org.uk/scheduler/job/1946327
# test job: [187dac290bfd0741b9d7d5490af825c33fd9baa4] https://lava.sirena.org.uk/scheduler/job/2101535
# bad: [187dac290bfd0741b9d7d5490af825c33fd9baa4] Add linux-next specific files for 20251118
git bisect bad 187dac290bfd0741b9d7d5490af825c33fd9baa4
# test job: [abb54b0b86a61f10649f9ef3f6ab6821ae6abe74] https://lava.sirena.org.uk/scheduler/job/2101660
# good: [abb54b0b86a61f10649f9ef3f6ab6821ae6abe74] Merge branch 'master' of https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git
git bisect good abb54b0b86a61f10649f9ef3f6ab6821ae6abe74
# test job: [ad048b22af91649db0797904f7452bbd082c4f72] https://lava.sirena.org.uk/scheduler/job/2101860
# good: [ad048b22af91649db0797904f7452bbd082c4f72] Merge branch 'for-backlight-next' of https://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight.git
git bisect good ad048b22af91649db0797904f7452bbd082c4f72
# test job: [2eb38aa81687e8bde227a4be8bc16aaea024b41a] https://lava.sirena.org.uk/scheduler/job/2102056
# good: [2eb38aa81687e8bde227a4be8bc16aaea024b41a] Merge branch 'driver-core-next' of https://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git
git bisect good 2eb38aa81687e8bde227a4be8bc16aaea024b41a
# test job: [276498a96b70a88fc8c42d9104edd0d79c1bf6a8] https://lava.sirena.org.uk/scheduler/job/2102243
# good: [276498a96b70a88fc8c42d9104edd0d79c1bf6a8] Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
git bisect good 276498a96b70a88fc8c42d9104edd0d79c1bf6a8
# test job: [36ebc989a5812e1de53b78054cb8a2f07b048d2b] https://lava.sirena.org.uk/scheduler/job/2102380
# bad: [36ebc989a5812e1de53b78054cb8a2f07b048d2b] Merge branch 'ntb-next' of https://github.com/jonmason/ntb.git
git bisect bad 36ebc989a5812e1de53b78054cb8a2f07b048d2b
# test job: [5bcc5021b9db0a2f07a041671c3c4a70889d813b] https://lava.sirena.org.uk/scheduler/job/2102409
# bad: [5bcc5021b9db0a2f07a041671c3c4a70889d813b] Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git
git bisect bad 5bcc5021b9db0a2f07a041671c3c4a70889d813b
# test job: [8e9536f35f91235a023bb97d1aa2ce34f702bcfa] https://lava.sirena.org.uk/scheduler/job/2102420
# bad: [8e9536f35f91235a023bb97d1aa2ce34f702bcfa] Merge branch 'gpio/for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git
git bisect bad 8e9536f35f91235a023bb97d1aa2ce34f702bcfa
# test job: [82e71fe4368699341333e7e0d059ef7df139cf95] https://lava.sirena.org.uk/scheduler/job/2102438
# bad: [82e71fe4368699341333e7e0d059ef7df139cf95] Merge tag 'gpio/shared-gpios-for-v6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git into gpio/for-next
git bisect bad 82e71fe4368699341333e7e0d059ef7df139cf95
# test job: [0efa5b2ca6fa7baab4c523b34cfb9495ec143d61] https://lava.sirena.org.uk/scheduler/job/2102456
# good: [0efa5b2ca6fa7baab4c523b34cfb9495ec143d61] gpio: aspeed: remove unneeded include
git bisect good 0efa5b2ca6fa7baab4c523b34cfb9495ec143d61
# test job: [7e061b462b3d43a1f85519f5aebdc77cbbe648c0] https://lava.sirena.org.uk/scheduler/job/2102591
# good: [7e061b462b3d43a1f85519f5aebdc77cbbe648c0] gpio: mmio: use lock guards
git bisect good 7e061b462b3d43a1f85519f5aebdc77cbbe648c0
# test job: [1e4f6db614a310cc34d07ffbf031c76ea9581bcf] https://lava.sirena.org.uk/scheduler/job/2102712
# good: [1e4f6db614a310cc34d07ffbf031c76ea9581bcf] gpiolib: support shared GPIOs in core subsystem code
git bisect good 1e4f6db614a310cc34d07ffbf031c76ea9581bcf
# test job: [b6d31cd41814a33c1a22b8c676131820440cc44e] https://lava.sirena.org.uk/scheduler/job/2102848
# good: [b6d31cd41814a33c1a22b8c676131820440cc44e] gpio: cdev: replace use of system_wq with system_percpu_wq
git bisect good b6d31cd41814a33c1a22b8c676131820440cc44e
# test job: [e511d484cbe44fe48a1b9f621f6a947c72503f9e] https://lava.sirena.org.uk/scheduler/job/2103002
# bad: [e511d484cbe44fe48a1b9f621f6a947c72503f9e] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM
git bisect bad e511d484cbe44fe48a1b9f621f6a947c72503f9e
# test job: [eb374f764a7012eda28019266a6d9191670c4fa5] https://lava.sirena.org.uk/scheduler/job/2103014
# good: [eb374f764a7012eda28019266a6d9191670c4fa5] gpio: provide gpiod_is_shared()
git bisect good eb374f764a7012eda28019266a6d9191670c4fa5
# first bad commit: [e511d484cbe44fe48a1b9f621f6a947c72503f9e] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 07/10] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM
  2025-11-18 14:06   ` Mark Brown
@ 2025-11-18 14:13     ` Bartosz Golaszewski
  2025-11-18 14:20       ` Mark Brown
  0 siblings, 1 reply; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-18 14:13 UTC (permalink / raw)
  To: Mark Brown
  Cc: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Alexey Klimov, Bjorn Andersson, Konrad Dybcio, linux-hardening,
	linux-kernel, linux-gpio, linux-arm-kernel, linux-sound,
	linux-arm-msm, Bartosz Golaszewski, Aishwarya.TCV

On Tue, Nov 18, 2025 at 3:06 PM Mark Brown <broonie@kernel.org> wrote:
>
> On Wed, Nov 12, 2025 at 02:55:36PM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> >
> > Some qualcomm platforms use shared GPIOs. Enable support for them by
> > selecting the Kconfig switch provided by GPIOLIB.
>
> This is causing boot failures for me in -next on the ARM FVP with
> defconfig, the select affects all platforms not just the Qualcomm ones.
> We get:
>
> [    0.137360] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000058
>
> ...
>
> [    0.140979] Call trace:
> [    0.141037]  gpio_shared_of_traverse+0x48/0x480 (P)
> [    0.141187]  gpio_shared_init+0x28/0x14c
> [    0.141314]  do_one_initcall+0x60/0x1d4
> [    0.141446]  kernel_init_freeable+0x24c/0x2c8
> [    0.141607]  kernel_init+0x20/0x140
>
> Full log:
>
>    https://lava.sirena.org.uk/scheduler/job/2101484#L692
>

Hi Mark!

Thanks for the heads-up. I'll try to fix it ASAP to avoid a revert.

I can't open the link:

500 Internal Server Error

FATAL: remaining connection slots are reserved for non-replication
superuser connections

Oops, something has gone wrong!

Any chance you could get the offending line out of this stack trace?

Bartosz

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 07/10] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM
  2025-11-18 14:13     ` Bartosz Golaszewski
@ 2025-11-18 14:20       ` Mark Brown
  2025-11-18 14:27         ` Bartosz Golaszewski
  0 siblings, 1 reply; 35+ messages in thread
From: Mark Brown @ 2025-11-18 14:20 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Alexey Klimov, Bjorn Andersson, Konrad Dybcio, linux-hardening,
	linux-kernel, linux-gpio, linux-arm-kernel, linux-sound,
	linux-arm-msm, Bartosz Golaszewski, Aishwarya.TCV

[-- Attachment #1: Type: text/plain, Size: 617 bytes --]

On Tue, Nov 18, 2025 at 03:13:49PM +0100, Bartosz Golaszewski wrote:

> Thanks for the heads-up. I'll try to fix it ASAP to avoid a revert.

> I can't open the link:

> 500 Internal Server Error

> FATAL: remaining connection slots are reserved for non-replication
> superuser connections

> Oops, something has gone wrong!

Retry, it's AI scrapers so those 500 responses are just glitches.

> Any chance you could get the offending line out of this stack trace?

   https://builds.sirena.org.uk/187dac290bfd0741b9d7d5490af825c33fd9baa4/arm64/defconfig/vmlinux.xz

/build/stage/linux/drivers/gpio/gpiolib-shared.c:87

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 07/10] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM
  2025-11-18 14:20       ` Mark Brown
@ 2025-11-18 14:27         ` Bartosz Golaszewski
  2025-11-18 19:46           ` Mark Brown
  0 siblings, 1 reply; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-18 14:27 UTC (permalink / raw)
  To: Mark Brown
  Cc: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Alexey Klimov, Bjorn Andersson, Konrad Dybcio, linux-hardening,
	linux-kernel, linux-gpio, linux-arm-kernel, linux-sound,
	linux-arm-msm, Bartosz Golaszewski, Aishwarya.TCV,
	Bartosz Golaszewski

On Tue, 18 Nov 2025 15:20:47 +0100, Mark Brown <broonie@kernel.org> said:
> On Tue, Nov 18, 2025 at 03:13:49PM +0100, Bartosz Golaszewski wrote:
>
>> Thanks for the heads-up. I'll try to fix it ASAP to avoid a revert.
>
>> I can't open the link:
>
>> 500 Internal Server Error
>
>> FATAL: remaining connection slots are reserved for non-replication
>> superuser connections
>
>> Oops, something has gone wrong!
>
> Retry, it's AI scrapers so those 500 responses are just glitches.
>
>> Any chance you could get the offending line out of this stack trace?
>
>    https://builds.sirena.org.uk/187dac290bfd0741b9d7d5490af825c33fd9baa4/arm64/defconfig/vmlinux.xz
>
> /build/stage/linux/drivers/gpio/gpiolib-shared.c:87
>

Oh, of_root may be NULL...

Could you try the following change please?

diff --git a/drivers/gpio/gpiolib-shared.c b/drivers/gpio/gpiolib-shared.c
index c22eaf05eef23..4ce574a21850b 100644
--- a/drivers/gpio/gpiolib-shared.c
+++ b/drivers/gpio/gpiolib-shared.c
@@ -205,7 +205,10 @@ static int gpio_shared_of_traverse(struct
device_node *curr)

 static int gpio_shared_of_scan(void)
 {
-	return gpio_shared_of_traverse(of_root);
+	if (of_root)
+		return gpio_shared_of_traverse(of_root);
+
+	return 0;
 }
 #else
 static int gpio_shared_of_scan(void)

Bart

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 07/10] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM
  2025-11-18 14:27         ` Bartosz Golaszewski
@ 2025-11-18 19:46           ` Mark Brown
  0 siblings, 0 replies; 35+ messages in thread
From: Mark Brown @ 2025-11-18 19:46 UTC (permalink / raw)
  To: Bartosz Golaszewski
  Cc: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Alexey Klimov, Bjorn Andersson, Konrad Dybcio, linux-hardening,
	linux-kernel, linux-gpio, linux-arm-kernel, linux-sound,
	linux-arm-msm, Bartosz Golaszewski, Aishwarya.TCV

[-- Attachment #1: Type: text/plain, Size: 291 bytes --]

On Tue, Nov 18, 2025 at 06:27:23AM -0800, Bartosz Golaszewski wrote:

> Oh, of_root may be NULL...
> 
> Could you try the following change please?

That seems to work on FVP, I've also seen the same failure on other
platforms including Orion O6 and Graviton 3 but didn't test there.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 00/10] gpio: improve support for shared GPIOs
  2025-11-18 11:15 ` Geert Uytterhoeven
  2025-11-18 11:55   ` Bartosz Golaszewski
@ 2025-11-18 23:23   ` Linus Walleij
  2025-11-19  8:01     ` Andy Shevchenko
  2025-11-19  8:33     ` Geert Uytterhoeven
  1 sibling, 2 replies; 35+ messages in thread
From: Linus Walleij @ 2025-11-18 23:23 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Bartosz Golaszewski, Kees Cook, Mika Westerberg, Dmitry Torokhov,
	Andrew Morton, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski, Linux-Renesas

On Tue, Nov 18, 2025 at 12:15 PM Geert Uytterhoeven
<geert@linux-m68k.org> wrote:

> We have a long-standing use-case on various Renesas R-Car Gen3 boards
> (e.g. Salvator-X(S) and ULCB[1]), where GPIOs are shared by LEDs and
> key switches.  Basically, the GPIO is connected to:
>   1. A key switch connecting to GND when closed, with pull-up.
>   2. The gate of an N-channel MOSFET, turning on an LED when driven
>      high.
>
> Hence:
>   - In output mode, the LED can be controlled freely,
>   - In input mode, the LED is on, unless the key is pressed,
>   - Hence the switch state can only be read when the LED is turned on.

Fantastic solution to a lack of GPIO lines.

This reminds me of the Amiga 500 power LED which was connected
to a GPIO which was cleverly also reused to control the audio filter,
with the effect that when you turned off the audio filter the power LED
went out and music toggling the filter off/on for effects would also
give you an incidental stroboscope.

> If you have any idea how to handle this, feel free to reply ;-)

Isn't it pretty clear from the system-level DTS how the line
is used?

If it is connected to a gpio key it gets assigned for that usecase
and handled by that driver and if it is connected to a gpio LED
it is handled by that driver.

For the input usecase the status of the LED is a byproduct and
should not reflect in software I think. It surely should not be
controllable and possible to set into output mode because
that sounds like a recipe for HW damage if you drive it
actively high and press the key at the same time.

gpio_keys {
    compatible = "gpio-keys";

    button-ok {
        gpios = <&gpio 0 GPIO_OPEN_DRAIN | GPIO_PULL_UP>;
    };
};

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 00/10] gpio: improve support for shared GPIOs
  2025-11-18 23:23   ` Linus Walleij
@ 2025-11-19  8:01     ` Andy Shevchenko
  2025-11-19  8:33     ` Geert Uytterhoeven
  1 sibling, 0 replies; 35+ messages in thread
From: Andy Shevchenko @ 2025-11-19  8:01 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Geert Uytterhoeven, Bartosz Golaszewski, Kees Cook,
	Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, Greg Kroah-Hartman,
	Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski, Linux-Renesas

On Wed, Nov 19, 2025 at 1:24 AM Linus Walleij <linus.walleij@linaro.org> wrote:
> On Tue, Nov 18, 2025 at 12:15 PM Geert Uytterhoeven
> <geert@linux-m68k.org> wrote:

...

> > We have a long-standing use-case on various Renesas R-Car Gen3 boards
> > (e.g. Salvator-X(S) and ULCB[1]), where GPIOs are shared by LEDs and
> > key switches.  Basically, the GPIO is connected to:
> >   1. A key switch connecting to GND when closed, with pull-up.
> >   2. The gate of an N-channel MOSFET, turning on an LED when driven
> >      high.
> >
> > Hence:
> >   - In output mode, the LED can be controlled freely,
> >   - In input mode, the LED is on, unless the key is pressed,
> >   - Hence the switch state can only be read when the LED is turned on.
>
> Fantastic solution to a lack of GPIO lines.

I feel a poster "SARCASM" behind this line :-)
That's what happened when old-school (in a bad term) HW engineers who
try to enforce their experience on the modern SoC-based platforms that
run GP OSes in multi-tasking, multi-user manner.

> This reminds me of the Amiga 500 power LED which was connected
> to a GPIO which was cleverly also reused to control the audio filter,
> with the effect that when you turned off the audio filter the power LED
> went out and music toggling the filter off/on for effects would also
> give you an incidental stroboscope.
>
> > If you have any idea how to handle this, feel free to reply ;-)
>
> Isn't it pretty clear from the system-level DTS how the line
> is used?
>
> If it is connected to a gpio key it gets assigned for that usecase
> and handled by that driver and if it is connected to a gpio LED
> it is handled by that driver.
>
> For the input usecase the status of the LED is a byproduct and
> should not reflect in software I think. It surely should not be
> controllable and possible to set into output mode because
> that sounds like a recipe for HW damage if you drive it
> actively high and press the key at the same time.
>
> gpio_keys {
>     compatible = "gpio-keys";
>
>     button-ok {
>         gpios = <&gpio 0 GPIO_OPEN_DRAIN | GPIO_PULL_UP>;
>     };
> };

This is my understanding as well.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 00/10] gpio: improve support for shared GPIOs
  2025-11-18 23:23   ` Linus Walleij
  2025-11-19  8:01     ` Andy Shevchenko
@ 2025-11-19  8:33     ` Geert Uytterhoeven
  2025-11-19 14:29       ` Linus Walleij
  1 sibling, 1 reply; 35+ messages in thread
From: Geert Uytterhoeven @ 2025-11-19  8:33 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Bartosz Golaszewski, Kees Cook, Mika Westerberg, Dmitry Torokhov,
	Andrew Morton, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski, Linux-Renesas

Hi Linus,

On Wed, 19 Nov 2025 at 00:24, Linus Walleij <linus.walleij@linaro.org> wrote:
> On Tue, Nov 18, 2025 at 12:15 PM Geert Uytterhoeven
> <geert@linux-m68k.org> wrote:
> > We have a long-standing use-case on various Renesas R-Car Gen3 boards
> > (e.g. Salvator-X(S) and ULCB[1]), where GPIOs are shared by LEDs and
> > key switches.  Basically, the GPIO is connected to:
> >   1. A key switch connecting to GND when closed, with pull-up.
> >   2. The gate of an N-channel MOSFET, turning on an LED when driven
> >      high.
> >
> > Hence:
> >   - In output mode, the LED can be controlled freely,
> >   - In input mode, the LED is on, unless the key is pressed,
> >   - Hence the switch state can only be read when the LED is turned on.
>
> > If you have any idea how to handle this, feel free to reply ;-)
>
> Isn't it pretty clear from the system-level DTS how the line
> is used?
>
> If it is connected to a gpio key it gets assigned for that usecase
> and handled by that driver and if it is connected to a gpio LED
> it is handled by that driver.
>
> For the input usecase the status of the LED is a byproduct and
> should not reflect in software I think. It surely should not be
> controllable and possible to set into output mode because
> that sounds like a recipe for HW damage if you drive it
> actively high and press the key at the same time.

Suitable resistors are present to prevent hardware damage.

> gpio_keys {
>     compatible = "gpio-keys";
>
>     button-ok {
>         gpios = <&gpio 0 GPIO_OPEN_DRAIN | GPIO_PULL_UP>;
>     };
> };

But only one of the gpio-keys and gpio-leds drivers can bind to the
GPIO, or am I missing something?
So I do think I need a new combined key-and-led driver, like Bartosz
suggested:
  - When the user turns the LED on, the GPIO is switched to input mode,
    and the switch works,
  - When the user turns the LED off, the GPIO is switched to output
    and driven low, and the switch does not work.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 00/10] gpio: improve support for shared GPIOs
  2025-11-19  8:33     ` Geert Uytterhoeven
@ 2025-11-19 14:29       ` Linus Walleij
  0 siblings, 0 replies; 35+ messages in thread
From: Linus Walleij @ 2025-11-19 14:29 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Bartosz Golaszewski, Kees Cook, Mika Westerberg, Dmitry Torokhov,
	Andrew Morton, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski, Linux-Renesas

On Wed, Nov 19, 2025 at 9:38 AM Geert Uytterhoeven <geert@linux-m68k.org> wrote:

> > For the input usecase the status of the LED is a byproduct and
> > should not reflect in software I think. It surely should not be
> > controllable and possible to set into output mode because
> > that sounds like a recipe for HW damage if you drive it
> > actively high and press the key at the same time.
>
> Suitable resistors are present to prevent hardware damage.

Aha, clever.

> > gpio_keys {
> >     compatible = "gpio-keys";
> >
> >     button-ok {
> >         gpios = <&gpio 0 GPIO_OPEN_DRAIN | GPIO_PULL_UP>;
> >     };
> > };
>
> But only one of the gpio-keys and gpio-leds drivers can bind to the
> GPIO, or am I missing something?
> So I do think I need a new combined key-and-led driver, like Bartosz
> suggested:
>   - When the user turns the LED on, the GPIO is switched to input mode,
>     and the switch works,
>   - When the user turns the LED off, the GPIO is switched to output
>     and driven low, and the switch does not work.

You will also have the byproduct that the LED being "on" in software
does not necessarily reflect the actual LED status, someone
may be pressing the key and then the LED is off even though
in sysfs it is clearly "on".

So the status in the LED classdevice also has to be forced to "off"
(brightness 0) anytime the input subsystem detects that the switch
is pressed.

It's going to be a lot of work I think, but I guess it can be done,
with a lot of special-casing and custom APIs.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: (subset) [PATCH v4 00/10] gpio: improve support for shared GPIOs
  2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
                   ` (11 preceding siblings ...)
  2025-11-18 11:15 ` Geert Uytterhoeven
@ 2025-11-20 10:39 ` Mark Brown
  2025-11-20 13:36 ` Mark Brown
  2025-11-21  0:27 ` Val Packett
  14 siblings, 0 replies; 35+ messages in thread
From: Mark Brown @ 2025-11-20 10:39 UTC (permalink / raw)
  To: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	Bartosz Golaszewski
  Cc: linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

On Wed, 12 Nov 2025 14:55:29 +0100, Bartosz Golaszewski wrote:
> Bjorn, Konrad: I should have Cc'ed you on v1 but I just went with what
> came out of b4 --auto-to-cc. It only gave me arm-msm. :( Patch 7 from
> this series however impacts Qualcomm platforms. It's a runtime dependency
> of patches 8 and 9. Would you mind Acking it so that I can take it into
> an immutable branch that I'll make available to Mark Brown for him to
> take patches 8-10 through the ASoC and regulator trees for v6.19?
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next

Thanks!

[10/10] regulator: make the subsystem aware of shared GPIOs
        commit: b871d9adffe5a64a1fd9edcb1aebbcc995b17901

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: (subset) [PATCH v4 00/10] gpio: improve support for shared GPIOs
  2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
                   ` (12 preceding siblings ...)
  2025-11-20 10:39 ` (subset) " Mark Brown
@ 2025-11-20 13:36 ` Mark Brown
  2025-11-21  0:27 ` Val Packett
  14 siblings, 0 replies; 35+ messages in thread
From: Mark Brown @ 2025-11-20 13:36 UTC (permalink / raw)
  To: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	Bartosz Golaszewski
  Cc: linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

On Wed, 12 Nov 2025 14:55:29 +0100, Bartosz Golaszewski wrote:
> Bjorn, Konrad: I should have Cc'ed you on v1 but I just went with what
> came out of b4 --auto-to-cc. It only gave me arm-msm. :( Patch 7 from
> this series however impacts Qualcomm platforms. It's a runtime dependency
> of patches 8 and 9. Would you mind Acking it so that I can take it into
> an immutable branch that I'll make available to Mark Brown for him to
> take patches 8-10 through the ASoC and regulator trees for v6.19?
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[08/10] ASoC: wsa881x: drop GPIOD_FLAGS_BIT_NONEXCLUSIVE flag from GPIO lookup
        commit: d01fbee5c0d3d3061fb16235b71f5a117128e2c1
[09/10] ASoC: wsa883x: drop GPIOD_FLAGS_BIT_NONEXCLUSIVE flag from GPIO lookup
        commit: 7a0a87712120329c034b0aae88bdaa05bd046f10

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 00/10] gpio: improve support for shared GPIOs
  2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
                   ` (13 preceding siblings ...)
  2025-11-20 13:36 ` Mark Brown
@ 2025-11-21  0:27 ` Val Packett
  2025-11-21  9:03   ` Bartosz Golaszewski
  14 siblings, 1 reply; 35+ messages in thread
From: Val Packett @ 2025-11-21  0:27 UTC (permalink / raw)
  To: Bartosz Golaszewski, Kees Cook, Mika Westerberg, Dmitry Torokhov,
	Andrew Morton, Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio
  Cc: linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

Hi,

On 11/12/25 10:55 AM, Bartosz Golaszewski wrote:
> ---
> Bartosz Golaszewski (10):
>        string: provide strends()
>        gpiolib: define GPIOD_FLAG_SHARED
>        gpiolib: implement low-level, shared GPIO support
>        gpio: shared-proxy: implement the shared GPIO proxy driver
>        gpiolib: support shared GPIOs in core subsystem code
>        gpio: provide gpiod_is_shared()
>        arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM
>        ASoC: wsa881x: drop GPIOD_FLAGS_BIT_NONEXCLUSIVE flag from GPIO lookup
>        ASoC: wsa883x: drop GPIOD_FLAGS_BIT_NONEXCLUSIVE flag from GPIO lookup
>        regulator: make the subsystem aware of shared GPIOs

this seems to actually have caused a regression for me, audio does not 
initialize anymore on hamoa due to EBUSY since upgrading 
from next-20251114 to next-20251118 or next-20251120:

[   11.748781] platform 
6800000.remoteproc:glink-edge:gpr:service@1:dais: Adding to iommu group 30
[   11.785864] wsa_macro 6aa0000.codec: using zero-initialized flat 
cache, this may cause unexpected behavior
[   11.796964] reset-gpio reset-gpio.0: error -EBUSY: Could not get 
reset gpios
[   11.796984] reset-gpio reset-gpio.0: probe with driver reset-gpio 
failed with error -16
[   11.894662] reset-gpio reset-gpio.1: error -EBUSY: Could not get 
reset gpios
[   11.894676] reset-gpio reset-gpio.1: probe with driver reset-gpio 
failed with error -16
[   12.006938] wcd938x_codec audio-codec: bound sdw:2:0:0217:010d:00:4 
(ops wcd_sdw_component_ops [snd_soc_wcd_common])
[   12.006964] wcd938x_codec audio-codec: bound sdw:3:0:0217:010d:00:3 
(ops wcd_sdw_component_ops [snd_soc_wcd_common])
[   15.424657] qcom-soundwire 6ab0000.soundwire: qcom_swrm_irq_handler: 
SWR CMD error, fifo status 0x4e00c00f, flushing fifo
[   21.994354] qcom-soundwire 6ab0000.soundwire: qcom_swrm_irq_handler: 
SWR CMD error, fifo status 0xe00c000, flushing fifo
[   21.996001] qcom-soundwire 6b10000.soundwire: qcom_swrm_irq_handler: 
SWR CMD error, fifo status 0x4e00c00f, flushing fifo
[   21.996239] platform sound: deferred probe pending: snd-x1e80100: WSA 
Playback: codec dai not found
[   21.996248] soundwire sdw:4:0:0217:0204:00:0: deferred probe pending: 
wsa884x-codec: Failed to get reset
[   21.996250] soundwire sdw:4:0:0217:0204:00:1: deferred probe pending: 
wsa884x-codec: Failed to get reset
[   21.996251] soundwire sdw:1:0:0217:0204:00:0: deferred probe pending: 
wsa884x-codec: Failed to get reset
[   21.996253] soundwire sdw:1:0:0217:0204:00:1: deferred probe pending: 
wsa884x-codec: Failed to get reset

gpio_shared_proxy, reset_gpio, pinctrl_sm8550_lpass_lpi are all built as 
modules and were autoloaded fine.

This is wsa884x (not wsa881x nor wsa883x), failing in 
devm_reset_control_get_optional_shared..


Thanks,
~val


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 00/10] gpio: improve support for shared GPIOs
  2025-11-21  0:27 ` Val Packett
@ 2025-11-21  9:03   ` Bartosz Golaszewski
  2025-11-21 10:20     ` Krzysztof Kozlowski
  0 siblings, 1 reply; 35+ messages in thread
From: Bartosz Golaszewski @ 2025-11-21  9:03 UTC (permalink / raw)
  To: Val Packett
  Cc: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

On Fri, Nov 21, 2025 at 1:28 AM Val Packett <val@packett.cool> wrote:
>
> Hi,
>
> On 11/12/25 10:55 AM, Bartosz Golaszewski wrote:
> > ---
> > Bartosz Golaszewski (10):
> >        string: provide strends()
> >        gpiolib: define GPIOD_FLAG_SHARED
> >        gpiolib: implement low-level, shared GPIO support
> >        gpio: shared-proxy: implement the shared GPIO proxy driver
> >        gpiolib: support shared GPIOs in core subsystem code
> >        gpio: provide gpiod_is_shared()
> >        arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM
> >        ASoC: wsa881x: drop GPIOD_FLAGS_BIT_NONEXCLUSIVE flag from GPIO lookup
> >        ASoC: wsa883x: drop GPIOD_FLAGS_BIT_NONEXCLUSIVE flag from GPIO lookup
> >        regulator: make the subsystem aware of shared GPIOs
>
> this seems to actually have caused a regression for me, audio does not
> initialize anymore on hamoa due to EBUSY since upgrading
> from next-20251114 to next-20251118 or next-20251120:
>

Thanks for the heads-up.

> [   11.748781] platform
> 6800000.remoteproc:glink-edge:gpr:service@1:dais: Adding to iommu group 30
> [   11.785864] wsa_macro 6aa0000.codec: using zero-initialized flat
> cache, this may cause unexpected behavior
> [   11.796964] reset-gpio reset-gpio.0: error -EBUSY: Could not get
> reset gpios
> [   11.796984] reset-gpio reset-gpio.0: probe with driver reset-gpio
> failed with error -16
> [   11.894662] reset-gpio reset-gpio.1: error -EBUSY: Could not get
> reset gpios
> [   11.894676] reset-gpio reset-gpio.1: probe with driver reset-gpio
> failed with error -16

It seems like it's the reset-gpio driver, not shared GPIOLIB path?
This driver has never used the GPIOD_FLAGS_BIT_NONEXCLUSIVE flag.

> [   12.006938] wcd938x_codec audio-codec: bound sdw:2:0:0217:010d:00:4
> (ops wcd_sdw_component_ops [snd_soc_wcd_common])
> [   12.006964] wcd938x_codec audio-codec: bound sdw:3:0:0217:010d:00:3
> (ops wcd_sdw_component_ops [snd_soc_wcd_common])
> [   15.424657] qcom-soundwire 6ab0000.soundwire: qcom_swrm_irq_handler:
> SWR CMD error, fifo status 0x4e00c00f, flushing fifo
> [   21.994354] qcom-soundwire 6ab0000.soundwire: qcom_swrm_irq_handler:
> SWR CMD error, fifo status 0xe00c000, flushing fifo
> [   21.996001] qcom-soundwire 6b10000.soundwire: qcom_swrm_irq_handler:
> SWR CMD error, fifo status 0x4e00c00f, flushing fifo
> [   21.996239] platform sound: deferred probe pending: snd-x1e80100: WSA
> Playback: codec dai not found
> [   21.996248] soundwire sdw:4:0:0217:0204:00:0: deferred probe pending:
> wsa884x-codec: Failed to get reset
> [   21.996250] soundwire sdw:4:0:0217:0204:00:1: deferred probe pending:
> wsa884x-codec: Failed to get reset
> [   21.996251] soundwire sdw:1:0:0217:0204:00:0: deferred probe pending:
> wsa884x-codec: Failed to get reset
> [   21.996253] soundwire sdw:1:0:0217:0204:00:1: deferred probe pending:
> wsa884x-codec: Failed to get reset
>
> gpio_shared_proxy, reset_gpio, pinctrl_sm8550_lpass_lpi are all built as
> modules and were autoloaded fine.
>
> This is wsa884x (not wsa881x nor wsa883x), failing in
> devm_reset_control_get_optional_shared..
>

Can you enable DEBUG_GPIO in menuconfig and post the entire kernel log
somewhere as well as the output of gpiodetect and gpioinfo after
booting?

Bartosz

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 00/10] gpio: improve support for shared GPIOs
  2025-11-21  9:03   ` Bartosz Golaszewski
@ 2025-11-21 10:20     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 35+ messages in thread
From: Krzysztof Kozlowski @ 2025-11-21 10:20 UTC (permalink / raw)
  To: Bartosz Golaszewski, Val Packett
  Cc: Kees Cook, Mika Westerberg, Dmitry Torokhov, Andrew Morton,
	Linus Walleij, Manivannan Sadhasivam, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Saravana Kannan,
	Greg Kroah-Hartman, Andy Shevchenko, Catalin Marinas, Will Deacon,
	Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Alexey Klimov, Bjorn Andersson, Konrad Dybcio,
	linux-hardening, linux-kernel, linux-gpio, linux-arm-kernel,
	linux-sound, linux-arm-msm, Bartosz Golaszewski

On 21/11/2025 10:03, Bartosz Golaszewski wrote:
> On Fri, Nov 21, 2025 at 1:28 AM Val Packett <val@packett.cool> wrote:
>>
>> Hi,
>>
>> On 11/12/25 10:55 AM, Bartosz Golaszewski wrote:
>>> ---
>>> Bartosz Golaszewski (10):
>>>        string: provide strends()
>>>        gpiolib: define GPIOD_FLAG_SHARED
>>>        gpiolib: implement low-level, shared GPIO support
>>>        gpio: shared-proxy: implement the shared GPIO proxy driver
>>>        gpiolib: support shared GPIOs in core subsystem code
>>>        gpio: provide gpiod_is_shared()
>>>        arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM
>>>        ASoC: wsa881x: drop GPIOD_FLAGS_BIT_NONEXCLUSIVE flag from GPIO lookup
>>>        ASoC: wsa883x: drop GPIOD_FLAGS_BIT_NONEXCLUSIVE flag from GPIO lookup
>>>        regulator: make the subsystem aware of shared GPIOs
>>
>> this seems to actually have caused a regression for me, audio does not
>> initialize anymore on hamoa due to EBUSY since upgrading
>> from next-20251114 to next-20251118 or next-20251120:
>>
> 
> Thanks for the heads-up.
> 
>> [   11.748781] platform
>> 6800000.remoteproc:glink-edge:gpr:service@1:dais: Adding to iommu group 30
>> [   11.785864] wsa_macro 6aa0000.codec: using zero-initialized flat
>> cache, this may cause unexpected behavior
>> [   11.796964] reset-gpio reset-gpio.0: error -EBUSY: Could not get
>> reset gpios
>> [   11.796984] reset-gpio reset-gpio.0: probe with driver reset-gpio
>> failed with error -16
>> [   11.894662] reset-gpio reset-gpio.1: error -EBUSY: Could not get
>> reset gpios
>> [   11.894676] reset-gpio reset-gpio.1: probe with driver reset-gpio
>> failed with error -16
> 
> It seems like it's the reset-gpio driver, not shared GPIOLIB path?
> This driver has never used the GPIOD_FLAGS_BIT_NONEXCLUSIVE flag.

NONEXCLUSIVE does not matter here. I think this is just broken code -
your patch 3 goes through allnodes for_each_property_of_node() and then
assumes it is shared GPIO, so probably this nicely breaks existing DTS
and reset-gpio. Well, it is not a shared GPIO, so all your assumptions
here are just wrong.

reset-gpio is already used on multiple Qualcomm and other SoC  platforms.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2025-11-21 10:20 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-12 13:55 [PATCH v4 00/10] gpio: improve support for shared GPIOs Bartosz Golaszewski
2025-11-12 13:55 ` [PATCH v4 01/10] string: provide strends() Bartosz Golaszewski
2025-11-17 20:33   ` Kees Cook
2025-11-18  9:47     ` Bartosz Golaszewski
2025-11-18 10:13       ` Andy Shevchenko
2025-11-12 13:55 ` [PATCH v4 02/10] gpiolib: define GPIOD_FLAG_SHARED Bartosz Golaszewski
2025-11-12 13:55 ` [PATCH v4 03/10] gpiolib: implement low-level, shared GPIO support Bartosz Golaszewski
2025-11-12 13:55 ` [PATCH v4 04/10] gpio: shared-proxy: implement the shared GPIO proxy driver Bartosz Golaszewski
2025-11-12 13:55 ` [PATCH v4 05/10] gpiolib: support shared GPIOs in core subsystem code Bartosz Golaszewski
2025-11-12 13:55 ` [PATCH v4 06/10] gpio: provide gpiod_is_shared() Bartosz Golaszewski
2025-11-12 13:55 ` [PATCH v4 07/10] arm64: select HAVE_SHARED_GPIOS for ARCH_QCOM Bartosz Golaszewski
2025-11-13  8:51   ` Arnd Bergmann
2025-11-14 19:40   ` Bjorn Andersson
2025-11-18 14:06   ` Mark Brown
2025-11-18 14:13     ` Bartosz Golaszewski
2025-11-18 14:20       ` Mark Brown
2025-11-18 14:27         ` Bartosz Golaszewski
2025-11-18 19:46           ` Mark Brown
2025-11-12 13:55 ` [PATCH v4 08/10] ASoC: wsa881x: drop GPIOD_FLAGS_BIT_NONEXCLUSIVE flag from GPIO lookup Bartosz Golaszewski
2025-11-12 13:55 ` [PATCH v4 09/10] ASoC: wsa883x: " Bartosz Golaszewski
2025-11-12 13:55 ` [PATCH v4 10/10] regulator: make the subsystem aware of shared GPIOs Bartosz Golaszewski
2025-11-17  9:20 ` (subset) [PATCH v4 00/10] gpio: improve support for " Bartosz Golaszewski
2025-11-18 11:15 ` Geert Uytterhoeven
2025-11-18 11:55   ` Bartosz Golaszewski
2025-11-18 12:55     ` Geert Uytterhoeven
2025-11-18 13:21       ` Bartosz Golaszewski
2025-11-18 23:23   ` Linus Walleij
2025-11-19  8:01     ` Andy Shevchenko
2025-11-19  8:33     ` Geert Uytterhoeven
2025-11-19 14:29       ` Linus Walleij
2025-11-20 10:39 ` (subset) " Mark Brown
2025-11-20 13:36 ` Mark Brown
2025-11-21  0:27 ` Val Packett
2025-11-21  9:03   ` Bartosz Golaszewski
2025-11-21 10:20     ` Krzysztof Kozlowski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).