[PATCH] mfd: core: update mfd_of_node_list list on mfd_remove_devices

From: Srinivas Kandagatla
Date: Wed Nov 18 2020 - 11:48:18 EST


Call to mfd_add_devices() after mfd_remove_devices() will always
fail in device tree use-case, because new device will find a matching node
in the global mfd_of_node_list resulting in mfd_match_of_node_to_dev()
to return -EAGAIN.

This is one of the use-case with WCD934x where mfd devices can disappear and
reappear when ADSP either restarts or its services restarts.

Fix this issue by removing the state entry in global mfd_of_node_list
during mfd_remove_devices.

Fixes: 466a62d7642f ("mfd: core: Make a best effort attempt to match devices with the correct of_nodes")
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@xxxxxxxxxx>
---
drivers/mfd/mfd-core.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index fc00aaccb5f7..3e845be895ac 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -359,6 +359,7 @@ static int mfd_remove_devices_fn(struct device *dev, void *data)
struct platform_device *pdev;
const struct mfd_cell *cell;
int *level = data;
+ struct mfd_of_node_entry *of_entry, *tmp;

if (dev->type != &mfd_dev_type)
return 0;
@@ -372,6 +373,12 @@ static int mfd_remove_devices_fn(struct device *dev, void *data)
regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies,
cell->num_parent_supplies);

+ list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list)
+ if (of_entry->dev == &pdev->dev) {
+ list_del(&of_entry->list);
+ kfree(of_entry);
+ }
+
platform_device_unregister(pdev);
return 0;
}
--
2.21.0