[PATCH v22 08/13] mfd: core: Add firmware-node support to MFD cells

Shivendra Pratap shivendra.pratap at oss.qualcomm.com
Mon May 18 09:41:33 PDT 2026



On 18-05-2026 14:27, Bartosz Golaszewski wrote:
> On Thu, 14 May 2026 16:25:49 +0200, Shivendra Pratap
> <shivendra.pratap at oss.qualcomm.com> 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 at oss.qualcomm.com>
>> Signed-off-by: Shivendra Pratap <shivendra.pratap at oss.qualcomm.com>
>> ---
>>   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



More information about the linux-arm-kernel mailing list