Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[pandora-kernel.git] / drivers / usb / core / driver.c
index 0a63e96..fca6172 100644 (file)
@@ -375,7 +375,7 @@ static int usb_unbind_interface(struct device *dev)
                 * Just re-enable it without affecting the endpoint toggles.
                 */
                usb_enable_interface(udev, intf, false);
-       } else if (!error && intf->dev.power.status == DPM_ON) {
+       } else if (!error && !intf->dev.power.in_suspend) {
                r = usb_set_interface(udev, intf->altsetting[0].
                                desc.bInterfaceNumber, 0);
                if (r < 0)
@@ -960,7 +960,7 @@ void usb_rebind_intf(struct usb_interface *intf)
        }
 
        /* Try to rebind the interface */
-       if (intf->dev.power.status == DPM_ON) {
+       if (!intf->dev.power.in_suspend) {
                intf->needs_binding = 0;
                rc = device_attach(&intf->dev);
                if (rc < 0)
@@ -1107,8 +1107,7 @@ static int usb_resume_interface(struct usb_device *udev,
        if (intf->condition == USB_INTERFACE_UNBOUND) {
 
                /* Carry out a deferred switch to altsetting 0 */
-               if (intf->needs_altsetting0 &&
-                               intf->dev.power.status == DPM_ON) {
+               if (intf->needs_altsetting0 && !intf->dev.power.in_suspend) {
                        usb_set_interface(udev, intf->altsetting[0].
                                        desc.bInterfaceNumber, 0);
                        intf->needs_altsetting0 = 0;
@@ -1261,6 +1260,7 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg)
                                        udev->reset_resume);
                }
        }
+       usb_mark_last_busy(udev);
 
  done:
        dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status);
@@ -1328,7 +1328,6 @@ int usb_resume(struct device *dev, pm_message_t msg)
                        pm_runtime_disable(dev);
                        pm_runtime_set_active(dev);
                        pm_runtime_enable(dev);
-                       usb_mark_last_busy(udev);
                        do_unbind_rebind(udev, DO_REBIND);
                }
        }
@@ -1397,32 +1396,7 @@ void usb_autosuspend_device(struct usb_device *udev)
        int     status;
 
        usb_mark_last_busy(udev);
-       status = pm_runtime_put_sync(&udev->dev);
-       dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n",
-                       __func__, atomic_read(&udev->dev.power.usage_count),
-                       status);
-}
-
-/**
- * usb_try_autosuspend_device - attempt an autosuspend of a USB device and its interfaces
- * @udev: the usb_device to autosuspend
- *
- * This routine should be called when a core subsystem thinks @udev may
- * be ready to autosuspend.
- *
- * @udev's usage counter left unchanged.  If it is 0 and all the interfaces
- * are inactive then an autosuspend will be attempted.  The attempt may
- * fail or be delayed.
- *
- * The caller must hold @udev's device lock.
- *
- * This routine can run only in process context.
- */
-void usb_try_autosuspend_device(struct usb_device *udev)
-{
-       int     status;
-
-       status = pm_runtime_idle(&udev->dev);
+       status = pm_runtime_put_sync_autosuspend(&udev->dev);
        dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n",
                        __func__, atomic_read(&udev->dev.power.usage_count),
                        status);
@@ -1508,32 +1482,11 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interface);
 void usb_autopm_put_interface_async(struct usb_interface *intf)
 {
        struct usb_device       *udev = interface_to_usbdev(intf);
-       unsigned long           last_busy;
-       int                     status = 0;
+       int                     status;
 
-       last_busy = udev->dev.power.last_busy;
        usb_mark_last_busy(udev);
        atomic_dec(&intf->pm_usage_cnt);
-       pm_runtime_put_noidle(&intf->dev);
-
-       if (udev->dev.power.runtime_auto) {
-               /* Optimization: Don't schedule a delayed autosuspend if
-                * the timer is already running and the expiration time
-                * wouldn't change.
-                *
-                * We have to use the interface's timer.  Attempts to
-                * schedule a suspend for the device would fail because
-                * the interface is still active.
-                */
-               if (intf->dev.power.timer_expires == 0 ||
-                               round_jiffies_up(last_busy) !=
-                               round_jiffies_up(jiffies)) {
-                       status = pm_schedule_suspend(&intf->dev,
-                                       jiffies_to_msecs(
-                                       round_jiffies_up_relative(
-                                               udev->autosuspend_delay)));
-               }
-       }
+       status = pm_runtime_put(&intf->dev);
        dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n",
                        __func__, atomic_read(&intf->dev.power.usage_count),
                        status);
@@ -1651,7 +1604,6 @@ static int autosuspend_check(struct usb_device *udev)
 {
        int                     w, i;
        struct usb_interface    *intf;
-       unsigned long           suspend_time, j;
 
        /* Fail if autosuspend is disabled, or any interfaces are in use, or
         * any interface drivers require remote wakeup but it isn't available.
@@ -1691,17 +1643,6 @@ static int autosuspend_check(struct usb_device *udev)
                return -EOPNOTSUPP;
        }
        udev->do_remote_wakeup = w;
-
-       /* If everything is okay but the device hasn't been idle for long
-        * enough, queue a delayed autosuspend request.
-        */
-       j = ACCESS_ONCE(jiffies);
-       suspend_time = udev->dev.power.last_busy + udev->autosuspend_delay;
-       if (time_before(j, suspend_time)) {
-               pm_schedule_suspend(&udev->dev, jiffies_to_msecs(
-                               round_jiffies_up_relative(suspend_time - j)));
-               return -EAGAIN;
-       }
        return 0;
 }
 
@@ -1718,20 +1659,6 @@ static int usb_runtime_suspend(struct device *dev)
                return -EAGAIN;
 
        status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND);
-
-       /* If an interface fails the suspend, adjust the last_busy
-        * time so that we don't get another suspend attempt right
-        * away.
-        */
-       if (status) {
-               udev->dev.power.last_busy = jiffies +
-                               (udev->autosuspend_delay == 0 ? HZ/2 : 0);
-       }
-
-       /* Prevent the parent from suspending immediately after */
-       else if (udev->parent)
-               usb_mark_last_busy(udev->parent);
-
        return status;
 }
 
@@ -1744,7 +1671,6 @@ static int usb_runtime_resume(struct device *dev)
         * and all its interfaces.
         */
        status = usb_resume_both(udev, PMSG_AUTO_RESUME);
-       usb_mark_last_busy(udev);
        return status;
 }
 
@@ -1756,7 +1682,7 @@ static int usb_runtime_idle(struct device *dev)
         * autosuspend checks.
         */
        if (autosuspend_check(udev) == 0)
-               pm_runtime_suspend(dev);
+               pm_runtime_autosuspend(dev);
        return 0;
 }