summaryrefslogtreecommitdiff
path: root/drivers/usb/host/usb-uclass.c
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2015-11-08 23:48:00 -0700
committerSimon Glass <sjg@chromium.org>2015-11-19 20:27:52 -0700
commiteae11bece69a277a25fefe54ea475ba02ede687e (patch)
tree1a15dfeb359a2329c0a1a7738b4cb7886e225ea8 /drivers/usb/host/usb-uclass.c
parente8ea5e8c8568c8cbb752e524e8eb74f776f5e262 (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.c23
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");