linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] of: Add of_device_destroy_children() function
@ 2014-05-08 16:37 Sylwester Nawrocki
  2014-05-08 20:33 ` Jason Gunthorpe
  2014-05-14 10:27 ` Grant Likely
  0 siblings, 2 replies; 6+ messages in thread
From: Sylwester Nawrocki @ 2014-05-08 16:37 UTC (permalink / raw)
  To: robh+dt, grant.likely
  Cc: devicetree, linux-arm-kernel, linux-kernel, Sylwester Nawrocki

This patch adds a helper function to unregister devices which
were created by an of_platform_populate() call. The pattern
used here can already be found in multiple drivers. This helper
can now be used instead of repeating similar code in drivers.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---

This patch has been tested on ARM only (on Exynos4412 Trats2 board).

 drivers/of/device.c       |   24 ++++++++++++++++++++++++
 include/linux/of_device.h |    3 +++
 2 files changed, 27 insertions(+)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index dafb973..9303197 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -190,3 +190,27 @@ int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)

 	return 0;
 }
+
+static int __remove_child_device(struct device *dev, void *unused)
+{
+	if (of_match_node(of_default_bus_match_table, dev->of_node))
+		of_device_destroy_children(dev);
+
+	device_unregister(dev);
+	return 0;
+}
+
+/**
+ * of_device_destroy_children - unregister @parent's child devices
+ * @parent: the parent device to start with
+ *
+ * Destroy all child devices of the @parent device, any grandchildren
+ * compatible with values listed in the of_default_bus_match_table will
+ * also be unregistered recursively.  This function can be used to
+ * destroy devices created by an of_platform_populate() call.
+ */
+void of_device_destroy_children(struct device *parent)
+{
+	device_for_each_child(parent, NULL, __remove_child_device);
+}
+EXPORT_SYMBOL(of_device_destroy_children);
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index ef37021..0c41e0b 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -32,6 +32,7 @@ extern void of_dev_put(struct platform_device *dev);
 extern int of_device_add(struct platform_device *pdev);
 extern int of_device_register(struct platform_device *ofdev);
 extern void of_device_unregister(struct platform_device *ofdev);
+extern void of_device_destroy_children(struct device *parent);

 extern ssize_t of_device_get_modalias(struct device *dev,
 					char *str, ssize_t len);
@@ -64,6 +65,8 @@ static inline int of_driver_match_device(struct device *dev,
 static inline void of_device_uevent(struct device *dev,
 			struct kobj_uevent_env *env) { }

+static inline void of_device_destroy_children(struct device *parent) { }
+
 static inline int of_device_get_modalias(struct device *dev,
 				   char *str, ssize_t len)
 {
--
1.7.9.5


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] of: Add of_device_destroy_children() function
  2014-05-08 16:37 [PATCH] of: Add of_device_destroy_children() function Sylwester Nawrocki
@ 2014-05-08 20:33 ` Jason Gunthorpe
  2014-05-09  9:53   ` Sylwester Nawrocki
  2014-05-14 10:25   ` Grant Likely
  2014-05-14 10:27 ` Grant Likely
  1 sibling, 2 replies; 6+ messages in thread
From: Jason Gunthorpe @ 2014-05-08 20:33 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: robh+dt, grant.likely, devicetree, linux-kernel, linux-arm-kernel

On Thu, May 08, 2014 at 06:37:49PM +0200, Sylwester Nawrocki wrote:
> This patch adds a helper function to unregister devices which
> were created by an of_platform_populate() call. The pattern
> used here can already be found in multiple drivers. This helper
> can now be used instead of repeating similar code in drivers.

I have a driver that does this as well, and what I found is that the
remove must be in reverse order from the create or things explode, and
that assumes the DT is topologically sorted according to dependency
(so no deferred probe).

AFAIK, there is no analog to deferred probe for removal, and
attempting to remove, say, a GPIO driver while an I2C bit bang is using
it just fails.

Jason

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] of: Add of_device_destroy_children() function
  2014-05-08 20:33 ` Jason Gunthorpe
@ 2014-05-09  9:53   ` Sylwester Nawrocki
  2014-05-14 10:25   ` Grant Likely
  1 sibling, 0 replies; 6+ messages in thread
From: Sylwester Nawrocki @ 2014-05-09  9:53 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: robh+dt, grant.likely, devicetree, linux-kernel, linux-arm-kernel

On 08/05/14 22:33, Jason Gunthorpe wrote:
> On Thu, May 08, 2014 at 06:37:49PM +0200, Sylwester Nawrocki wrote:
>> This patch adds a helper function to unregister devices which
>> were created by an of_platform_populate() call. The pattern
>> used here can already be found in multiple drivers. This helper
>> can now be used instead of repeating similar code in drivers.
> 
> I have a driver that does this as well, and what I found is that the
> remove must be in reverse order from the create or things explode, and
> that assumes the DT is topologically sorted according to dependency
> (so no deferred probe).
> 
> AFAIK, there is no analog to deferred probe for removal, and
> attempting to remove, say, a GPIO driver while an I2C bit bang is using
> it just fails.

Thanks for the feedback, I knew I could be missing some of nasty
details like this. Looks like we need a complete implementation
of of_platform_unpopulate(). Since the are cases where the remove
order is insignificant, I'm wondering whether it still would be
useful to have a helper like device_unregister_children() which
would remove only direct children of a device ? At least this
solves my current problem.

Since the dependencies will likely never be fully described in DT
I guess we would need to create a list while actually creating
devices, to be able to walk in reverse order while destroying them.

--
Regards,
Sylwester


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] of: Add of_device_destroy_children() function
  2014-05-08 20:33 ` Jason Gunthorpe
  2014-05-09  9:53   ` Sylwester Nawrocki
@ 2014-05-14 10:25   ` Grant Likely
  1 sibling, 0 replies; 6+ messages in thread
