diff options
Diffstat (limited to 'drivers/usb/host/usb-uclass.c')
-rw-r--r-- | drivers/usb/host/usb-uclass.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c index 7a03435ba7..a1cd0ad2d6 100644 --- a/drivers/usb/host/usb-uclass.c +++ b/drivers/usb/host/usb-uclass.c @@ -9,6 +9,7 @@ #define LOG_CATEGORY UCLASS_USB #include <common.h> +#include <bootdev.h> #include <dm.h> #include <errno.h> #include <log.h> @@ -208,6 +209,13 @@ int usb_stop(void) #ifdef CONFIG_USB_STORAGE usb_stor_reset(); #endif + if (CONFIG_IS_ENABLED(BOOTSTD)) { + int ret; + + ret = bootdev_unhunt(UCLASS_USB); + if (IS_ENABLED(CONFIG_BOOTSTD_FULL) && ret && ret != -EALREADY) + printf("failed to unhunt USB (err=%dE)\n", ret); + } uc_priv->companion_device_count = 0; usb_started = 0; @@ -249,6 +257,37 @@ static void remove_inactive_children(struct uclass *uc, struct udevice *bus) } } +static int usb_probe_companion(struct udevice *bus) +{ + struct udevice *companion_dev; + int ret; + + /* + * Enforce optional companion controller is marked as such in order to + * 1st scan the primary controller, before the companion controller + * (ownership is given to companion when low or full speed devices + * have been detected). + */ + ret = uclass_get_device_by_phandle(UCLASS_USB, bus, "companion", &companion_dev); + if (!ret) { + struct usb_bus_priv *companion_bus_priv; + + debug("%s is the companion of %s\n", companion_dev->name, bus->name); + companion_bus_priv = dev_get_uclass_priv(companion_dev); + companion_bus_priv->companion = true; + } else if (ret && ret != -ENOENT && ret != -ENODEV) { + /* + * Treat everything else than no companion or disabled + * companion as an error. (It may not be enabled on boards + * that have a High-Speed HUB to handle FS and LS traffic). + */ + printf("Failed to get companion (ret=%d)\n", ret); + return ret; + } + + return 0; +} + int usb_init(void) { int controllers_initialized = 0; @@ -299,6 +338,11 @@ int usb_init(void) printf("probe failed, error %d\n", ret); continue; } + + ret = usb_probe_companion(bus); + if (ret) + continue; + controllers_initialized++; usb_started = true; } |