[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251006-reset-gpios-swnodes-v1-3-6d3325b9af42@linaro.org>
Date: Mon, 06 Oct 2025 15:00:18 +0200
From: Bartosz Golaszewski <brgl@...ev.pl>
To: Linus Walleij <linus.walleij@...aro.org>,
Bartosz Golaszewski <brgl@...ev.pl>,
Andy Shevchenko <andriy.shevchenko@...ux.intel.com>,
Daniel Scally <djrscally@...il.com>,
Heikki Krogerus <heikki.krogerus@...ux.intel.com>,
Sakari Ailus <sakari.ailus@...ux.intel.com>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
"Rafael J. Wysocki" <rafael@...nel.org>, Danilo Krummrich <dakr@...nel.org>,
Philipp Zabel <p.zabel@...gutronix.de>,
Krzysztof Kozlowski <krzk@...nel.org>
Cc: linux-gpio@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-acpi@...r.kernel.org,
Bartosz Golaszewski <bartosz.golaszewski@...aro.org>
Subject: [PATCH 3/9] software node: allow referencing firmware nodes
From: Bartosz Golaszewski <bartosz.golaszewski@...aro.org>
At the moment software nodes can only reference other software nodes.
This is a limitation for devices created, for instance, on the auxiliary
bus with a dynamic software node attached which cannot reference devices
the firmware node of which is "real" (as an OF node or otherwise).
Make it possible for a software node to reference all firmware nodes in
addition to static software nodes. To that end: use a union of different
pointers in struct software_node_ref_args and add an enum indicating
what kind of reference given instance of it is. Rework the helper macros
and deprecate the existing ones whose names don't indicate the reference
type.
Software node graphs remain the same, as in: the remote endpoints still
have to be software nodes.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@...aro.org>
---
drivers/base/swnode.c | 21 ++++++++++++++++----
include/linux/property.h | 51 +++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 61 insertions(+), 11 deletions(-)
diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
index a60ba4327db8b967034b296b73c948aa5746a094..b7e91c60c1d51b167adc88afb0f06feeeccf900c 100644
--- a/drivers/base/swnode.c
+++ b/drivers/base/swnode.c
@@ -535,9 +535,19 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
ref_array = prop->pointer;
ref = &ref_array[index];
- refnode = software_node_fwnode(ref->node);
- if (!refnode)
- return -ENOENT;
+ switch (ref->type) {
+ case SOFTWARE_NODE_REF_SWNODE:
+ refnode = software_node_fwnode(ref->swnode);
+ if (!refnode)
+ return -ENOENT;
+ break;
+ case SOFTWARE_NODE_REF_FWNODE:
+ refnode = ref->fwnode;
+ break;
+ default:
+ WARN_ON(1);
+ return -EINVAL;
+ }
if (nargs_prop) {
error = fwnode_property_read_u32_array(refnode, nargs_prop,
@@ -634,7 +644,10 @@ software_node_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)
ref = prop->pointer;
- return software_node_get(software_node_fwnode(ref[0].node));
+ if (ref->type != SOFTWARE_NODE_REF_SWNODE)
+ return NULL;
+
+ return software_node_get(software_node_fwnode(ref[0].swnode));
}
static struct fwnode_handle *
diff --git a/include/linux/property.h b/include/linux/property.h
index 50b26589dd70d1756f3b8644255c24a011e2617c..af72f579e8026cee2456b0983819e7a4bf0c6805 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -353,25 +353,50 @@ fwnode_property_string_array_count(const struct fwnode_handle *fwnode,
struct software_node;
+enum software_node_ref_type {
+ /* References a software node. */
+ SOFTWARE_NODE_REF_SWNODE = 0,
+ /* References a firmware node. */
+ SOFTWARE_NODE_REF_FWNODE,
+};
+
/**
* struct software_node_ref_args - Reference property with additional arguments
- * @node: Reference to a software node
+ * @swnode: Reference to a software node
+ * @fwnode: Alternative reference to a firmware node handle
* @nargs: Number of elements in @args array
* @args: Integer arguments
*/
struct software_node_ref_args {
- const struct software_node *node;
+ enum software_node_ref_type type;
+ union {
+ const struct software_node *swnode;
+ struct fwnode_handle *fwnode;
+ };
unsigned int nargs;
u64 args[NR_FWNODE_REFERENCE_ARGS];
};
-#define SOFTWARE_NODE_REFERENCE(_ref_, ...) \
+#define __SOFTWARE_NODE_REF(_ref, _type, _node, ...) \
(const struct software_node_ref_args) { \
- .node = _ref_, \
+ .type = _type, \
+ ._node = _ref, \
.nargs = COUNT_ARGS(__VA_ARGS__), \
.args = { __VA_ARGS__ }, \
}
+#define SOFTWARE_NODE_REF_SWNODE(_ref, ...) \
+ __SOFTWARE_NODE_REF(_ref, SOFTWARE_NODE_REF_SWNODE, \
+ swnode, __VA_ARGS__)
+
+#define SOFTWARE_NODE_REF_FWNODE(_ref, ...) \
+ __SOFTWARE_NODE_REF(_ref, SOFTWARE_NODE_REF_FWNODE, \
+ fwnode, __VA_ARGS__)
+
+/* DEPRECATED, use SOFTWARE_NODE_REF_SWNODE() instead. */
+#define SOFTWARE_NODE_REFERENCE(_ref, ...) \
+ SOFTWARE_NODE_REF_SWNODE(_ref, __VA_ARGS__)
+
/**
* struct property_entry - "Built-in" device property representation.
* @name: Name of the property.
@@ -463,14 +488,26 @@ struct property_entry {
#define PROPERTY_ENTRY_STRING(_name_, _val_) \
__PROPERTY_ENTRY_ELEMENT(_name_, str, STRING, _val_)
-#define PROPERTY_ENTRY_REF(_name_, _ref_, ...) \
+#define __PROPERTY_ENTRY_REF(_type, _name, _ref, ...) \
(struct property_entry) { \
- .name = _name_, \
+ .name = _name, \
.length = sizeof(struct software_node_ref_args), \
.type = DEV_PROP_REF, \
- { .pointer = &SOFTWARE_NODE_REFERENCE(_ref_, ##__VA_ARGS__), }, \
+ { .pointer = &_type(_ref, ##__VA_ARGS__), }, \
}
+#define PROPERTY_ENTRY_REF_SWNODE(_name, _ref, ...) \
+ __PROPERTY_ENTRY_REF(SOFTWARE_NODE_REF_SWNODE, \
+ _name, _ref, __VA_ARGS__)
+
+#define PROPERTY_ENTRY_REF_FWNODE(_name, _ref, ...) \
+ __PROPERTY_ENTRY_REF(SOFTWARE_NODE_REF_FWNODE, \
+ _name, _ref, __VA_ARGS__)
+
+/* DEPRECATED, use PROPERTY_ENTRY_REF_SWNODE() instead. */
+#define PROPERTY_ENTRY_REF(_name, _ref, ...) \
+ PROPERTY_ENTRY_REF_SWNODE(_name, _ref, __VA_ARGS__)
+
#define PROPERTY_ENTRY_BOOL(_name_) \
(struct property_entry) { \
.name = _name_, \
--
2.48.1
Powered by blists - more mailing lists