diff mbox

[v5,3/7] of/platform: expose of_platform_device_destroy()

Message ID 20160902082245.7119-4-dh.herrmann@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

David Herrmann Sept. 2, 2016, 8:22 a.m. UTC
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@gmail.com>
---
 drivers/of/platform.c       | 35 ++++++++++++++++++++++++++---------
 include/linux/of_platform.h |  1 +
 2 files changed, 27 insertions(+), 9 deletions(-)

Comments

Tom Gundersen Sept. 2, 2016, 10:21 a.m. UTC | #1
On Fri, Sep 2, 2016 at 10:22 AM, David Herrmann <dh.herrmann@gmail.com> 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@gmail.com>

Reviewed-by: Tom Gundersen <teg@jklm.no>

> ---
>  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@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
diff mbox

Patch

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,