[PATCH v2 5/8] driver core: platform: warn on bad fwnode assignment

From: Johan Hovold

Date: Tue Nov 10 2026 - 03:54:47 EST


Commit e6054f410c97 ("driver core: platform: amend the API contract for
fwnode setters") added a warning to platform_device_set_fwnode() in case
the current firmware node pointer points to a software node as that may
prevent software_node_notify_remove() from being called.

This is only an issue if the platform device has been registered however
as software_node_notify() is only called for registered devices. A
bigger issue is that a secondary firmware node assigned before the call
may be silently lost (and leaked in case of software nodes) as these
helpers do not use set_primary_fwnode().

Replace the current software node check with a warning in case the
device already has a primary or secondary firmware node assigned to
catch any (hard-to-debug) issues due to a secondary node being assigned
before the call.

Note that this also avoids making claims about the device firmware node
pointing to the primary firmware node, which is not the case when the
device only has a secondary node.

Fixes: e6054f410c97 ("driver core: platform: amend the API contract for fwnode setters")
Cc: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxxxxxxxx>
Signed-off-by: Johan Hovold <johan@xxxxxxxxxx>
---
drivers/base/platform.c | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index e0b38dbd5acf..869c044f8182 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -709,8 +709,7 @@ EXPORT_SYMBOL_GPL(platform_device_add_data);
* Assign an OF node to this platform device. Internally keep track of the
* reference count. Devices created with platform_device_alloc() must use this
* function instead of assigning the node manually. This function must not be
- * called for a platform device that already has a software node as its primary
- * firmware node assigned.
+ * called for a platform device that already has a firmware node assigned.
*/
void platform_device_set_of_node(struct platform_device *pdev,
struct device_node *np)
@@ -727,19 +726,16 @@ EXPORT_SYMBOL_GPL(platform_device_set_of_node);
* Assign a firmware node to this platform device. Internally keep track of the
* reference count. Devices created with platform_device_alloc() must use this
* function instead of assigning the node manually. This function must not be
- * called for a platform device that already has a software node as its primary
- * firmware node assigned.
+ * called for a platform device that already has a firmware node assigned.
*/
void platform_device_set_fwnode(struct platform_device *pdev,
struct fwnode_handle *fwnode)
{
/*
- * If we call this function for a platform device whose primary
- * firmware node is a software node, we'll never end up calling the
- * symmetric software_node_notify_remove(). There are no users for this
- * right now in the tree so just disallow it.
+ * A secondary firmware node may be lost as set_primary_fwnode() is
+ * not used here, warn for now if a node has already been set.
*/
- WARN_ON(is_software_node(dev_fwnode(&pdev->dev)));
+ WARN_ON(dev_fwnode(&pdev->dev));
fwnode_handle_put(pdev->dev.fwnode);
device_set_node(&pdev->dev, fwnode_handle_get(fwnode));
}
@@ -752,14 +748,16 @@ EXPORT_SYMBOL_GPL(platform_device_set_fwnode);
*
* Reuses the OF node of another device in this platform device while
* internally keeping track of reference counting. This function must not be
- * called for a platform device that already has a software node as its primary
- * firmware node assigned.
+ * called for a platform device that already has a firmware node assigned.
*/
void platform_device_set_of_node_from_dev(struct platform_device *pdev,
const struct device *dev2)
{
- /* See platform_device_set_fwnode(). */
- WARN_ON(is_software_node(dev_fwnode(&pdev->dev)));
+ /*
+ * A secondary firmware node may be lost as set_primary_fwnode() is
+ * not used here, warn for now if a node has already been set.
+ */
+ WARN_ON(dev_fwnode(&pdev->dev));
device_set_of_node_from_dev(&pdev->dev, dev2);
pdev->dev.fwnode = of_fwnode_handle(pdev->dev.of_node);
}
--
2.56.0