On Fri, Sep 2, 2016 at 10:22 AM, David Herrmann <dh.herrmann@xxxxxxxxx> wrote: > We already expose of_platform_device_create(), but give the caller no > chance to revert its effect. Make sure we also provide the counterpart > of_platform_device_destroy(). > > This requires a small refactoring, since so far the internal destructor > is used as iterator to for_each_device(), but we don't want to expose it > with the "void *data" parameter. So provide > of_platform_device_depopulate() as new iterator, which calls into > of_platform_device_destroy(). > > While at it, drop the unused 'children_left' argument by > of_platform_notify(). It is a left-over that somehow was never removed. > > Signed-off-by: David Herrmann <dh.herrmann@xxxxxxxxx> Reviewed-by: Tom Gundersen <teg@xxxxxxx> > --- > drivers/of/platform.c | 35 ++++++++++++++++++++++++++--------- > include/linux/of_platform.h | 1 + > 2 files changed, 27 insertions(+), 9 deletions(-) > > diff --git a/drivers/of/platform.c b/drivers/of/platform.c > index f39ccd5..f9bb563 100644 > --- a/drivers/of/platform.c > +++ b/drivers/of/platform.c > @@ -524,15 +524,18 @@ static int __init of_platform_default_populate_init(void) > arch_initcall_sync(of_platform_default_populate_init); > #endif > > -static int of_platform_device_destroy(struct device *dev, void *data) > +/** > + * of_platform_device_destroy - unregister an of_device > + * @dev: device to unregister > + * > + * This is the inverse operation of of_platform_device_create(). It unregisters > + * the passed device, if registered. > + */ > +void of_platform_device_destroy(struct device *dev) > { > /* Do not touch devices not populated from the device tree */ > if (!dev->of_node || !of_node_check_flag(dev->of_node, OF_POPULATED)) > - return 0; > - > - /* Recurse for any nodes that were treated as busses */ > - if (of_node_check_flag(dev->of_node, OF_POPULATED_BUS)) > - device_for_each_child(dev, NULL, of_platform_device_destroy); > + return; > > if (dev->bus == &platform_bus_type) > platform_device_unregister(to_platform_device(dev)); > @@ -544,6 +547,20 @@ static int of_platform_device_destroy(struct device *dev, void *data) > of_dma_deconfigure(dev); > of_node_clear_flag(dev->of_node, OF_POPULATED); > of_node_clear_flag(dev->of_node, OF_POPULATED_BUS); > +} > +EXPORT_SYMBOL(of_platform_device_destroy); > + > +static int of_platform_device_depopulate(struct device *dev, void *data) > +{ > + /* Do not touch devices not populated from the device tree */ > + if (!dev->of_node || !of_node_check_flag(dev->of_node, OF_POPULATED)) > + return 0; > + > + /* Recurse for any nodes that were treated as busses */ > + if (of_node_check_flag(dev->of_node, OF_POPULATED_BUS)) > + device_for_each_child(dev, NULL, of_platform_device_depopulate); > + > + of_platform_device_destroy(dev); > return 0; > } > > @@ -562,7 +579,8 @@ static int of_platform_device_destroy(struct device *dev, void *data) > void of_platform_depopulate(struct device *parent) > { > if (parent->of_node && of_node_check_flag(parent->of_node, OF_POPULATED_BUS)) { > - device_for_each_child(parent, NULL, of_platform_device_destroy); > + device_for_each_child(parent, NULL, > + of_platform_device_depopulate); > of_node_clear_flag(parent->of_node, OF_POPULATED_BUS); > } > } > @@ -574,7 +592,6 @@ static int of_platform_notify(struct notifier_block *nb, > { > struct of_reconfig_data *rd = arg; > struct platform_device *pdev_parent, *pdev; > - bool children_left; > > switch (of_reconfig_get_state_change(action, rd)) { > case OF_RECONFIG_CHANGE_ADD: > @@ -612,7 +629,7 @@ static int of_platform_notify(struct notifier_block *nb, > return NOTIFY_OK; /* no? not meant for us */ > > /* unregister takes one ref away */ > - of_platform_device_destroy(&pdev->dev, &children_left); > + of_platform_device_depopulate(&pdev->dev, NULL); > > /* and put the reference of the find */ > of_dev_put(pdev); > diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h > index 956a100..a9017d3 100644 > --- a/include/linux/of_platform.h > +++ b/include/linux/of_platform.h > @@ -63,6 +63,7 @@ extern struct platform_device *of_find_device_by_node(struct device_node *np); > extern struct platform_device *of_platform_device_create(struct device_node *np, > const char *bus_id, > struct device *parent); > +extern void of_platform_device_destroy(struct device *dev); > > extern int of_platform_bus_probe(struct device_node *root, > const struct of_device_id *matches, > -- > 2.9.3 > > _______________________________________________ > dri-devel mailing list > dri-devel@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/dri-devel _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel