diff options
| author | Linux Build Service Account <lnxbuild@quicinc.com> | 2017-07-06 23:41:23 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-07-06 23:41:23 -0700 |
| commit | 97aeb32ee2273d4e39a93ee5f11566271af993fd (patch) | |
| tree | 21df7d15be17df9ec35e45af5e5b960bfb42fba1 | |
| parent | e46fafb501980533c5d9331cca71697dba4dbbf6 (diff) | |
| parent | 493d8a74b6ef923bff21e44c71ae2c6a67d6578b (diff) | |
Merge "regulator: core: fix a possible race in disable_work handling"
| -rw-r--r-- | drivers/regulator/core.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index adf621430b41..188920367e84 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2361,6 +2361,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) @@ -2404,10 +2412,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); |
