[PATCH v5 3/7] of/platform: expose of_platform_device_destroy()
David Herrmann
dh.herrmann at gmail.com
Fri Sep 2 08:22:41 UTC 2016
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 at gmail.com>
---
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
More information about the dri-devel
mailing list