Merge branch 'pm-qos'
[firefly-linux-kernel-4.4.55.git] / drivers / base / power / runtime.c
index 59894873a3b37de88a50d3b5e1f22ce67e454858..3148b10dc2e59b92dd5913e2b34c446d54ac69b7 100644 (file)
@@ -147,6 +147,8 @@ static int rpm_check_suspend_allowed(struct device *dev)
            || (dev->power.request_pending
                        && dev->power.request == RPM_REQ_RESUME))
                retval = -EAGAIN;
+       else if (__dev_pm_qos_read_value(dev) < 0)
+               retval = -EPERM;
        else if (dev->power.runtime_status == RPM_SUSPENDED)
                retval = 1;
 
@@ -388,7 +390,6 @@ static int rpm_suspend(struct device *dev, int rpmflags)
                goto repeat;
        }
 
-       dev->power.deferred_resume = false;
        if (dev->power.no_callbacks)
                goto no_callback;       /* Assume success. */
 
@@ -403,12 +404,6 @@ static int rpm_suspend(struct device *dev, int rpmflags)
                goto out;
        }
 
-       if (__dev_pm_qos_read_value(dev) < 0) {
-               /* Negative PM QoS constraint means "never suspend". */
-               retval = -EPERM;
-               goto out;
-       }
-
        __update_runtime_status(dev, RPM_SUSPENDING);
 
        if (dev->pm_domain)
@@ -440,6 +435,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
        wake_up_all(&dev->power.wait_queue);
 
        if (dev->power.deferred_resume) {
+               dev->power.deferred_resume = false;
                rpm_resume(dev, 0);
                retval = -EAGAIN;
                goto out;
@@ -513,6 +509,9 @@ static int rpm_resume(struct device *dev, int rpmflags)
  repeat:
        if (dev->power.runtime_error)
                retval = -EINVAL;
+       else if (dev->power.disable_depth == 1 && dev->power.is_suspended
+           && dev->power.runtime_status == RPM_ACTIVE)
+               retval = 1;
        else if (dev->power.disable_depth > 0)
                retval = -EACCES;
        if (retval)
@@ -584,6 +583,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
                    || dev->parent->power.runtime_status == RPM_ACTIVE) {
                        atomic_inc(&dev->parent->power.child_count);
                        spin_unlock(&dev->parent->power.lock);
+                       retval = 1;
                        goto no_callback;       /* Assume success. */
                }
                spin_unlock(&dev->parent->power.lock);
@@ -664,7 +664,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
        }
        wake_up_all(&dev->power.wait_queue);
 
-       if (!retval)
+       if (retval >= 0)
                rpm_idle(dev, RPM_ASYNC);
 
  out: