drivers/base/swnode.c | 105 +++++++++++++++++++++ drivers/pinctrl/intel/pinctrl-baytrail.c | 40 +++++++- drivers/pinctrl/intel/pinctrl-cherryview.c | 47 ++++++++- drivers/platform/x86/x86-android-tablets/Kconfig | 1 + drivers/platform/x86/x86-android-tablets/acer.c | 11 ++- drivers/platform/x86/x86-android-tablets/asus.c | 9 +- drivers/platform/x86/x86-android-tablets/core.c | 47 +-------- drivers/platform/x86/x86-android-tablets/lenovo.c | 31 +++--- drivers/platform/x86/x86-android-tablets/other.c | 23 ++--- .../x86/x86-android-tablets/shared-psy-info.c | 7 +- .../x86/x86-android-tablets/x86-android-tablets.h | 4 - include/linux/pinctrl/intel.h | 17 ++++ include/linux/property.h | 18 ++++ 13 files changed, 270 insertions(+), 90 deletions(-)
Problem statement: GPIO software node lookup should rely exclusively on
matching the addresses of the referenced firmware nodes. I tried to
enforce it with commit e5d527be7e69 ("gpio: swnode: don't use the
swnode's name as the key for GPIO lookup") but it broke existing
users who abuse the software node mechanism by creating "dummy" software
nodes named after the device they want to get GPIOs from but never
attaching them to the actual GPIO devices. They rely on the current
behavior of GPIOLIB where it will match the label of the GPIO controller
against the name of the software node and does not require a true link.
x86-android-tablets driver is one of the abusers in that it creates
dummy software nodes for baytrail and cherryview GPIO controllers but
they don't really reference these devices. Before we can reapply
e5d527be7e69 and support matching by fwnode address exclusively, we need
to convert all the users to using actual fwnode references.
It's possible for drivers to reference real firmware nodes from software
nodes via PROPERTY_ENTRY_REF() in general or PROPERTY_ENTRY_GPIO()
specifically but for platform devices binding to real firmware nodes (DT
or ACPI) it's cumbersome as they would need to dynamically look for the
right nodes and create references dynamically with no way of using
static const software nodes.
This series proposes a solution in the form of automatic secondary
software node assignment (I'm open to better naming ideas). We extend
the swnode API with functions allowing to set up a behind-the-scenes bus
notifier for a group of named software nodes. It will wait for bus
events and when a device is added, it will check its name against the
software node's name and - on match - assign the software node as the
secondary firmware node of the device's *real* firmware node.
For now it only supports name matching but I suppose we could extend it
with additional mechanisms if needed. I didn't plan to introduce a
generic API for this initially but the code in cherryview and baytrail
drivers ended up being exactly the same so I decided to factor it out
into common library code.
First patch provides the new interfaces. Next two patches set up
automatic secondary fwnodes for intel baytrail and cherryview drivers.
Finally patch 4/4 replaces the dummy software nodes with ones that will
end up actually being attached to the relevant devices.
GPIOLIB is now able to match a GPIO controller by both its primary as
well as secondary firmware node. While I don't have the relevant
hardware, I tested the series and the new behavior on x86 qemu with
a dummy ACPI table and modified gpio-sim. I assume it will work in real
life but testing is welcome.
Merging strategy: This touches three trees and there are build-time
dependencies. I think it should go through the x86 platform tree with
Ilpo providing an immutable branch for the driver core and pinctrl
trees.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
Bartosz Golaszewski (4):
software node: support automatic secondary fwnode assignment
pinctrl: intel: expose software nodes for baytrail GPIO devices
pinctrl: intel: expose software nodes for cherryiew GPIO devices
platform/x86: x86-android-tablets: enable fwnode matching of GPIO chips
drivers/base/swnode.c | 105 +++++++++++++++++++++
drivers/pinctrl/intel/pinctrl-baytrail.c | 40 +++++++-
drivers/pinctrl/intel/pinctrl-cherryview.c | 47 ++++++++-
drivers/platform/x86/x86-android-tablets/Kconfig | 1 +
drivers/platform/x86/x86-android-tablets/acer.c | 11 ++-
drivers/platform/x86/x86-android-tablets/asus.c | 9 +-
drivers/platform/x86/x86-android-tablets/core.c | 47 +--------
drivers/platform/x86/x86-android-tablets/lenovo.c | 31 +++---
drivers/platform/x86/x86-android-tablets/other.c | 23 ++---
.../x86/x86-android-tablets/shared-psy-info.c | 7 +-
.../x86/x86-android-tablets/x86-android-tablets.h | 4 -
include/linux/pinctrl/intel.h | 17 ++++
include/linux/property.h | 18 ++++
13 files changed, 270 insertions(+), 90 deletions(-)
---
base-commit: f50e991d263338028b296f4398c669feca8f0c3b
change-id: 20260319-baytrail-real-swnode-7de7a3870f78
Best regards,
--
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Hi Bartosz,
On Thu, Mar 19, 2026 at 05:10:53PM +0100, Bartosz Golaszewski wrote:
> Problem statement: GPIO software node lookup should rely exclusively on
> matching the addresses of the referenced firmware nodes. I tried to
> enforce it with commit e5d527be7e69 ("gpio: swnode: don't use the
> swnode's name as the key for GPIO lookup") but it broke existing
> users who abuse the software node mechanism by creating "dummy" software
> nodes named after the device they want to get GPIOs from but never
> attaching them to the actual GPIO devices. They rely on the current
> behavior of GPIOLIB where it will match the label of the GPIO controller
> against the name of the software node and does not require a true link.
>
> x86-android-tablets driver is one of the abusers in that it creates
> dummy software nodes for baytrail and cherryview GPIO controllers but
> they don't really reference these devices. Before we can reapply
> e5d527be7e69 and support matching by fwnode address exclusively, we need
> to convert all the users to using actual fwnode references.
>
> It's possible for drivers to reference real firmware nodes from software
> nodes via PROPERTY_ENTRY_REF() in general or PROPERTY_ENTRY_GPIO()
> specifically but for platform devices binding to real firmware nodes (DT
> or ACPI) it's cumbersome as they would need to dynamically look for the
> right nodes and create references dynamically with no way of using
> static const software nodes.
>
> This series proposes a solution in the form of automatic secondary
> software node assignment (I'm open to better naming ideas). We extend
> the swnode API with functions allowing to set up a behind-the-scenes bus
> notifier for a group of named software nodes. It will wait for bus
> events and when a device is added, it will check its name against the
> software node's name and - on match - assign the software node as the
> secondary firmware node of the device's *real* firmware node.
The more I think about the current approaches with strict identity
matching the less I like them, and the reason is that strict identity
matching establishes rigid links between consumers and producers of
GPIOS/swnodes, and puts us into link order hell. For example, I believe
if andoird tablets drivers were in drivers/android vs
drivers/platform/... the current scheme would break since the nodes
would not be registered and GPIO lookups would fail with -ENOENT vs
-EPROBE_DEFER.
Given that this series somewhat re-introduces the name matching, I
wonder if we can not do something like the following (the rough draft):
diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
index 51320837f3a9..b0e8923a092c 100644
--- a/drivers/base/swnode.c
+++ b/drivers/base/swnode.c
@@ -509,6 +509,7 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
struct swnode *swnode = to_swnode(fwnode);
const struct software_node_ref_args *ref_array;
const struct software_node_ref_args *ref;
+ const struct software_node *ref_swnode;
const struct property_entry *prop;
struct fwnode_handle *refnode;
u32 nargs_prop_val;
@@ -550,7 +551,10 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
refnode = software_node_fwnode(ref->swnode);
else if (ref->fwnode)
refnode = ref->fwnode;
- else
+ else if (ref->swnode_name) {
+ ref_swnode = software_node_find_by_name(NULL, ref->swnode_name);
+ refnode = ref_swnode ? software_node_fwnode(ref_swnode) : NULL;
+ } else
return -EINVAL;
if (!refnode)
diff --git a/include/linux/property.h b/include/linux/property.h
index e30ef23a9af3..44e96ee47272 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -363,6 +363,7 @@ struct software_node;
struct software_node_ref_args {
const struct software_node *swnode;
struct fwnode_handle *fwnode;
+ const char *swnode_name;
unsigned int nargs;
u64 args[NR_FWNODE_REFERENCE_ARGS];
};
@@ -373,6 +374,9 @@ struct software_node_ref_args {
const struct software_node *: _ref_, \
struct software_node *: _ref_, \
default: NULL), \
+ .swnode_name = _Generic(_ref_, \
+ const char *: _ref_, \
+ default: NULL), \
.fwnode = _Generic(_ref_, \
struct fwnode_handle *: _ref_, \
default: NULL), \
This will allow consumers specify top-level software node name instead
of software node structure, and it will get resolved to concrete
firmware node. GPIOLIB can continue matching on node identity.
WDYT?
Also, you need to update the existing documentation in order to be able
to call the existing documented practice an "abuse" ;)
Thanks.
--
Dmitry
On Fri, 20 Mar 2026 02:49:02 +0100, Dmitry Torokhov
<dmitry.torokhov@gmail.com> said:
> Hi Bartosz,
>
> On Thu, Mar 19, 2026 at 05:10:53PM +0100, Bartosz Golaszewski wrote:
>>
>> This series proposes a solution in the form of automatic secondary
>> software node assignment (I'm open to better naming ideas). We extend
>> the swnode API with functions allowing to set up a behind-the-scenes bus
>> notifier for a group of named software nodes. It will wait for bus
>> events and when a device is added, it will check its name against the
>> software node's name and - on match - assign the software node as the
>> secondary firmware node of the device's *real* firmware node.
>
> The more I think about the current approaches with strict identity
> matching the less I like them, and the reason is that strict identity
> matching establishes rigid links between consumers and producers of
> GPIOS/swnodes, and puts us into link order hell. For example, I believe
> if andoird tablets drivers were in drivers/android vs
> drivers/platform/... the current scheme would break since the nodes
> would not be registered and GPIO lookups would fail with -ENOENT vs
> -EPROBE_DEFER.
>
Why would they not get registered? They get attached when the target devices
are added in modules this module depends on. They are exported symbols so the
prerequisite modules will get loaded before and the module's init function
will have run by the time the software nodes are referred to by the fwnode
interface at which point they will have been registered with the swnode
framework.
> Given that this series somewhat re-introduces the name matching, I
> wonder if we can not do something like the following (the rough draft):
>
I'm open to better ideas and possibly multiple matching mechanisms but this
just fit in this particular case. I'm not overly attached to name matching. We
may as well use whatever properties ACPI provides to identify the devices and
assign them their swnodes.
> diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
> index 51320837f3a9..b0e8923a092c 100644
> --- a/drivers/base/swnode.c
> +++ b/drivers/base/swnode.c
> @@ -509,6 +509,7 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
> struct swnode *swnode = to_swnode(fwnode);
> const struct software_node_ref_args *ref_array;
> const struct software_node_ref_args *ref;
> + const struct software_node *ref_swnode;
> const struct property_entry *prop;
> struct fwnode_handle *refnode;
> u32 nargs_prop_val;
> @@ -550,7 +551,10 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
> refnode = software_node_fwnode(ref->swnode);
> else if (ref->fwnode)
> refnode = ref->fwnode;
> - else
> + else if (ref->swnode_name) {
> + ref_swnode = software_node_find_by_name(NULL, ref->swnode_name);
> + refnode = ref_swnode ? software_node_fwnode(ref_swnode) : NULL;
> + } else
> return -EINVAL;
>
> if (!refnode)
> diff --git a/include/linux/property.h b/include/linux/property.h
> index e30ef23a9af3..44e96ee47272 100644
> --- a/include/linux/property.h
> +++ b/include/linux/property.h
> @@ -363,6 +363,7 @@ struct software_node;
> struct software_node_ref_args {
> const struct software_node *swnode;
> struct fwnode_handle *fwnode;
> + const char *swnode_name;
> unsigned int nargs;
> u64 args[NR_FWNODE_REFERENCE_ARGS];
> };
> @@ -373,6 +374,9 @@ struct software_node_ref_args {
> const struct software_node *: _ref_, \
> struct software_node *: _ref_, \
> default: NULL), \
> + .swnode_name = _Generic(_ref_, \
> + const char *: _ref_, \
> + default: NULL), \
> .fwnode = _Generic(_ref_, \
> struct fwnode_handle *: _ref_, \
> default: NULL), \
>
> This will allow consumers specify top-level software node name instead
> of software node structure, and it will get resolved to concrete
> firmware node. GPIOLIB can continue matching on node identity.
>
> WDYT?
>
I think it's bad design and even bigger abuse of the software node concept.
What you're proposing is effectively allowing to use struct software_node as
a misleading string wrapper. You wouldn't use it to pass any properties to
the device you're pointing to - because how if there's no link between them -
you would just store an arbitrary string in a structure that serves
a completely different purpose.
Which is BTW exactly what was done in GPIO and - while there's no denying that
I signed-off on these patches - it goes to show just how misleading this design
is - I was aware of this development and queued the patches but only really
understood what was going on when it was too late and this pattern was
copy-pasted all over the kernel.
Software nodes are just an implementation of firmware nodes and as such should
follow the same principles. If a software node describes a device, it should be
attached to it so that references can be resolved by checking the address of
the underlying firmware node handle and not by string matching. I will die on
that hill. :)
If you want to match string, use GPIO lookup tables. I remember your point about
wanting to use PROPERTY_ENTRY_REF() for consistency and fully support it, but
please do use *references* because otherwise it's just a lookup table with extra
steps.
Just think about it: what if we try to generalize fw_devlink to software nodes?
It would be completely broken for the offending GPIO users because there's no
real link between the software nodes supposedly pointing to the GPIO
controllers and the controllers themselves.
> Also, you need to update the existing documentation in order to be able
> to call the existing documented practice an "abuse" ;)
>
Yes, I should.
Thanks,
Bartosz
On Fri, Mar 20, 2026 at 01:33:06PM -0700, Bartosz Golaszewski wrote:
> On Fri, 20 Mar 2026 02:49:02 +0100, Dmitry Torokhov
> <dmitry.torokhov@gmail.com> said:
> > Hi Bartosz,
> >
> > On Thu, Mar 19, 2026 at 05:10:53PM +0100, Bartosz Golaszewski wrote:
> >>
> >> This series proposes a solution in the form of automatic secondary
> >> software node assignment (I'm open to better naming ideas). We extend
> >> the swnode API with functions allowing to set up a behind-the-scenes bus
> >> notifier for a group of named software nodes. It will wait for bus
> >> events and when a device is added, it will check its name against the
> >> software node's name and - on match - assign the software node as the
> >> secondary firmware node of the device's *real* firmware node.
> >
> > The more I think about the current approaches with strict identity
> > matching the less I like them, and the reason is that strict identity
> > matching establishes rigid links between consumers and producers of
> > GPIOS/swnodes, and puts us into link order hell. For example, I believe
> > if andoird tablets drivers were in drivers/android vs
> > drivers/platform/... the current scheme would break since the nodes
> > would not be registered and GPIO lookups would fail with -ENOENT vs
> > -EPROBE_DEFER.
> >
>
> Why would they not get registered? They get attached when the target devices
> are added in modules this module depends on. They are exported symbols so the
> prerequisite modules will get loaded before and the module's init function
> will have run by the time the software nodes are referred to by the fwnode
> interface at which point they will have been registered with the swnode
> framework.
I mentioned link order, which implies no modules are involved. When code
is built into the kernel initialization follows link order, which is
typically alphabetical. To ensure the order you require you either need
to move targets inside makefiles or change some drivers from
module_init() to <some other>_initcall(). This is known as "link order
hell" that was very common before deferred probing was introduced.
>
> > Given that this series somewhat re-introduces the name matching, I
> > wonder if we can not do something like the following (the rough draft):
> >
>
> I'm open to better ideas and possibly multiple matching mechanisms but this
> just fit in this particular case. I'm not overly attached to name matching. We
> may as well use whatever properties ACPI provides to identify the devices and
> assign them their swnodes.
What ACPI has to do with this? Oftentimes we are dealing with non x86
systems.
>
> > diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
> > index 51320837f3a9..b0e8923a092c 100644
> > --- a/drivers/base/swnode.c
> > +++ b/drivers/base/swnode.c
> > @@ -509,6 +509,7 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
> > struct swnode *swnode = to_swnode(fwnode);
> > const struct software_node_ref_args *ref_array;
> > const struct software_node_ref_args *ref;
> > + const struct software_node *ref_swnode;
> > const struct property_entry *prop;
> > struct fwnode_handle *refnode;
> > u32 nargs_prop_val;
> > @@ -550,7 +551,10 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
> > refnode = software_node_fwnode(ref->swnode);
> > else if (ref->fwnode)
> > refnode = ref->fwnode;
> > - else
> > + else if (ref->swnode_name) {
> > + ref_swnode = software_node_find_by_name(NULL, ref->swnode_name);
> > + refnode = ref_swnode ? software_node_fwnode(ref_swnode) : NULL;
> > + } else
> > return -EINVAL;
> >
> > if (!refnode)
> > diff --git a/include/linux/property.h b/include/linux/property.h
> > index e30ef23a9af3..44e96ee47272 100644
> > --- a/include/linux/property.h
> > +++ b/include/linux/property.h
> > @@ -363,6 +363,7 @@ struct software_node;
> > struct software_node_ref_args {
> > const struct software_node *swnode;
> > struct fwnode_handle *fwnode;
> > + const char *swnode_name;
> > unsigned int nargs;
> > u64 args[NR_FWNODE_REFERENCE_ARGS];
> > };
> > @@ -373,6 +374,9 @@ struct software_node_ref_args {
> > const struct software_node *: _ref_, \
> > struct software_node *: _ref_, \
> > default: NULL), \
> > + .swnode_name = _Generic(_ref_, \
> > + const char *: _ref_, \
> > + default: NULL), \
> > .fwnode = _Generic(_ref_, \
> > struct fwnode_handle *: _ref_, \
> > default: NULL), \
> >
> > This will allow consumers specify top-level software node name instead
> > of software node structure, and it will get resolved to concrete
> > firmware node. GPIOLIB can continue matching on node identity.
> >
> > WDYT?
> >
>
> I think it's bad design and even bigger abuse of the software node concept.
> What you're proposing is effectively allowing to use struct software_node as
> a misleading string wrapper. You wouldn't use it to pass any properties to
> the device you're pointing to - because how if there's no link between them -
> you would just store an arbitrary string in a structure that serves
> a completely different purpose.
I think you completely misunderstood the proposal. We are not using
software node as a string wrapper, we give an opportunity to use
software node name to resolve to the real software node at the time we
try to resolve the reference. The software node is still expected to be
bound to the target device (unlike the original approach that has a
dangling software node which name expected to match gpiochip label).
I think this actually a very good approach: it severs the tight coupling
while still maintains the spirit of firmware nodes being attached to
devices. The only difference we are using object's name and not its
address as starting point. Similarly how you use name derived from
device name to locate and assign secondary node in this patch series.
>
> Which is BTW exactly what was done in GPIO and - while there's no denying that
> I signed-off on these patches - it goes to show just how misleading this design
> is - I was aware of this development and queued the patches but only really
> understood what was going on when it was too late and this pattern was
> copy-pasted all over the kernel.
>
> Software nodes are just an implementation of firmware nodes and as such should
> follow the same principles. If a software node describes a device, it should be
> attached to it
Yes, and the patch above solves this.
> so that references can be resolved by checking the address of
> the underlying firmware node handle and not by string matching. I will die on
> that hill. :)
I would like to understand why. I outlined the problems with this
approach (too tight coupling, needing to export nodes, include
additional headers, and deal with the link order issues, along with
potential changes to the system initialization/probe order). What are
the drawbacks of name matching as long as we do not create
dangling/shadow nodes?
You are saying that you want resolve strictly by address, but have you
looked at how OF references are resolved? Hint: phandle is not a raw
address. It's actually a 32 bit integer! Look at ACPI. It also does not
simply have a pointer to another ACPI node there, the data structure is
much more complex.
So why are you trying to make software nodes different from all the
other firmware nodes?
>
> If you want to match string, use GPIO lookup tables. I remember your point about
> wanting to use PROPERTY_ENTRY_REF() for consistency and fully support it, but
> please do use *references* because otherwise it's just a lookup table with extra
> steps.
>
> Just think about it: what if we try to generalize fw_devlink to software nodes?
> It would be completely broken for the offending GPIO users because there's no
> real link between the software nodes supposedly pointing to the GPIO
> controllers and the controllers themselves.
There is, you just misunderstood the proposal I'm afraid.
Thanks.
--
Dmitry
On Sat, 21 Mar 2026 08:01:30 +0100, Dmitry Torokhov
<dmitry.torokhov@gmail.com> said:
> On Fri, Mar 20, 2026 at 01:33:06PM -0700, Bartosz Golaszewski wrote:
>> On Fri, 20 Mar 2026 02:49:02 +0100, Dmitry Torokhov
>> <dmitry.torokhov@gmail.com> said:
>> > Hi Bartosz,
>> >
>> > On Thu, Mar 19, 2026 at 05:10:53PM +0100, Bartosz Golaszewski wrote:
>> >>
>> >> This series proposes a solution in the form of automatic secondary
>> >> software node assignment (I'm open to better naming ideas). We extend
>> >> the swnode API with functions allowing to set up a behind-the-scenes bus
>> >> notifier for a group of named software nodes. It will wait for bus
>> >> events and when a device is added, it will check its name against the
>> >> software node's name and - on match - assign the software node as the
>> >> secondary firmware node of the device's *real* firmware node.
>> >
>> > The more I think about the current approaches with strict identity
>> > matching the less I like them, and the reason is that strict identity
>> > matching establishes rigid links between consumers and producers of
>> > GPIOS/swnodes, and puts us into link order hell. For example, I believe
>> > if andoird tablets drivers were in drivers/android vs
>> > drivers/platform/... the current scheme would break since the nodes
>> > would not be registered and GPIO lookups would fail with -ENOENT vs
>> > -EPROBE_DEFER.
>> >
>>
>> Why would they not get registered? They get attached when the target devices
>> are added in modules this module depends on. They are exported symbols so the
>> prerequisite modules will get loaded before and the module's init function
>> will have run by the time the software nodes are referred to by the fwnode
>> interface at which point they will have been registered with the swnode
>> framework.
>
> I mentioned link order, which implies no modules are involved. When code
> is built into the kernel initialization follows link order, which is
> typically alphabetical. To ensure the order you require you either need
> to move targets inside makefiles or change some drivers from
> module_init() to <some other>_initcall(). This is known as "link order
> hell" that was very common before deferred probing was introduced.
>
Maybe we should return -EPROBE_DEFER in GPIO swnode lookup when
fwnode_property_get_reference_args() returns -ENOENT because if there's a
software node that's not yet been registered as a firmware node, it's not much
different from there being a firmware node not bound to a device yet - which
is grounds for probe deferral.
>>
>> > Given that this series somewhat re-introduces the name matching, I
>> > wonder if we can not do something like the following (the rough draft):
>> >
>>
>> I'm open to better ideas and possibly multiple matching mechanisms but this
>> just fit in this particular case. I'm not overly attached to name matching. We
>> may as well use whatever properties ACPI provides to identify the devices and
>> assign them their swnodes.
>
> What ACPI has to do with this? Oftentimes we are dealing with non x86
> systems.
>
What I meant is: name matching is only one method of assigning software nodes
to devices. Here I went with waiting for devices but with DT we may as well
look up a node by compatible depending on the driver. For ACPI we may probably
use some mechanism that matches the devices to the software node in a more
specific way. That's just hypothetical, I don't know if there even is one.
IOW: device-name-to-software-node name matching is only one of possible methods.
>>
>> > diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
>> > index 51320837f3a9..b0e8923a092c 100644
>> > --- a/drivers/base/swnode.c
>> > +++ b/drivers/base/swnode.c
>> > @@ -509,6 +509,7 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
>> > struct swnode *swnode = to_swnode(fwnode);
>> > const struct software_node_ref_args *ref_array;
>> > const struct software_node_ref_args *ref;
>> > + const struct software_node *ref_swnode;
>> > const struct property_entry *prop;
>> > struct fwnode_handle *refnode;
>> > u32 nargs_prop_val;
>> > @@ -550,7 +551,10 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
>> > refnode = software_node_fwnode(ref->swnode);
>> > else if (ref->fwnode)
>> > refnode = ref->fwnode;
>> > - else
>> > + else if (ref->swnode_name) {
>> > + ref_swnode = software_node_find_by_name(NULL, ref->swnode_name);
>> > + refnode = ref_swnode ? software_node_fwnode(ref_swnode) : NULL;
>> > + } else
>> > return -EINVAL;
>> >
>> > if (!refnode)
>> > diff --git a/include/linux/property.h b/include/linux/property.h
>> > index e30ef23a9af3..44e96ee47272 100644
>> > --- a/include/linux/property.h
>> > +++ b/include/linux/property.h
>> > @@ -363,6 +363,7 @@ struct software_node;
>> > struct software_node_ref_args {
>> > const struct software_node *swnode;
>> > struct fwnode_handle *fwnode;
>> > + const char *swnode_name;
>> > unsigned int nargs;
>> > u64 args[NR_FWNODE_REFERENCE_ARGS];
>> > };
>> > @@ -373,6 +374,9 @@ struct software_node_ref_args {
>> > const struct software_node *: _ref_, \
>> > struct software_node *: _ref_, \
>> > default: NULL), \
>> > + .swnode_name = _Generic(_ref_, \
>> > + const char *: _ref_, \
>> > + default: NULL), \
>> > .fwnode = _Generic(_ref_, \
>> > struct fwnode_handle *: _ref_, \
>> > default: NULL), \
>> >
>> > This will allow consumers specify top-level software node name instead
>> > of software node structure, and it will get resolved to concrete
>> > firmware node. GPIOLIB can continue matching on node identity.
>> >
>> > WDYT?
>> >
>>
>> I think it's bad design and even bigger abuse of the software node concept.
>> What you're proposing is effectively allowing to use struct software_node as
>> a misleading string wrapper. You wouldn't use it to pass any properties to
>> the device you're pointing to - because how if there's no link between them -
>> you would just store an arbitrary string in a structure that serves
>> a completely different purpose.
>
> I think you completely misunderstood the proposal. We are not using
Ok, I didn't fully get that part, I was OoO on Friday and should have probably
not rushed a late evening answer. :)
> software node as a string wrapper, we give an opportunity to use
> software node name to resolve to the real software node at the time we
> try to resolve the reference. The software node is still expected to be
> bound to the target device (unlike the original approach that has a
> dangling software node which name expected to match gpiochip label).
>
> I think this actually a very good approach: it severs the tight coupling
> while still maintains the spirit of firmware nodes being attached to
> devices. The only difference we are using object's name and not its
> address as starting point. Similarly how you use name derived from
> device name to locate and assign secondary node in this patch series.
>
I still don't like it. It forces us to use names for the remote software nodes,
which are after all C structures that we could identify by addresses alone.
Even this series could be reworked to drop the names from the GPIO software
nodes.
software_node_find_by_name() only goes through the list of registered software
nodes so we'd still end up returning -ENOENT for nodes which have not been
registered yet and wouldn't be able to tell this situation apart from a case
where there's no such software node at all.
The consumer driver still needs to know the remote device by an arbitrary
string.
I think you're exaggarating the possible problems with link order. I believe
that issue could be fixed by returning EPROBE_DEFER when a software node is
not yet known by an fwnode handle but we know it is there so it's just a matter
of it getting registered.
That being said, I would like to hear from driver core maintainers in general
and from software node maintainers in particular.
>>
>> Which is BTW exactly what was done in GPIO and - while there's no denying that
>> I signed-off on these patches - it goes to show just how misleading this design
>> is - I was aware of this development and queued the patches but only really
>> understood what was going on when it was too late and this pattern was
>> copy-pasted all over the kernel.
>>
>> Software nodes are just an implementation of firmware nodes and as such should
>> follow the same principles. If a software node describes a device, it should be
>> attached to it
>
> Yes, and the patch above solves this.
>
I would say it just pushes the string matching deeper.
>> so that references can be resolved by checking the address of
>> the underlying firmware node handle and not by string matching. I will die on
>> that hill. :)
>
> I would like to understand why. I outlined the problems with this
> approach (too tight coupling, needing to export nodes, include
> additional headers, and deal with the link order issues, along with
> potential changes to the system initialization/probe order). What are
> the drawbacks of name matching as long as we do not create
> dangling/shadow nodes?
>
> You are saying that you want resolve strictly by address, but have you
> looked at how OF references are resolved? Hint: phandle is not a raw
> address. It's actually a 32 bit integer! Look at ACPI. It also does not
> simply have a pointer to another ACPI node there, the data structure is
> much more complex.
>
That's dictated by the binary format of devicetree where:
prop = <&foo>;
Is translated to:
foo {
phandle = <0x123>;
};
prop = <0x123>;
And I suppose this could be translated into addresses of respective struct
device_node objects already at the tree unflattening stage - just like is
done for parent-child relationships.
However, this is very much hidden from users and someone who deals with DT
sources always sees a proper reference to a node (by path, label or otherwise).
Here we're talking about referring to firmware nodes by name which does happen
but is typically reserved for some special cases and well-known nodes.
Bartosz
On Mon, Mar 23, 2026 at 04:40:11AM -0700, Bartosz Golaszewski wrote:
> On Sat, 21 Mar 2026 08:01:30 +0100, Dmitry Torokhov
> <dmitry.torokhov@gmail.com> said:
> > On Fri, Mar 20, 2026 at 01:33:06PM -0700, Bartosz Golaszewski wrote:
> >> On Fri, 20 Mar 2026 02:49:02 +0100, Dmitry Torokhov
> >> <dmitry.torokhov@gmail.com> said:
> >> > Hi Bartosz,
> >> >
> >> > On Thu, Mar 19, 2026 at 05:10:53PM +0100, Bartosz Golaszewski wrote:
> >> >>
> >> >> This series proposes a solution in the form of automatic secondary
> >> >> software node assignment (I'm open to better naming ideas). We extend
> >> >> the swnode API with functions allowing to set up a behind-the-scenes bus
> >> >> notifier for a group of named software nodes. It will wait for bus
> >> >> events and when a device is added, it will check its name against the
> >> >> software node's name and - on match - assign the software node as the
> >> >> secondary firmware node of the device's *real* firmware node.
> >> >
> >> > The more I think about the current approaches with strict identity
> >> > matching the less I like them, and the reason is that strict identity
> >> > matching establishes rigid links between consumers and producers of
> >> > GPIOS/swnodes, and puts us into link order hell. For example, I believe
> >> > if andoird tablets drivers were in drivers/android vs
> >> > drivers/platform/... the current scheme would break since the nodes
> >> > would not be registered and GPIO lookups would fail with -ENOENT vs
> >> > -EPROBE_DEFER.
> >> >
> >>
> >> Why would they not get registered? They get attached when the target devices
> >> are added in modules this module depends on. They are exported symbols so the
> >> prerequisite modules will get loaded before and the module's init function
> >> will have run by the time the software nodes are referred to by the fwnode
> >> interface at which point they will have been registered with the swnode
> >> framework.
> >
> > I mentioned link order, which implies no modules are involved. When code
> > is built into the kernel initialization follows link order, which is
> > typically alphabetical. To ensure the order you require you either need
> > to move targets inside makefiles or change some drivers from
> > module_init() to <some other>_initcall(). This is known as "link order
> > hell" that was very common before deferred probing was introduced.
> >
>
> Maybe we should return -EPROBE_DEFER in GPIO swnode lookup when
> fwnode_property_get_reference_args() returns -ENOENT because if there's a
> software node that's not yet been registered as a firmware node, it's not much
> different from there being a firmware node not bound to a device yet - which
> is grounds for probe deferral.
Yes, I think this is a good idea.
>
> >>
> >> > Given that this series somewhat re-introduces the name matching, I
> >> > wonder if we can not do something like the following (the rough draft):
> >> >
> >>
> >> I'm open to better ideas and possibly multiple matching mechanisms but this
> >> just fit in this particular case. I'm not overly attached to name matching. We
> >> may as well use whatever properties ACPI provides to identify the devices and
> >> assign them their swnodes.
> >
> > What ACPI has to do with this? Oftentimes we are dealing with non x86
> > systems.
> >
>
> What I meant is: name matching is only one method of assigning software nodes
> to devices. Here I went with waiting for devices but with DT we may as well
> look up a node by compatible depending on the driver. For ACPI we may probably
> use some mechanism that matches the devices to the software node in a more
> specific way. That's just hypothetical, I don't know if there even is one.
>
> IOW: device-name-to-software-node name matching is only one of possible methods.
I see.
>
> >>
> >> > diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
> >> > index 51320837f3a9..b0e8923a092c 100644
> >> > --- a/drivers/base/swnode.c
> >> > +++ b/drivers/base/swnode.c
> >> > @@ -509,6 +509,7 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
> >> > struct swnode *swnode = to_swnode(fwnode);
> >> > const struct software_node_ref_args *ref_array;
> >> > const struct software_node_ref_args *ref;
> >> > + const struct software_node *ref_swnode;
> >> > const struct property_entry *prop;
> >> > struct fwnode_handle *refnode;
> >> > u32 nargs_prop_val;
> >> > @@ -550,7 +551,10 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
> >> > refnode = software_node_fwnode(ref->swnode);
> >> > else if (ref->fwnode)
> >> > refnode = ref->fwnode;
> >> > - else
> >> > + else if (ref->swnode_name) {
> >> > + ref_swnode = software_node_find_by_name(NULL, ref->swnode_name);
> >> > + refnode = ref_swnode ? software_node_fwnode(ref_swnode) : NULL;
> >> > + } else
> >> > return -EINVAL;
> >> >
> >> > if (!refnode)
> >> > diff --git a/include/linux/property.h b/include/linux/property.h
> >> > index e30ef23a9af3..44e96ee47272 100644
> >> > --- a/include/linux/property.h
> >> > +++ b/include/linux/property.h
> >> > @@ -363,6 +363,7 @@ struct software_node;
> >> > struct software_node_ref_args {
> >> > const struct software_node *swnode;
> >> > struct fwnode_handle *fwnode;
> >> > + const char *swnode_name;
> >> > unsigned int nargs;
> >> > u64 args[NR_FWNODE_REFERENCE_ARGS];
> >> > };
> >> > @@ -373,6 +374,9 @@ struct software_node_ref_args {
> >> > const struct software_node *: _ref_, \
> >> > struct software_node *: _ref_, \
> >> > default: NULL), \
> >> > + .swnode_name = _Generic(_ref_, \
> >> > + const char *: _ref_, \
> >> > + default: NULL), \
> >> > .fwnode = _Generic(_ref_, \
> >> > struct fwnode_handle *: _ref_, \
> >> > default: NULL), \
> >> >
> >> > This will allow consumers specify top-level software node name instead
> >> > of software node structure, and it will get resolved to concrete
> >> > firmware node. GPIOLIB can continue matching on node identity.
> >> >
> >> > WDYT?
> >> >
> >>
> >> I think it's bad design and even bigger abuse of the software node concept.
> >> What you're proposing is effectively allowing to use struct software_node as
> >> a misleading string wrapper. You wouldn't use it to pass any properties to
> >> the device you're pointing to - because how if there's no link between them -
> >> you would just store an arbitrary string in a structure that serves
> >> a completely different purpose.
> >
> > I think you completely misunderstood the proposal. We are not using
>
> Ok, I didn't fully get that part, I was OoO on Friday and should have probably
> not rushed a late evening answer. :)
>
> > software node as a string wrapper, we give an opportunity to use
> > software node name to resolve to the real software node at the time we
> > try to resolve the reference. The software node is still expected to be
> > bound to the target device (unlike the original approach that has a
> > dangling software node which name expected to match gpiochip label).
> >
> > I think this actually a very good approach: it severs the tight coupling
> > while still maintains the spirit of firmware nodes being attached to
> > devices. The only difference we are using object's name and not its
> > address as starting point. Similarly how you use name derived from
> > device name to locate and assign secondary node in this patch series.
> >
>
> I still don't like it. It forces us to use names for the remote software nodes,
> which are after all C structures that we could identify by addresses alone.
> Even this series could be reworked to drop the names from the GPIO software
> nodes.
The whole device property business is string matching, because that is
what device properties are. If we want strict type matching we should
continue using per-driver platform data, it provides type safety. But I
think the preference is to actually use properties for configuring
devices.
>
> software_node_find_by_name() only goes through the list of registered software
> nodes so we'd still end up returning -ENOENT for nodes which have not been
> registered yet and wouldn't be able to tell this situation apart from a case
> where there's no such software node at all.
Yes, we'd need to convert this to -EPROBE_DEFER similarly to what you
proposed above.
>
> The consumer driver still needs to know the remote device by an arbitrary
> string.
Yes, but I think this is acceptable because of increased flexibility.
>
> I think you're exaggarating the possible problems with link order. I believe
> that issue could be fixed by returning EPROBE_DEFER when a software node is
> not yet known by an fwnode handle but we know it is there so it's just a matter
> of it getting registered.
You need to have the module loaded and initialized so that the address
can be resolved. This changes link order and may produce unwanted
changes to the device init order.
>
> That being said, I would like to hear from driver core maintainers in general
> and from software node maintainers in particular.
I think I'll send out a forma patch and we can discuss further.
Thanks.
--
Dmitry
© 2016 - 2026 Red Hat, Inc.