* [PATCH v2 01/10] lib: string_helpers: export and rename struct strarray
2026-11-13 15:47 [PATCH v2 00/10] gpio: make gpiolib-shared more fwnode-centric Bartosz Golaszewski
@ 2026-11-13 15:47 ` Bartosz Golaszewski
2026-11-13 16:09 ` Andy Shevchenko
2026-11-13 15:47 ` [PATCH v2 02/10] lib: string_helpers: implement a CLASS() for string arrays Bartosz Golaszewski
` (8 subsequent siblings)
9 siblings, 1 reply; 17+ messages in thread
From: Bartosz Golaszewski @ 2026-11-13 15:47 UTC (permalink / raw)
To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Bartosz Golaszewski, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Johan Hovold, Hans Verkuil, Laurent Pinchart,
Kees Cook, Andy Shevchenko, Len Brown, Rob Herring,
Saravana Kannan, Linus Walleij, Andrew Morton,
Gustavo A. R. Silva
Cc: linux-acpi, driver-core, linux-kernel, linux-hardening,
devicetree, linux-gpio, Bartosz Golaszewski
Ahead of introducing a CLASS() for string arrays, make the existing
struct strarray public in linux/string_helpers.h. Rename it to kstrarray
to avoid any potential conflicts in the future and make it clear, it's a
kernel type.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
include/linux/string_helpers.h | 5 +++++
lib/string_helpers.c | 9 ++-------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
index 3fb88a1e989833ad5ea1a46858efa16e3971bf08..c9f08066439bdd33cc26e2054dbe1ba2e867aee7 100644
--- a/include/linux/string_helpers.h
+++ b/include/linux/string_helpers.h
@@ -116,6 +116,11 @@ char *kstrdup_quotable_file(struct file *file, gfp_t gfp);
char *kstrdup_and_replace(const char *src, char old, char new, gfp_t gfp);
+struct kstrarray {
+ char **array __counted_by_ptr(n);
+ size_t n;
+};
+
char **kasprintf_strarray(gfp_t gfp, const char *prefix, size_t n);
void kfree_strarray(char **array, size_t n);
diff --git a/lib/string_helpers.c b/lib/string_helpers.c
index 98d6ed0eaab7e9f3d54e420c404629a28b925bf4..8ec7ff6dac1212fe8a1f242654944ba6e5568e20 100644
--- a/lib/string_helpers.c
+++ b/lib/string_helpers.c
@@ -804,21 +804,16 @@ void kfree_strarray(char **array, size_t n)
}
EXPORT_SYMBOL_GPL(kfree_strarray);
-struct strarray {
- char **array __counted_by_ptr(n);
- size_t n;
-};
-
static void devm_kfree_strarray(struct device *dev, void *res)
{
- struct strarray *array = res;
+ struct kstrarray *array = res;
kfree_strarray(array->array, array->n);
}
char **devm_kasprintf_strarray(struct device *dev, const char *prefix, size_t n)
{
- struct strarray *ptr;
+ struct kstrarray *ptr;
ptr = devres_alloc(devm_kfree_strarray, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH v2 01/10] lib: string_helpers: export and rename struct strarray
2026-11-13 15:47 ` [PATCH v2 01/10] lib: string_helpers: export and rename struct strarray Bartosz Golaszewski
@ 2026-11-13 16:09 ` Andy Shevchenko
0 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2026-11-13 16:09 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Daniel Scally, Heikki Krogerus, Sakari Ailus, Bartosz Golaszewski,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Johan Hovold, Hans Verkuil, Laurent Pinchart, Kees Cook,
Andy Shevchenko, Len Brown, Rob Herring, Saravana Kannan,
Linus Walleij, Andrew Morton, Gustavo A. R. Silva, linux-acpi,
driver-core, linux-kernel, linux-hardening, devicetree,
linux-gpio
On Fri, Nov 13, 2026 at 04:47:01PM +0100, Bartosz Golaszewski wrote:
> Ahead of introducing a CLASS() for string arrays, make the existing
> struct strarray public in linux/string_helpers.h. Rename it to kstrarray
> to avoid any potential conflicts in the future and make it clear, it's a
> kernel type.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 02/10] lib: string_helpers: implement a CLASS() for string arrays
2026-11-13 15:47 [PATCH v2 00/10] gpio: make gpiolib-shared more fwnode-centric Bartosz Golaszewski
2026-11-13 15:47 ` [PATCH v2 01/10] lib: string_helpers: export and rename struct strarray Bartosz Golaszewski
@ 2026-11-13 15:47 ` Bartosz Golaszewski
2026-11-13 16:09 ` Andy Shevchenko
2026-11-13 15:47 ` [PATCH v2 03/10] fwnode: define the property_get_names() operation Bartosz Golaszewski
` (7 subsequent siblings)
9 siblings, 1 reply; 17+ messages in thread
From: Bartosz Golaszewski @ 2026-11-13 15:47 UTC (permalink / raw)
To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Bartosz Golaszewski, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Johan Hovold, Hans Verkuil, Laurent Pinchart,
Kees Cook, Andy Shevchenko, Len Brown, Rob Herring,
Saravana Kannan, Linus Walleij, Andrew Morton,
Gustavo A. R. Silva
Cc: linux-acpi, driver-core, linux-kernel, linux-hardening,
devicetree, linux-gpio, Bartosz Golaszewski
Provide a CLASS() for managed arrays of strings. It can be used for
automated release of temporary string arrays when they go out of scope.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
include/linux/string_helpers.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
index c9f08066439bdd33cc26e2054dbe1ba2e867aee7..4db73bc7d4623cf45954cc8794c5baff6fb23241 100644
--- a/include/linux/string_helpers.h
+++ b/include/linux/string_helpers.h
@@ -3,6 +3,7 @@
#define _LINUX_STRING_HELPERS_H_
#include <linux/bits.h>
+#include <linux/cleanup.h>
#include <linux/ctype.h>
#include <linux/string_choices.h>
#include <linux/string.h>
@@ -124,6 +125,12 @@ struct kstrarray {
char **kasprintf_strarray(gfp_t gfp, const char *prefix, size_t n);
void kfree_strarray(char **array, size_t n);
+DEFINE_CLASS(strarray,
+ struct kstrarray,
+ kfree_strarray(_T.array, _T.n),
+ ((struct kstrarray){ .array = array, .n = size }),
+ char **array, size_t size);
+
char **devm_kasprintf_strarray(struct device *dev, const char *prefix, size_t n);
#endif
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH v2 02/10] lib: string_helpers: implement a CLASS() for string arrays
2026-11-13 15:47 ` [PATCH v2 02/10] lib: string_helpers: implement a CLASS() for string arrays Bartosz Golaszewski
@ 2026-11-13 16:09 ` Andy Shevchenko
0 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2026-11-13 16:09 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Daniel Scally, Heikki Krogerus, Sakari Ailus, Bartosz Golaszewski,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Johan Hovold, Hans Verkuil, Laurent Pinchart, Kees Cook,
Andy Shevchenko, Len Brown, Rob Herring, Saravana Kannan,
Linus Walleij, Andrew Morton, Gustavo A. R. Silva, linux-acpi,
driver-core, linux-kernel, linux-hardening, devicetree,
linux-gpio
On Fri, Nov 13, 2026 at 04:47:02PM +0100, Bartosz Golaszewski wrote:
> Provide a CLASS() for managed arrays of strings. It can be used for
> automated release of temporary string arrays when they go out of scope.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 03/10] fwnode: define the property_get_names() operation
2026-11-13 15:47 [PATCH v2 00/10] gpio: make gpiolib-shared more fwnode-centric Bartosz Golaszewski
2026-11-13 15:47 ` [PATCH v2 01/10] lib: string_helpers: export and rename struct strarray Bartosz Golaszewski
2026-11-13 15:47 ` [PATCH v2 02/10] lib: string_helpers: implement a CLASS() for string arrays Bartosz Golaszewski
@ 2026-11-13 15:47 ` Bartosz Golaszewski
2026-11-13 15:47 ` [PATCH v2 04/10] device property: provide fwnode_property_get_names() Bartosz Golaszewski
` (6 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Bartosz Golaszewski @ 2026-11-13 15:47 UTC (permalink / raw)
To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Bartosz Golaszewski, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Johan Hovold, Hans Verkuil, Laurent Pinchart,
Kees Cook, Andy Shevchenko, Len Brown, Rob Herring,
Saravana Kannan, Linus Walleij, Andrew Morton,
Gustavo A. R. Silva
Cc: linux-acpi, driver-core, linux-kernel, linux-hardening,
devicetree, linux-gpio, Bartosz Golaszewski
Define a new fwnode operation allowing to retrieve the list of all
properties of given firmware node in a dynamically allocated array of
strings.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
include/linux/fwnode.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
index a9dcaf7e70765637a0c33af2ae0ac541e15752ad..2d7e0b9245d445d473c7317bd27058abe5750b40 100644
--- a/include/linux/fwnode.h
+++ b/include/linux/fwnode.h
@@ -125,6 +125,13 @@ struct fwnode_reference_args {
* success, a negative error code otherwise.
* @property_read_string_array: Read an array of string properties. Return zero
* on success, a negative error code otherwise.
+ * @property_get_names: Retrieve the list of all properties of this firmware
+ * node. On success: returns the number of properties and
+ * sets *props to an array of NULL-terminated strings that
+ * must be freed by the user with kfree_strarray(). If
+ * there are no properties, 0 is returned and the props
+ * pointer is not changed. Returns negative error number on
+ * failure.
* @get_name: Return the name of an fwnode.
* @get_name_prefix: Get a prefix for a node (for printing purposes).
* @get_parent: Return the parent of an fwnode.
@@ -162,6 +169,8 @@ struct fwnode_operations {
(*property_read_string_array)(const struct fwnode_handle *fwnode_handle,
const char *propname, const char **val,
size_t nval);
+ int (*property_get_names)(const struct fwnode_handle *fwnode,
+ char ***props);
const char *(*get_name)(const struct fwnode_handle *fwnode);
const char *(*get_name_prefix)(const struct fwnode_handle *fwnode);
struct fwnode_handle *(*get_parent)(const struct fwnode_handle *fwnode);
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 04/10] device property: provide fwnode_property_get_names()
2026-11-13 15:47 [PATCH v2 00/10] gpio: make gpiolib-shared more fwnode-centric Bartosz Golaszewski
` (2 preceding siblings ...)
2026-11-13 15:47 ` [PATCH v2 03/10] fwnode: define the property_get_names() operation Bartosz Golaszewski
@ 2026-11-13 15:47 ` Bartosz Golaszewski
2026-11-13 16:13 ` Andy Shevchenko
2026-11-13 15:47 ` [PATCH v2 05/10] of: property: implement the .property_get_names() fwnode operation Bartosz Golaszewski
` (5 subsequent siblings)
9 siblings, 1 reply; 17+ messages in thread
From: Bartosz Golaszewski @ 2026-11-13 15:47 UTC (permalink / raw)
To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Bartosz Golaszewski, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Johan Hovold, Hans Verkuil, Laurent Pinchart,
Kees Cook, Andy Shevchenko, Len Brown, Rob Herring,
Saravana Kannan, Linus Walleij, Andrew Morton,
Gustavo A. R. Silva
Cc: linux-acpi, driver-core, linux-kernel, linux-hardening,
devicetree, linux-gpio, Bartosz Golaszewski
Provide fwnode_property_get_names() - a new fwnode function that allows
callers to retrieve the list of all properties of given firmware node.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
drivers/base/property.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/property.h | 1 +
2 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 7728116e296872b7ea4d4475aee72d95edf63eb6..d3c54c3d11c42ba4aef68687fc27291c7f33beb6 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -11,11 +11,13 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/export.h>
+#include <linux/minmax.h>
#include <linux/of.h>
+#include <linux/overflow.h>
#include <linux/property.h>
#include <linux/phy.h>
#include <linux/slab.h>
-#include <linux/string.h>
+#include <linux/string_helpers.h>
#include <linux/types.h>
struct fwnode_handle *__dev_fwnode(struct device *dev)
@@ -542,6 +544,82 @@ int fwnode_property_match_string(const struct fwnode_handle *fwnode,
}
EXPORT_SYMBOL_GPL(fwnode_property_match_string);
+/**
+ * fwnode_property_get_names - get the list of all properties of this fwnode
+ * @fwnode: Firmware node to get the list of properties for
+ * @props: Pointer to an array of strings. It will contain the address of the
+ * string list containing the property names. Must not be NULL.
+ *
+ * The list also includes the properties of the secondary firmware node, if
+ * any. Properties present in both nodes are listed once with the ones from the
+ * primary node taking precedence.
+ *
+ * Return: Number of property names written into *props. If > 0, the caller must
+ * free the array with kfree_strarray(). If the node contains no
+ * properties or an error occurred, *props is left untouched.
+ * %-EINVAL if arguments are not valid
+ * %-ENXIO if no suitable firmware interface is present
+ * %-ENOMEM if memory allocation failed
+ */
+int fwnode_property_get_names(const struct fwnode_handle *fwnode, char ***props)
+{
+ int ret1, ret2 = -ENXIO, n1, n2, i, j, count;
+ char **prim = NULL, **sec = NULL, **merged;
+
+ if (IS_ERR_OR_NULL(fwnode) || !props)
+ return -EINVAL;
+
+ ret1 = fwnode_call_int_op(fwnode, property_get_names, &prim);
+ if (!IS_ERR_OR_NULL(fwnode->secondary))
+ ret2 = fwnode_call_int_op(fwnode->secondary, property_get_names, &sec);
+
+ if (ret1 == -ENXIO && ret2 == -ENXIO)
+ return -ENXIO;
+
+ n1 = max(ret1, 0);
+ n2 = max(ret2, 0);
+
+ CLASS(strarray, prim_props)(prim, n1);
+ CLASS(strarray, sec_props)(sec, n2);
+
+ if (ret1 < 0 && ret1 != -ENXIO)
+ return ret1;
+
+ if (ret2 < 0 && ret2 != -ENXIO)
+ return ret2;
+
+ if (n1 == 0 && n2 == 0)
+ return 0;
+
+ merged = kcalloc(size_add(n1, n2), sizeof(*merged), GFP_KERNEL);
+ if (!merged)
+ return -ENOMEM;
+
+ /* The strings are now owned by merged, only free the container. */
+ for (i = 0; i < n1; i++) {
+ merged[i] = prim_props.array[i];
+ prim_props.array[i] = NULL;
+ }
+ count = n1;
+
+ /* Properties from the primary node take precedence. */
+ for (i = 0; i < n2; i++) {
+ for (j = 0; j < n1; j++) {
+ if (!strcmp(merged[j], sec_props.array[i]))
+ break;
+ }
+
+ if (j >= n1) {
+ merged[count++] = sec_props.array[i];
+ sec_props.array[i] = NULL;
+ }
+ }
+
+ *props = merged;
+ return count;
+}
+EXPORT_SYMBOL_GPL(fwnode_property_get_names);
+
/**
* fwnode_property_match_property_string - find a property string value in an array and return index
* @fwnode: Firmware node to get the property of
diff --git a/include/linux/property.h b/include/linux/property.h
index 9143fe4f5c05179e595ba875aafbcb006a740824..a70f3c4c087dd85390951da950c3632f89c6cfd1 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -77,6 +77,7 @@ int fwnode_property_read_string(const struct fwnode_handle *fwnode,
const char *propname, const char **val);
int fwnode_property_match_string(const struct fwnode_handle *fwnode,
const char *propname, const char *string);
+int fwnode_property_get_names(const struct fwnode_handle *fwnode, char ***props);
bool fwnode_device_is_available(const struct fwnode_handle *fwnode);
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH v2 04/10] device property: provide fwnode_property_get_names()
2026-11-13 15:47 ` [PATCH v2 04/10] device property: provide fwnode_property_get_names() Bartosz Golaszewski
@ 2026-11-13 16:13 ` Andy Shevchenko
0 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2026-11-13 16:13 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Daniel Scally, Heikki Krogerus, Sakari Ailus, Bartosz Golaszewski,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Johan Hovold, Hans Verkuil, Laurent Pinchart, Kees Cook,
Andy Shevchenko, Len Brown, Rob Herring, Saravana Kannan,
Linus Walleij, Andrew Morton, Gustavo A. R. Silva, linux-acpi,
driver-core, linux-kernel, linux-hardening, devicetree,
linux-gpio
On Fri, Nov 13, 2026 at 04:47:04PM +0100, Bartosz Golaszewski wrote:
> Provide fwnode_property_get_names() - a new fwnode function that allows
> callers to retrieve the list of all properties of given firmware node.
I don't understand why we have this patch separated from previous one?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 05/10] of: property: implement the .property_get_names() fwnode operation
2026-11-13 15:47 [PATCH v2 00/10] gpio: make gpiolib-shared more fwnode-centric Bartosz Golaszewski
` (3 preceding siblings ...)
2026-11-13 15:47 ` [PATCH v2 04/10] device property: provide fwnode_property_get_names() Bartosz Golaszewski
@ 2026-11-13 15:47 ` Bartosz Golaszewski
2026-11-13 15:47 ` [PATCH v2 06/10] fwnode: define the count_references() " Bartosz Golaszewski
` (4 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Bartosz Golaszewski @ 2026-11-13 15:47 UTC (permalink / raw)
To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Bartosz Golaszewski, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Johan Hovold, Hans Verkuil, Laurent Pinchart,
Kees Cook, Andy Shevchenko, Len Brown, Rob Herring,
Saravana Kannan, Linus Walleij, Andrew Morton,
Gustavo A. R. Silva
Cc: linux-acpi, driver-core, linux-kernel, linux-hardening,
devicetree, linux-gpio, Bartosz Golaszewski
Implement the property_get_names() callback from the fwnode interface
for OF nodes.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
drivers/of/property.c | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/drivers/of/property.c b/drivers/of/property.c
index 45e55f61848801ed497702c6cfe501009904c49d..53f2c84bcb96d3a00f3cd2371010628493d49bc4 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -27,7 +27,7 @@
#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <linux/of_irq.h>
-#include <linux/string.h>
+#include <linux/string_helpers.h>
#include <linux/moduleparam.h>
#include "of_private.h"
@@ -1120,6 +1120,37 @@ of_fwnode_property_read_string_array(const struct fwnode_handle *fwnode,
of_property_count_strings(node, propname);
}
+static int of_fwnode_property_get_names(const struct fwnode_handle *fwnode,
+ char ***props)
+{
+ const struct device_node *node = to_of_node(fwnode);
+ struct property *prop;
+ int count = 0, i = 0;
+ char **names;
+
+ for_each_property_of_node(node, prop)
+ count++;
+
+ if (count == 0)
+ return 0;
+
+ names = kcalloc(count, sizeof(*names), GFP_KERNEL);
+ if (!names)
+ return -ENOMEM;
+
+ for_each_property_of_node(node, prop) {
+ names[i] = kstrdup(prop->name, GFP_KERNEL);
+ if (!names[i]) {
+ kfree_strarray(names, i);
+ return -ENOMEM;
+ }
+ i++;
+ }
+
+ *props = names;
+ return count;
+}
+
static const char *of_fwnode_get_name(const struct fwnode_handle *fwnode)
{
return kbasename(to_of_node(fwnode)->full_name);
@@ -1712,6 +1743,7 @@ const struct fwnode_operations of_fwnode_ops = {
.property_read_bool = of_fwnode_property_read_bool,
.property_read_int_array = of_fwnode_property_read_int_array,
.property_read_string_array = of_fwnode_property_read_string_array,
+ .property_get_names = of_fwnode_property_get_names,
.get_name = of_fwnode_get_name,
.get_name_prefix = of_fwnode_get_name_prefix,
.get_parent = of_fwnode_get_parent,
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 06/10] fwnode: define the count_references() fwnode operation
2026-11-13 15:47 [PATCH v2 00/10] gpio: make gpiolib-shared more fwnode-centric Bartosz Golaszewski
` (4 preceding siblings ...)
2026-11-13 15:47 ` [PATCH v2 05/10] of: property: implement the .property_get_names() fwnode operation Bartosz Golaszewski
@ 2026-11-13 15:47 ` Bartosz Golaszewski
2026-11-13 15:47 ` [PATCH v2 07/10] device property: provide fwnode_property_count_references() Bartosz Golaszewski
` (3 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Bartosz Golaszewski @ 2026-11-13 15:47 UTC (permalink / raw)
To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Bartosz Golaszewski, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Johan Hovold, Hans Verkuil, Laurent Pinchart,
Kees Cook, Andy Shevchenko, Len Brown, Rob Herring,
Saravana Kannan, Linus Walleij, Andrew Morton,
Gustavo A. R. Silva
Cc: linux-acpi, driver-core, linux-kernel, linux-hardening,
devicetree, linux-gpio, Bartosz Golaszewski
Add a new fwnode callback allowing to count all references of given
firmware node.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
include/linux/fwnode.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
index 2d7e0b9245d445d473c7317bd27058abe5750b40..15acade60564ddb5f5a48f2235b626466d77dbdf 100644
--- a/include/linux/fwnode.h
+++ b/include/linux/fwnode.h
@@ -137,6 +137,10 @@ struct fwnode_reference_args {
* @get_parent: Return the parent of an fwnode.
* @get_next_child_node: Return the next child node in an iteration.
* @get_named_child_node: Return a child node with a given name.
+ * @count_references: Return the number of references in a property, including
+ * empty ones. @nargs_prop names the property in the
+ * referenced node holding the number of arguments, if NULL
+ * the references have no arguments.
* @get_reference_args: Return a reference pointed to by a property, with args
* @graph_get_next_endpoint: Return an endpoint node in an iteration.
* @graph_get_remote_endpoint: Return the remote endpoint node of a local
@@ -180,6 +184,8 @@ struct fwnode_operations {
struct fwnode_handle *
(*get_named_child_node)(const struct fwnode_handle *fwnode,
const char *name);
+ int (*count_references)(const struct fwnode_handle *fwnode,
+ const char *prop, const char *nargs_prop);
int (*get_reference_args)(const struct fwnode_handle *fwnode,
const char *prop, const char *nargs_prop,
unsigned int nargs, unsigned int index,
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 07/10] device property: provide fwnode_property_count_references()
2026-11-13 15:47 [PATCH v2 00/10] gpio: make gpiolib-shared more fwnode-centric Bartosz Golaszewski
` (5 preceding siblings ...)
2026-11-13 15:47 ` [PATCH v2 06/10] fwnode: define the count_references() " Bartosz Golaszewski
@ 2026-11-13 15:47 ` Bartosz Golaszewski
2026-11-13 16:13 ` Andy Shevchenko
2026-11-13 15:47 ` [PATCH v2 08/10] of: property: implement the count_references() fwnode operation Bartosz Golaszewski
` (2 subsequent siblings)
9 siblings, 1 reply; 17+ messages in thread
From: Bartosz Golaszewski @ 2026-11-13 15:47 UTC (permalink / raw)
To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Bartosz Golaszewski, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Johan Hovold, Hans Verkuil, Laurent Pinchart,
Kees Cook, Andy Shevchenko, Len Brown, Rob Herring,
Saravana Kannan, Linus Walleij, Andrew Morton,
Gustavo A. R. Silva
Cc: linux-acpi, driver-core, linux-kernel, linux-hardening,
devicetree, linux-gpio, Bartosz Golaszewski
Provide fwnode_property_count_references() - a new fwnode function that
allows callers to retrieve the number of references in given property.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
drivers/base/property.c | 35 +++++++++++++++++++++++++++++++++++
include/linux/property.h | 3 +++
2 files changed, 38 insertions(+)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index d3c54c3d11c42ba4aef68687fc27291c7f33beb6..3cbeb147134143cf68af3213ee75c371af363f2e 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -655,6 +655,41 @@ int fwnode_property_match_property_string(const struct fwnode_handle *fwnode,
}
EXPORT_SYMBOL_GPL(fwnode_property_match_property_string);
+/**
+ * fwnode_property_count_references() - Count the references in a property
+ * @fwnode: Firmware node where to look for the property
+ * @prop: The name of the property
+ * @nargs_prop: The name of the property telling the number of arguments in the
+ * referred node. NULL if the references have no arguments.
+ *
+ * Empty references count too, so every index in the range [0, count) can be
+ * passed to fwnode_property_get_reference_args(), which may still fail for
+ * empty entries.
+ *
+ * Return: Number of references on success,
+ * %-ENOENT if the property was not found,
+ * %-EINVAL on parse error.
+ */
+int fwnode_property_count_references(const struct fwnode_handle *fwnode,
+ const char *prop, const char *nargs_prop)
+{
+ int ret;
+
+ if (IS_ERR_OR_NULL(fwnode))
+ return -ENOENT;
+
+ ret = fwnode_call_int_op(fwnode, count_references, prop, nargs_prop);
+ if (ret >= 0)
+ return ret;
+
+ if (IS_ERR_OR_NULL(fwnode->secondary))
+ return ret;
+
+ return fwnode_call_int_op(fwnode->secondary, count_references, prop,
+ nargs_prop);
+}
+EXPORT_SYMBOL_GPL(fwnode_property_count_references);
+
/**
* fwnode_property_get_reference_args() - Find a reference with arguments
* @fwnode: Firmware node where to look for the reference
diff --git a/include/linux/property.h b/include/linux/property.h
index a70f3c4c087dd85390951da950c3632f89c6cfd1..9f0b9aab5920513cd468572fa96dbe3371609591 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -137,6 +137,9 @@ int device_property_match_property_string(const struct device *dev,
return fwnode_property_match_property_string(dev_fwnode(dev), propname, array, n);
}
+int fwnode_property_count_references(const struct fwnode_handle *fwnode,
+ const char *prop, const char *nargs_prop);
+
int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,
const char *prop, const char *nargs_prop,
unsigned int nargs, unsigned int index,
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH v2 07/10] device property: provide fwnode_property_count_references()
2026-11-13 15:47 ` [PATCH v2 07/10] device property: provide fwnode_property_count_references() Bartosz Golaszewski
@ 2026-11-13 16:13 ` Andy Shevchenko
0 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2026-11-13 16:13 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Daniel Scally, Heikki Krogerus, Sakari Ailus, Bartosz Golaszewski,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Johan Hovold, Hans Verkuil, Laurent Pinchart, Kees Cook,
Andy Shevchenko, Len Brown, Rob Herring, Saravana Kannan,
Linus Walleij, Andrew Morton, Gustavo A. R. Silva, linux-acpi,
driver-core, linux-kernel, linux-hardening, devicetree,
linux-gpio
On Fri, Nov 13, 2026 at 04:47:07PM +0100, Bartosz Golaszewski wrote:
> Provide fwnode_property_count_references() - a new fwnode function that
> allows callers to retrieve the number of references in given property.
I don't understand why we have this patch separated from previous one?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 08/10] of: property: implement the count_references() fwnode operation
2026-11-13 15:47 [PATCH v2 00/10] gpio: make gpiolib-shared more fwnode-centric Bartosz Golaszewski
` (6 preceding siblings ...)
2026-11-13 15:47 ` [PATCH v2 07/10] device property: provide fwnode_property_count_references() Bartosz Golaszewski
@ 2026-11-13 15:47 ` Bartosz Golaszewski
2026-11-13 15:47 ` [PATCH v2 09/10] gpio: shared: removed unused field from struct gpio_shared_entry Bartosz Golaszewski
2026-11-13 15:47 ` [PATCH v2 10/10] gpio: shared: generalize most code to firmware nodes Bartosz Golaszewski
9 siblings, 0 replies; 17+ messages in thread
From: Bartosz Golaszewski @ 2026-11-13 15:47 UTC (permalink / raw)
To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Bartosz Golaszewski, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Johan Hovold, Hans Verkuil, Laurent Pinchart,
Kees Cook, Andy Shevchenko, Len Brown, Rob Herring,
Saravana Kannan, Linus Walleij, Andrew Morton,
Gustavo A. R. Silva
Cc: linux-acpi, driver-core, linux-kernel, linux-hardening,
devicetree, linux-gpio, Bartosz Golaszewski
Implement the property_count_references() fwnode operation for OF nodes
by wrapping the existing of_count_phandle_with_args().
Acked-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
drivers/of/property.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/of/property.c b/drivers/of/property.c
index 53f2c84bcb96d3a00f3cd2371010628493d49bc4..c2f5c338b6d1e7f3515be76d21ba6ef097e65e04 100644
--- a/drivers/of/property.c
+++ b/drivers/of/property.c
@@ -1233,6 +1233,12 @@ of_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
return 0;
}
+static int of_fwnode_count_references(const struct fwnode_handle *fwnode,
+ const char *prop, const char *nargs_prop)
+{
+ return of_count_phandle_with_args(to_of_node(fwnode), prop, nargs_prop);
+}
+
static struct fwnode_handle *
of_fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
struct fwnode_handle *prev)
@@ -1749,6 +1755,7 @@ const struct fwnode_operations of_fwnode_ops = {
.get_parent = of_fwnode_get_parent,
.get_next_child_node = of_fwnode_get_next_child_node,
.get_named_child_node = of_fwnode_get_named_child_node,
+ .count_references = of_fwnode_count_references,
.get_reference_args = of_fwnode_get_reference_args,
.graph_get_next_endpoint = of_fwnode_graph_get_next_endpoint,
.graph_get_remote_endpoint = of_fwnode_graph_get_remote_endpoint,
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* [PATCH v2 09/10] gpio: shared: removed unused field from struct gpio_shared_entry
2026-11-13 15:47 [PATCH v2 00/10] gpio: make gpiolib-shared more fwnode-centric Bartosz Golaszewski
` (7 preceding siblings ...)
2026-11-13 15:47 ` [PATCH v2 08/10] of: property: implement the count_references() fwnode operation Bartosz Golaszewski
@ 2026-11-13 15:47 ` Bartosz Golaszewski
2026-11-13 16:14 ` Andy Shevchenko
2026-11-13 15:47 ` [PATCH v2 10/10] gpio: shared: generalize most code to firmware nodes Bartosz Golaszewski
9 siblings, 1 reply; 17+ messages in thread
From: Bartosz Golaszewski @ 2026-11-13 15:47 UTC (permalink / raw)
To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Bartosz Golaszewski, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Johan Hovold, Hans Verkuil, Laurent Pinchart,
Kees Cook, Andy Shevchenko, Len Brown, Rob Herring,
Saravana Kannan, Linus Walleij, Andrew Morton,
Gustavo A. R. Silva
Cc: linux-acpi, driver-core, linux-kernel, linux-hardening,
devicetree, linux-gpio, Bartosz Golaszewski
The index field in struct gpio_shared_entry is an unused leftover.
Remove it.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
drivers/gpio/gpiolib-shared.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/gpio/gpiolib-shared.c b/drivers/gpio/gpiolib-shared.c
index edb04a5bb987e12faf96e5b70198a9fabf60ad0a..44af3bc1494e47310973844a0ef19ac3ec5cd719 100644
--- a/drivers/gpio/gpiolib-shared.c
+++ b/drivers/gpio/gpiolib-shared.c
@@ -51,8 +51,6 @@ struct gpio_shared_entry {
struct fwnode_handle *fwnode;
/* Hardware offset of the GPIO within its chip. */
unsigned int offset;
- /* Index in the property value array. */
- size_t index;
/* Synchronizes the modification of shared_desc and offset. */
struct mutex lock;
struct gpio_shared_desc *shared_desc;
@@ -233,7 +231,6 @@ static int gpio_shared_of_traverse(struct device_node *curr)
entry->fwnode = fwnode_handle_get(fwnode);
entry->offset = offset;
- entry->index = count;
INIT_LIST_HEAD(&entry->refs);
mutex_init(&entry->lock);
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH v2 09/10] gpio: shared: removed unused field from struct gpio_shared_entry
2026-11-13 15:47 ` [PATCH v2 09/10] gpio: shared: removed unused field from struct gpio_shared_entry Bartosz Golaszewski
@ 2026-11-13 16:14 ` Andy Shevchenko
0 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2026-11-13 16:14 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Daniel Scally, Heikki Krogerus, Sakari Ailus, Bartosz Golaszewski,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Johan Hovold, Hans Verkuil, Laurent Pinchart, Kees Cook,
Andy Shevchenko, Len Brown, Rob Herring, Saravana Kannan,
Linus Walleij, Andrew Morton, Gustavo A. R. Silva, linux-acpi,
driver-core, linux-kernel, linux-hardening, devicetree,
linux-gpio
On Fri, Nov 13, 2026 at 04:47:09PM +0100, Bartosz Golaszewski wrote:
> The index field in struct gpio_shared_entry is an unused leftover.
> Remove it.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 10/10] gpio: shared: generalize most code to firmware nodes
2026-11-13 15:47 [PATCH v2 00/10] gpio: make gpiolib-shared more fwnode-centric Bartosz Golaszewski
` (8 preceding siblings ...)
2026-11-13 15:47 ` [PATCH v2 09/10] gpio: shared: removed unused field from struct gpio_shared_entry Bartosz Golaszewski
@ 2026-11-13 15:47 ` Bartosz Golaszewski
2026-11-13 16:19 ` Andy Shevchenko
9 siblings, 1 reply; 17+ messages in thread
From: Bartosz Golaszewski @ 2026-11-13 15:47 UTC (permalink / raw)
To: Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Bartosz Golaszewski, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Johan Hovold, Hans Verkuil, Laurent Pinchart,
Kees Cook, Andy Shevchenko, Len Brown, Rob Herring,
Saravana Kannan, Linus Walleij, Andrew Morton,
Gustavo A. R. Silva
Cc: linux-acpi, driver-core, linux-kernel, linux-hardening,
devicetree, linux-gpio, Bartosz Golaszewski
Ahead of adding support for sharing of GPIOs for other types of firmware
nodes, convert as much code in gpiolib-shared.c as possible to using
fwnode APIs and guard the remaining OF-specific bits with CONFIG_OF
guards.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
drivers/gpio/gpiolib-shared.c | 239 ++++++++++++++++++++++--------------------
1 file changed, 128 insertions(+), 111 deletions(-)
diff --git a/drivers/gpio/gpiolib-shared.c b/drivers/gpio/gpiolib-shared.c
index 44af3bc1494e47310973844a0ef19ac3ec5cd719..edd61d16f065f4e4f2c440ef0529a2365d0bda44 100644
--- a/drivers/gpio/gpiolib-shared.c
+++ b/drivers/gpio/gpiolib-shared.c
@@ -22,7 +22,7 @@
#include <linux/printk.h>
#include <linux/property.h>
#include <linux/slab.h>
-#include <linux/string.h>
+#include <linux/string_helpers.h>
#include "gpiolib.h"
#include "gpiolib-shared.h"
@@ -61,7 +61,6 @@ struct gpio_shared_entry {
static LIST_HEAD(gpio_shared_list);
static DEFINE_IDA(gpio_shared_ida);
-#if IS_ENABLED(CONFIG_OF)
static struct gpio_shared_entry *
gpio_shared_find_entry(struct fwnode_handle *controller_node,
unsigned int offset)
@@ -131,157 +130,159 @@ static int gpio_shared_setup_reset_proxy(struct gpio_shared_entry *entry,
}
/* Handle all special nodes that we should ignore. */
-static bool gpio_shared_of_node_ignore(struct device_node *node)
+static bool gpio_shared_fwnode_ignore(struct fwnode_handle *fwnode)
{
/* Ignore disabled devices. */
- if (!of_device_is_available(node))
+ if (!fwnode_device_is_available(fwnode))
return true;
/*
- * __symbols__ is a special, internal node and should not be considered
- * when scanning for shared GPIOs.
+ * On OF-systems __symbols__ is a special, internal node and should not
+ * be considered when scanning for shared GPIOs.
*/
- if (of_node_name_eq(node, "__symbols__"))
+ if (fwnode_name_eq(fwnode, "__symbols__"))
return true;
/*
* GPIO hogs have a "gpios" property which is not a phandle and can't
* possibly refer to a shared GPIO.
*/
- if (of_property_present(node, "gpio-hog"))
+ if (fwnode_property_present(fwnode, "gpio-hog"))
return true;
return false;
}
-static int gpio_shared_of_traverse(struct device_node *curr)
+static int gpio_shared_fwnode_scan_property(struct fwnode_handle *curr,
+ const char *propname)
{
+ struct fwnode_reference_args args;
struct gpio_shared_entry *entry;
size_t con_id_len, suffix_len;
- struct fwnode_handle *fwnode;
- struct of_phandle_args args;
struct gpio_shared_ref *ref;
- struct property *prop;
unsigned int offset;
const char *suffix;
- int ret, count, i;
+ int ret, i, count;
- if (gpio_shared_of_node_ignore(curr))
+ /*
+ * 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(propname, "-gpios") && !strends(propname, "-gpio") &&
+ strcmp(propname, "gpios") != 0 && strcmp(propname, "gpio") != 0)
return 0;
- 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;
+ count = fwnode_property_count_references(curr, propname, "#gpio-cells");
+ if (count <= 0)
+ return 0;
- for (i = 0; i < count; i++) {
- struct device_node *np __free(device_node) = NULL;
- char *con_id __free(kfree) = NULL;
+ for (i = 0; i < count; i++) {
+ struct fwnode_handle *fwnode __free(fwnode_handle) = NULL;
+ char *con_id __free(kfree) = NULL;
- ret = of_parse_phandle_with_args(curr, prop->name,
- "#gpio-cells", i,
+ ret = fwnode_property_get_reference_args(curr, propname,
+ "#gpio-cells", 0, i,
&args);
- if (ret)
- continue;
+ if (ret)
+ continue;
- np = args.np;
+ fwnode = args.fwnode;
- if (!of_property_present(np, "gpio-controller"))
- continue;
+ if (!fwnode_property_present(fwnode, "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;
+ /*
+ * 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.nargs != 2)
+ continue;
- fwnode = of_fwnode_handle(args.np);
- offset = args.args[0];
+ offset = args.args[0];
- entry = gpio_shared_find_entry(fwnode, offset);
- if (!entry) {
- entry = kzalloc_obj(*entry);
- if (!entry)
- return -ENOMEM;
+ entry = gpio_shared_find_entry(fwnode, offset);
+ if (!entry) {
+ entry = kzalloc_obj(*entry);
+ if (!entry)
+ return -ENOMEM;
- entry->fwnode = fwnode_handle_get(fwnode);
- entry->offset = offset;
- INIT_LIST_HEAD(&entry->refs);
- mutex_init(&entry->lock);
+ entry->fwnode = fwnode_handle_get(fwnode);
+ entry->offset = offset;
+ INIT_LIST_HEAD(&entry->refs);
+ mutex_init(&entry->lock);
- list_add_tail(&entry->list, &gpio_shared_list);
- }
+ list_add_tail(&entry->list, &gpio_shared_list);
+ }
- if (strends(prop->name, "gpios"))
- suffix = "-gpios";
- else if (strends(prop->name, "gpio"))
- suffix = "-gpio";
- else
- suffix = NULL;
- if (!suffix)
- continue;
+ if (strends(propname, "gpios"))
+ suffix = "-gpios";
+ else if (strends(propname, "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")) {
- con_id = kstrdup(prop->name, GFP_KERNEL);
- if (!con_id)
- return -ENOMEM;
+ /* We only set con_id if there's actually one. */
+ if (strcmp(propname, "gpios") && strcmp(propname, "gpio")) {
+ con_id = kstrdup(propname, GFP_KERNEL);
+ if (!con_id)
+ return -ENOMEM;
- con_id_len = strlen(con_id);
- suffix_len = strlen(suffix);
+ con_id_len = strlen(con_id);
+ suffix_len = strlen(suffix);
- con_id[con_id_len - suffix_len] = '\0';
- }
+ con_id[con_id_len - suffix_len] = '\0';
+ }
- struct fwnode_handle *curr_fwnode =
- fwnode_handle_get(of_fwnode_handle(curr));
- ref = gpio_shared_make_ref(curr_fwnode, con_id, args.args[1]);
- if (!ref) {
- fwnode_handle_put(curr_fwnode);
- return -ENOMEM;
- }
+ ref = gpio_shared_make_ref(fwnode_handle_get(curr), con_id, args.args[1]);
+ if (!ref) {
+ fwnode_handle_put(curr);
+ 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));
+ 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(&ref->list, &entry->refs);
+ list_add_tail(&ref->list, &entry->refs);
- if (strcmp(prop->name, "reset-gpios") == 0) {
- ret = gpio_shared_setup_reset_proxy(entry, args.args[1]);
- if (ret)
- return ret;
- }
+ if (strcmp(propname, "reset-gpios") == 0) {
+ ret = gpio_shared_setup_reset_proxy(entry, args.args[1]);
+ if (ret)
+ return ret;
}
}
- for_each_child_of_node_scoped(curr, child) {
- ret = gpio_shared_of_traverse(child);
+ return 0;
+}
+
+static int gpio_shared_fwnode_scan_properties(struct fwnode_handle *curr)
+{
+ char **props;
+ int ret, i;
+
+ ret = fwnode_property_get_names(curr, &props);
+ if (ret <= 0)
+ return ret;
+
+ CLASS(strarray, names)(props, ret);
+
+ for (i = 0; i < names.n; i++) {
+ ret = gpio_shared_fwnode_scan_property(curr, names.array[i]);
if (ret)
return ret;
}
@@ -289,19 +290,35 @@ static int gpio_shared_of_traverse(struct device_node *curr)
return 0;
}
-static int gpio_shared_of_scan(void)
+static __maybe_unused int gpio_shared_fwnode_traverse(struct fwnode_handle *curr)
{
- if (of_root)
- return gpio_shared_of_traverse(of_root);
+ int ret;
+
+ if (gpio_shared_fwnode_ignore(curr))
+ return 0;
+
+ ret = gpio_shared_fwnode_scan_properties(curr);
+ if (ret)
+ return ret;
+
+ fwnode_for_each_child_node_scoped(curr, child) {
+ ret = gpio_shared_fwnode_traverse(child);
+ if (ret)
+ return ret;
+ }
return 0;
}
-#else
+
static int gpio_shared_of_scan(void)
{
+#if IS_ENABLED(CONFIG_OF)
+ if (of_root)
+ return gpio_shared_fwnode_traverse(of_fwnode_handle(of_root));
+#endif
+
return 0;
}
-#endif /* CONFIG_OF */
static void gpio_shared_adev_release(struct device *dev)
{
--
2.47.3
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH v2 10/10] gpio: shared: generalize most code to firmware nodes
2026-11-13 15:47 ` [PATCH v2 10/10] gpio: shared: generalize most code to firmware nodes Bartosz Golaszewski
@ 2026-11-13 16:19 ` Andy Shevchenko
0 siblings, 0 replies; 17+ messages in thread
From: Andy Shevchenko @ 2026-11-13 16:19 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Daniel Scally, Heikki Krogerus, Sakari Ailus, Bartosz Golaszewski,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Johan Hovold, Hans Verkuil, Laurent Pinchart, Kees Cook,
Andy Shevchenko, Len Brown, Rob Herring, Saravana Kannan,
Linus Walleij, Andrew Morton, Gustavo A. R. Silva, linux-acpi,
driver-core, linux-kernel, linux-hardening, devicetree,
linux-gpio
On Fri, Nov 13, 2026 at 04:47:10PM +0100, Bartosz Golaszewski wrote:
> Ahead of adding support for sharing of GPIOs for other types of firmware
> nodes, convert as much code in gpiolib-shared.c as possible to using
> fwnode APIs and guard the remaining OF-specific bits with CONFIG_OF
> guards.
...
> -static int gpio_shared_of_scan(void)
> +static __maybe_unused int gpio_shared_fwnode_traverse(struct fwnode_handle *curr)
> {
> - if (of_root)
> - return gpio_shared_of_traverse(of_root);
> + int ret;
> +
> + if (gpio_shared_fwnode_ignore(curr))
> + return 0;
> +
> + ret = gpio_shared_fwnode_scan_properties(curr);
> + if (ret)
> + return ret;
> +
> + fwnode_for_each_child_node_scoped(curr, child) {
> + ret = gpio_shared_fwnode_traverse(child);
> + if (ret)
> + return ret;
> + }
>
> return 0;
> }
> -#else
> +
> static int gpio_shared_of_scan(void)
> {
> +#if IS_ENABLED(CONFIG_OF)
> + if (of_root)
> + return gpio_shared_fwnode_traverse(of_fwnode_handle(of_root));
> +#endif
> +
> return 0;
> }
> -#endif /* CONFIG_OF */
Hmm... What do you exactly get from the compiler without this uglyfication?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 17+ messages in thread