diff options
-rw-r--r-- | drivers/usb/host/usb-uclass.c | 33 | ||||
-rw-r--r-- | include/usb.h | 3 |
2 files changed, 31 insertions, 5 deletions
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c index ad778b4..749257c 100644 --- a/drivers/usb/host/usb-uclass.c +++ b/drivers/usb/host/usb-uclass.c @@ -171,6 +171,7 @@ static void usb_scan_bus(struct udevice *bus, bool recurse) int usb_init(void) { int controllers_initialized = 0; + struct usb_bus_priv *priv; struct udevice *bus; struct uclass *uc; int count = 0; @@ -198,15 +199,37 @@ int usb_init(void) printf("probe failed, error %d\n", ret); continue; } - /* - * lowlevel init is OK, now scan the bus for devices - * i.e. search HUBs and configure them - */ controllers_initialized++; - usb_scan_bus(bus, true); usb_started = true; } + /* + * lowlevel init done, now scan the bus for devices i.e. search HUBs + * and configure them, first scan primary controllers. + */ + uclass_foreach_dev(bus, uc) { + if (!device_active(bus)) + continue; + + priv = dev_get_uclass_priv(bus); + if (!priv->companion) + usb_scan_bus(bus, true); + } + + /* + * Now that the primary controllers have been scanned and have handed + * over any devices they do not understand to their companions, scan + * the companions. + */ + uclass_foreach_dev(bus, uc) { + if (!device_active(bus)) + continue; + + priv = dev_get_uclass_priv(bus); + if (priv->companion) + usb_scan_bus(bus, true); + } + debug("scan end\n"); /* if we were not able to find at least one working bus, bail out */ if (!count) diff --git a/include/usb.h b/include/usb.h index 609b13d..5043bc3 100644 --- a/include/usb.h +++ b/include/usb.h @@ -608,10 +608,13 @@ struct usb_dev_platdata { * @desc_before_addr: true if we can read a device descriptor before it * has been assigned an address. For XHCI this is not possible * so this will be false. + * @companion: True if this is a companion controller to another USB + * controller */ struct usb_bus_priv { int next_addr; bool desc_before_addr; + bool companion; }; /** |