}
 EXPORT_SYMBOL_GPL(usb_find_interface);
 
+struct each_dev_arg {
+       void *data;
+       int (*fn)(struct usb_device *, void *);
+};
+
+static int __each_dev(struct device *dev, void *data)
+{
+       struct each_dev_arg *arg = (struct each_dev_arg *)data;
+
+       /* There are struct usb_interface on the same bus, filter them out */
+       if (!is_usb_device(dev))
+               return 0;
+
+       return arg->fn(container_of(dev, struct usb_device, dev), arg->data);
+}
+
+/**
+ * usb_for_each_dev - iterate over all USB devices in the system
+ * @data: data pointer that will be handed to the callback function
+ * @fn: callback function to be called for each USB device
+ *
+ * Iterate over all USB devices and call @fn for each, passing it @data. If it
+ * returns anything other than 0, we break the iteration prematurely and return
+ * that value.
+ */
+int usb_for_each_dev(void *data, int (*fn)(struct usb_device *, void *))
+{
+       struct each_dev_arg arg = {data, fn};
+
+       return bus_for_each_dev(&usb_bus_type, NULL, &arg, __each_dev);
+}
+EXPORT_SYMBOL_GPL(usb_for_each_dev);
+
 /**
  * usb_release_dev - free a usb device structure when all users of it are finished.
  * @dev: device that's been disconnected
 
        u16             wLength
 );
 
+static int persist_enabled_on_companion(struct usb_device *udev, void *unused)
+{
+       return !udev->maxchild && udev->persist_enabled &&
+               udev->bus->root_hub->speed < USB_SPEED_HIGH;
+}
+
 /* After a power loss, ports that were owned by the companion must be
  * reset so that the companion can still own them.
  */
        if (!ehci->owned_ports)
                return;
 
+       /*
+        * USB 1.1 devices are mostly HIDs, which don't need to persist across
+        * suspends. If we ensure that none of our companion's devices have
+        * persist_enabled (by looking through all USB 1.1 buses in the system),
+        * we can skip this and avoid slowing resume down. Devices without
+        * persist will just get reenumerated shortly after resume anyway.
+        */
+       if (!usb_for_each_dev(NULL, persist_enabled_on_companion))
+               return;
+
        /* Make sure the ports are powered */
        port = HCS_N_PORTS(ehci->hcs_params);
        while (port--) {
 
 extern int usb_match_one_id(struct usb_interface *interface,
                            const struct usb_device_id *id);
 
+extern int usb_for_each_dev(void *data, int (*fn)(struct usb_device *, void *));
 extern struct usb_interface *usb_find_interface(struct usb_driver *drv,
                int minor);
 extern struct usb_interface *usb_ifnum_to_if(const struct usb_device *dev,