Message ID | 1429449662-9782-2-git-send-email-sjg@chromium.org |
---|---|
State | Accepted |
Delegated to: | Simon Glass |
Headers | show |
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>
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 --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;
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(-)