Skip to content

Commit 114294d

Browse files
charleskeepaxLee Jones
authored andcommitted
mfd: mfd-core: Add mechanism for removal of a subset of children
Currently, the only way to remove MFD children is with a call to mfd_remove_devices, which will remove all the children. Under some circumstances it is useful to remove only a subset of the child devices. For example if some additional clean up is required between removal of certain child devices. To accomplish this a level field is added to mfd_cell, the normal mfd_remove_devices is modified to not remove devices that are set to a higher level and a corresponding mfd_remove_devices_late function is added to remove those children. See further discussion at: https://lore.kernel.org/lkml/20200616075834.GF2608702@dell/ Suggested-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
1 parent 4ee1d9d commit 114294d

2 files changed

Lines changed: 20 additions & 1 deletion

File tree

drivers/mfd/mfd-core.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,13 +356,17 @@ static int mfd_remove_devices_fn(struct device *dev, void *data)
356356
{
357357
struct platform_device *pdev;
358358
const struct mfd_cell *cell;
359+
int *level = data;
359360

360361
if (dev->type != &mfd_dev_type)
361362
return 0;
362363

363364
pdev = to_platform_device(dev);
364365
cell = mfd_get_cell(pdev);
365366

367+
if (level && cell->level > *level)
368+
return 0;
369+
366370
regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies,
367371
cell->num_parent_supplies);
368372

@@ -372,9 +376,19 @@ static int mfd_remove_devices_fn(struct device *dev, void *data)
372376
return 0;
373377
}
374378

379+
void mfd_remove_devices_late(struct device *parent)
380+
{
381+
int level = MFD_DEP_LEVEL_HIGH;
382+
383+
device_for_each_child_reverse(parent, &level, mfd_remove_devices_fn);
384+
}
385+
EXPORT_SYMBOL(mfd_remove_devices_late);
386+
375387
void mfd_remove_devices(struct device *parent)
376388
{
377-
device_for_each_child_reverse(parent, NULL, mfd_remove_devices_fn);
389+
int level = MFD_DEP_LEVEL_NORMAL;
390+
391+
device_for_each_child_reverse(parent, &level, mfd_remove_devices_fn);
378392
}
379393
EXPORT_SYMBOL(mfd_remove_devices);
380394

include/linux/mfd/core.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
#define MFD_CELL_NAME(_name) \
4747
MFD_CELL_ALL(_name, NULL, NULL, 0, 0, NULL, 0, false, NULL)
4848

49+
#define MFD_DEP_LEVEL_NORMAL 0
50+
#define MFD_DEP_LEVEL_HIGH 1
51+
4952
struct irq_domain;
5053
struct property_entry;
5154

@@ -63,6 +66,7 @@ struct mfd_cell_acpi_match {
6366
struct mfd_cell {
6467
const char *name;
6568
int id;
69+
int level;
6670

6771
int (*enable)(struct platform_device *dev);
6872
int (*disable)(struct platform_device *dev);
@@ -150,6 +154,7 @@ static inline int mfd_add_hotplug_devices(struct device *parent,
150154
}
151155

152156
extern void mfd_remove_devices(struct device *parent);
157+
extern void mfd_remove_devices_late(struct device *parent);
153158

154159
extern int devm_mfd_add_devices(struct device *dev, int id,
155160
const struct mfd_cell *cells, int n_devs,

0 commit comments

Comments
 (0)