Re: [PATCH v22 08/13] mfd: core: Add firmware-node support to MFD cells
From: Shivendra Pratap
Date: Mon May 18 2026 - 12:47:17 EST
On 18-05-2026 14:27, Bartosz Golaszewski wrote:
On Thu, 14 May 2026 16:25:49 +0200, Shivendra Pratap
<shivendra.pratap@xxxxxxxxxxxxxxxx> said:
MFD core has no way to register a child device using an explicit firmware
node. This prevents drivers from registering child nodes when those nodes
do not define a compatible string. One such example is the PSCI
"reboot-mode" node, which omits a compatible string as it describes
boot-states provided by the underlying firmware.
Extend struct mfd_cell with a callback that allows drivers to provide an
explicit firmware node. The node is added to the MFD child device during
registration when none is assigned by device tree, ACPI, or software
matching.
Suggested-by: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxxxxxxxx>
Signed-off-by: Shivendra Pratap <shivendra.pratap@xxxxxxxxxxxxxxxx>
---
drivers/mfd/mfd-core.c | 30 ++++++++++++++++++++++++++++++
include/linux/mfd/core.h | 14 ++++++++++++++
2 files changed, 44 insertions(+)
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 7aa32b90cf1eb7fa0a05bf3dc506e60a262c9850..cc2a2a924d6d3044e29a9f864b536ee325ed797b 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/acpi.h>
+#include <linux/fwnode.h>
#include <linux/list.h>
#include <linux/property.h>
#include <linux/mfd/core.h>
@@ -148,6 +149,11 @@ static int mfd_match_of_node_to_dev(struct platform_device *pdev,
return 0;
}
+static void mfd_child_fwnode_put(void *data)
+{
+ fwnode_handle_put(data);
+}
Ah, this seems to answer my previous question, but...
+
static int mfd_add_device(struct device *parent, int id,
const struct mfd_cell *cell,
struct resource *mem_base,
@@ -156,6 +162,7 @@ static int mfd_add_device(struct device *parent, int id,
struct resource *res;
struct platform_device *pdev;
struct mfd_of_node_entry *of_entry, *tmp;
+ struct fwnode_handle *fwnode;
bool disabled = false;
int ret = -ENOMEM;
int platform_id;
@@ -224,6 +231,29 @@ static int mfd_add_device(struct device *parent, int id,
mfd_acpi_add_device(cell, pdev);
+ if (!pdev->dev.fwnode && cell->get_child_fwnode) {
+ fwnode = cell->get_child_fwnode(parent);
+ if (fwnode) {
+ device_set_node(&pdev->dev, fwnode);
+
+ /*
+ * platform_device_release() drops only of_node refs.
Which is a separate problem we're discussing elsewhere. It should probably drop
the fwnode reference it holds, not the one of of_node.
+ * Track non-OF fwnodes explicitly so they are put on
+ * all teardown paths.
+ */
+ if (!to_of_node(fwnode)) {
+ ret = devm_add_action(&pdev->dev,
+ mfd_child_fwnode_put,
+ fwnode);
What if the device never gets bound to the driver? The release will never be
called, this is why it's wrong to schedule devres actions for unbound devices
and one of the reasons for patch 1 in this series.
What I suggest for now is: in tear-down path: see if the cell has the
get_child_fwnode() callback and - if so - drop the reference. Add a big, fat
comment saying that this must be removed if we decide to switch to dropping the
device's fwnode reference in platform driver core which may happen soon.
Ack. sure. lets me work it out.
thanks,
Shivendra