Merge tag 'dlm-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm
[platform/kernel/linux-starfive.git] / drivers / usb / core / message.c
index ca717da..b548cf1 100644 (file)
@@ -1308,10 +1308,19 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
         * Remove the current alt setting and add the new alt setting.
         */
        mutex_lock(hcd->bandwidth_mutex);
+       /* Disable LPM, and re-enable it once the new alt setting is installed,
+        * so that the xHCI driver can recalculate the U1/U2 timeouts.
+        */
+       if (usb_disable_lpm(dev)) {
+               dev_err(&iface->dev, "%s Failed to disable LPM\n.", __func__);
+               mutex_unlock(hcd->bandwidth_mutex);
+               return -ENOMEM;
+       }
        ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt);
        if (ret < 0) {
                dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n",
                                alternate);
+               usb_enable_lpm(dev);
                mutex_unlock(hcd->bandwidth_mutex);
                return ret;
        }
@@ -1334,6 +1343,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
        } else if (ret < 0) {
                /* Re-instate the old alt setting */
                usb_hcd_alloc_bandwidth(dev, NULL, alt, iface->cur_altsetting);
+               usb_enable_lpm(dev);
                mutex_unlock(hcd->bandwidth_mutex);
                return ret;
        }
@@ -1354,6 +1364,9 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
 
        iface->cur_altsetting = alt;
 
+       /* Now that the interface is installed, re-enable LPM. */
+       usb_unlocked_enable_lpm(dev);
+
        /* If the interface only has one altsetting and the device didn't
         * accept the request, we attempt to carry out the equivalent action
         * by manually clearing the HALT feature for each endpoint in the
@@ -1437,6 +1450,14 @@ int usb_reset_configuration(struct usb_device *dev)
        config = dev->actconfig;
        retval = 0;
        mutex_lock(hcd->bandwidth_mutex);
+       /* Disable LPM, and re-enable it once the configuration is reset, so
+        * that the xHCI driver can recalculate the U1/U2 timeouts.
+        */
+       if (usb_disable_lpm(dev)) {
+               dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__);
+               mutex_unlock(hcd->bandwidth_mutex);
+               return -ENOMEM;
+       }
        /* Make sure we have enough bandwidth for each alternate setting 0 */
        for (i = 0; i < config->desc.bNumInterfaces; i++) {
                struct usb_interface *intf = config->interface[i];
@@ -1465,6 +1486,7 @@ reset_old_alts:
                                usb_hcd_alloc_bandwidth(dev, NULL,
                                                alt, intf->cur_altsetting);
                }
+               usb_enable_lpm(dev);
                mutex_unlock(hcd->bandwidth_mutex);
                return retval;
        }
@@ -1502,6 +1524,8 @@ reset_old_alts:
                        create_intf_ep_devs(intf);
                }
        }
+       /* Now that the interfaces are installed, re-enable LPM. */
+       usb_unlocked_enable_lpm(dev);
        return 0;
 }
 EXPORT_SYMBOL_GPL(usb_reset_configuration);
@@ -1763,8 +1787,18 @@ free_interfaces:
         * this call fails, the device state is unchanged.
         */
        mutex_lock(hcd->bandwidth_mutex);
+       /* Disable LPM, and re-enable it once the new configuration is
+        * installed, so that the xHCI driver can recalculate the U1/U2
+        * timeouts.
+        */
+       if (usb_disable_lpm(dev)) {
+               dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__);
+               mutex_unlock(hcd->bandwidth_mutex);
+               return -ENOMEM;
+       }
        ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
        if (ret < 0) {
+               usb_enable_lpm(dev);
                mutex_unlock(hcd->bandwidth_mutex);
                usb_autosuspend_device(dev);
                goto free_interfaces;
@@ -1784,6 +1818,7 @@ free_interfaces:
        if (!cp) {
                usb_set_device_state(dev, USB_STATE_ADDRESS);
                usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
+               usb_enable_lpm(dev);
                mutex_unlock(hcd->bandwidth_mutex);
                usb_autosuspend_device(dev);
                goto free_interfaces;
@@ -1838,6 +1873,9 @@ free_interfaces:
                        !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
                cp->string = usb_cache_string(dev, cp->desc.iConfiguration);
 
+       /* Now that the interfaces are installed, re-enable LPM. */
+       usb_unlocked_enable_lpm(dev);
+
        /* Now that all the interfaces are set up, register them
         * to trigger binding of drivers to interfaces.  probe()
         * routines may install different altsettings and may