aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/s5pv210-cpufreq.c
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2013-10-25 10:15:48 -0400
committerRafael J. Wysocki <rjw@rjwysocki.net>2013-10-25 16:42:24 -0400
commit9c0ebcf78fde0ffa348a95a544c6d3f2dac5af65 (patch)
tree0aa1814b3cdbd6900a6494d8f0c56551d90cf693 /drivers/cpufreq/s5pv210-cpufreq.c
parent6ddee424fea2d269c2f402278d93165c7b92dc58 (diff)
cpufreq: Implement light weight ->target_index() routine
Currently, the prototype of cpufreq_drivers target routines is: int target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation); And most of the drivers call cpufreq_frequency_table_target() to get a valid index of their frequency table which is closest to the target_freq. And they don't use target_freq and relation after that. So, it makes sense to just do this work in cpufreq core before calling cpufreq_frequency_table_target() and simply pass index instead. But this can be done only with drivers which expose their frequency table with cpufreq core. For others we need to stick with the old prototype of target() until those drivers are converted to expose frequency tables. This patch implements the new light weight prototype for target_index() routine. It looks like this: int target_index(struct cpufreq_policy *policy, unsigned int index); CPUFreq core will call cpufreq_frequency_table_target() before calling this routine and pass index to it. Because CPUFreq core now requires to call routines present in freq_table.c CONFIG_CPU_FREQ_TABLE must be enabled all the time. This also marks target() interface as deprecated. So, that new drivers avoid using it. And Documentation is updated accordingly. It also converts existing .target() to newly defined light weight .target_index() routine for many driver. Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no> Acked-by: Jesper Nilsson <jesper.nilsson@axis.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Russell King <linux@arm.linux.org.uk> Acked-by: David S. Miller <davem@davemloft.net> Tested-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rjw@rjwysocki.net>
Diffstat (limited to 'drivers/cpufreq/s5pv210-cpufreq.c')
-rw-r--r--drivers/cpufreq/s5pv210-cpufreq.c54
1 files changed, 14 insertions, 40 deletions
diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c
index 600b4f472e28..5978b94e0340 100644
--- a/drivers/cpufreq/s5pv210-cpufreq.c
+++ b/drivers/cpufreq/s5pv210-cpufreq.c
@@ -36,16 +36,7 @@ static DEFINE_MUTEX(set_freq_lock);
36/* Use 800MHz when entering sleep mode */ 36/* Use 800MHz when entering sleep mode */
37#define SLEEP_FREQ (800 * 1000) 37#define SLEEP_FREQ (800 * 1000)
38 38
39/* 39/* Tracks if cpu freqency can be updated anymore */
40 * relation has an additional symantics other than the standard of cpufreq
41 * DISALBE_FURTHER_CPUFREQ: disable further access to target
42 * ENABLE_FURTUER_CPUFREQ: enable access to target
43 */
44enum cpufreq_access {
45 DISABLE_FURTHER_CPUFREQ = 0x10,
46 ENABLE_FURTHER_CPUFREQ = 0x20,
47};
48
49static bool no_cpufreq_access; 40static bool no_cpufreq_access;
50 41
51/* 42/*
@@ -182,12 +173,10 @@ static unsigned int s5pv210_getspeed(unsigned int cpu)
182 return clk_get_rate(cpu_clk) / 1000; 173 return clk_get_rate(cpu_clk) / 1000;
183} 174}
184 175
185static int s5pv210_target(struct cpufreq_policy *policy, 176static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index)
186 unsigned int target_freq,
187 unsigned int relation)
188{ 177{
189 unsigned long reg; 178 unsigned long reg;
190 unsigned int index, priv_index; 179 unsigned int priv_index;
191 unsigned int pll_changing = 0; 180 unsigned int pll_changing = 0;
192 unsigned int bus_speed_changing = 0; 181 unsigned int bus_speed_changing = 0;
193 int arm_volt, int_volt; 182 int arm_volt, int_volt;
@@ -195,9 +184,6 @@ static int s5pv210_target(struct cpufreq_policy *policy,
195 184
196 mutex_lock(&set_freq_lock); 185 mutex_lock(&set_freq_lock);
197 186
198 if (relation & ENABLE_FURTHER_CPUFREQ)
199 no_cpufreq_access = false;
200
201 if (no_cpufreq_access) { 187 if (no_cpufreq_access) {
202#ifdef CONFIG_PM_VERBOSE 188#ifdef CONFIG_PM_VERBOSE
203 pr_err("%s:%d denied access to %s as it is disabled" 189 pr_err("%s:%d denied access to %s as it is disabled"
@@ -207,27 +193,13 @@ static int s5pv210_target(struct cpufreq_policy *policy,
207 goto exit; 193 goto exit;
208 } 194 }
209 195
210 if (relation & DISABLE_FURTHER_CPUFREQ)
211 no_cpufreq_access = true;
212
213 relation &= ~(ENABLE_FURTHER_CPUFREQ | DISABLE_FURTHER_CPUFREQ);
214
215 freqs.old = s5pv210_getspeed(0); 196 freqs.old = s5pv210_getspeed(0);
216
217 if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
218 target_freq, relation, &index)) {
219 ret = -EINVAL;
220 goto exit;
221 }
222
223 freqs.new = s5pv210_freq_table[index].frequency; 197 freqs.new = s5pv210_freq_table[index].frequency;
224 198
225 if (freqs.new == freqs.old)
226 goto exit;
227
228 /* Finding current running level index */ 199 /* Finding current running level index */
229 if (cpufreq_frequency_table_target(policy, s5pv210_freq_table, 200 if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
230 freqs.old, relation, &priv_index)) { 201 freqs.old, CPUFREQ_RELATION_H,
202 &priv_index)) {
231 ret = -EINVAL; 203 ret = -EINVAL;
232 goto exit; 204 goto exit;
233 } 205 }
@@ -559,16 +531,18 @@ static int s5pv210_cpufreq_notifier_event(struct notifier_block *this,
559 531
560 switch (event) { 532 switch (event) {
561 case PM_SUSPEND_PREPARE: 533 case PM_SUSPEND_PREPARE:
562 ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 534 ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0);
563 DISABLE_FURTHER_CPUFREQ);
564 if (ret < 0) 535 if (ret < 0)
565 return NOTIFY_BAD; 536 return NOTIFY_BAD;
566 537
538 /* Disable updation of cpu frequency */
539 no_cpufreq_access = true;
567 return NOTIFY_OK; 540 return NOTIFY_OK;
568 case PM_POST_RESTORE: 541 case PM_POST_RESTORE:
569 case PM_POST_SUSPEND: 542 case PM_POST_SUSPEND:
570 cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 543 /* Enable updation of cpu frequency */
571 ENABLE_FURTHER_CPUFREQ); 544 no_cpufreq_access = false;
545 cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0);
572 546
573 return NOTIFY_OK; 547 return NOTIFY_OK;
574 } 548 }
@@ -581,18 +555,18 @@ static int s5pv210_cpufreq_reboot_notifier_event(struct notifier_block *this,
581{ 555{
582 int ret; 556 int ret;
583 557
584 ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 558 ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0);
585 DISABLE_FURTHER_CPUFREQ);
586 if (ret < 0) 559 if (ret < 0)
587 return NOTIFY_BAD; 560 return NOTIFY_BAD;
588 561
562 no_cpufreq_access = true;
589 return NOTIFY_DONE; 563 return NOTIFY_DONE;
590} 564}
591 565
592static struct cpufreq_driver s5pv210_driver = { 566static struct cpufreq_driver s5pv210_driver = {
593 .flags = CPUFREQ_STICKY, 567 .flags = CPUFREQ_STICKY,
594 .verify = cpufreq_generic_frequency_table_verify, 568 .verify = cpufreq_generic_frequency_table_verify,
595 .target = s5pv210_target, 569 .target_index = s5pv210_target,
596 .get = s5pv210_getspeed, 570 .get = s5pv210_getspeed,
597 .init = s5pv210_cpu_init, 571 .init = s5pv210_cpu_init,
598 .name = "s5pv210", 572 .name = "s5pv210",