From: Simon Glass Date: Sun, 19 Apr 2015 13:20:58 +0000 (-0600) Subject: dm: core: Handle recursive unbinding of uclass devices X-Git-Tag: v2015.07-rc1~69^2~19 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=07d260e047680971d926bc9a573f9291f39fc988;p=oweals%2Fu-boot.git 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 --- diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 7627ad141b..9fec8c9c7a 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;