Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jacob Shin and committed by
Rafael J. Wysocki
fb30809e 5800043b

+57 -8
+4
drivers/cpufreq/cpufreq_governor.h
··· 263 263 struct common_dbs_data *cdata, unsigned int event); 264 264 void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, 265 265 unsigned int delay, bool all_cpus); 266 + void od_register_powersave_bias_handler(unsigned int (*f) 267 + (struct cpufreq_policy *, unsigned int, unsigned int), 268 + unsigned int powersave_bias); 269 + void od_unregister_powersave_bias_handler(void); 266 270 #endif /* _CPUFREQ_GOVERNER_H */
+53 -8
drivers/cpufreq/cpufreq_ondemand.c
··· 24 24 #include <linux/sysfs.h> 25 25 #include <linux/tick.h> 26 26 #include <linux/types.h> 27 + #include <linux/cpu.h> 27 28 28 29 #include "cpufreq_governor.h" 29 30 ··· 40 39 #define MAX_FREQUENCY_UP_THRESHOLD (100) 41 40 42 41 static DEFINE_PER_CPU(struct od_cpu_dbs_info_s, od_cpu_dbs_info); 42 + 43 + static struct od_ops od_ops; 43 44 44 45 #ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND 45 46 static struct cpufreq_governor cpufreq_gov_ondemand; ··· 83 80 * Returns the freq_hi to be used right now and will set freq_hi_jiffies, 84 81 * freq_lo, and freq_lo_jiffies in percpu area for averaging freqs. 85 82 */ 86 - static unsigned int powersave_bias_target(struct cpufreq_policy *policy, 83 + static unsigned int generic_powersave_bias_target(struct cpufreq_policy *policy, 87 84 unsigned int freq_next, unsigned int relation) 88 85 { 89 86 unsigned int freq_req, freq_reduc, freq_avg; ··· 148 145 struct od_dbs_tuners *od_tuners = dbs_data->tuners; 149 146 150 147 if (od_tuners->powersave_bias) 151 - freq = powersave_bias_target(p, freq, CPUFREQ_RELATION_H); 148 + freq = od_ops.powersave_bias_target(p, freq, 149 + CPUFREQ_RELATION_H); 152 150 else if (p->cur == p->max) 153 151 return; 154 152 ··· 209 205 if (!od_tuners->powersave_bias) { 210 206 __cpufreq_driver_target(policy, freq_next, 211 207 CPUFREQ_RELATION_L); 212 - } else { 213 - int freq = powersave_bias_target(policy, freq_next, 214 - CPUFREQ_RELATION_L); 215 - __cpufreq_driver_target(policy, freq, 216 - CPUFREQ_RELATION_L); 208 + return; 217 209 } 210 + 211 + freq_next = od_ops.powersave_bias_target(policy, freq_next, 212 + CPUFREQ_RELATION_L); 213 + __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L); 218 214 } 219 215 } 220 216 ··· 561 557 562 558 static struct od_ops od_ops = { 563 559 .powersave_bias_init_cpu = ondemand_powersave_bias_init_cpu, 564 - .powersave_bias_target = powersave_bias_target, 560 + .powersave_bias_target = generic_powersave_bias_target, 565 561 .freq_increase = dbs_freq_increase, 566 562 }; 567 563 ··· 577 573 .init = od_init, 578 574 .exit = od_exit, 579 575 }; 576 + 577 + static void od_set_powersave_bias(unsigned int powersave_bias) 578 + { 579 + struct cpufreq_policy *policy; 580 + struct dbs_data *dbs_data; 581 + struct od_dbs_tuners *od_tuners; 582 + unsigned int cpu; 583 + cpumask_t done; 584 + 585 + cpumask_clear(&done); 586 + 587 + get_online_cpus(); 588 + for_each_online_cpu(cpu) { 589 + if (cpumask_test_cpu(cpu, &done)) 590 + continue; 591 + 592 + policy = per_cpu(od_cpu_dbs_info, cpu).cdbs.cur_policy; 593 + dbs_data = policy->governor_data; 594 + od_tuners = dbs_data->tuners; 595 + od_tuners->powersave_bias = powersave_bias; 596 + 597 + cpumask_or(&done, &done, policy->cpus); 598 + } 599 + put_online_cpus(); 600 + } 601 + 602 + void od_register_powersave_bias_handler(unsigned int (*f) 603 + (struct cpufreq_policy *, unsigned int, unsigned int), 604 + unsigned int powersave_bias) 605 + { 606 + od_ops.powersave_bias_target = f; 607 + od_set_powersave_bias(powersave_bias); 608 + } 609 + EXPORT_SYMBOL_GPL(od_register_powersave_bias_handler); 610 + 611 + void od_unregister_powersave_bias_handler(void) 612 + { 613 + od_ops.powersave_bias_target = generic_powersave_bias_target; 614 + od_set_powersave_bias(0); 615 + } 616 + EXPORT_SYMBOL_GPL(od_unregister_powersave_bias_handler); 580 617 581 618 static int od_cpufreq_governor_dbs(struct cpufreq_policy *policy, 582 619 unsigned int event)