usb: onboard-hub: add driver to manage onboard hub supplies

The main issue the driver addresses is that a USB hub needs to be
powered before it can be discovered. This is often solved by using
"regulator-always-on".

This driver is inspired by the Linux v6.1 driver. It only enables (or
disables) the hub vdd (3v3) supply, so it can be enumerated.
Scanning of the device tree is done in a similar manner to the sandbox,
by the usb-uclass. DT part looks like:

&usbh_ehci {
	...
	#address-cells = <1>;
	#size-cells = <0>;
	hub@1 {
		compatible = "usb424,2514";
		reg = <1>;
		vdd-supply = <&v3v3>;
	};
};

When the bus gets probed, the driver is automatically probed/removed from
the bus tree, as an example on stm32:
STM32MP> usb start
starting USB...
STM32MP> dm tree
 Class     Index  Probed  Driver                Name
-----------------------------------------------------------
 usb           0  [ + ]   ehci_generic          |   |-- usb@5800d000
 usb_hub       0  [ + ]   usb_onboard_hub       |   |   `-- hub@1
 usb_hub       1  [ + ]   usb_hub               |   |       `-- usb_hub

STM32MP> usb tree
USB device tree:
  1  Hub (480 Mb/s, 0mA)
  |  u-boot EHCI Host Controller
  |
  +-2  Hub (480 Mb/s, 2mA)

Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 8efd461..ebe6bf9 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -105,6 +105,16 @@
 	  Say Y here if you want to use a USB keyboard for U-Boot command line
 	  input.
 
+config USB_ONBOARD_HUB
+	bool "Onboard USB hub support"
+	depends on DM_USB
+	---help---
+	  Say Y here if you want to support discrete onboard USB hubs that
+	  don't require an additional control bus for initialization, but
+	  need some non-trivial form of initialization, such as enabling a
+	  power regulator. An example for such a hub is the Microchip
+	  USB2514B.
+
 if USB_KEYBOARD
 
 config USB_KEYBOARD_FN_KEYS
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
index 956e2a4..93c318c 100644
--- a/drivers/usb/host/usb-uclass.c
+++ b/drivers/usb/host/usb-uclass.c
@@ -271,19 +271,23 @@
 		/* init low_level USB */
 		printf("Bus %s: ", bus->name);
 
-#ifdef CONFIG_SANDBOX
 		/*
 		 * For Sandbox, we need scan the device tree each time when we
 		 * start the USB stack, in order to re-create the emulated USB
 		 * devices and bind drivers for them before we actually do the
 		 * driver probe.
+		 *
+		 * For USB onboard HUB, we need to do some non-trivial init
+		 * like enabling a power regulator, before enumeration.
 		 */
-		ret = dm_scan_fdt_dev(bus);
-		if (ret) {
-			printf("Sandbox USB device scan failed (%d)\n", ret);
-			continue;
+		if (IS_ENABLED(CONFIG_SANDBOX) ||
+		    IS_ENABLED(CONFIG_USB_ONBOARD_HUB)) {
+			ret = dm_scan_fdt_dev(bus);
+			if (ret) {
+				printf("USB device scan from fdt failed (%d)", ret);
+				continue;
+			}
 		}
-#endif
 
 		ret = device_probe(bus);
 		if (ret == -ENODEV) {	/* No such device. */