Merge remote-tracking branch 'regulator/fix/core' into regulator-linus
[sfrench/cifs-2.6.git] / drivers / regulator / core.c
index e567fa54980b6df80c3ef4757aa57086986eca68..9f4d484eb25d9ce17e3c2c7c0da8216350425980 100644 (file)
@@ -2396,6 +2396,14 @@ static void regulator_disable_work(struct work_struct *work)
        count = rdev->deferred_disables;
        rdev->deferred_disables = 0;
 
+       /*
+        * Workqueue functions queue the new work instance while the previous
+        * work instance is being processed. Cancel the queued work instance
+        * as the work instance under processing does the job of the queued
+        * work instance.
+        */
+       cancel_delayed_work(&rdev->disable_work);
+
        for (i = 0; i < count; i++) {
                ret = _regulator_disable(rdev);
                if (ret != 0)
@@ -2439,10 +2447,10 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)
 
        mutex_lock(&rdev->mutex);
        rdev->deferred_disables++;
+       mod_delayed_work(system_power_efficient_wq, &rdev->disable_work,
+                        msecs_to_jiffies(ms));
        mutex_unlock(&rdev->mutex);
 
-       queue_delayed_work(system_power_efficient_wq, &rdev->disable_work,
-                          msecs_to_jiffies(ms));
        return 0;
 }
 EXPORT_SYMBOL_GPL(regulator_disable_deferred);