aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Shin <jacob.shin@amd.com>2013-04-02 10:56:56 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-04-10 07:19:26 -0400
commitfb30809efa3edeb692a6b29125a07c9eceb322dc (patch)
tree2664f62ce2ca5f280defc9c3b96009007118c48f
parent5800043b2488a1c4c6e859af860644d37419d58b (diff)
cpufreq: ondemand: allow custom powersave_bias_target handler to be registered
This allows for another [arch specific] driver to hook into existing powersave bias function of the ondemand governor. i.e. This allows AMD specific powersave bias function (in a separate AMD specific driver) to aid ondemand governor's frequency transition decisions. Signed-off-by: Jacob Shin <jacob.shin@amd.com> Acked-by: Thomas Renninger <trenn@suse.de> Acked-by: Borislav Petkov <bp@suse.de> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/cpufreq/cpufreq_governor.h4
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c61
2 files changed, 57 insertions, 8 deletions
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
index 513cc8234e5e..9f668e94dead 100644
--- a/drivers/cpufreq/cpufreq_governor.h
+++ b/drivers/cpufreq/cpufreq_governor.h
@@ -263,4 +263,8 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
263 struct common_dbs_data *cdata, unsigned int event); 263 struct common_dbs_data *cdata, unsigned int event);
264void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, 264void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy,
265 unsigned int delay, bool all_cpus); 265 unsigned int delay, bool all_cpus);
266void od_register_powersave_bias_handler(unsigned int (*f)
267 (struct cpufreq_policy *, unsigned int, unsigned int),
268 unsigned int powersave_bias);
269void od_unregister_powersave_bias_handler(void);
266#endif /* _CPUFREQ_GOVERNER_H */ 270#endif /* _CPUFREQ_GOVERNER_H */
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 14714787b724..b0ffef96bf77 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -24,6 +24,7 @@
24#include <linux/sysfs.h> 24#include <linux/sysfs.h>
25#include <linux/tick.h> 25#include <linux/tick.h>
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/cpu.h>
27 28
28#include "cpufreq_governor.h" 29#include "cpufreq_governor.h"
29 30
@@ -40,6 +41,8 @@
40 41
41static DEFINE_PER_CPU(struct od_cpu_dbs_info_s, od_cpu_dbs_info); 42static DEFINE_PER_CPU(struct od_cpu_dbs_info_s, od_cpu_dbs_info);
42 43
44static struct od_ops od_ops;
45
43#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND 46#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
44static struct cpufreq_governor cpufreq_gov_ondemand; 47static struct cpufreq_governor cpufreq_gov_ondemand;
45#endif 48#endif
@@ -80,7 +83,7 @@ static int should_io_be_busy(void)
80 * Returns the freq_hi to be used right now and will set freq_hi_jiffies, 83 * Returns the freq_hi to be used right now and will set freq_hi_jiffies,
81 * freq_lo, and freq_lo_jiffies in percpu area for averaging freqs. 84 * freq_lo, and freq_lo_jiffies in percpu area for averaging freqs.
82 */ 85 */
83static unsigned int powersave_bias_target(struct cpufreq_policy *policy, 86static unsigned int generic_powersave_bias_target(struct cpufreq_policy *policy,
84 unsigned int freq_next, unsigned int relation) 87 unsigned int freq_next, unsigned int relation)
85{ 88{
86 unsigned int freq_req, freq_reduc, freq_avg; 89 unsigned int freq_req, freq_reduc, freq_avg;
@@ -145,7 +148,8 @@ static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq)
145 struct od_dbs_tuners *od_tuners = dbs_data->tuners; 148 struct od_dbs_tuners *od_tuners = dbs_data->tuners;
146 149
147 if (od_tuners->powersave_bias) 150 if (od_tuners->powersave_bias)
148 freq = powersave_bias_target(p, freq, CPUFREQ_RELATION_H); 151 freq = od_ops.powersave_bias_target(p, freq,
152 CPUFREQ_RELATION_H);
149 else if (p->cur == p->max) 153 else if (p->cur == p->max)
150 return; 154 return;
151 155
@@ -205,12 +209,12 @@ static void od_check_cpu(int cpu, unsigned int load_freq)
205 if (!od_tuners->powersave_bias) { 209 if (!od_tuners->powersave_bias) {
206 __cpufreq_driver_target(policy, freq_next, 210 __cpufreq_driver_target(policy, freq_next,
207 CPUFREQ_RELATION_L); 211 CPUFREQ_RELATION_L);
208 } else { 212 return;
209 int freq = powersave_bias_target(policy, freq_next,
210 CPUFREQ_RELATION_L);
211 __cpufreq_driver_target(policy, freq,
212 CPUFREQ_RELATION_L);
213 } 213 }
214
215 freq_next = od_ops.powersave_bias_target(policy, freq_next,
216 CPUFREQ_RELATION_L);
217 __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L);
214 } 218 }
215} 219}
216 220
@@ -557,7 +561,7 @@ define_get_cpu_dbs_routines(od_cpu_dbs_info);
557 561
558static struct od_ops od_ops = { 562static struct od_ops od_ops = {
559 .powersave_bias_init_cpu = ondemand_powersave_bias_init_cpu, 563 .powersave_bias_init_cpu = ondemand_powersave_bias_init_cpu,
560 .powersave_bias_target = powersave_bias_target, 564 .powersave_bias_target = generic_powersave_bias_target,
561 .freq_increase = dbs_freq_increase, 565 .freq_increase = dbs_freq_increase,
562}; 566};
563 567
@@ -574,6 +578,47 @@ static struct common_dbs_data od_dbs_cdata = {
574 .exit = od_exit, 578 .exit = od_exit,
575}; 579};
576 580
581static void od_set_powersave_bias(unsigned int powersave_bias)
582{
583 struct cpufreq_policy *policy;
584 struct dbs_data *dbs_data;
585 struct od_dbs_tuners *od_tuners;
586 unsigned int cpu;
587 cpumask_t done;
588
589 cpumask_clear(&done);
590
591 get_online_cpus();
592 for_each_online_cpu(cpu) {
593 if (cpumask_test_cpu(cpu, &done))
594 continue;
595
596 policy = per_cpu(od_cpu_dbs_info, cpu).cdbs.cur_policy;
597 dbs_data = policy->governor_data;
598 od_tuners = dbs_data->tuners;
599 od_tuners->powersave_bias = powersave_bias;
600
601 cpumask_or(&done, &done, policy->cpus);
602 }
603 put_online_cpus();
604}
605
606void od_register_powersave_bias_handler(unsigned int (*f)
607 (struct cpufreq_policy *, unsigned int, unsigned int),
608 unsigned int powersave_bias)
609{
610 od_ops.powersave_bias_target = f;
611 od_set_powersave_bias(powersave_bias);
612}
613EXPORT_SYMBOL_GPL(od_register_powersave_bias_handler);
614
615void od_unregister_powersave_bias_handler(void)
616{
617 od_ops.powersave_bias_target = generic_powersave_bias_target;
618 od_set_powersave_bias(0);
619}
620EXPORT_SYMBOL_GPL(od_unregister_powersave_bias_handler);
621
577static int od_cpufreq_governor_dbs(struct cpufreq_policy *policy, 622static int od_cpufreq_governor_dbs(struct cpufreq_policy *policy,
578 unsigned int event) 623 unsigned int event)
579{ 624{