]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
cpufreq: Clean up after a failing light-weight initialization
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 27 Dec 2013 00:07:11 +0000 (01:07 +0100)
committerJiri Slaby <jslaby@suse.cz>
Fri, 3 Mar 2017 10:31:16 +0000 (11:31 +0100)
commit 72368d122c7479aa6e14fbbd334717b8a0c157a6 upstream.

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>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
drivers/cpufreq/cpufreq.c

index 4ad48da0cccbdaccde67ada8cec142e5d8ac4ec8..355a5597e09882fa45db55bb17d896188f83d2e2 100644 (file)
@@ -1044,15 +1044,17 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
        read_unlock_irqrestore(&cpufreq_driver_lock, flags);
 #endif
 
-       if (frozen)
-               /* Restore the saved policy when doing light-weight init */
-               policy = cpufreq_policy_restore(cpu);
-       else
+       /*
+        * Restore the saved policy when doing light-weight init and fall back
+        * to the full init if that fails.
+        */
+       policy = frozen ? cpufreq_policy_restore(cpu) : NULL;
+       if (!policy) {
+               frozen = false;
                policy = cpufreq_policy_alloc();
-
-       if (!policy)
-               goto nomem_out;
-
+               if (!policy)
+                       goto nomem_out;
+       }
 
        /*
         * In the resume path, since we restore a saved policy, the assignment
@@ -1135,8 +1137,11 @@ err_out_unregister:
        write_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
 err_set_policy_cpu:
-       if (frozen)
+       if (frozen) {
+               /* Do not leave stale fallback data behind. */
+               per_cpu(cpufreq_cpu_data_fallback, cpu) = NULL;
                cpufreq_policy_put_kobj(policy);
+       }
        cpufreq_policy_free(policy);
 
 nomem_out: