diff options
author | Simon Glass <sjg@chromium.org> | 2015-11-08 23:48:00 -0700 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2015-11-19 20:27:52 -0700 |
commit | eae11bece69a277a25fefe54ea475ba02ede687e (patch) | |
tree | 1a15dfeb359a2329c0a1a7738b4cb7886e225ea8 /drivers/usb/host/usb-uclass.c | |
parent | e8ea5e8c8568c8cbb752e524e8eb74f776f5e262 (diff) |
dm: usb: Remove inactive children after a bus scan
Each scan of the USB bus may return different results. Existing driver-model
devices are reused when found, but if a device no longer exists it will stay
around, de-activated, but bound.
Detect these devices and remove them after the scan completes.
Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/usb/host/usb-uclass.c')
-rw-r--r-- | drivers/usb/host/usb-uclass.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c index 4aa92f8ee7..50538e0bd7 100644 --- a/drivers/usb/host/usb-uclass.c +++ b/drivers/usb/host/usb-uclass.c @@ -202,6 +202,20 @@ static void usb_scan_bus(struct udevice *bus, bool recurse) printf("%d USB Device(s) found\n", priv->next_addr); } +static void remove_inactive_children(struct uclass *uc, struct udevice *bus) +{ + uclass_foreach_dev(bus, uc) { + struct udevice *dev, *next; + + if (!device_active(bus)) + continue; + device_foreach_child_safe(dev, next, bus) { + if (!device_active(dev)) + device_unbind(dev); + } + } +} + int usb_init(void) { int controllers_initialized = 0; @@ -270,6 +284,15 @@ int usb_init(void) } debug("scan end\n"); + + /* Remove any devices that were not found on this scan */ + remove_inactive_children(uc, bus); + + ret = uclass_get(UCLASS_USB_HUB, &uc); + if (ret) + return ret; + remove_inactive_children(uc, bus); + /* if we were not able to find at least one working bus, bail out */ if (!count) printf("No controllers found\n"); |