diff mbox

[U-Boot,1/5] dm: core: Handle recursive unbinding of uclass devices

Message ID 1429449662-9782-2-git-send-email-sjg@chromium.org
State Accepted
Delegated to: Simon Glass
Headers show

Commit Message

Simon Glass April 19, 2015, 1:20 p.m. UTC
Since a device can have children in the same uclass as itself, we need
to handle unbinding carefully: we must allow that unbinding a device in a
uclass may cause another device in the same uclass to be unbound.

Adjust the code to cope.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/core/uclass.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

Comments

Joe Hershberger April 21, 2015, 3:30 p.m. UTC | #1
Hi Simon,

On Sun, Apr 19, 2015 at 8:20 AM, Simon Glass <sjg@chromium.org> wrote:
> Since a device can have children in the same uclass as itself, we need
> to handle unbinding carefully: we must allow that unbinding a device in a
> uclass may cause another device in the same uclass to be unbound.
>
> Adjust the code to cope.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>

This fixed the seg fault I was seeing. Thanks!

Reviewed-by: Joe Hershberger <joe.hershberger@ni.com>
Tested-by: Joe Hershberger <joe.hershberger@ni.com>
Simon Glass April 22, 2015, 6:01 p.m. UTC | #2
On 21 April 2015 at 09:30, Joe Hershberger <joe.hershberger@gmail.com> wrote:
> Hi Simon,
>
> On Sun, Apr 19, 2015 at 8:20 AM, Simon Glass <sjg@chromium.org> wrote:
>> Since a device can have children in the same uclass as itself, we need
>> to handle unbinding carefully: we must allow that unbinding a device in a
>> uclass may cause another device in the same uclass to be unbound.
>>
>> Adjust the code to cope.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>
> This fixed the seg fault I was seeing. Thanks!
>
> Reviewed-by: Joe Hershberger <joe.hershberger@ni.com>
> Tested-by: Joe Hershberger <joe.hershberger@ni.com>

Applied to u-boot-dm.
diff mbox

Patch

diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 98c15e5..45fcd08 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -99,10 +99,18 @@  fail_mem:
 int uclass_destroy(struct uclass *uc)
 {
 	struct uclass_driver *uc_drv;
-	struct udevice *dev, *tmp;
+	struct udevice *dev;
 	int ret;
 
-	list_for_each_entry_safe(dev, tmp, &uc->dev_head, uclass_node) {
+	/*
+	 * We cannot use list_for_each_entry_safe() here. If a device in this
+	 * uclass has a child device also in this uclass, it will be also be
+	 * unbound (by the recursion in the call to device_unbind() below).
+	 * We can loop until the list is empty.
+	 */
+	while (!list_empty(&uc->dev_head)) {
+		dev = list_first_entry(&uc->dev_head, struct udevice,
+				       uclass_node);
 		ret = device_remove(dev);
 		if (ret)
 			return ret;