aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-12-26 19:07:11 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-12-29 09:30:36 -0500
commit72368d122c7479aa6e14fbbd334717b8a0c157a6 (patch)
treecf521f1fb24d4a77c5b1dc9df0d896d9f0db9729
parenta27a9ab706c8f5bb8bbd320d2e9c5d089e380c6a (diff)
cpufreq: Clean up after a failing light-weight initialization
If cpufreq_policy_restore() returns NULL during system resume, __cpufreq_add_dev() should just fall back to the full initialization instead of returning an error, because that may actually make things work. Moreover, it should not leave stale fallback data behind after it has failed to restore a previously existing policy. This change is based on Viresh Kumar's work. Fixes: 5302c3fb2e62 ("cpufreq: Perform light-weight init/teardown during suspend/resume") Reported-by: Bjørn Mork <bjorn@mork.no> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Cc: 3.12+ <stable@vger.kernel.org> # 3.12+
-rw-r--r--drivers/cpufreq/cpufreq.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 16d7b4ac94be..f13a663d1da5 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1016,15 +1016,17 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
1016 read_unlock_irqrestore(&cpufreq_driver_lock, flags); 1016 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
1017#endif 1017#endif
1018 1018
1019 if (frozen) 1019 /*
1020 /* Restore the saved policy when doing light-weight init */ 1020 * Restore the saved policy when doing light-weight init and fall back
1021 policy = cpufreq_policy_restore(cpu); 1021 * to the full init if that fails.
1022 else 1022 */
1023 policy = frozen ? cpufreq_policy_restore(cpu) : NULL;
1024 if (!policy) {
1025 frozen = false;
1023 policy = cpufreq_policy_alloc(); 1026 policy = cpufreq_policy_alloc();
1024 1027 if (!policy)
1025 if (!policy) 1028 goto nomem_out;
1026 goto nomem_out; 1029 }
1027
1028 1030
1029 /* 1031 /*
1030 * In the resume path, since we restore a saved policy, the assignment 1032 * In the resume path, since we restore a saved policy, the assignment
@@ -1118,8 +1120,11 @@ err_get_freq:
1118 if (cpufreq_driver->exit) 1120 if (cpufreq_driver->exit)
1119 cpufreq_driver->exit(policy); 1121 cpufreq_driver->exit(policy);
1120err_set_policy_cpu: 1122err_set_policy_cpu:
1121 if (frozen) 1123 if (frozen) {
1124 /* Do not leave stale fallback data behind. */
1125 per_cpu(cpufreq_cpu_data_fallback, cpu) = NULL;
1122 cpufreq_policy_put_kobj(policy); 1126 cpufreq_policy_put_kobj(policy);
1127 }
1123 cpufreq_policy_free(policy); 1128 cpufreq_policy_free(policy);
1124 1129
1125nomem_out: 1130nomem_out: