aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c157
1 files changed, 140 insertions, 17 deletions
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index f507a869acbc..34874c2f1885 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -55,6 +55,10 @@ struct cpu_dbs_info_s {
55 struct cpufreq_policy *cur_policy; 55 struct cpufreq_policy *cur_policy;
56 struct work_struct work; 56 struct work_struct work;
57 unsigned int enable; 57 unsigned int enable;
58 struct cpufreq_frequency_table *freq_table;
59 unsigned int freq_lo;
60 unsigned int freq_lo_jiffies;
61 unsigned int freq_hi_jiffies;
58}; 62};
59static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); 63static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
60 64
@@ -72,15 +76,15 @@ static DEFINE_MUTEX(dbs_mutex);
72 76
73static struct workqueue_struct *kondemand_wq; 77static struct workqueue_struct *kondemand_wq;
74 78
75struct dbs_tuners { 79static struct dbs_tuners {
76 unsigned int sampling_rate; 80 unsigned int sampling_rate;
77 unsigned int up_threshold; 81 unsigned int up_threshold;
78 unsigned int ignore_nice; 82 unsigned int ignore_nice;
79}; 83 unsigned int powersave_bias;
80 84} dbs_tuners_ins = {
81static struct dbs_tuners dbs_tuners_ins = {
82 .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, 85 .up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
83 .ignore_nice = 0, 86 .ignore_nice = 0,
87 .powersave_bias = 0,
84}; 88};
85 89
86static inline cputime64_t get_cpu_idle_time(unsigned int cpu) 90static inline cputime64_t get_cpu_idle_time(unsigned int cpu)
@@ -96,6 +100,69 @@ static inline cputime64_t get_cpu_idle_time(unsigned int cpu)
96 return retval; 100 return retval;
97} 101}
98 102
103/*
104 * Find right freq to be set now with powersave_bias on.
105 * Returns the freq_hi to be used right now and will set freq_hi_jiffies,
106 * freq_lo, and freq_lo_jiffies in percpu area for averaging freqs.
107 */
108unsigned int powersave_bias_target(struct cpufreq_policy *policy,
109 unsigned int freq_next, unsigned int relation)
110{
111 unsigned int freq_req, freq_reduc, freq_avg;
112 unsigned int freq_hi, freq_lo;
113 unsigned int index = 0;
114 unsigned int jiffies_total, jiffies_hi, jiffies_lo;
115 struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, policy->cpu);
116
117 if (!dbs_info->freq_table) {
118 dbs_info->freq_lo = 0;
119 dbs_info->freq_lo_jiffies = 0;
120 return freq_next;
121 }
122
123 cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_next,
124 relation, &index);
125 freq_req = dbs_info->freq_table[index].frequency;
126 freq_reduc = freq_req * dbs_tuners_ins.powersave_bias / 1000;
127 freq_avg = freq_req - freq_reduc;
128
129 /* Find freq bounds for freq_avg in freq_table */
130 index = 0;
131 cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_avg,
132 CPUFREQ_RELATION_H, &index);
133 freq_lo = dbs_info->freq_table[index].frequency;
134 index = 0;
135 cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_avg,
136 CPUFREQ_RELATION_L, &index);
137 freq_hi = dbs_info->freq_table[index].frequency;
138
139 /* Find out how long we have to be in hi and lo freqs */
140 if (freq_hi == freq_lo) {
141 dbs_info->freq_lo = 0;
142 dbs_info->freq_lo_jiffies = 0;
143 return freq_lo;
144 }
145 jiffies_total = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
146 jiffies_hi = (freq_avg - freq_lo) * jiffies_total;
147 jiffies_hi += ((freq_hi - freq_lo) / 2);
148 jiffies_hi /= (freq_hi - freq_lo);
149 jiffies_lo = jiffies_total - jiffies_hi;
150 dbs_info->freq_lo = freq_lo;
151 dbs_info->freq_lo_jiffies = jiffies_lo;
152 dbs_info->freq_hi_jiffies = jiffies_hi;
153 return freq_hi;
154}
155
156static void ondemand_powersave_bias_init(void)
157{
158 int i;
159 for_each_online_cpu(i) {
160 struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, i);
161 dbs_info->freq_table = cpufreq_frequency_get_table(i);
162 dbs_info->freq_lo = 0;
163 }
164}
165
99/************************** sysfs interface ************************/ 166/************************** sysfs interface ************************/
100static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) 167static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
101{ 168{
@@ -124,6 +191,7 @@ static ssize_t show_##file_name \
124show_one(sampling_rate, sampling_rate); 191show_one(sampling_rate, sampling_rate);
125show_one(up_threshold, up_threshold); 192show_one(up_threshold, up_threshold);
126show_one(ignore_nice_load, ignore_nice); 193show_one(ignore_nice_load, ignore_nice);
194show_one(powersave_bias, powersave_bias);
127 195
128static ssize_t store_sampling_rate(struct cpufreq_policy *unused, 196static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
129 const char *buf, size_t count) 197 const char *buf, size_t count)
@@ -198,6 +266,27 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
198 return count; 266 return count;
199} 267}
200 268
269static ssize_t store_powersave_bias(struct cpufreq_policy *unused,
270 const char *buf, size_t count)
271{
272 unsigned int input;
273 int ret;
274 ret = sscanf(buf, "%u", &input);
275
276 if (ret != 1)
277 return -EINVAL;
278
279 if (input > 1000)
280 input = 1000;
281
282 mutex_lock(&dbs_mutex);
283 dbs_tuners_ins.powersave_bias = input;
284 ondemand_powersave_bias_init();
285 mutex_unlock(&dbs_mutex);
286
287 return count;
288}
289
201#define define_one_rw(_name) \ 290#define define_one_rw(_name) \
202static struct freq_attr _name = \ 291static struct freq_attr _name = \
203__ATTR(_name, 0644, show_##_name, store_##_name) 292__ATTR(_name, 0644, show_##_name, store_##_name)
@@ -205,6 +294,7 @@ __ATTR(_name, 0644, show_##_name, store_##_name)
205define_one_rw(sampling_rate); 294define_one_rw(sampling_rate);
206define_one_rw(up_threshold); 295define_one_rw(up_threshold);
207define_one_rw(ignore_nice_load); 296define_one_rw(ignore_nice_load);
297define_one_rw(powersave_bias);
208 298
209static struct attribute * dbs_attributes[] = { 299static struct attribute * dbs_attributes[] = {
210 &sampling_rate_max.attr, 300 &sampling_rate_max.attr,
@@ -212,6 +302,7 @@ static struct attribute * dbs_attributes[] = {
212 &sampling_rate.attr, 302 &sampling_rate.attr,
213 &up_threshold.attr, 303 &up_threshold.attr,
214 &ignore_nice_load.attr, 304 &ignore_nice_load.attr,
305 &powersave_bias.attr,
215 NULL 306 NULL
216}; 307};
217 308
@@ -234,6 +325,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
234 if (!this_dbs_info->enable) 325 if (!this_dbs_info->enable)
235 return; 326 return;
236 327
328 this_dbs_info->freq_lo = 0;
237 policy = this_dbs_info->cur_policy; 329 policy = this_dbs_info->cur_policy;
238 cur_jiffies = jiffies64_to_cputime64(get_jiffies_64()); 330 cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
239 total_ticks = (unsigned int) cputime64_sub(cur_jiffies, 331 total_ticks = (unsigned int) cputime64_sub(cur_jiffies,
@@ -274,11 +366,18 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
274 /* Check for frequency increase */ 366 /* Check for frequency increase */
275 if (load > dbs_tuners_ins.up_threshold) { 367 if (load > dbs_tuners_ins.up_threshold) {
276 /* if we are already at full speed then break out early */ 368 /* if we are already at full speed then break out early */
277 if (policy->cur == policy->max) 369 if (!dbs_tuners_ins.powersave_bias) {
278 return; 370 if (policy->cur == policy->max)
279 371 return;
280 __cpufreq_driver_target(policy, policy->max, 372
281 CPUFREQ_RELATION_H); 373 __cpufreq_driver_target(policy, policy->max,
374 CPUFREQ_RELATION_H);
375 } else {
376 int freq = powersave_bias_target(policy, policy->max,
377 CPUFREQ_RELATION_H);
378 __cpufreq_driver_target(policy, freq,
379 CPUFREQ_RELATION_L);
380 }
282 return; 381 return;
283 } 382 }
284 383
@@ -293,14 +392,23 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
293 * policy. To be safe, we focus 10 points under the threshold. 392 * policy. To be safe, we focus 10 points under the threshold.
294 */ 393 */
295 if (load < (dbs_tuners_ins.up_threshold - 10)) { 394 if (load < (dbs_tuners_ins.up_threshold - 10)) {
296 unsigned int freq_next; 395 unsigned int freq_next = (policy->cur * load) /
297 freq_next = (policy->cur * load) /
298 (dbs_tuners_ins.up_threshold - 10); 396 (dbs_tuners_ins.up_threshold - 10);
299 397 if (!dbs_tuners_ins.powersave_bias) {
300 __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L); 398 __cpufreq_driver_target(policy, freq_next,
399 CPUFREQ_RELATION_L);
400 } else {
401 int freq = powersave_bias_target(policy, freq_next,
402 CPUFREQ_RELATION_L);
403 __cpufreq_driver_target(policy, freq,
404 CPUFREQ_RELATION_L);
405 }
301 } 406 }
302} 407}
303 408
409/* Sampling types */
410enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE};
411
304static void do_dbs_timer(void *data) 412static void do_dbs_timer(void *data)
305{ 413{
306 unsigned int cpu = smp_processor_id(); 414 unsigned int cpu = smp_processor_id();
@@ -311,10 +419,24 @@ static void do_dbs_timer(void *data)
311 419
312 if (!dbs_info->enable) 420 if (!dbs_info->enable)
313 return; 421 return;
314 422 /* Common NORMAL_SAMPLE setup */
315 lock_cpu_hotplug(); 423 INIT_WORK(&dbs_info->work, do_dbs_timer, (void *)DBS_NORMAL_SAMPLE);
316 dbs_check_cpu(dbs_info); 424 if (!dbs_tuners_ins.powersave_bias ||
317 unlock_cpu_hotplug(); 425 (unsigned long) data == DBS_NORMAL_SAMPLE) {
426 lock_cpu_hotplug();
427 dbs_check_cpu(dbs_info);
428 unlock_cpu_hotplug();
429 if (dbs_info->freq_lo) {
430 /* Setup timer for SUB_SAMPLE */
431 INIT_WORK(&dbs_info->work, do_dbs_timer,
432 (void *)DBS_SUB_SAMPLE);
433 delay = dbs_info->freq_hi_jiffies;
434 }
435 } else {
436 __cpufreq_driver_target(dbs_info->cur_policy,
437 dbs_info->freq_lo,
438 CPUFREQ_RELATION_H);
439 }
318 queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay); 440 queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay);
319} 441}
320 442
@@ -325,6 +447,7 @@ static inline void dbs_timer_init(unsigned int cpu)
325 int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); 447 int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
326 delay -= jiffies % delay; 448 delay -= jiffies % delay;
327 449
450 ondemand_powersave_bias_init();
328 INIT_WORK(&dbs_info->work, do_dbs_timer, 0); 451 INIT_WORK(&dbs_info->work, do_dbs_timer, 0);
329 queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay); 452 queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay);
330} 453}