cpufreq: Implement cpufreq_generic_suspend()
authorViresh Kumar <viresh.kumar@linaro.org>
Tue, 4 Mar 2014 03:00:27 +0000 (11:00 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 6 Mar 2014 14:04:12 +0000 (15:04 +0100)
Multiple platforms need to set CPUs to a particular frequency before
suspending the system, so provide a common infrastructure for them.

Those platforms only need to point their ->suspend callback pointers
to the generic routine.

Tested-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
[rjw: Changelog]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/cpufreq/cpufreq.c
include/linux/cpufreq.h

index 289a407a92078a0f30f61923bfcfd7113d57d20b..61dd72b8c143501f4477d780e0f37c7a5e16d39f 100644 (file)
@@ -1567,6 +1567,32 @@ static struct subsys_interface cpufreq_interface = {
        .remove_dev     = cpufreq_remove_dev,
 };
 
+/*
+ * In case platform wants some specific frequency to be configured
+ * during suspend..
+ */
+int cpufreq_generic_suspend(struct cpufreq_policy *policy)
+{
+       int ret;
+
+       if (!policy->suspend_freq) {
+               pr_err("%s: suspend_freq can't be zero\n", __func__);
+               return -EINVAL;
+       }
+
+       pr_debug("%s: Setting suspend-freq: %u\n", __func__,
+                       policy->suspend_freq);
+
+       ret = __cpufreq_driver_target(policy, policy->suspend_freq,
+                       CPUFREQ_RELATION_H);
+       if (ret)
+               pr_err("%s: unable to set suspend-freq: %u. err: %d\n",
+                               __func__, policy->suspend_freq, ret);
+
+       return ret;
+}
+EXPORT_SYMBOL(cpufreq_generic_suspend);
+
 /**
  * cpufreq_suspend() - Suspend CPUFreq governors
  *
index 94ed907c6999916bf122bf50b8158fe5373ca16c..325bab04271b167c43338f00b12925abc0247a9a 100644 (file)
@@ -74,6 +74,8 @@ struct cpufreq_policy {
        unsigned int            max;    /* in kHz */
        unsigned int            cur;    /* in kHz, only needed if cpufreq
                                         * governors are used */
+       unsigned int            suspend_freq; /* freq to set during suspend */
+
        unsigned int            policy; /* see above */
        struct cpufreq_governor *governor; /* see below */
        void                    *governor_data;
@@ -299,6 +301,7 @@ cpufreq_verify_within_cpu_limits(struct cpufreq_policy *policy)
 #ifdef CONFIG_CPU_FREQ
 void cpufreq_suspend(void);
 void cpufreq_resume(void);
+int cpufreq_generic_suspend(struct cpufreq_policy *policy);
 #else
 static inline void cpufreq_suspend(void) {}
 static inline void cpufreq_resume(void) {}