From: Grant Likely @ 2014-05-14 10:25 UTC (permalink / raw)
  To: Jason Gunthorpe, Sylwester Nawrocki
  Cc: robh+dt, devicetree, linux-kernel, linux-arm-kernel

On Thu, 8 May 2014 14:33:39 -0600, Jason Gunthorpe <jgunthorpe@obsidianresearch.com> wrote:
> On Thu, May 08, 2014 at 06:37:49PM +0200, Sylwester Nawrocki wrote:
> > This patch adds a helper function to unregister devices which
> > were created by an of_platform_populate() call. The pattern
> > used here can already be found in multiple drivers. This helper
> > can now be used instead of repeating similar code in drivers.
> 
> I have a driver that does this as well, and what I found is that the
> remove must be in reverse order from the create or things explode, and
> that assumes the DT is topologically sorted according to dependency
> (so no deferred probe).

That is the tip of a much larger problem that we don't have any good way
to solve. There is no dependency tracking beyond the nature Linux driver
model tree. For example, the removal of a GPIO driver has no way to
tell users that it is going away, and so there is no way to force a
driver remove when it happens.

If we created a managed api for requesting resource (ie.
devm_request_gpio()), then it would be possible for the gpio core to
force a remove event on any driver that doesn't have the ability to
gracefully handle a remove.

