Merge remote-tracking branch 'lsk/v3.10/topic/arm64-misc' into linux-linaro-lsk
[firefly-linux-kernel-4.4.55.git] / drivers / regulator / core.c
index 815d6df8bd5f70fab479247c81c6afe7fa746841..874dd261b2480066ad2e5c2e7ecb630d846da878 100644 (file)
@@ -919,6 +919,8 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
        return 0;
 }
 
+static int _regulator_do_enable(struct regulator_dev *rdev);
+
 /**
  * set_machine_constraints - sets regulator constraints
  * @rdev: regulator source
@@ -975,10 +977,9 @@ static int set_machine_constraints(struct regulator_dev *rdev,
        /* If the constraints say the regulator should be on at this point
         * and we have control then make sure it is enabled.
         */
-       if ((rdev->constraints->always_on || rdev->constraints->boot_on) &&
-           ops->enable) {
-               ret = ops->enable(rdev);
-               if (ret < 0) {
+       if (rdev->constraints->always_on || rdev->constraints->boot_on) {
+               ret = _regulator_do_enable(rdev);
+               if (ret < 0 && ret != -EINVAL) {
                        rdev_err(rdev, "failed to enable\n");
                        goto out;
                }
@@ -1711,8 +1712,6 @@ static int _regulator_do_disable(struct regulator_dev *rdev)
 
        trace_regulator_disable_complete(rdev_get_name(rdev));
 
-       _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
-                            NULL);
        return 0;
 }
 
@@ -1736,6 +1735,8 @@ static int _regulator_disable(struct regulator_dev *rdev)
                                rdev_err(rdev, "failed to disable\n");
                                return ret;
                        }
+                       _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE,
+                                       NULL);
                }
 
                rdev->use_count = 0;
@@ -1788,20 +1789,16 @@ static int _regulator_force_disable(struct regulator_dev *rdev)
 {
        int ret = 0;
 
-       /* force disable */
-       if (rdev->desc->ops->disable) {
-               /* ah well, who wants to live forever... */
-               ret = rdev->desc->ops->disable(rdev);
-               if (ret < 0) {
-                       rdev_err(rdev, "failed to force disable\n");
-                       return ret;
-               }
-               /* notify other consumers that power has been forced off */
-               _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
-                       REGULATOR_EVENT_DISABLE, NULL);
+       ret = _regulator_do_disable(rdev);
+       if (ret < 0) {
+               rdev_err(rdev, "failed to force disable\n");
+               return ret;
        }
 
-       return ret;
+       _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
+                       REGULATOR_EVENT_DISABLE, NULL);
+
+       return 0;
 }
 
 /**
@@ -1890,8 +1887,9 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)
        rdev->deferred_disables++;
        mutex_unlock(&rdev->mutex);
 
-       ret = schedule_delayed_work(&rdev->disable_work,
-                                   msecs_to_jiffies(ms));
+       ret = queue_delayed_work(system_power_efficient_wq,
+                                &rdev->disable_work,
+                                msecs_to_jiffies(ms));
        if (ret < 0)
                return ret;
        else
@@ -3787,23 +3785,18 @@ int regulator_suspend_finish(void)
 
        mutex_lock(&regulator_list_mutex);
        list_for_each_entry(rdev, &regulator_list, list) {
-               struct regulator_ops *ops = rdev->desc->ops;
-
                mutex_lock(&rdev->mutex);
-               if ((rdev->use_count > 0  || rdev->constraints->always_on) &&
-                               ops->enable) {
-                       error = ops->enable(rdev);
+               if (rdev->use_count > 0  || rdev->constraints->always_on) {
+                       error = _regulator_do_enable(rdev);
                        if (error)
                                ret = error;
                } else {
                        if (!has_full_constraints)
                                goto unlock;
-                       if (!ops->disable)
-                               goto unlock;
                        if (!_regulator_is_enabled(rdev))
                                goto unlock;
 
-                       error = ops->disable(rdev);
+                       error = _regulator_do_disable(rdev);
                        if (error)
                                ret = error;
                }
@@ -3993,7 +3986,7 @@ static int __init regulator_init_complete(void)
                ops = rdev->desc->ops;
                c = rdev->constraints;
 
-               if (!ops->disable || (c && c->always_on))
+               if (c && c->always_on)
                        continue;
 
                mutex_lock(&rdev->mutex);
@@ -4014,7 +4007,7 @@ static int __init regulator_init_complete(void)
                        /* We log since this may kill the system if it
                         * goes wrong. */
                        rdev_info(rdev, "disabling\n");
-                       ret = ops->disable(rdev);
+                       ret = _regulator_do_disable(rdev);
                        if (ret != 0) {
                                rdev_err(rdev, "couldn't disable: %d\n", ret);
                        }