dm: usb: Add support for companion controllers
authorHans de Goede <hdegoede@redhat.com>
Sun, 10 May 2015 12:10:20 +0000 (14:10 +0200)
committerSimon Glass <sjg@chromium.org>
Fri, 15 May 2015 00:49:31 +0000 (18:49 -0600)
USB companion controllers must be scanned after the main controller has
been scanned, so that any devices which the main controller which to hand
over to the companion have actually been handed over before we scan the
companion.

As there are no guarantees that this will magically happen in the right
order, split the scanning of the buses in 2 phases, first main controllers,
and then companion controllers.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Simon Glass <sjg@chromium.org>
drivers/usb/host/usb-uclass.c
include/usb.h

index ad778b481f66dfe71eba19ed7a9d9003dcb4fa86..749257cf6d8fd04aa0f195040772e8b9a73a29e5 100644 (file)
@@ -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)
index 609b13d2af56953c33ed47d330e5db65dc989fbc..5043bc39849953139031190d9f420804dc3c3445 100644 (file)
@@ -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;
 };
 
 /**