From 07d260e047680971d926bc9a573f9291f39fc988 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 19 Apr 2015 07:20:58 -0600 Subject: [PATCH] dm: core: Handle recursive unbinding of uclass devices 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 Reviewed-by: Joe Hershberger Tested-by: Joe Hershberger --- drivers/core/uclass.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 7627ad1..9fec8c9 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;