The exact same problem exists for IRQs, clocks, regulators, or pretty
much any cross-tree dependency.  :-(

> AFAIK, there is no analog to deferred probe for removal, and
> attempting to remove, say, a GPIO driver while an I2C bit bang is using
> it just fails.

Indeed, it is a completely different operation.

g.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] of: Add of_device_destroy_children() function
  2014-05-08 16:37 [PATCH] of: Add of_device_destroy_children() function Sylwester Nawrocki
  2014-05-08 20:33 ` Jason Gunthorpe
@ 2014-05-14 10:27 ` Grant Likely
  2014-05-14 11:55   ` Sylwester Nawrocki
  1 sibling, 1 reply; 6+ messages in thread
From: Grant Likely @ 2014-05-14 10:27 UTC (permalink / raw)
  To: Sylwester Nawrocki, robh+dt
  Cc: devicetree, linux-arm-kernel, linux-kernel, Sylwester Nawrocki

On Thu, 08 May 2014 18:37:49 +0200, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
> This patch adds a helper function to unregister devices which
> were created by an of_platform_populate() call. The pattern
> used here can already be found in multiple drivers. This helper
> can now be used instead of repeating similar code in drivers.
> 
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> ---

Pawel has also submitted a patch for this. That patch is a little more
careful about how it removes nodes, so I'll be going with that one.

g.

> 
> This patch has been tested on ARM only (on Exynos4412 Trats2 board).
> 
>  drivers/of/device.c       |   24 ++++++++++++++++++++++++
>  include/linux/of_device.h |    3 +++
>  2 files changed, 27 insertions(+)
> 
> diff --git a/drivers/of/device.c b/drivers/of/device.c
> index dafb973..9303197 100644
> --- a/drivers/of/device.c
> +++ b/drivers/of/device.c
> @@ -190,3 +190,27 @@ int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
> 
>  	return 0;
>  }
> +
> +static int __remove_child_device(struct device *dev, void *unused)
> +{
> +	if (of_match_node(of_default_bus_match_table, dev->of_node))
> +		of_device_destroy_children(dev);
> +
> +	device_unregister(dev);
> +	return 0;
> +}
> +
> +/**
> + * of_device_destroy_children - unregister @parent's child devices
> + * @parent: the parent device to start with
> + *
> + * Destroy all child devices of the @parent device, any grandchildren
> + * compatible with values listed in the of_default_bus_match_table will
> + * also be unregistered recursively.  This function can be used to
> + * destroy devices created by an of_platform_populate() call.
> + */
> +void of_device_destroy_children(struct device *parent)
> +{
> +	device_for_each_child(parent, NULL, __remove_child_device);
> +}
> +EXPORT_SYMBOL(of_device_destroy_children);
> diff --git a/include/linux/of_device.h b/include/linux/of_device.h
> index ef37021..0c41e0b 100644
> --- a/include/linux/of_device.h
> +++ b/include/linux/of_device.h
> @@ -32,6 +32,7 @@ extern void of_dev_put(struct platform_device *dev);
>  extern int of_device_add(struct platform_device *pdev);
>  extern int of_device_register(struct platform_device *ofdev);
>  extern void of_device_unregister(struct platform_device *ofdev);
> +extern void of_device_destroy_children(struct device *parent);
> 
>  extern ssize_t of_device_get_modalias(struct device *dev,
>  					char *str, ssize_t len);
> @@ -64,6 +65,8 @@ static inline int of_driver_match_device(struct device *dev,
>  static inline void of_device_uevent(struct device *dev,
>  			struct kobj_uevent_env *env) { }
> 
> +static inline void of_device_destroy_children(struct device *parent) { }
> +
>  static inline int of_device_get_modalias(struct device *dev,
>  				   char *str, ssize_t len)
>  {
> --
> 1.7.9.5
> 


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] of: Add of_device_destroy_children() function
  2014-05-14 10:27 ` Grant Likely
@ 2014-05-14 11:55   ` Sylwester Nawrocki
  0 siblings, 0 replies; 6+ messages in thread
From: Sylwester Nawrocki @ 2014-05-14 11:55 UTC (permalink / raw)
  To: Grant Likely; +Cc: robh+dt, devicetree, linux-arm-kernel, linux-kernel

On 14/05/14 12:27, Grant Likely wrote:
> On Thu, 08 May 2014 18:37:49 +0200, Sylwester Nawrocki <s.nawrocki@samsung.com> wrote:
>> > This patch adds a helper function to unregister devices which
>> > were created by an of_platform_populate() call. The pattern
>> > used here can already be found in multiple drivers. This helper
>> > can now be used instead of repeating similar code in drivers.
>> > 
>> > Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
>> > Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
>> > ---
>
> Pawel has also submitted a patch for this. That patch is a little more
> careful about how it removes nodes, so I'll be going with that one.

OK, it's good to know we have already a good solution. I'll give a try
Pawel's patch then.

Thanks,
Sylwester

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-05-14 11:55 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-08 16:37 [PATCH] of: Add of_device_destroy_children() function Sylwester Nawrocki
2014-05-08 20:33 ` Jason Gunthorpe
2014-05-09  9:53   ` Sylwester Nawrocki
2014-05-14 10:25   ` Grant Likely
2014-05-14 10:27 ` Grant Likely
2014-05-14 11:55   ` Sylwester Nawrocki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).