aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/cpu-freq/cpu-drivers.txt27
-rw-r--r--Documentation/cpu-freq/governors.txt4
-rw-r--r--arch/arm/mach-sa1100/generic.c20
-rw-r--r--arch/arm/mach-sa1100/generic.h2
-rw-r--r--drivers/cpufreq/acpi-cpufreq.c21
-rw-r--r--drivers/cpufreq/arm_big_little.c17
-rw-r--r--drivers/cpufreq/at32ap-cpufreq.c23
-rw-r--r--drivers/cpufreq/blackfin-cpufreq.c17
-rw-r--r--drivers/cpufreq/cpufreq-cpu0.c17
-rw-r--r--drivers/cpufreq/cpufreq.c57
-rw-r--r--drivers/cpufreq/cris-artpec3-cpufreq.c18
-rw-r--r--drivers/cpufreq/cris-etraxfs-cpufreq.c17
-rw-r--r--drivers/cpufreq/davinci-cpufreq.c16
-rw-r--r--drivers/cpufreq/dbx500-cpufreq.c16
-rw-r--r--drivers/cpufreq/e_powersaver.c17
-rw-r--r--drivers/cpufreq/elanfreq.c34
-rw-r--r--drivers/cpufreq/exynos-cpufreq.c21
-rw-r--r--drivers/cpufreq/exynos5440-cpufreq.c21
-rw-r--r--drivers/cpufreq/ia64-acpi-cpufreq.c21
-rw-r--r--drivers/cpufreq/imx6q-cpufreq.c17
-rw-r--r--drivers/cpufreq/kirkwood-cpufreq.c19
-rw-r--r--drivers/cpufreq/longhaul.c13
-rw-r--r--drivers/cpufreq/loongson2_cpufreq.c21
-rw-r--r--drivers/cpufreq/maple-cpufreq.c16
-rw-r--r--drivers/cpufreq/omap-cpufreq.c31
-rw-r--r--drivers/cpufreq/p4-clockmod.c18
-rw-r--r--drivers/cpufreq/pasemi-cpufreq.c12
-rw-r--r--drivers/cpufreq/pmac32-cpufreq.c12
-rw-r--r--drivers/cpufreq/pmac64-cpufreq.c17
-rw-r--r--drivers/cpufreq/powernow-k6.c35
-rw-r--r--drivers/cpufreq/powernow-k7.c22
-rw-r--r--drivers/cpufreq/powernow-k8.c24
-rw-r--r--drivers/cpufreq/ppc-corenet-cpufreq.c15
-rw-r--r--drivers/cpufreq/ppc_cbe_cpufreq.c12
-rw-r--r--drivers/cpufreq/pxa2xx-cpufreq.c13
-rw-r--r--drivers/cpufreq/pxa3xx-cpufreq.c17
-rw-r--r--drivers/cpufreq/s3c2416-cpufreq.c17
-rw-r--r--drivers/cpufreq/s3c64xx-cpufreq.c18
-rw-r--r--drivers/cpufreq/s5pv210-cpufreq.c54
-rw-r--r--drivers/cpufreq/sa1100-cpufreq.c24
-rw-r--r--drivers/cpufreq/sa1110-cpufreq.c26
-rw-r--r--drivers/cpufreq/sc520_freq.c19
-rw-r--r--drivers/cpufreq/sparc-us2e-cpufreq.c21
-rw-r--r--drivers/cpufreq/sparc-us3-cpufreq.c23
-rw-r--r--drivers/cpufreq/spear-cpufreq.c12
-rw-r--r--drivers/cpufreq/speedstep-centrino.c27
-rw-r--r--drivers/cpufreq/speedstep-ich.c24
-rw-r--r--drivers/cpufreq/speedstep-smi.c20
-rw-r--r--drivers/cpufreq/tegra-cpufreq.c12
-rw-r--r--include/linux/cpufreq.h4
50 files changed, 242 insertions, 759 deletions
diff --git a/Documentation/cpu-freq/cpu-drivers.txt b/Documentation/cpu-freq/cpu-drivers.txt
index 40282e617913..8b1a4451422e 100644
--- a/Documentation/cpu-freq/cpu-drivers.txt
+++ b/Documentation/cpu-freq/cpu-drivers.txt
@@ -23,8 +23,8 @@ Contents:
231.1 Initialization 231.1 Initialization
241.2 Per-CPU Initialization 241.2 Per-CPU Initialization
251.3 verify 251.3 verify
261.4 target or setpolicy? 261.4 target/target_index or setpolicy?
271.5 target 271.5 target/target_index
281.6 setpolicy 281.6 setpolicy
292. Frequency Table Helpers 292. Frequency Table Helpers
30 30
@@ -56,7 +56,8 @@ cpufreq_driver.init - A pointer to the per-CPU initialization
56cpufreq_driver.verify - A pointer to a "verification" function. 56cpufreq_driver.verify - A pointer to a "verification" function.
57 57
58cpufreq_driver.setpolicy _or_ 58cpufreq_driver.setpolicy _or_
59cpufreq_driver.target - See below on the differences. 59cpufreq_driver.target/
60target_index - See below on the differences.
60 61
61And optionally 62And optionally
62 63
@@ -66,7 +67,7 @@ cpufreq_driver.resume - A pointer to a per-CPU resume function
66 which is called with interrupts disabled 67 which is called with interrupts disabled
67 and _before_ the pre-suspend frequency 68 and _before_ the pre-suspend frequency
68 and/or policy is restored by a call to 69 and/or policy is restored by a call to
69 ->target or ->setpolicy. 70 ->target/target_index or ->setpolicy.
70 71
71cpufreq_driver.attr - A pointer to a NULL-terminated list of 72cpufreq_driver.attr - A pointer to a NULL-terminated list of
72 "struct freq_attr" which allow to 73 "struct freq_attr" which allow to
@@ -103,8 +104,8 @@ policy->governor must contain the "default policy" for
103 this CPU. A few moments later, 104 this CPU. A few moments later,
104 cpufreq_driver.verify and either 105 cpufreq_driver.verify and either
105 cpufreq_driver.setpolicy or 106 cpufreq_driver.setpolicy or
106 cpufreq_driver.target is called with 107 cpufreq_driver.target/target_index is called
107 these values. 108 with these values.
108 109
109For setting some of these values (cpuinfo.min[max]_freq, policy->min[max]), the 110For setting some of these values (cpuinfo.min[max]_freq, policy->min[max]), the
110frequency table helpers might be helpful. See the section 2 for more information 111frequency table helpers might be helpful. See the section 2 for more information
@@ -133,20 +134,28 @@ range) is within policy->min and policy->max. If necessary, increase
133policy->max first, and only if this is no solution, decrease policy->min. 134policy->max first, and only if this is no solution, decrease policy->min.
134 135
135 136
1361.4 target or setpolicy? 1371.4 target/target_index or setpolicy?
137---------------------------- 138----------------------------
138 139
139Most cpufreq drivers or even most cpu frequency scaling algorithms 140Most cpufreq drivers or even most cpu frequency scaling algorithms
140only allow the CPU to be set to one frequency. For these, you use the 141only allow the CPU to be set to one frequency. For these, you use the
141->target call. 142->target/target_index call.
142 143
143Some cpufreq-capable processors switch the frequency between certain 144Some cpufreq-capable processors switch the frequency between certain
144limits on their own. These shall use the ->setpolicy call 145limits on their own. These shall use the ->setpolicy call
145 146
146 147
1471.4. target 1481.4. target/target_index
148------------- 149-------------
149 150
151The target_index call has two arguments: struct cpufreq_policy *policy,
152and unsigned int index (into the exposed frequency table).
153
154The CPUfreq driver must set the new frequency when called here. The
155actual frequency must be determined by freq_table[index].frequency.
156
157Deprecated:
158----------
150The target call has three arguments: struct cpufreq_policy *policy, 159The target call has three arguments: struct cpufreq_policy *policy,
151unsigned int target_frequency, unsigned int relation. 160unsigned int target_frequency, unsigned int relation.
152 161
diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt
index 219970ba54b7..77ec21574fb1 100644
--- a/Documentation/cpu-freq/governors.txt
+++ b/Documentation/cpu-freq/governors.txt
@@ -40,7 +40,7 @@ Most cpufreq drivers (in fact, all except one, longrun) or even most
40cpu frequency scaling algorithms only offer the CPU to be set to one 40cpu frequency scaling algorithms only offer the CPU to be set to one
41frequency. In order to offer dynamic frequency scaling, the cpufreq 41frequency. In order to offer dynamic frequency scaling, the cpufreq
42core must be able to tell these drivers of a "target frequency". So 42core must be able to tell these drivers of a "target frequency". So
43these specific drivers will be transformed to offer a "->target" 43these specific drivers will be transformed to offer a "->target/target_index"
44call instead of the existing "->setpolicy" call. For "longrun", all 44call instead of the existing "->setpolicy" call. For "longrun", all
45stays the same, though. 45stays the same, though.
46 46
@@ -71,7 +71,7 @@ CPU can be set to switch independently | CPU can only be set
71 / the limits of policy->{min,max} 71 / the limits of policy->{min,max}
72 / \ 72 / \
73 / \ 73 / \
74 Using the ->setpolicy call, Using the ->target call, 74 Using the ->setpolicy call, Using the ->target/target_index call,
75 the limits and the the frequency closest 75 the limits and the the frequency closest
76 "policy" is set. to target_freq is set. 76 "policy" is set. to target_freq is set.
77 It is assured that it 77 It is assured that it
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index cb4b2ca3cf6b..d4ea142c4edd 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -62,26 +62,6 @@ struct cpufreq_frequency_table sa11x0_freq_table[NR_FREQS+1] = {
62 { .frequency = CPUFREQ_TABLE_END, }, 62 { .frequency = CPUFREQ_TABLE_END, },
63}; 63};
64 64
65/* rounds up(!) */
66unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
67{
68 int i;
69
70 for (i = 0; i < NR_FREQS; i++)
71 if (sa11x0_freq_table[i].frequency >= khz)
72 break;
73
74 return i;
75}
76
77unsigned int sa11x0_ppcr_to_freq(unsigned int idx)
78{
79 unsigned int freq = 0;
80 if (idx < NR_FREQS)
81 freq = sa11x0_freq_table[idx].frequency;
82 return freq;
83}
84
85unsigned int sa11x0_getspeed(unsigned int cpu) 65unsigned int sa11x0_getspeed(unsigned int cpu)
86{ 66{
87 if (cpu) 67 if (cpu)
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
index cbdfae744dc5..0d92e119b36b 100644
--- a/arch/arm/mach-sa1100/generic.h
+++ b/arch/arm/mach-sa1100/generic.h
@@ -21,9 +21,7 @@ extern void sa1110_mb_enable(void);
21extern void sa1110_mb_disable(void); 21extern void sa1110_mb_disable(void);
22 22
23extern struct cpufreq_frequency_table sa11x0_freq_table[]; 23extern struct cpufreq_frequency_table sa11x0_freq_table[];
24extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
25extern unsigned int sa11x0_getspeed(unsigned int cpu); 24extern unsigned int sa11x0_getspeed(unsigned int cpu);
26extern unsigned int sa11x0_ppcr_to_freq(unsigned int idx);
27 25
28struct flash_platform_data; 26struct flash_platform_data;
29struct resource; 27struct resource;
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index a1717d7367c1..889cec0a9022 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -424,17 +424,17 @@ static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq,
424} 424}
425 425
426static int acpi_cpufreq_target(struct cpufreq_policy *policy, 426static int acpi_cpufreq_target(struct cpufreq_policy *policy,
427 unsigned int target_freq, unsigned int relation) 427 unsigned int index)
428{ 428{
429 struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); 429 struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
430 struct acpi_processor_performance *perf; 430 struct acpi_processor_performance *perf;
431 struct cpufreq_freqs freqs; 431 struct cpufreq_freqs freqs;
432 struct drv_cmd cmd; 432 struct drv_cmd cmd;
433 unsigned int next_state = 0; /* Index into freq_table */
434 unsigned int next_perf_state = 0; /* Index into perf table */ 433 unsigned int next_perf_state = 0; /* Index into perf table */
435 int result = 0; 434 int result = 0;
436 435
437 pr_debug("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu); 436 pr_debug("acpi_cpufreq_target %d (%d)\n",
437 data->freq_table[index].frequency, policy->cpu);
438 438
439 if (unlikely(data == NULL || 439 if (unlikely(data == NULL ||
440 data->acpi_data == NULL || data->freq_table == NULL)) { 440 data->acpi_data == NULL || data->freq_table == NULL)) {
@@ -442,16 +442,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
442 } 442 }
443 443
444 perf = data->acpi_data; 444 perf = data->acpi_data;
445 result = cpufreq_frequency_table_target(policy, 445 next_perf_state = data->freq_table[index].driver_data;
446 data->freq_table,
447 target_freq,
448 relation, &next_state);
449 if (unlikely(result)) {
450 result = -ENODEV;
451 goto out;
452 }
453
454 next_perf_state = data->freq_table[next_state].driver_data;
455 if (perf->state == next_perf_state) { 446 if (perf->state == next_perf_state) {
456 if (unlikely(data->resume)) { 447 if (unlikely(data->resume)) {
457 pr_debug("Called after resume, resetting to P%d\n", 448 pr_debug("Called after resume, resetting to P%d\n",
@@ -493,7 +484,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
493 cmd.mask = cpumask_of(policy->cpu); 484 cmd.mask = cpumask_of(policy->cpu);
494 485
495 freqs.old = perf->states[perf->state].core_frequency * 1000; 486 freqs.old = perf->states[perf->state].core_frequency * 1000;
496 freqs.new = data->freq_table[next_state].frequency; 487 freqs.new = data->freq_table[index].frequency;
497 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 488 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
498 489
499 drv_write(&cmd); 490 drv_write(&cmd);
@@ -923,7 +914,7 @@ static struct freq_attr *acpi_cpufreq_attr[] = {
923 914
924static struct cpufreq_driver acpi_cpufreq_driver = { 915static struct cpufreq_driver acpi_cpufreq_driver = {
925 .verify = cpufreq_generic_frequency_table_verify, 916 .verify = cpufreq_generic_frequency_table_verify,
926 .target = acpi_cpufreq_target, 917 .target_index = acpi_cpufreq_target,
927 .bios_limit = acpi_processor_get_bios_limit, 918 .bios_limit = acpi_processor_get_bios_limit,
928 .init = acpi_cpufreq_cpu_init, 919 .init = acpi_cpufreq_cpu_init,
929 .exit = acpi_cpufreq_cpu_exit, 920 .exit = acpi_cpufreq_cpu_exit,
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c
index 086f7c17ff58..163e3378fe17 100644
--- a/drivers/cpufreq/arm_big_little.c
+++ b/drivers/cpufreq/arm_big_little.c
@@ -49,28 +49,21 @@ static unsigned int bL_cpufreq_get(unsigned int cpu)
49 49
50/* Set clock frequency */ 50/* Set clock frequency */
51static int bL_cpufreq_set_target(struct cpufreq_policy *policy, 51static int bL_cpufreq_set_target(struct cpufreq_policy *policy,
52 unsigned int target_freq, unsigned int relation) 52 unsigned int index)
53{ 53{
54 struct cpufreq_freqs freqs; 54 struct cpufreq_freqs freqs;
55 u32 cpu = policy->cpu, freq_tab_idx, cur_cluster; 55 u32 cpu = policy->cpu, cur_cluster;
56 int ret = 0; 56 int ret = 0;
57 57
58 cur_cluster = cpu_to_cluster(policy->cpu); 58 cur_cluster = cpu_to_cluster(policy->cpu);
59 59
60 freqs.old = bL_cpufreq_get(policy->cpu); 60 freqs.old = bL_cpufreq_get(policy->cpu);
61 61 freqs.new = freq_table[cur_cluster][index].frequency;
62 /* Determine valid target frequency using freq_table */
63 cpufreq_frequency_table_target(policy, freq_table[cur_cluster],
64 target_freq, relation, &freq_tab_idx);
65 freqs.new = freq_table[cur_cluster][freq_tab_idx].frequency;
66 62
67 pr_debug("%s: cpu: %d, cluster: %d, oldfreq: %d, target freq: %d, new freq: %d\n", 63 pr_debug("%s: cpu: %d, cluster: %d, oldfreq: %d, target freq: %d, new freq: %d\n",
68 __func__, cpu, cur_cluster, freqs.old, target_freq, 64 __func__, cpu, cur_cluster, freqs.old, freqs.new,
69 freqs.new); 65 freqs.new);
70 66
71 if (freqs.old == freqs.new)
72 return 0;
73
74 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 67 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
75 68
76 ret = clk_set_rate(clk[cur_cluster], freqs.new * 1000); 69 ret = clk_set_rate(clk[cur_cluster], freqs.new * 1000);
@@ -200,7 +193,7 @@ static struct cpufreq_driver bL_cpufreq_driver = {
200 .flags = CPUFREQ_STICKY | 193 .flags = CPUFREQ_STICKY |
201 CPUFREQ_HAVE_GOVERNOR_PER_POLICY, 194 CPUFREQ_HAVE_GOVERNOR_PER_POLICY,
202 .verify = cpufreq_generic_frequency_table_verify, 195 .verify = cpufreq_generic_frequency_table_verify,
203 .target = bL_cpufreq_set_target, 196 .target_index = bL_cpufreq_set_target,
204 .get = bL_cpufreq_get, 197 .get = bL_cpufreq_get,
205 .init = bL_cpufreq_init, 198 .init = bL_cpufreq_init,
206 .exit = bL_cpufreq_exit, 199 .exit = bL_cpufreq_exit,
diff --git a/drivers/cpufreq/at32ap-cpufreq.c b/drivers/cpufreq/at32ap-cpufreq.c
index 7439deddd5cf..81d07527bde6 100644
--- a/drivers/cpufreq/at32ap-cpufreq.c
+++ b/drivers/cpufreq/at32ap-cpufreq.c
@@ -35,25 +35,12 @@ static unsigned int at32_get_speed(unsigned int cpu)
35static unsigned int ref_freq; 35static unsigned int ref_freq;
36static unsigned long loops_per_jiffy_ref; 36static unsigned long loops_per_jiffy_ref;
37 37
38static int at32_set_target(struct cpufreq_policy *policy, 38static int at32_set_target(struct cpufreq_policy *policy, unsigned int index)
39 unsigned int target_freq,
40 unsigned int relation)
41{ 39{
42 struct cpufreq_freqs freqs; 40 struct cpufreq_freqs freqs;
43 long freq;
44
45 /* Convert target_freq from kHz to Hz */
46 freq = clk_round_rate(cpuclk, target_freq * 1000);
47
48 /* Check if policy->min <= new_freq <= policy->max */
49 if(freq < (policy->min * 1000) || freq > (policy->max * 1000))
50 return -EINVAL;
51
52 pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000);
53 41
54 freqs.old = at32_get_speed(0); 42 freqs.old = at32_get_speed(0);
55 freqs.new = (freq + 500) / 1000; 43 freqs.new = freq_table[index].frequency;
56 freqs.flags = 0;
57 44
58 if (!ref_freq) { 45 if (!ref_freq) {
59 ref_freq = freqs.old; 46 ref_freq = freqs.old;
@@ -64,13 +51,13 @@ static int at32_set_target(struct cpufreq_policy *policy,
64 if (freqs.old < freqs.new) 51 if (freqs.old < freqs.new)
65 boot_cpu_data.loops_per_jiffy = cpufreq_scale( 52 boot_cpu_data.loops_per_jiffy = cpufreq_scale(
66 loops_per_jiffy_ref, ref_freq, freqs.new); 53 loops_per_jiffy_ref, ref_freq, freqs.new);
67 clk_set_rate(cpuclk, freq); 54 clk_set_rate(cpuclk, freqs.new * 1000);
68 if (freqs.new < freqs.old) 55 if (freqs.new < freqs.old)
69 boot_cpu_data.loops_per_jiffy = cpufreq_scale( 56 boot_cpu_data.loops_per_jiffy = cpufreq_scale(
70 loops_per_jiffy_ref, ref_freq, freqs.new); 57 loops_per_jiffy_ref, ref_freq, freqs.new);
71 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 58 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
72 59
73 pr_debug("cpufreq: set frequency %lu Hz\n", freq); 60 pr_debug("cpufreq: set frequency %u Hz\n", freqs.new * 1000);
74 61
75 return 0; 62 return 0;
76} 63}
@@ -139,7 +126,7 @@ static struct cpufreq_driver at32_driver = {
139 .name = "at32ap", 126 .name = "at32ap",
140 .init = at32_cpufreq_driver_init, 127 .init = at32_cpufreq_driver_init,
141 .verify = cpufreq_generic_frequency_table_verify, 128 .verify = cpufreq_generic_frequency_table_verify,
142 .target = at32_set_target, 129 .target_index = at32_set_target,
143 .get = at32_get_speed, 130 .get = at32_get_speed,
144 .flags = CPUFREQ_STICKY, 131 .flags = CPUFREQ_STICKY,
145}; 132};
diff --git a/drivers/cpufreq/blackfin-cpufreq.c b/drivers/cpufreq/blackfin-cpufreq.c
index 0bc9e8c2c79b..12528b28d45d 100644
--- a/drivers/cpufreq/blackfin-cpufreq.c
+++ b/drivers/cpufreq/blackfin-cpufreq.c
@@ -127,14 +127,11 @@ unsigned long cpu_set_cclk(int cpu, unsigned long new)
127} 127}
128#endif 128#endif
129 129
130static int bfin_target(struct cpufreq_policy *policy, 130static int bfin_target(struct cpufreq_policy *policy, unsigned int index)
131 unsigned int target_freq, unsigned int relation)
132{ 131{
133#ifndef CONFIG_BF60x 132#ifndef CONFIG_BF60x
134 unsigned int plldiv; 133 unsigned int plldiv;
135#endif 134#endif
136 unsigned int index;
137 unsigned long cclk_hz;
138 struct cpufreq_freqs freqs; 135 struct cpufreq_freqs freqs;
139 static unsigned long lpj_ref; 136 static unsigned long lpj_ref;
140 static unsigned int lpj_ref_freq; 137 static unsigned int lpj_ref_freq;
@@ -144,17 +141,11 @@ static int bfin_target(struct cpufreq_policy *policy,
144 cycles_t cycles; 141 cycles_t cycles;
145#endif 142#endif
146 143
147 if (cpufreq_frequency_table_target(policy, bfin_freq_table, target_freq,
148 relation, &index))
149 return -EINVAL;
150
151 cclk_hz = bfin_freq_table[index].frequency;
152
153 freqs.old = bfin_getfreq_khz(0); 144 freqs.old = bfin_getfreq_khz(0);
154 freqs.new = cclk_hz; 145 freqs.new = bfin_freq_table[index].frequency;
155 146
156 pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n", 147 pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n",
157 cclk_hz, target_freq, freqs.old); 148 freqs.new, freqs.new, freqs.old);
158 149
159 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 150 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
160#ifndef CONFIG_BF60x 151#ifndef CONFIG_BF60x
@@ -209,7 +200,7 @@ static int __bfin_cpu_init(struct cpufreq_policy *policy)
209 200
210static struct cpufreq_driver bfin_driver = { 201static struct cpufreq_driver bfin_driver = {
211 .verify = cpufreq_generic_frequency_table_verify, 202 .verify = cpufreq_generic_frequency_table_verify,
212 .target = bfin_target, 203 .target_index = bfin_target,
213 .get = bfin_getfreq_khz, 204 .get = bfin_getfreq_khz,
214 .init = __bfin_cpu_init, 205 .init = __bfin_cpu_init,
215 .exit = cpufreq_generic_exit, 206 .exit = cpufreq_generic_exit,
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
index 33ab6504c447..4dbe7efd86e5 100644
--- a/drivers/cpufreq/cpufreq-cpu0.c
+++ b/drivers/cpufreq/cpufreq-cpu0.c
@@ -35,24 +35,14 @@ static unsigned int cpu0_get_speed(unsigned int cpu)
35 return clk_get_rate(cpu_clk) / 1000; 35 return clk_get_rate(cpu_clk) / 1000;
36} 36}
37 37
38static int cpu0_set_target(struct cpufreq_policy *policy, 38static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
39 unsigned int target_freq, unsigned int relation)
40{ 39{
41 struct cpufreq_freqs freqs; 40 struct cpufreq_freqs freqs;
42 struct dev_pm_opp *opp; 41 struct dev_pm_opp *opp;
43 unsigned long volt = 0, volt_old = 0, tol = 0; 42 unsigned long volt = 0, volt_old = 0, tol = 0;
44 long freq_Hz, freq_exact; 43 long freq_Hz, freq_exact;
45 unsigned int index;
46 int ret; 44 int ret;
47 45
48 ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
49 relation, &index);
50 if (ret) {
51 pr_err("failed to match target freqency %d: %d\n",
52 target_freq, ret);
53 return ret;
54 }
55
56 freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000); 46 freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
57 if (freq_Hz < 0) 47 if (freq_Hz < 0)
58 freq_Hz = freq_table[index].frequency * 1000; 48 freq_Hz = freq_table[index].frequency * 1000;
@@ -60,9 +50,6 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
60 freqs.new = freq_Hz / 1000; 50 freqs.new = freq_Hz / 1000;
61 freqs.old = clk_get_rate(cpu_clk) / 1000; 51 freqs.old = clk_get_rate(cpu_clk) / 1000;
62 52
63 if (freqs.old == freqs.new)
64 return 0;
65
66 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 53 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
67 54
68 if (!IS_ERR(cpu_reg)) { 55 if (!IS_ERR(cpu_reg)) {
@@ -128,7 +115,7 @@ static int cpu0_cpufreq_init(struct cpufreq_policy *policy)
128static struct cpufreq_driver cpu0_cpufreq_driver = { 115static struct cpufreq_driver cpu0_cpufreq_driver = {
129 .flags = CPUFREQ_STICKY, 116 .flags = CPUFREQ_STICKY,
130 .verify = cpufreq_generic_frequency_table_verify, 117 .verify = cpufreq_generic_frequency_table_verify,
131 .target = cpu0_set_target, 118 .target_index = cpu0_set_target,
132 .get = cpu0_get_speed, 119 .get = cpu0_get_speed,
133 .init = cpu0_cpufreq_init, 120 .init = cpu0_cpufreq_init,
134 .exit = cpufreq_generic_exit, 121 .exit = cpufreq_generic_exit,
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index ec391d7f010b..87ed83a6c894 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -47,6 +47,11 @@ static LIST_HEAD(cpufreq_policy_list);
47static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); 47static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
48#endif 48#endif
49 49
50static inline bool has_target(void)
51{
52 return cpufreq_driver->target_index || cpufreq_driver->target;
53}
54
50/* 55/*
51 * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure 56 * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
52 * all cpufreq/hotplug/workqueue/etc related lock issues. 57 * all cpufreq/hotplug/workqueue/etc related lock issues.
@@ -392,7 +397,7 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
392 *policy = CPUFREQ_POLICY_POWERSAVE; 397 *policy = CPUFREQ_POLICY_POWERSAVE;
393 err = 0; 398 err = 0;
394 } 399 }
395 } else if (cpufreq_driver->target) { 400 } else if (has_target()) {
396 struct cpufreq_governor *t; 401 struct cpufreq_governor *t;
397 402
398 mutex_lock(&cpufreq_governor_mutex); 403 mutex_lock(&cpufreq_governor_mutex);
@@ -550,7 +555,7 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
550 ssize_t i = 0; 555 ssize_t i = 0;
551 struct cpufreq_governor *t; 556 struct cpufreq_governor *t;
552 557
553 if (!cpufreq_driver->target) { 558 if (!has_target()) {
554 i += sprintf(buf, "performance powersave"); 559 i += sprintf(buf, "performance powersave");
555 goto out; 560 goto out;
556 } 561 }
@@ -835,7 +840,7 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy,
835 if (ret) 840 if (ret)
836 goto err_out_kobj_put; 841 goto err_out_kobj_put;
837 } 842 }
838 if (cpufreq_driver->target) { 843 if (has_target()) {
839 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); 844 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
840 if (ret) 845 if (ret)
841 goto err_out_kobj_put; 846 goto err_out_kobj_put;
@@ -884,10 +889,10 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
884 unsigned int cpu, struct device *dev, 889 unsigned int cpu, struct device *dev,
885 bool frozen) 890 bool frozen)
886{ 891{
887 int ret = 0, has_target = !!cpufreq_driver->target; 892 int ret = 0;
888 unsigned long flags; 893 unsigned long flags;
889 894
890 if (has_target) { 895 if (has_target()) {
891 ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); 896 ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
892 if (ret) { 897 if (ret) {
893 pr_err("%s: Failed to stop governor\n", __func__); 898 pr_err("%s: Failed to stop governor\n", __func__);
@@ -905,7 +910,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
905 910
906 unlock_policy_rwsem_write(policy->cpu); 911 unlock_policy_rwsem_write(policy->cpu);
907 912
908 if (has_target) { 913 if (has_target()) {
909 if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || 914 if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
910 (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) { 915 (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
911 pr_err("%s: Failed to start governor\n", __func__); 916 pr_err("%s: Failed to start governor\n", __func__);
@@ -1215,7 +1220,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,
1215 return -EINVAL; 1220 return -EINVAL;
1216 } 1221 }
1217 1222
1218 if (cpufreq_driver->target) { 1223 if (has_target()) {
1219 ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); 1224 ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
1220 if (ret) { 1225 if (ret) {
1221 pr_err("%s: Failed to stop governor\n", __func__); 1226 pr_err("%s: Failed to stop governor\n", __func__);
@@ -1280,7 +1285,7 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
1280 1285
1281 /* If cpu is last user of policy, free policy */ 1286 /* If cpu is last user of policy, free policy */
1282 if (cpus == 1) { 1287 if (cpus == 1) {
1283 if (cpufreq_driver->target) { 1288 if (has_target()) {
1284 ret = __cpufreq_governor(policy, 1289 ret = __cpufreq_governor(policy,
1285 CPUFREQ_GOV_POLICY_EXIT); 1290 CPUFREQ_GOV_POLICY_EXIT);
1286 if (ret) { 1291 if (ret) {
@@ -1323,7 +1328,7 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
1323 if (!frozen) 1328 if (!frozen)
1324 cpufreq_policy_free(policy); 1329 cpufreq_policy_free(policy);
1325 } else { 1330 } else {
1326 if (cpufreq_driver->target) { 1331 if (has_target()) {
1327 if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || 1332 if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
1328 (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) { 1333 (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
1329 pr_err("%s: Failed to start governor\n", 1334 pr_err("%s: Failed to start governor\n",
@@ -1694,12 +1699,41 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
1694 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n", 1699 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1695 policy->cpu, target_freq, relation, old_target_freq); 1700 policy->cpu, target_freq, relation, old_target_freq);
1696 1701
1702 /*
1703 * This might look like a redundant call as we are checking it again
1704 * after finding index. But it is left intentionally for cases where
1705 * exactly same freq is called again and so we can save on few function
1706 * calls.
1707 */
1697 if (target_freq == policy->cur) 1708 if (target_freq == policy->cur)
1698 return 0; 1709 return 0;
1699 1710
1700 if (cpufreq_driver->target) 1711 if (cpufreq_driver->target)
1701 retval = cpufreq_driver->target(policy, target_freq, relation); 1712 retval = cpufreq_driver->target(policy, target_freq, relation);
1713 else if (cpufreq_driver->target_index) {
1714 struct cpufreq_frequency_table *freq_table;
1715 int index;
1702 1716
1717 freq_table = cpufreq_frequency_get_table(policy->cpu);
1718 if (unlikely(!freq_table)) {
1719 pr_err("%s: Unable to find freq_table\n", __func__);
1720 goto out;
1721 }
1722
1723 retval = cpufreq_frequency_table_target(policy, freq_table,
1724 target_freq, relation, &index);
1725 if (unlikely(retval)) {
1726 pr_err("%s: Unable to find matching freq\n", __func__);
1727 goto out;
1728 }
1729
1730 if (freq_table[index].frequency == policy->cur)
1731 retval = 0;
1732 else
1733 retval = cpufreq_driver->target_index(policy, index);
1734 }
1735
1736out:
1703 return retval; 1737 return retval;
1704} 1738}
1705EXPORT_SYMBOL_GPL(__cpufreq_driver_target); 1739EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
@@ -2025,7 +2059,7 @@ int cpufreq_update_policy(unsigned int cpu)
2025 pr_debug("Driver did not initialize current freq"); 2059 pr_debug("Driver did not initialize current freq");
2026 policy->cur = new_policy.cur; 2060 policy->cur = new_policy.cur;
2027 } else { 2061 } else {
2028 if (policy->cur != new_policy.cur && cpufreq_driver->target) 2062 if (policy->cur != new_policy.cur && has_target())
2029 cpufreq_out_of_sync(cpu, policy->cur, 2063 cpufreq_out_of_sync(cpu, policy->cur,
2030 new_policy.cur); 2064 new_policy.cur);
2031 } 2065 }
@@ -2103,7 +2137,8 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
2103 return -ENODEV; 2137 return -ENODEV;
2104 2138
2105 if (!driver_data || !driver_data->verify || !driver_data->init || 2139 if (!driver_data || !driver_data->verify || !driver_data->init ||
2106 ((!driver_data->setpolicy) && (!driver_data->target))) 2140 !(driver_data->setpolicy || driver_data->target_index ||
2141 driver_data->target))
2107 return -EINVAL; 2142 return -EINVAL;
2108 2143
2109 pr_debug("trying to register driver %s\n", driver_data->name); 2144 pr_debug("trying to register driver %s\n", driver_data->name);
diff --git a/drivers/cpufreq/cris-artpec3-cpufreq.c b/drivers/cpufreq/cris-artpec3-cpufreq.c
index 05fdc7e40257..841857cf1562 100644
--- a/drivers/cpufreq/cris-artpec3-cpufreq.c
+++ b/drivers/cpufreq/cris-artpec3-cpufreq.c
@@ -27,8 +27,7 @@ static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
27 return clk_ctrl.pll ? 200000 : 6000; 27 return clk_ctrl.pll ? 200000 : 6000;
28} 28}
29 29
30static void cris_freq_set_cpu_state(struct cpufreq_policy *policy, 30static int cris_freq_target(struct cpufreq_policy *policy, unsigned int state)
31 unsigned int state)
32{ 31{
33 struct cpufreq_freqs freqs; 32 struct cpufreq_freqs freqs;
34 reg_clkgen_rw_clk_ctrl clk_ctrl; 33 reg_clkgen_rw_clk_ctrl clk_ctrl;
@@ -52,19 +51,6 @@ static void cris_freq_set_cpu_state(struct cpufreq_policy *policy,
52 local_irq_enable(); 51 local_irq_enable();
53 52
54 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 53 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
55};
56
57static int cris_freq_target(struct cpufreq_policy *policy,
58 unsigned int target_freq,
59 unsigned int relation)
60{
61 unsigned int newstate = 0;
62
63 if (cpufreq_frequency_table_target(policy, cris_freq_table,
64 target_freq, relation, &newstate))
65 return -EINVAL;
66
67 cris_freq_set_cpu_state(policy, newstate);
68 54
69 return 0; 55 return 0;
70} 56}
@@ -77,7 +63,7 @@ static int cris_freq_cpu_init(struct cpufreq_policy *policy)
77static struct cpufreq_driver cris_freq_driver = { 63static struct cpufreq_driver cris_freq_driver = {
78 .get = cris_freq_get_cpu_frequency, 64 .get = cris_freq_get_cpu_frequency,
79 .verify = cpufreq_generic_frequency_table_verify, 65 .verify = cpufreq_generic_frequency_table_verify,
80 .target = cris_freq_target, 66 .target_index = cris_freq_target,
81 .init = cris_freq_cpu_init, 67 .init = cris_freq_cpu_init,
82 .exit = cpufreq_generic_exit, 68 .exit = cpufreq_generic_exit,
83 .name = "cris_freq", 69 .name = "cris_freq",
diff --git a/drivers/cpufreq/cris-etraxfs-cpufreq.c b/drivers/cpufreq/cris-etraxfs-cpufreq.c
index fac2b26932dd..c58811abd961 100644
--- a/drivers/cpufreq/cris-etraxfs-cpufreq.c
+++ b/drivers/cpufreq/cris-etraxfs-cpufreq.c
@@ -27,8 +27,7 @@ static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
27 return clk_ctrl.pll ? 200000 : 6000; 27 return clk_ctrl.pll ? 200000 : 6000;
28} 28}
29 29
30static void cris_freq_set_cpu_state(struct cpufreq_policy *policy, 30static int cris_freq_target(struct cpufreq_policy *policy, unsigned int state)
31 unsigned int state)
32{ 31{
33 struct cpufreq_freqs freqs; 32 struct cpufreq_freqs freqs;
34 reg_config_rw_clk_ctrl clk_ctrl; 33 reg_config_rw_clk_ctrl clk_ctrl;
@@ -52,18 +51,6 @@ static void cris_freq_set_cpu_state(struct cpufreq_policy *policy,
52 local_irq_enable(); 51 local_irq_enable();
53 52
54 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 53 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
55};
56
57static int cris_freq_target(struct cpufreq_policy *policy,
58 unsigned int target_freq, unsigned int relation)
59{
60 unsigned int newstate = 0;
61
62 if (cpufreq_frequency_table_target
63 (policy, cris_freq_table, target_freq, relation, &newstate))
64 return -EINVAL;
65
66 cris_freq_set_cpu_state(policy, newstate);
67 54
68 return 0; 55 return 0;
69} 56}
@@ -76,7 +63,7 @@ static int cris_freq_cpu_init(struct cpufreq_policy *policy)
76static struct cpufreq_driver cris_freq_driver = { 63static struct cpufreq_driver cris_freq_driver = {
77 .get = cris_freq_get_cpu_frequency, 64 .get = cris_freq_get_cpu_frequency,
78 .verify = cpufreq_generic_frequency_table_verify, 65 .verify = cpufreq_generic_frequency_table_verify,
79 .target = cris_freq_target, 66 .target_index = cris_freq_target,
80 .init = cris_freq_cpu_init, 67 .init = cris_freq_cpu_init,
81 .exit = cpufreq_generic_exit, 68 .exit = cpufreq_generic_exit,
82 .name = "cris_freq", 69 .name = "cris_freq",
diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c
index 972583baf9e8..1f5d8a569c77 100644
--- a/drivers/cpufreq/davinci-cpufreq.c
+++ b/drivers/cpufreq/davinci-cpufreq.c
@@ -66,28 +66,18 @@ static unsigned int davinci_getspeed(unsigned int cpu)
66 return clk_get_rate(cpufreq.armclk) / 1000; 66 return clk_get_rate(cpufreq.armclk) / 1000;
67} 67}
68 68
69static int davinci_target(struct cpufreq_policy *policy, 69static int davinci_target(struct cpufreq_policy *policy, unsigned int idx)
70 unsigned int target_freq, unsigned int relation)
71{ 70{
72 int ret = 0; 71 int ret = 0;
73 unsigned int idx;
74 struct cpufreq_freqs freqs; 72 struct cpufreq_freqs freqs;
75 struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; 73 struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
76 struct clk *armclk = cpufreq.armclk; 74 struct clk *armclk = cpufreq.armclk;
77 75
78 freqs.old = davinci_getspeed(0); 76 freqs.old = davinci_getspeed(0);
79 freqs.new = clk_round_rate(armclk, target_freq * 1000) / 1000; 77 freqs.new = pdata->freq_table[idx].frequency;
80
81 if (freqs.old == freqs.new)
82 return ret;
83 78
84 dev_dbg(cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new); 79 dev_dbg(cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new);
85 80
86 ret = cpufreq_frequency_table_target(policy, pdata->freq_table,
87 freqs.new, relation, &idx);
88 if (ret)
89 return -EINVAL;
90
91 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 81 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
92 82
93 /* if moving to higher frequency, up the voltage beforehand */ 83 /* if moving to higher frequency, up the voltage beforehand */
@@ -148,7 +138,7 @@ static int davinci_cpu_init(struct cpufreq_policy *policy)
148static struct cpufreq_driver davinci_driver = { 138static struct cpufreq_driver davinci_driver = {
149 .flags = CPUFREQ_STICKY, 139 .flags = CPUFREQ_STICKY,
150 .verify = davinci_verify_speed, 140 .verify = davinci_verify_speed,
151 .target = davinci_target, 141 .target_index = davinci_target,
152 .get = davinci_getspeed, 142 .get = davinci_getspeed,
153 .init = davinci_cpu_init, 143 .init = davinci_cpu_init,
154 .exit = cpufreq_generic_exit, 144 .exit = cpufreq_generic_exit,
diff --git a/drivers/cpufreq/dbx500-cpufreq.c b/drivers/cpufreq/dbx500-cpufreq.c
index a60f7693c18e..238b16976be1 100644
--- a/drivers/cpufreq/dbx500-cpufreq.c
+++ b/drivers/cpufreq/dbx500-cpufreq.c
@@ -20,23 +20,13 @@ static struct cpufreq_frequency_table *freq_table;
20static struct clk *armss_clk; 20static struct clk *armss_clk;
21 21
22static int dbx500_cpufreq_target(struct cpufreq_policy *policy, 22static int dbx500_cpufreq_target(struct cpufreq_policy *policy,
23 unsigned int target_freq, 23 unsigned int index)
24 unsigned int relation)
25{ 24{
26 struct cpufreq_freqs freqs; 25 struct cpufreq_freqs freqs;
27 unsigned int idx;
28 int ret; 26 int ret;
29 27
30 /* Lookup the next frequency */
31 if (cpufreq_frequency_table_target(policy, freq_table, target_freq,
32 relation, &idx))
33 return -EINVAL;
34
35 freqs.old = policy->cur; 28 freqs.old = policy->cur;
36 freqs.new = freq_table[idx].frequency; 29 freqs.new = freq_table[index].frequency;
37
38 if (freqs.old == freqs.new)
39 return 0;
40 30
41 /* pre-change notification */ 31 /* pre-change notification */
42 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 32 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
@@ -80,7 +70,7 @@ static int dbx500_cpufreq_init(struct cpufreq_policy *policy)
80static struct cpufreq_driver dbx500_cpufreq_driver = { 70static struct cpufreq_driver dbx500_cpufreq_driver = {
81 .flags = CPUFREQ_STICKY | CPUFREQ_CONST_LOOPS, 71 .flags = CPUFREQ_STICKY | CPUFREQ_CONST_LOOPS,
82 .verify = cpufreq_generic_frequency_table_verify, 72 .verify = cpufreq_generic_frequency_table_verify,
83 .target = dbx500_cpufreq_target, 73 .target_index = dbx500_cpufreq_target,
84 .get = dbx500_cpufreq_getspeed, 74 .get = dbx500_cpufreq_getspeed,
85 .init = dbx500_cpufreq_init, 75 .init = dbx500_cpufreq_init,
86 .name = "DBX500", 76 .name = "DBX500",
diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c
index 2c11ce3c67bd..b39c4ef60a7a 100644
--- a/drivers/cpufreq/e_powersaver.c
+++ b/drivers/cpufreq/e_powersaver.c
@@ -168,12 +168,9 @@ postchange:
168 return err; 168 return err;
169} 169}
170 170
171static int eps_target(struct cpufreq_policy *policy, 171static int eps_target(struct cpufreq_policy *policy, unsigned int index)
172 unsigned int target_freq,
173 unsigned int relation)
174{ 172{
175 struct eps_cpu_data *centaur; 173 struct eps_cpu_data *centaur;
176 unsigned int newstate = 0;
177 unsigned int cpu = policy->cpu; 174 unsigned int cpu = policy->cpu;
178 unsigned int dest_state; 175 unsigned int dest_state;
179 int ret; 176 int ret;
@@ -182,16 +179,8 @@ static int eps_target(struct cpufreq_policy *policy,
182 return -ENODEV; 179 return -ENODEV;
183 centaur = eps_cpu[cpu]; 180 centaur = eps_cpu[cpu];
184 181
185 if (unlikely(cpufreq_frequency_table_target(policy,
186 &eps_cpu[cpu]->freq_table[0],
187 target_freq,
188 relation,
189 &newstate))) {
190 return -EINVAL;
191 }
192
193 /* Make frequency transition */ 182 /* Make frequency transition */
194 dest_state = centaur->freq_table[newstate].driver_data & 0xffff; 183 dest_state = centaur->freq_table[index].driver_data & 0xffff;
195 ret = eps_set_state(centaur, policy, dest_state); 184 ret = eps_set_state(centaur, policy, dest_state);
196 if (ret) 185 if (ret)
197 printk(KERN_ERR "eps: Timeout!\n"); 186 printk(KERN_ERR "eps: Timeout!\n");
@@ -418,7 +407,7 @@ static int eps_cpu_exit(struct cpufreq_policy *policy)
418 407
419static struct cpufreq_driver eps_driver = { 408static struct cpufreq_driver eps_driver = {
420 .verify = cpufreq_generic_frequency_table_verify, 409 .verify = cpufreq_generic_frequency_table_verify,
421 .target = eps_target, 410 .target_index = eps_target,
422 .init = eps_cpu_init, 411 .init = eps_cpu_init,
423 .exit = eps_cpu_exit, 412 .exit = eps_cpu_exit,
424 .get = eps_get, 413 .get = eps_get,
diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c
index d91a645a27ae..4ab41539514f 100644
--- a/drivers/cpufreq/elanfreq.c
+++ b/drivers/cpufreq/elanfreq.c
@@ -105,20 +105,8 @@ static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu)
105} 105}
106 106
107 107
108/** 108static int elanfreq_target(struct cpufreq_policy *policy,
109 * elanfreq_set_cpu_frequency: Change the CPU core frequency 109 unsigned int state)
110 * @cpu: cpu number
111 * @freq: frequency in kHz
112 *
113 * This function takes a frequency value and changes the CPU frequency
114 * according to this. Note that the frequency has to be checked by
115 * elanfreq_validatespeed() for correctness!
116 *
117 * There is no return value.
118 */
119
120static void elanfreq_set_cpu_state(struct cpufreq_policy *policy,
121 unsigned int state)
122{ 110{
123 struct cpufreq_freqs freqs; 111 struct cpufreq_freqs freqs;
124 112
@@ -162,25 +150,9 @@ static void elanfreq_set_cpu_state(struct cpufreq_policy *policy,
162 local_irq_enable(); 150 local_irq_enable();
163 151
164 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 152 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
165};
166
167
168static int elanfreq_target(struct cpufreq_policy *policy,
169 unsigned int target_freq,
170 unsigned int relation)
171{
172 unsigned int newstate = 0;
173
174 if (cpufreq_frequency_table_target(policy, &elanfreq_table[0],
175 target_freq, relation, &newstate))
176 return -EINVAL;
177
178 elanfreq_set_cpu_state(policy, newstate);
179 153
180 return 0; 154 return 0;
181} 155}
182
183
184/* 156/*
185 * Module init and exit code 157 * Module init and exit code
186 */ 158 */
@@ -237,7 +209,7 @@ __setup("elanfreq=", elanfreq_setup);
237static struct cpufreq_driver elanfreq_driver = { 209static struct cpufreq_driver elanfreq_driver = {
238 .get = elanfreq_get_cpu_frequency, 210 .get = elanfreq_get_cpu_frequency,
239 .verify = cpufreq_generic_frequency_table_verify, 211 .verify = cpufreq_generic_frequency_table_verify,
240 .target = elanfreq_target, 212 .target_index = elanfreq_target,
241 .init = elanfreq_cpu_init, 213 .init = elanfreq_cpu_init,
242 .exit = cpufreq_generic_exit, 214 .exit = cpufreq_generic_exit,
243 .name = "elanfreq", 215 .name = "elanfreq",
diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
index 3e4af676f43d..9982fcb82257 100644
--- a/drivers/cpufreq/exynos-cpufreq.c
+++ b/drivers/cpufreq/exynos-cpufreq.c
@@ -65,9 +65,6 @@ static int exynos_cpufreq_scale(unsigned int target_freq)
65 freqs.old = policy->cur; 65 freqs.old = policy->cur;
66 freqs.new = target_freq; 66 freqs.new = target_freq;
67 67
68 if (freqs.new == freqs.old)
69 goto out;
70
71 /* 68 /*
72 * The policy max have been changed so that we cannot get proper 69 * The policy max have been changed so that we cannot get proper
73 * old_index with cpufreq_frequency_table_target(). Thus, ignore 70 * old_index with cpufreq_frequency_table_target(). Thus, ignore
@@ -151,13 +148,9 @@ out:
151 return ret; 148 return ret;
152} 149}
153 150
154static int exynos_target(struct cpufreq_policy *policy, 151static int exynos_target(struct cpufreq_policy *policy, unsigned int index)
155 unsigned int target_freq,
156 unsigned int relation)
157{ 152{
158 struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; 153 struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
159 unsigned int index;
160 unsigned int new_freq;
161 int ret = 0; 154 int ret = 0;
162 155
163 mutex_lock(&cpufreq_lock); 156 mutex_lock(&cpufreq_lock);
@@ -165,15 +158,7 @@ static int exynos_target(struct cpufreq_policy *policy,
165 if (frequency_locked) 158 if (frequency_locked)
166 goto out; 159 goto out;
167 160
168 if (cpufreq_frequency_table_target(policy, freq_table, 161 ret = exynos_cpufreq_scale(freq_table[index].frequency);
169 target_freq, relation, &index)) {
170 ret = -EINVAL;
171 goto out;
172 }
173
174 new_freq = freq_table[index].frequency;
175
176 ret = exynos_cpufreq_scale(new_freq);
177 162
178out: 163out:
179 mutex_unlock(&cpufreq_lock); 164 mutex_unlock(&cpufreq_lock);
@@ -247,7 +232,7 @@ static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
247static struct cpufreq_driver exynos_driver = { 232static struct cpufreq_driver exynos_driver = {
248 .flags = CPUFREQ_STICKY, 233 .flags = CPUFREQ_STICKY,
249 .verify = cpufreq_generic_frequency_table_verify, 234 .verify = cpufreq_generic_frequency_table_verify,
250 .target = exynos_target, 235 .target_index = exynos_target,
251 .get = exynos_getspeed, 236 .get = exynos_getspeed,
252 .init = exynos_cpufreq_cpu_init, 237 .init = exynos_cpufreq_cpu_init,
253 .exit = cpufreq_generic_exit, 238 .exit = cpufreq_generic_exit,
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c
index 8ae5e2925bf1..1bf9b060d522 100644
--- a/drivers/cpufreq/exynos5440-cpufreq.c
+++ b/drivers/cpufreq/exynos5440-cpufreq.c
@@ -214,27 +214,17 @@ static unsigned int exynos_getspeed(unsigned int cpu)
214 return dvfs_info->cur_frequency; 214 return dvfs_info->cur_frequency;
215} 215}
216 216
217static int exynos_target(struct cpufreq_policy *policy, 217static int exynos_target(struct cpufreq_policy *policy, unsigned int index)
218 unsigned int target_freq,
219 unsigned int relation)
220{ 218{
221 unsigned int index, tmp; 219 unsigned int tmp;
222 int ret = 0, i; 220 int i;
223 struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; 221 struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table;
224 222
225 mutex_lock(&cpufreq_lock); 223 mutex_lock(&cpufreq_lock);
226 224
227 ret = cpufreq_frequency_table_target(policy, freq_table,
228 target_freq, relation, &index);
229 if (ret)
230 goto out;
231
232 freqs.old = dvfs_info->cur_frequency; 225 freqs.old = dvfs_info->cur_frequency;
233 freqs.new = freq_table[index].frequency; 226 freqs.new = freq_table[index].frequency;
234 227
235 if (freqs.old == freqs.new)
236 goto out;
237
238 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 228 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
239 229
240 /* Set the target frequency in all C0_3_PSTATE register */ 230 /* Set the target frequency in all C0_3_PSTATE register */
@@ -245,9 +235,8 @@ static int exynos_target(struct cpufreq_policy *policy,
245 235
246 __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + i * 4); 236 __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + i * 4);
247 } 237 }
248out:
249 mutex_unlock(&cpufreq_lock); 238 mutex_unlock(&cpufreq_lock);
250 return ret; 239 return 0;
251} 240}
252 241
253static void exynos_cpufreq_work(struct work_struct *work) 242static void exynos_cpufreq_work(struct work_struct *work)
@@ -325,7 +314,7 @@ static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
325static struct cpufreq_driver exynos_driver = { 314static struct cpufreq_driver exynos_driver = {
326 .flags = CPUFREQ_STICKY, 315 .flags = CPUFREQ_STICKY,
327 .verify = cpufreq_generic_frequency_table_verify, 316 .verify = cpufreq_generic_frequency_table_verify,
328 .target = exynos_target, 317 .target_index = exynos_target,
329 .get = exynos_getspeed, 318 .get = exynos_getspeed,
330 .init = exynos_cpufreq_cpu_init, 319 .init = exynos_cpufreq_cpu_init,
331 .exit = cpufreq_generic_exit, 320 .exit = cpufreq_generic_exit,
diff --git a/drivers/cpufreq/ia64-acpi-cpufreq.c b/drivers/cpufreq/ia64-acpi-cpufreq.c
index 90c6598415fd..4695fa22406a 100644
--- a/drivers/cpufreq/ia64-acpi-cpufreq.c
+++ b/drivers/cpufreq/ia64-acpi-cpufreq.c
@@ -227,26 +227,11 @@ acpi_cpufreq_get (
227static int 227static int
228acpi_cpufreq_target ( 228acpi_cpufreq_target (
229 struct cpufreq_policy *policy, 229 struct cpufreq_policy *policy,
230 unsigned int target_freq, 230 unsigned int index)
231 unsigned int relation)
232{ 231{
233 struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu]; 232 return processor_set_freq(acpi_io_data[policy->cpu], policy, index);
234 unsigned int next_state = 0;
235 unsigned int result = 0;
236
237 pr_debug("acpi_cpufreq_setpolicy\n");
238
239 result = cpufreq_frequency_table_target(policy,
240 data->freq_table, target_freq, relation, &next_state);
241 if (result)
242 return (result);
243
244 result = processor_set_freq(data, policy, next_state);
245
246 return (result);
247} 233}
248 234
249
250static int 235static int
251acpi_cpufreq_cpu_init ( 236acpi_cpufreq_cpu_init (
252 struct cpufreq_policy *policy) 237 struct cpufreq_policy *policy)
@@ -379,7 +364,7 @@ acpi_cpufreq_cpu_exit (
379 364
380static struct cpufreq_driver acpi_cpufreq_driver = { 365static struct cpufreq_driver acpi_cpufreq_driver = {
381 .verify = cpufreq_generic_frequency_table_verify, 366 .verify = cpufreq_generic_frequency_table_verify,
382 .target = acpi_cpufreq_target, 367 .target_index = acpi_cpufreq_target,
383 .get = acpi_cpufreq_get, 368 .get = acpi_cpufreq_get,
384 .init = acpi_cpufreq_cpu_init, 369 .init = acpi_cpufreq_cpu_init,
385 .exit = acpi_cpufreq_cpu_exit, 370 .exit = acpi_cpufreq_cpu_exit,
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index be23892282e3..07af3b0de069 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -40,30 +40,17 @@ static unsigned int imx6q_get_speed(unsigned int cpu)
40 return clk_get_rate(arm_clk) / 1000; 40 return clk_get_rate(arm_clk) / 1000;
41} 41}
42 42
43static int imx6q_set_target(struct cpufreq_policy *policy, 43static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
44 unsigned int target_freq, unsigned int relation)
45{ 44{
46 struct cpufreq_freqs freqs; 45 struct cpufreq_freqs freqs;
47 struct dev_pm_opp *opp; 46 struct dev_pm_opp *opp;
48 unsigned long freq_hz, volt, volt_old; 47 unsigned long freq_hz, volt, volt_old;
49 unsigned int index;
50 int ret; 48 int ret;
51 49
52 ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
53 relation, &index);
54 if (ret) {
55 dev_err(cpu_dev, "failed to match target frequency %d: %d\n",
56 target_freq, ret);
57 return ret;
58 }
59
60 freqs.new = freq_table[index].frequency; 50 freqs.new = freq_table[index].frequency;
61 freq_hz = freqs.new * 1000; 51 freq_hz = freqs.new * 1000;
62 freqs.old = clk_get_rate(arm_clk) / 1000; 52 freqs.old = clk_get_rate(arm_clk) / 1000;
63 53
64 if (freqs.old == freqs.new)
65 return 0;
66
67 rcu_read_lock(); 54 rcu_read_lock();
68 opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz); 55 opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
69 if (IS_ERR(opp)) { 56 if (IS_ERR(opp)) {
@@ -159,7 +146,7 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
159 146
160static struct cpufreq_driver imx6q_cpufreq_driver = { 147static struct cpufreq_driver imx6q_cpufreq_driver = {
161 .verify = cpufreq_generic_frequency_table_verify, 148 .verify = cpufreq_generic_frequency_table_verify,
162 .target = imx6q_set_target, 149 .target_index = imx6q_set_target,
163 .get = imx6q_get_speed, 150 .get = imx6q_get_speed,
164 .init = imx6q_cpufreq_init, 151 .init = imx6q_cpufreq_init,
165 .exit = cpufreq_generic_exit, 152 .exit = cpufreq_generic_exit,
diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c
index fff8653c8e9b..0ae4dd7e1f2d 100644
--- a/drivers/cpufreq/kirkwood-cpufreq.c
+++ b/drivers/cpufreq/kirkwood-cpufreq.c
@@ -55,8 +55,8 @@ static unsigned int kirkwood_cpufreq_get_cpu_frequency(unsigned int cpu)
55 return kirkwood_freq_table[0].frequency; 55 return kirkwood_freq_table[0].frequency;
56} 56}
57 57
58static void kirkwood_cpufreq_set_cpu_state(struct cpufreq_policy *policy, 58static int kirkwood_cpufreq_target(struct cpufreq_policy *policy,
59 unsigned int index) 59 unsigned int index)
60{ 60{
61 struct cpufreq_freqs freqs; 61 struct cpufreq_freqs freqs;
62 unsigned int state = kirkwood_freq_table[index].driver_data; 62 unsigned int state = kirkwood_freq_table[index].driver_data;
@@ -100,19 +100,6 @@ static void kirkwood_cpufreq_set_cpu_state(struct cpufreq_policy *policy,
100 local_irq_enable(); 100 local_irq_enable();
101 } 101 }
102 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 102 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
103};
104
105static int kirkwood_cpufreq_target(struct cpufreq_policy *policy,
106 unsigned int target_freq,
107 unsigned int relation)
108{
109 unsigned int index = 0;
110
111 if (cpufreq_frequency_table_target(policy, kirkwood_freq_table,
112 target_freq, relation, &index))
113 return -EINVAL;
114
115 kirkwood_cpufreq_set_cpu_state(policy, index);
116 103
117 return 0; 104 return 0;
118} 105}
@@ -126,7 +113,7 @@ static int kirkwood_cpufreq_cpu_init(struct cpufreq_policy *policy)
126static struct cpufreq_driver kirkwood_cpufreq_driver = { 113static struct cpufreq_driver kirkwood_cpufreq_driver = {
127 .get = kirkwood_cpufreq_get_cpu_frequency, 114 .get = kirkwood_cpufreq_get_cpu_frequency,
128 .verify = cpufreq_generic_frequency_table_verify, 115 .verify = cpufreq_generic_frequency_table_verify,
129 .target = kirkwood_cpufreq_target, 116 .target_index = kirkwood_cpufreq_target,
130 .init = kirkwood_cpufreq_cpu_init, 117 .init = kirkwood_cpufreq_cpu_init,
131 .exit = cpufreq_generic_exit, 118 .exit = cpufreq_generic_exit,
132 .name = "kirkwood-cpufreq", 119 .name = "kirkwood-cpufreq",
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c
index 14df4974fb45..45bafddfd8ea 100644
--- a/drivers/cpufreq/longhaul.c
+++ b/drivers/cpufreq/longhaul.c
@@ -626,21 +626,12 @@ static void longhaul_setup_voltagescaling(void)
626 626
627 627
628static int longhaul_target(struct cpufreq_policy *policy, 628static int longhaul_target(struct cpufreq_policy *policy,
629 unsigned int target_freq, unsigned int relation) 629 unsigned int table_index)
630{ 630{
631 unsigned int table_index = 0;
632 unsigned int i; 631 unsigned int i;
633 unsigned int dir = 0; 632 unsigned int dir = 0;
634 u8 vid, current_vid; 633 u8 vid, current_vid;
635 634
636 if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq,
637 relation, &table_index))
638 return -EINVAL;
639
640 /* Don't set same frequency again */
641 if (longhaul_index == table_index)
642 return 0;
643
644 if (!can_scale_voltage) 635 if (!can_scale_voltage)
645 longhaul_setstate(policy, table_index); 636 longhaul_setstate(policy, table_index);
646 else { 637 else {
@@ -919,7 +910,7 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy)
919 910
920static struct cpufreq_driver longhaul_driver = { 911static struct cpufreq_driver longhaul_driver = {
921 .verify = cpufreq_generic_frequency_table_verify, 912 .verify = cpufreq_generic_frequency_table_verify,
922 .target = longhaul_target, 913 .target_index = longhaul_target,
923 .get = longhaul_get, 914 .get = longhaul_get,
924 .init = longhaul_cpu_init, 915 .init = longhaul_cpu_init,
925 .exit = cpufreq_generic_exit, 916 .exit = cpufreq_generic_exit,
diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c
index 2c8ec8e06449..41a8e2cdf940 100644
--- a/drivers/cpufreq/loongson2_cpufreq.c
+++ b/drivers/cpufreq/loongson2_cpufreq.c
@@ -53,11 +53,9 @@ static unsigned int loongson2_cpufreq_get(unsigned int cpu)
53 * Here we notify other drivers of the proposed change and the final change. 53 * Here we notify other drivers of the proposed change and the final change.
54 */ 54 */
55static int loongson2_cpufreq_target(struct cpufreq_policy *policy, 55static int loongson2_cpufreq_target(struct cpufreq_policy *policy,
56 unsigned int target_freq, 56 unsigned int index)
57 unsigned int relation)
58{ 57{
59 unsigned int cpu = policy->cpu; 58 unsigned int cpu = policy->cpu;
60 unsigned int newstate = 0;
61 cpumask_t cpus_allowed; 59 cpumask_t cpus_allowed;
62 struct cpufreq_freqs freqs; 60 struct cpufreq_freqs freqs;
63 unsigned int freq; 61 unsigned int freq;
@@ -65,26 +63,17 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy,
65 cpus_allowed = current->cpus_allowed; 63 cpus_allowed = current->cpus_allowed;
66 set_cpus_allowed_ptr(current, cpumask_of(cpu)); 64 set_cpus_allowed_ptr(current, cpumask_of(cpu));
67 65
68 if (cpufreq_frequency_table_target
69 (policy, &loongson2_clockmod_table[0], target_freq, relation,
70 &newstate))
71 return -EINVAL;
72
73 freq = 66 freq =
74 ((cpu_clock_freq / 1000) * 67 ((cpu_clock_freq / 1000) *
75 loongson2_clockmod_table[newstate].driver_data) / 8; 68 loongson2_clockmod_table[index].driver_data) / 8;
76 if (freq < policy->min || freq > policy->max)
77 return -EINVAL;
78 69
79 pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000); 70 pr_debug("cpufreq: requested frequency %u Hz\n",
71 loongson2_clockmod_table[index].frequency * 1000);
80 72
81 freqs.old = loongson2_cpufreq_get(cpu); 73 freqs.old = loongson2_cpufreq_get(cpu);
82 freqs.new = freq; 74 freqs.new = freq;
83 freqs.flags = 0; 75 freqs.flags = 0;
84 76
85 if (freqs.new == freqs.old)
86 return 0;
87
88 /* notifiers */ 77 /* notifiers */
89 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 78 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
90 79
@@ -145,7 +134,7 @@ static struct cpufreq_driver loongson2_cpufreq_driver = {
145 .name = "loongson2", 134 .name = "loongson2",
146 .init = loongson2_cpufreq_cpu_init, 135 .init = loongson2_cpufreq_cpu_init,
147 .verify = cpufreq_generic_frequency_table_verify, 136 .verify = cpufreq_generic_frequency_table_verify,
148 .target = loongson2_cpufreq_target, 137 .target_index = loongson2_cpufreq_target,
149 .get = loongson2_cpufreq_get, 138 .get = loongson2_cpufreq_get,
150 .exit = loongson2_cpufreq_exit, 139 .exit = loongson2_cpufreq_exit,
151 .attr = cpufreq_generic_attr, 140 .attr = cpufreq_generic_attr,
diff --git a/drivers/cpufreq/maple-cpufreq.c b/drivers/cpufreq/maple-cpufreq.c
index eb1e1766baed..4e2da0874bfb 100644
--- a/drivers/cpufreq/maple-cpufreq.c
+++ b/drivers/cpufreq/maple-cpufreq.c
@@ -131,26 +131,18 @@ static int maple_scom_query_freq(void)
131 */ 131 */
132 132
133static int maple_cpufreq_target(struct cpufreq_policy *policy, 133static int maple_cpufreq_target(struct cpufreq_policy *policy,
134 unsigned int target_freq, unsigned int relation) 134 unsigned int index)
135{ 135{
136 unsigned int newstate = 0;
137 struct cpufreq_freqs freqs; 136 struct cpufreq_freqs freqs;
138 int rc; 137 int rc;
139 138
140 if (cpufreq_frequency_table_target(policy, maple_cpu_freqs,
141 target_freq, relation, &newstate))
142 return -EINVAL;
143
144 if (maple_pmode_cur == newstate)
145 return 0;
146
147 mutex_lock(&maple_switch_mutex); 139 mutex_lock(&maple_switch_mutex);
148 140
149 freqs.old = maple_cpu_freqs[maple_pmode_cur].frequency; 141 freqs.old = maple_cpu_freqs[maple_pmode_cur].frequency;
150 freqs.new = maple_cpu_freqs[newstate].frequency; 142 freqs.new = maple_cpu_freqs[index].frequency;
151 143
152 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 144 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
153 rc = maple_scom_switch_freq(newstate); 145 rc = maple_scom_switch_freq(index);
154 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 146 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
155 147
156 mutex_unlock(&maple_switch_mutex); 148 mutex_unlock(&maple_switch_mutex);
@@ -173,7 +165,7 @@ static struct cpufreq_driver maple_cpufreq_driver = {
173 .flags = CPUFREQ_CONST_LOOPS, 165 .flags = CPUFREQ_CONST_LOOPS,
174 .init = maple_cpufreq_cpu_init, 166 .init = maple_cpufreq_cpu_init,
175 .verify = cpufreq_generic_frequency_table_verify, 167 .verify = cpufreq_generic_frequency_table_verify,
176 .target = maple_cpufreq_target, 168 .target_index = maple_cpufreq_target,
177 .get = maple_cpufreq_get_speed, 169 .get = maple_cpufreq_get_speed,
178 .attr = cpufreq_generic_attr, 170 .attr = cpufreq_generic_attr,
179}; 171};
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index ac552d090463..b5512712298f 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -51,40 +51,15 @@ static unsigned int omap_getspeed(unsigned int cpu)
51 return rate; 51 return rate;
52} 52}
53 53
54static int omap_target(struct cpufreq_policy *policy, 54static int omap_target(struct cpufreq_policy *policy, unsigned int index)
55 unsigned int target_freq,
56 unsigned int relation)
57{ 55{
58 unsigned int i;
59 int r, ret = 0; 56 int r, ret = 0;
60 struct cpufreq_freqs freqs; 57 struct cpufreq_freqs freqs;
61 struct dev_pm_opp *opp; 58 struct dev_pm_opp *opp;
62 unsigned long freq, volt = 0, volt_old = 0, tol = 0; 59 unsigned long freq, volt = 0, volt_old = 0, tol = 0;
63 60
64 if (!freq_table) {
65 dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__,
66 policy->cpu);
67 return -EINVAL;
68 }
69
70 ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
71 relation, &i);
72 if (ret) {
73 dev_dbg(mpu_dev, "%s: cpu%d: no freq match for %d(ret=%d)\n",
74 __func__, policy->cpu, target_freq, ret);
75 return ret;
76 }
77 freqs.new = freq_table[i].frequency;
78 if (!freqs.new) {
79 dev_err(mpu_dev, "%s: cpu%d: no match for freq %d\n", __func__,
80 policy->cpu, target_freq);
81 return -EINVAL;
82 }
83
84 freqs.old = omap_getspeed(policy->cpu); 61 freqs.old = omap_getspeed(policy->cpu);
85 62 freqs.new = freq_table[index].frequency;
86 if (freqs.old == freqs.new && policy->cur == freqs.new)
87 return ret;
88 63
89 freq = freqs.new * 1000; 64 freq = freqs.new * 1000;
90 ret = clk_round_rate(mpu_clk, freq); 65 ret = clk_round_rate(mpu_clk, freq);
@@ -200,7 +175,7 @@ static int omap_cpu_exit(struct cpufreq_policy *policy)
200static struct cpufreq_driver omap_driver = { 175static struct cpufreq_driver omap_driver = {
201 .flags = CPUFREQ_STICKY, 176 .flags = CPUFREQ_STICKY,
202 .verify = cpufreq_generic_frequency_table_verify, 177 .verify = cpufreq_generic_frequency_table_verify,
203 .target = omap_target, 178 .target_index = omap_target,
204 .get = omap_getspeed, 179 .get = omap_getspeed,
205 .init = omap_cpu_init, 180 .init = omap_cpu_init,
206 .exit = omap_cpu_exit, 181 .exit = omap_cpu_exit,
diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c
index 6164c1cca504..3c23053afdfd 100644
--- a/drivers/cpufreq/p4-clockmod.c
+++ b/drivers/cpufreq/p4-clockmod.c
@@ -105,23 +105,13 @@ static struct cpufreq_frequency_table p4clockmod_table[] = {
105}; 105};
106 106
107 107
108static int cpufreq_p4_target(struct cpufreq_policy *policy, 108static int cpufreq_p4_target(struct cpufreq_policy *policy, unsigned int index)
109 unsigned int target_freq,
110 unsigned int relation)
111{ 109{
112 unsigned int newstate = DC_RESV;
113 struct cpufreq_freqs freqs; 110 struct cpufreq_freqs freqs;
114 int i; 111 int i;
115 112
116 if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0],
117 target_freq, relation, &newstate))
118 return -EINVAL;
119
120 freqs.old = cpufreq_p4_get(policy->cpu); 113 freqs.old = cpufreq_p4_get(policy->cpu);
121 freqs.new = stock_freq * p4clockmod_table[newstate].driver_data / 8; 114 freqs.new = stock_freq * p4clockmod_table[index].driver_data / 8;
122
123 if (freqs.new == freqs.old)
124 return 0;
125 115
126 /* notifiers */ 116 /* notifiers */
127 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 117 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
@@ -131,7 +121,7 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy,
131 * Developer's Manual, Volume 3 121 * Developer's Manual, Volume 3
132 */ 122 */
133 for_each_cpu(i, policy->cpus) 123 for_each_cpu(i, policy->cpus)
134 cpufreq_p4_setdc(i, p4clockmod_table[newstate].driver_data); 124 cpufreq_p4_setdc(i, p4clockmod_table[index].driver_data);
135 125
136 /* notifiers */ 126 /* notifiers */
137 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 127 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
@@ -255,7 +245,7 @@ static unsigned int cpufreq_p4_get(unsigned int cpu)
255 245
256static struct cpufreq_driver p4clockmod_driver = { 246static struct cpufreq_driver p4clockmod_driver = {
257 .verify = cpufreq_generic_frequency_table_verify, 247 .verify = cpufreq_generic_frequency_table_verify,
258 .target = cpufreq_p4_target, 248 .target_index = cpufreq_p4_target,
259 .init = cpufreq_p4_cpu_init, 249 .init = cpufreq_p4_cpu_init,
260 .exit = cpufreq_generic_exit, 250 .exit = cpufreq_generic_exit,
261 .get = cpufreq_p4_get, 251 .get = cpufreq_p4_get,
diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c
index 1cca332728c3..17424ddc7f67 100644
--- a/drivers/cpufreq/pasemi-cpufreq.c
+++ b/drivers/cpufreq/pasemi-cpufreq.c
@@ -240,19 +240,11 @@ static int pas_cpufreq_cpu_exit(struct cpufreq_policy *policy)
240} 240}
241 241
242static int pas_cpufreq_target(struct cpufreq_policy *policy, 242static int pas_cpufreq_target(struct cpufreq_policy *policy,
243 unsigned int target_freq, 243 unsigned int pas_astate_new)
244 unsigned int relation)
245{ 244{
246 struct cpufreq_freqs freqs; 245 struct cpufreq_freqs freqs;
247 int pas_astate_new;
248 int i; 246 int i;
249 247
250 cpufreq_frequency_table_target(policy,
251 pas_freqs,
252 target_freq,
253 relation,
254 &pas_astate_new);
255
256 freqs.old = policy->cur; 248 freqs.old = policy->cur;
257 freqs.new = pas_freqs[pas_astate_new].frequency; 249 freqs.new = pas_freqs[pas_astate_new].frequency;
258 250
@@ -282,7 +274,7 @@ static struct cpufreq_driver pas_cpufreq_driver = {
282 .init = pas_cpufreq_cpu_init, 274 .init = pas_cpufreq_cpu_init,
283 .exit = pas_cpufreq_cpu_exit, 275 .exit = pas_cpufreq_cpu_exit,
284 .verify = cpufreq_generic_frequency_table_verify, 276 .verify = cpufreq_generic_frequency_table_verify,
285 .target = pas_cpufreq_target, 277 .target_index = pas_cpufreq_target,
286 .attr = cpufreq_generic_attr, 278 .attr = cpufreq_generic_attr,
287}; 279};
288 280
diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c
index 6eac1e230078..05f705e1b7a2 100644
--- a/drivers/cpufreq/pmac32-cpufreq.c
+++ b/drivers/cpufreq/pmac32-cpufreq.c
@@ -374,17 +374,11 @@ static unsigned int pmac_cpufreq_get_speed(unsigned int cpu)
374} 374}
375 375
376static int pmac_cpufreq_target( struct cpufreq_policy *policy, 376static int pmac_cpufreq_target( struct cpufreq_policy *policy,
377 unsigned int target_freq, 377 unsigned int index)
378 unsigned int relation)
379{ 378{
380 unsigned int newstate = 0;
381 int rc; 379 int rc;
382 380
383 if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs, 381 rc = do_set_cpu_speed(policy, index, 1);
384 target_freq, relation, &newstate))
385 return -EINVAL;
386
387 rc = do_set_cpu_speed(policy, newstate, 1);
388 382
389 ppc_proc_freq = cur_freq * 1000ul; 383 ppc_proc_freq = cur_freq * 1000ul;
390 return rc; 384 return rc;
@@ -453,7 +447,7 @@ static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
453 447
454static struct cpufreq_driver pmac_cpufreq_driver = { 448static struct cpufreq_driver pmac_cpufreq_driver = {
455 .verify = cpufreq_generic_frequency_table_verify, 449 .verify = cpufreq_generic_frequency_table_verify,
456 .target = pmac_cpufreq_target, 450 .target_index = pmac_cpufreq_target,
457 .get = pmac_cpufreq_get_speed, 451 .get = pmac_cpufreq_get_speed,
458 .init = pmac_cpufreq_cpu_init, 452 .init = pmac_cpufreq_cpu_init,
459 .suspend = pmac_cpufreq_suspend, 453 .suspend = pmac_cpufreq_suspend,
diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c
index 5261b92d768b..234b598ce416 100644
--- a/drivers/cpufreq/pmac64-cpufreq.c
+++ b/drivers/cpufreq/pmac64-cpufreq.c
@@ -312,27 +312,18 @@ static int g5_pfunc_query_freq(void)
312 * Common interface to the cpufreq core 312 * Common interface to the cpufreq core
313 */ 313 */
314 314
315static int g5_cpufreq_target(struct cpufreq_policy *policy, 315static int g5_cpufreq_target(struct cpufreq_policy *policy, unsigned int index)
316 unsigned int target_freq, unsigned int relation)
317{ 316{
318 unsigned int newstate = 0;
319 struct cpufreq_freqs freqs; 317 struct cpufreq_freqs freqs;
320 int rc; 318 int rc;
321 319
322 if (cpufreq_frequency_table_target(policy, g5_cpu_freqs,
323 target_freq, relation, &newstate))
324 return -EINVAL;
325
326 if (g5_pmode_cur == newstate)
327 return 0;
328
329 mutex_lock(&g5_switch_mutex); 320 mutex_lock(&g5_switch_mutex);
330 321
331 freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency; 322 freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency;
332 freqs.new = g5_cpu_freqs[newstate].frequency; 323 freqs.new = g5_cpu_freqs[index].frequency;
333 324
334 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 325 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
335 rc = g5_switch_freq(newstate); 326 rc = g5_switch_freq(index);
336 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 327 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
337 328
338 mutex_unlock(&g5_switch_mutex); 329 mutex_unlock(&g5_switch_mutex);
@@ -355,7 +346,7 @@ static struct cpufreq_driver g5_cpufreq_driver = {
355 .flags = CPUFREQ_CONST_LOOPS, 346 .flags = CPUFREQ_CONST_LOOPS,
356 .init = g5_cpufreq_cpu_init, 347 .init = g5_cpufreq_cpu_init,
357 .verify = cpufreq_generic_frequency_table_verify, 348 .verify = cpufreq_generic_frequency_table_verify,
358 .target = g5_cpufreq_target, 349 .target_index = g5_cpufreq_target,
359 .get = g5_cpufreq_get_speed, 350 .get = g5_cpufreq_get_speed,
360 .attr = cpufreq_generic_attr, 351 .attr = cpufreq_generic_attr,
361}; 352};
diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c
index eda17024a34a..643e7952cad3 100644
--- a/drivers/cpufreq/powernow-k6.c
+++ b/drivers/cpufreq/powernow-k6.c
@@ -63,12 +63,12 @@ static int powernow_k6_get_cpu_multiplier(void)
63 63
64 64
65/** 65/**
66 * powernow_k6_set_state - set the PowerNow! multiplier 66 * powernow_k6_target - set the PowerNow! multiplier
67 * @best_i: clock_ratio[best_i] is the target multiplier 67 * @best_i: clock_ratio[best_i] is the target multiplier
68 * 68 *
69 * Tries to change the PowerNow! multiplier 69 * Tries to change the PowerNow! multiplier
70 */ 70 */
71static void powernow_k6_set_state(struct cpufreq_policy *policy, 71static int powernow_k6_target(struct cpufreq_policy *policy,
72 unsigned int best_i) 72 unsigned int best_i)
73{ 73{
74 unsigned long outvalue = 0, invalue = 0; 74 unsigned long outvalue = 0, invalue = 0;
@@ -77,7 +77,7 @@ static void powernow_k6_set_state(struct cpufreq_policy *policy,
77 77
78 if (clock_ratio[best_i].driver_data > max_multiplier) { 78 if (clock_ratio[best_i].driver_data > max_multiplier) {
79 printk(KERN_ERR PFX "invalid target frequency\n"); 79 printk(KERN_ERR PFX "invalid target frequency\n");
80 return; 80 return -EINVAL;
81 } 81 }
82 82
83 freqs.old = busfreq * powernow_k6_get_cpu_multiplier(); 83 freqs.old = busfreq * powernow_k6_get_cpu_multiplier();
@@ -100,31 +100,6 @@ static void powernow_k6_set_state(struct cpufreq_policy *policy,
100 100
101 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 101 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
102 102
103 return;
104}
105
106
107/**
108 * powernow_k6_setpolicy - sets a new CPUFreq policy
109 * @policy: new policy
110 * @target_freq: the target frequency
111 * @relation: how that frequency relates to achieved frequency
112 * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
113 *
114 * sets a new CPUFreq policy
115 */
116static int powernow_k6_target(struct cpufreq_policy *policy,
117 unsigned int target_freq,
118 unsigned int relation)
119{
120 unsigned int newstate = 0;
121
122 if (cpufreq_frequency_table_target(policy, &clock_ratio[0],
123 target_freq, relation, &newstate))
124 return -EINVAL;
125
126 powernow_k6_set_state(policy, newstate);
127
128 return 0; 103 return 0;
129} 104}
130 105
@@ -161,7 +136,7 @@ static int powernow_k6_cpu_exit(struct cpufreq_policy *policy)
161 unsigned int i; 136 unsigned int i;
162 for (i = 0; i < 8; i++) { 137 for (i = 0; i < 8; i++) {
163 if (i == max_multiplier) 138 if (i == max_multiplier)
164 powernow_k6_set_state(policy, i); 139 powernow_k6_target(policy, i);
165 } 140 }
166 cpufreq_frequency_table_put_attr(policy->cpu); 141 cpufreq_frequency_table_put_attr(policy->cpu);
167 return 0; 142 return 0;
@@ -176,7 +151,7 @@ static unsigned int powernow_k6_get(unsigned int cpu)
176 151
177static struct cpufreq_driver powernow_k6_driver = { 152static struct cpufreq_driver powernow_k6_driver = {
178 .verify = cpufreq_generic_frequency_table_verify, 153 .verify = cpufreq_generic_frequency_table_verify,
179 .target = powernow_k6_target, 154 .target_index = powernow_k6_target,
180 .init = powernow_k6_cpu_init, 155 .init = powernow_k6_cpu_init,
181 .exit = powernow_k6_cpu_exit, 156 .exit = powernow_k6_cpu_exit,
182 .get = powernow_k6_get, 157 .get = powernow_k6_get,
diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c
index 44d345bad6fb..946708a1d745 100644
--- a/drivers/cpufreq/powernow-k7.c
+++ b/drivers/cpufreq/powernow-k7.c
@@ -248,7 +248,7 @@ static void change_VID(int vid)
248} 248}
249 249
250 250
251static void change_speed(struct cpufreq_policy *policy, unsigned int index) 251static int powernow_target(struct cpufreq_policy *policy, unsigned int index)
252{ 252{
253 u8 fid, vid; 253 u8 fid, vid;
254 struct cpufreq_freqs freqs; 254 struct cpufreq_freqs freqs;
@@ -291,6 +291,8 @@ static void change_speed(struct cpufreq_policy *policy, unsigned int index)
291 local_irq_enable(); 291 local_irq_enable();
292 292
293 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 293 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
294
295 return 0;
294} 296}
295 297
296 298
@@ -533,22 +535,6 @@ static int powernow_decode_bios(int maxfid, int startvid)
533} 535}
534 536
535 537
536static int powernow_target(struct cpufreq_policy *policy,
537 unsigned int target_freq,
538 unsigned int relation)
539{
540 unsigned int newstate;
541
542 if (cpufreq_frequency_table_target(policy, powernow_table, target_freq,
543 relation, &newstate))
544 return -EINVAL;
545
546 change_speed(policy, newstate);
547
548 return 0;
549}
550
551
552/* 538/*
553 * We use the fact that the bus frequency is somehow 539 * We use the fact that the bus frequency is somehow
554 * a multiple of 100000/3 khz, then we compute sgtc according 540 * a multiple of 100000/3 khz, then we compute sgtc according
@@ -694,7 +680,7 @@ static int powernow_cpu_exit(struct cpufreq_policy *policy)
694 680
695static struct cpufreq_driver powernow_driver = { 681static struct cpufreq_driver powernow_driver = {
696 .verify = cpufreq_generic_frequency_table_verify, 682 .verify = cpufreq_generic_frequency_table_verify,
697 .target = powernow_target, 683 .target_index = powernow_target,
698 .get = powernow_get, 684 .get = powernow_get,
699#ifdef CONFIG_X86_POWERNOW_K7_ACPI 685#ifdef CONFIG_X86_POWERNOW_K7_ACPI
700 .bios_limit = acpi_processor_get_bios_limit, 686 .bios_limit = acpi_processor_get_bios_limit,
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index 298beb742ebb..62a1ce47d3df 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -977,20 +977,17 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data,
977 977
978struct powernowk8_target_arg { 978struct powernowk8_target_arg {
979 struct cpufreq_policy *pol; 979 struct cpufreq_policy *pol;
980 unsigned targfreq; 980 unsigned newstate;
981 unsigned relation;
982}; 981};
983 982
984static long powernowk8_target_fn(void *arg) 983static long powernowk8_target_fn(void *arg)
985{ 984{
986 struct powernowk8_target_arg *pta = arg; 985 struct powernowk8_target_arg *pta = arg;
987 struct cpufreq_policy *pol = pta->pol; 986 struct cpufreq_policy *pol = pta->pol;
988 unsigned targfreq = pta->targfreq; 987 unsigned newstate = pta->newstate;
989 unsigned relation = pta->relation;
990 struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); 988 struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
991 u32 checkfid; 989 u32 checkfid;
992 u32 checkvid; 990 u32 checkvid;
993 unsigned int newstate;
994 int ret; 991 int ret;
995 992
996 if (!data) 993 if (!data)
@@ -1004,8 +1001,9 @@ static long powernowk8_target_fn(void *arg)
1004 return -EIO; 1001 return -EIO;
1005 } 1002 }
1006 1003
1007 pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n", 1004 pr_debug("targ: cpu %d, %d kHz, min %d, max %d\n",
1008 pol->cpu, targfreq, pol->min, pol->max, relation); 1005 pol->cpu, data->powernow_table[newstate].frequency, pol->min,
1006 pol->max);
1009 1007
1010 if (query_current_values_with_pending_wait(data)) 1008 if (query_current_values_with_pending_wait(data))
1011 return -EIO; 1009 return -EIO;
@@ -1021,10 +1019,6 @@ static long powernowk8_target_fn(void *arg)
1021 checkvid, data->currvid); 1019 checkvid, data->currvid);
1022 } 1020 }
1023 1021
1024 if (cpufreq_frequency_table_target(pol, data->powernow_table,
1025 targfreq, relation, &newstate))
1026 return -EIO;
1027
1028 mutex_lock(&fidvid_mutex); 1022 mutex_lock(&fidvid_mutex);
1029 1023
1030 powernow_k8_acpi_pst_values(data, newstate); 1024 powernow_k8_acpi_pst_values(data, newstate);
@@ -1044,11 +1038,9 @@ static long powernowk8_target_fn(void *arg)
1044} 1038}
1045 1039
1046/* Driver entry point to switch to the target frequency */ 1040/* Driver entry point to switch to the target frequency */
1047static int powernowk8_target(struct cpufreq_policy *pol, 1041static int powernowk8_target(struct cpufreq_policy *pol, unsigned index)
1048 unsigned targfreq, unsigned relation)
1049{ 1042{
1050 struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq, 1043 struct powernowk8_target_arg pta = { .pol = pol, .newstate = index };
1051 .relation = relation };
1052 1044
1053 return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); 1045 return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta);
1054} 1046}
@@ -1213,7 +1205,7 @@ out:
1213 1205
1214static struct cpufreq_driver cpufreq_amd64_driver = { 1206static struct cpufreq_driver cpufreq_amd64_driver = {
1215 .verify = cpufreq_generic_frequency_table_verify, 1207 .verify = cpufreq_generic_frequency_table_verify,
1216 .target = powernowk8_target, 1208 .target_index = powernowk8_target,
1217 .bios_limit = acpi_processor_get_bios_limit, 1209 .bios_limit = acpi_processor_get_bios_limit,
1218 .init = powernowk8_cpu_init, 1210 .init = powernowk8_cpu_init,
1219 .exit = powernowk8_cpu_exit, 1211 .exit = powernowk8_cpu_exit,
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c
index a0f562ca292d..79d8e9c46b6d 100644
--- a/drivers/cpufreq/ppc-corenet-cpufreq.c
+++ b/drivers/cpufreq/ppc-corenet-cpufreq.c
@@ -251,27 +251,20 @@ static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
251} 251}
252 252
253static int corenet_cpufreq_target(struct cpufreq_policy *policy, 253static int corenet_cpufreq_target(struct cpufreq_policy *policy,
254 unsigned int target_freq, unsigned int relation) 254 unsigned int index)
255{ 255{
256 struct cpufreq_freqs freqs; 256 struct cpufreq_freqs freqs;
257 unsigned int new;
258 struct clk *parent; 257 struct clk *parent;
259 int ret; 258 int ret;
260 struct cpu_data *data = per_cpu(cpu_data, policy->cpu); 259 struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
261 260
262 cpufreq_frequency_table_target(policy, data->table,
263 target_freq, relation, &new);
264
265 if (policy->cur == data->table[new].frequency)
266 return 0;
267
268 freqs.old = policy->cur; 261 freqs.old = policy->cur;
269 freqs.new = data->table[new].frequency; 262 freqs.new = data->table[index].frequency;
270 263
271 mutex_lock(&cpufreq_lock); 264 mutex_lock(&cpufreq_lock);
272 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 265 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
273 266
274 parent = of_clk_get(data->parent, data->table[new].driver_data); 267 parent = of_clk_get(data->parent, data->table[index].driver_data);
275 ret = clk_set_parent(data->clk, parent); 268 ret = clk_set_parent(data->clk, parent);
276 if (ret) 269 if (ret)
277 freqs.new = freqs.old; 270 freqs.new = freqs.old;
@@ -288,7 +281,7 @@ static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
288 .init = corenet_cpufreq_cpu_init, 281 .init = corenet_cpufreq_cpu_init,
289 .exit = __exit_p(corenet_cpufreq_cpu_exit), 282 .exit = __exit_p(corenet_cpufreq_cpu_exit),
290 .verify = cpufreq_generic_frequency_table_verify, 283 .verify = cpufreq_generic_frequency_table_verify,
291 .target = corenet_cpufreq_target, 284 .target_index = corenet_cpufreq_target,
292 .get = corenet_cpufreq_get_speed, 285 .get = corenet_cpufreq_get_speed,
293 .attr = cpufreq_generic_attr, 286 .attr = cpufreq_generic_attr,
294}; 287};
diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c
index 38540d1f5939..52f707d5f458 100644
--- a/drivers/cpufreq/ppc_cbe_cpufreq.c
+++ b/drivers/cpufreq/ppc_cbe_cpufreq.c
@@ -129,18 +129,10 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
129} 129}
130 130
131static int cbe_cpufreq_target(struct cpufreq_policy *policy, 131static int cbe_cpufreq_target(struct cpufreq_policy *policy,
132 unsigned int target_freq, 132 unsigned int cbe_pmode_new)
133 unsigned int relation)
134{ 133{
135 int rc; 134 int rc;
136 struct cpufreq_freqs freqs; 135 struct cpufreq_freqs freqs;
137 unsigned int cbe_pmode_new;
138
139 cpufreq_frequency_table_target(policy,
140 cbe_freqs,
141 target_freq,
142 relation,
143 &cbe_pmode_new);
144 136
145 freqs.old = policy->cur; 137 freqs.old = policy->cur;
146 freqs.new = cbe_freqs[cbe_pmode_new].frequency; 138 freqs.new = cbe_freqs[cbe_pmode_new].frequency;
@@ -164,7 +156,7 @@ static int cbe_cpufreq_target(struct cpufreq_policy *policy,
164 156
165static struct cpufreq_driver cbe_cpufreq_driver = { 157static struct cpufreq_driver cbe_cpufreq_driver = {
166 .verify = cpufreq_generic_frequency_table_verify, 158 .verify = cpufreq_generic_frequency_table_verify,
167 .target = cbe_cpufreq_target, 159 .target_index = cbe_cpufreq_target,
168 .init = cbe_cpufreq_cpu_init, 160 .init = cbe_cpufreq_cpu_init,
169 .exit = cpufreq_generic_exit, 161 .exit = cpufreq_generic_exit,
170 .name = "cbe-cpufreq", 162 .name = "cbe-cpufreq",
diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c
index 29aca574317b..183bc13f13e5 100644
--- a/drivers/cpufreq/pxa2xx-cpufreq.c
+++ b/drivers/cpufreq/pxa2xx-cpufreq.c
@@ -267,14 +267,11 @@ static unsigned int pxa_cpufreq_get(unsigned int cpu)
267 return get_clk_frequency_khz(0); 267 return get_clk_frequency_khz(0);
268} 268}
269 269
270static int pxa_set_target(struct cpufreq_policy *policy, 270static int pxa_set_target(struct cpufreq_policy *policy, unsigned int idx)
271 unsigned int target_freq,
272 unsigned int relation)
273{ 271{
274 struct cpufreq_frequency_table *pxa_freqs_table; 272 struct cpufreq_frequency_table *pxa_freqs_table;
275 pxa_freqs_t *pxa_freq_settings; 273 pxa_freqs_t *pxa_freq_settings;
276 struct cpufreq_freqs freqs; 274 struct cpufreq_freqs freqs;
277 unsigned int idx;
278 unsigned long flags; 275 unsigned long flags;
279 unsigned int new_freq_cpu, new_freq_mem; 276 unsigned int new_freq_cpu, new_freq_mem;
280 unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg; 277 unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg;
@@ -283,12 +280,6 @@ static int pxa_set_target(struct cpufreq_policy *policy,
283 /* Get the current policy */ 280 /* Get the current policy */
284 find_freq_tables(&pxa_freqs_table, &pxa_freq_settings); 281 find_freq_tables(&pxa_freqs_table, &pxa_freq_settings);
285 282
286 /* Lookup the next frequency */
287 if (cpufreq_frequency_table_target(policy, pxa_freqs_table,
288 target_freq, relation, &idx)) {
289 return -EINVAL;
290 }
291
292 new_freq_cpu = pxa_freq_settings[idx].khz; 283 new_freq_cpu = pxa_freq_settings[idx].khz;
293 new_freq_mem = pxa_freq_settings[idx].membus; 284 new_freq_mem = pxa_freq_settings[idx].membus;
294 freqs.old = policy->cur; 285 freqs.old = policy->cur;
@@ -448,7 +439,7 @@ static int pxa_cpufreq_init(struct cpufreq_policy *policy)
448 439
449static struct cpufreq_driver pxa_cpufreq_driver = { 440static struct cpufreq_driver pxa_cpufreq_driver = {
450 .verify = cpufreq_generic_frequency_table_verify, 441 .verify = cpufreq_generic_frequency_table_verify,
451 .target = pxa_set_target, 442 .target_index = pxa_set_target,
452 .init = pxa_cpufreq_init, 443 .init = pxa_cpufreq_init,
453 .exit = cpufreq_generic_exit, 444 .exit = cpufreq_generic_exit,
454 .get = pxa_cpufreq_get, 445 .get = pxa_cpufreq_get,
diff --git a/drivers/cpufreq/pxa3xx-cpufreq.c b/drivers/cpufreq/pxa3xx-cpufreq.c
index 47fbee49d6e5..132e37d578c2 100644
--- a/drivers/cpufreq/pxa3xx-cpufreq.c
+++ b/drivers/cpufreq/pxa3xx-cpufreq.c
@@ -155,24 +155,16 @@ static unsigned int pxa3xx_cpufreq_get(unsigned int cpu)
155 return pxa3xx_get_clk_frequency_khz(0); 155 return pxa3xx_get_clk_frequency_khz(0);
156} 156}
157 157
158static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy, 158static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy, unsigned int index)
159 unsigned int target_freq,
160 unsigned int relation)
161{ 159{
162 struct pxa3xx_freq_info *next; 160 struct pxa3xx_freq_info *next;
163 struct cpufreq_freqs freqs; 161 struct cpufreq_freqs freqs;
164 unsigned long flags; 162 unsigned long flags;
165 int idx;
166 163
167 if (policy->cpu != 0) 164 if (policy->cpu != 0)
168 return -EINVAL; 165 return -EINVAL;
169 166
170 /* Lookup the next frequency */ 167 next = &pxa3xx_freqs[index];
171 if (cpufreq_frequency_table_target(policy, pxa3xx_freqs_table,
172 target_freq, relation, &idx))
173 return -EINVAL;
174
175 next = &pxa3xx_freqs[idx];
176 168
177 freqs.old = policy->cur; 169 freqs.old = policy->cur;
178 freqs.new = next->cpufreq_mhz * 1000; 170 freqs.new = next->cpufreq_mhz * 1000;
@@ -181,9 +173,6 @@ static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy,
181 freqs.old / 1000, freqs.new / 1000, 173 freqs.old / 1000, freqs.new / 1000,
182 (freqs.old == freqs.new) ? " (skipped)" : ""); 174 (freqs.old == freqs.new) ? " (skipped)" : "");
183 175
184 if (freqs.old == target_freq)
185 return 0;
186
187 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 176 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
188 177
189 local_irq_save(flags); 178 local_irq_save(flags);
@@ -225,7 +214,7 @@ static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy)
225 214
226static struct cpufreq_driver pxa3xx_cpufreq_driver = { 215static struct cpufreq_driver pxa3xx_cpufreq_driver = {
227 .verify = cpufreq_generic_frequency_table_verify, 216 .verify = cpufreq_generic_frequency_table_verify,
228 .target = pxa3xx_cpufreq_set, 217 .target_index = pxa3xx_cpufreq_set,
229 .init = pxa3xx_cpufreq_init, 218 .init = pxa3xx_cpufreq_init,
230 .exit = cpufreq_generic_exit, 219 .exit = cpufreq_generic_exit,
231 .get = pxa3xx_cpufreq_get, 220 .get = pxa3xx_cpufreq_get,
diff --git a/drivers/cpufreq/s3c2416-cpufreq.c b/drivers/cpufreq/s3c2416-cpufreq.c
index 26a35d137157..4188accd34ab 100644
--- a/drivers/cpufreq/s3c2416-cpufreq.c
+++ b/drivers/cpufreq/s3c2416-cpufreq.c
@@ -217,24 +217,15 @@ static int s3c2416_cpufreq_leave_dvs(struct s3c2416_data *s3c_freq, int idx)
217} 217}
218 218
219static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy, 219static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy,
220 unsigned int target_freq, 220 unsigned int index)
221 unsigned int relation)
222{ 221{
223 struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; 222 struct s3c2416_data *s3c_freq = &s3c2416_cpufreq;
224 struct cpufreq_freqs freqs; 223 struct cpufreq_freqs freqs;
225 int idx, ret, to_dvs = 0; 224 int idx, ret, to_dvs = 0;
226 unsigned int i;
227 225
228 mutex_lock(&cpufreq_lock); 226 mutex_lock(&cpufreq_lock);
229 227
230 pr_debug("cpufreq: to %dKHz, relation %d\n", target_freq, relation); 228 idx = s3c_freq->freq_table[index].driver_data;
231
232 ret = cpufreq_frequency_table_target(policy, s3c_freq->freq_table,
233 target_freq, relation, &i);
234 if (ret != 0)
235 goto out;
236
237 idx = s3c_freq->freq_table[i].driver_data;
238 229
239 if (idx == SOURCE_HCLK) 230 if (idx == SOURCE_HCLK)
240 to_dvs = 1; 231 to_dvs = 1;
@@ -256,7 +247,7 @@ static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy,
256 */ 247 */
257 freqs.new = (s3c_freq->is_dvs && !to_dvs) 248 freqs.new = (s3c_freq->is_dvs && !to_dvs)
258 ? clk_get_rate(s3c_freq->hclk) / 1000 249 ? clk_get_rate(s3c_freq->hclk) / 1000
259 : s3c_freq->freq_table[i].frequency; 250 : s3c_freq->freq_table[index].frequency;
260 251
261 pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new); 252 pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new);
262 253
@@ -505,7 +496,7 @@ err_hclk:
505static struct cpufreq_driver s3c2416_cpufreq_driver = { 496static struct cpufreq_driver s3c2416_cpufreq_driver = {
506 .flags = 0, 497 .flags = 0,
507 .verify = cpufreq_generic_frequency_table_verify, 498 .verify = cpufreq_generic_frequency_table_verify,
508 .target = s3c2416_cpufreq_set_target, 499 .target_index = s3c2416_cpufreq_set_target,
509 .get = s3c2416_cpufreq_get_speed, 500 .get = s3c2416_cpufreq_get_speed,
510 .init = s3c2416_cpufreq_driver_init, 501 .init = s3c2416_cpufreq_driver_init,
511 .name = "s3c2416", 502 .name = "s3c2416",
diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c
index 461617332033..8bdcf32a4418 100644
--- a/drivers/cpufreq/s3c64xx-cpufreq.c
+++ b/drivers/cpufreq/s3c64xx-cpufreq.c
@@ -63,26 +63,16 @@ static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu)
63} 63}
64 64
65static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, 65static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
66 unsigned int target_freq, 66 unsigned int index)
67 unsigned int relation)
68{ 67{
69 int ret; 68 int ret;
70 unsigned int i;
71 struct cpufreq_freqs freqs; 69 struct cpufreq_freqs freqs;
72 struct s3c64xx_dvfs *dvfs; 70 struct s3c64xx_dvfs *dvfs;
73 71
74 ret = cpufreq_frequency_table_target(policy, s3c64xx_freq_table,
75 target_freq, relation, &i);
76 if (ret != 0)
77 return ret;
78
79 freqs.old = clk_get_rate(armclk) / 1000; 72 freqs.old = clk_get_rate(armclk) / 1000;
80 freqs.new = s3c64xx_freq_table[i].frequency; 73 freqs.new = s3c64xx_freq_table[index].frequency;
81 freqs.flags = 0; 74 freqs.flags = 0;
82 dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[i].driver_data]; 75 dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data];
83
84 if (freqs.old == freqs.new)
85 return 0;
86 76
87 pr_debug("Transition %d-%dkHz\n", freqs.old, freqs.new); 77 pr_debug("Transition %d-%dkHz\n", freqs.old, freqs.new);
88 78
@@ -254,7 +244,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
254static struct cpufreq_driver s3c64xx_cpufreq_driver = { 244static struct cpufreq_driver s3c64xx_cpufreq_driver = {
255 .flags = 0, 245 .flags = 0,
256 .verify = cpufreq_generic_frequency_table_verify, 246 .verify = cpufreq_generic_frequency_table_verify,
257 .target = s3c64xx_cpufreq_set_target, 247 .target_index = s3c64xx_cpufreq_set_target,
258 .get = s3c64xx_cpufreq_get_speed, 248 .get = s3c64xx_cpufreq_get_speed,
259 .init = s3c64xx_cpufreq_driver_init, 249 .init = s3c64xx_cpufreq_driver_init,
260 .name = "s3c", 250 .name = "s3c",
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",
diff --git a/drivers/cpufreq/sa1100-cpufreq.c b/drivers/cpufreq/sa1100-cpufreq.c
index b282cea47e62..b0da1fe40b1d 100644
--- a/drivers/cpufreq/sa1100-cpufreq.c
+++ b/drivers/cpufreq/sa1100-cpufreq.c
@@ -177,36 +177,20 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed)
177 } 177 }
178} 178}
179 179
180static int sa1100_target(struct cpufreq_policy *policy, 180static int sa1100_target(struct cpufreq_policy *policy, unsigned int ppcr)
181 unsigned int target_freq,
182 unsigned int relation)
183{ 181{
184 unsigned int cur = sa11x0_getspeed(0); 182 unsigned int cur = sa11x0_getspeed(0);
185 unsigned int new_ppcr;
186 struct cpufreq_freqs freqs; 183 struct cpufreq_freqs freqs;
187 184
188 new_ppcr = sa11x0_freq_to_ppcr(target_freq);
189 switch (relation) {
190 case CPUFREQ_RELATION_L:
191 if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max)
192 new_ppcr--;
193 break;
194 case CPUFREQ_RELATION_H:
195 if ((sa11x0_ppcr_to_freq(new_ppcr) > target_freq) &&
196 (sa11x0_ppcr_to_freq(new_ppcr - 1) >= policy->min))
197 new_ppcr--;
198 break;
199 }
200
201 freqs.old = cur; 185 freqs.old = cur;
202 freqs.new = sa11x0_ppcr_to_freq(new_ppcr); 186 freqs.new = sa11x0_freq_table[ppcr].frequency;
203 187
204 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 188 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
205 189
206 if (freqs.new > cur) 190 if (freqs.new > cur)
207 sa1100_update_dram_timings(cur, freqs.new); 191 sa1100_update_dram_timings(cur, freqs.new);
208 192
209 PPCR = new_ppcr; 193 PPCR = ppcr;
210 194
211 if (freqs.new < cur) 195 if (freqs.new < cur)
212 sa1100_update_dram_timings(cur, freqs.new); 196 sa1100_update_dram_timings(cur, freqs.new);
@@ -224,7 +208,7 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy)
224static struct cpufreq_driver sa1100_driver __refdata = { 208static struct cpufreq_driver sa1100_driver __refdata = {
225 .flags = CPUFREQ_STICKY, 209 .flags = CPUFREQ_STICKY,
226 .verify = cpufreq_generic_frequency_table_verify, 210 .verify = cpufreq_generic_frequency_table_verify,
227 .target = sa1100_target, 211 .target_index = sa1100_target,
228 .get = sa11x0_getspeed, 212 .get = sa11x0_getspeed,
229 .init = sa1100_cpu_init, 213 .init = sa1100_cpu_init,
230 .name = "sa1100", 214 .name = "sa1100",
diff --git a/drivers/cpufreq/sa1110-cpufreq.c b/drivers/cpufreq/sa1110-cpufreq.c
index bca04c0b4a73..55b1818c3e49 100644
--- a/drivers/cpufreq/sa1110-cpufreq.c
+++ b/drivers/cpufreq/sa1110-cpufreq.c
@@ -229,34 +229,16 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram)
229/* 229/*
230 * Ok, set the CPU frequency. 230 * Ok, set the CPU frequency.
231 */ 231 */
232static int sa1110_target(struct cpufreq_policy *policy, 232static int sa1110_target(struct cpufreq_policy *policy, unsigned int ppcr)
233 unsigned int target_freq,
234 unsigned int relation)
235{ 233{
236 struct sdram_params *sdram = &sdram_params; 234 struct sdram_params *sdram = &sdram_params;
237 struct cpufreq_freqs freqs; 235 struct cpufreq_freqs freqs;
238 struct sdram_info sd; 236 struct sdram_info sd;
239 unsigned long flags; 237 unsigned long flags;
240 unsigned int ppcr, unused; 238 unsigned int unused;
241
242 switch (relation) {
243 case CPUFREQ_RELATION_L:
244 ppcr = sa11x0_freq_to_ppcr(target_freq);
245 if (sa11x0_ppcr_to_freq(ppcr) > policy->max)
246 ppcr--;
247 break;
248 case CPUFREQ_RELATION_H:
249 ppcr = sa11x0_freq_to_ppcr(target_freq);
250 if (ppcr && (sa11x0_ppcr_to_freq(ppcr) > target_freq) &&
251 (sa11x0_ppcr_to_freq(ppcr-1) >= policy->min))
252 ppcr--;
253 break;
254 default:
255 return -EINVAL;
256 }
257 239
258 freqs.old = sa11x0_getspeed(0); 240 freqs.old = sa11x0_getspeed(0);
259 freqs.new = sa11x0_ppcr_to_freq(ppcr); 241 freqs.new = sa11x0_freq_table[ppcr].frequency;
260 242
261 sdram_calculate_timing(&sd, freqs.new, sdram); 243 sdram_calculate_timing(&sd, freqs.new, sdram);
262 244
@@ -340,7 +322,7 @@ static int __init sa1110_cpu_init(struct cpufreq_policy *policy)
340static struct cpufreq_driver sa1110_driver __refdata = { 322static struct cpufreq_driver sa1110_driver __refdata = {
341 .flags = CPUFREQ_STICKY, 323 .flags = CPUFREQ_STICKY,
342 .verify = cpufreq_generic_frequency_table_verify, 324 .verify = cpufreq_generic_frequency_table_verify,
343 .target = sa1110_target, 325 .target_index = sa1110_target,
344 .get = sa11x0_getspeed, 326 .get = sa11x0_getspeed,
345 .init = sa1110_cpu_init, 327 .init = sa1110_cpu_init,
346 .name = "sa1110", 328 .name = "sa1110",
diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c
index 9047ab1ca014..6c86452e1737 100644
--- a/drivers/cpufreq/sc520_freq.c
+++ b/drivers/cpufreq/sc520_freq.c
@@ -53,8 +53,7 @@ static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu)
53 } 53 }
54} 54}
55 55
56static void sc520_freq_set_cpu_state(struct cpufreq_policy *policy, 56static int sc520_freq_target(struct cpufreq_policy *policy, unsigned int state)
57 unsigned int state)
58{ 57{
59 58
60 struct cpufreq_freqs freqs; 59 struct cpufreq_freqs freqs;
@@ -76,24 +75,10 @@ static void sc520_freq_set_cpu_state(struct cpufreq_policy *policy,
76 local_irq_enable(); 75 local_irq_enable();
77 76
78 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 77 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
79};
80
81static int sc520_freq_target(struct cpufreq_policy *policy,
82 unsigned int target_freq,
83 unsigned int relation)
84{
85 unsigned int newstate = 0;
86
87 if (cpufreq_frequency_table_target(policy, sc520_freq_table,
88 target_freq, relation, &newstate))
89 return -EINVAL;
90
91 sc520_freq_set_cpu_state(policy, newstate);
92 78
93 return 0; 79 return 0;
94} 80}
95 81
96
97/* 82/*
98 * Module init and exit code 83 * Module init and exit code
99 */ 84 */
@@ -117,7 +102,7 @@ static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
117static struct cpufreq_driver sc520_freq_driver = { 102static struct cpufreq_driver sc520_freq_driver = {
118 .get = sc520_freq_get_cpu_frequency, 103 .get = sc520_freq_get_cpu_frequency,
119 .verify = cpufreq_generic_frequency_table_verify, 104 .verify = cpufreq_generic_frequency_table_verify,
120 .target = sc520_freq_target, 105 .target_index = sc520_freq_target,
121 .init = sc520_freq_cpu_init, 106 .init = sc520_freq_cpu_init,
122 .exit = cpufreq_generic_exit, 107 .exit = cpufreq_generic_exit,
123 .name = "sc520_freq", 108 .name = "sc520_freq",
diff --git a/drivers/cpufreq/sparc-us2e-cpufreq.c b/drivers/cpufreq/sparc-us2e-cpufreq.c
index 291688c1da9a..3bf5b8f03661 100644
--- a/drivers/cpufreq/sparc-us2e-cpufreq.c
+++ b/drivers/cpufreq/sparc-us2e-cpufreq.c
@@ -245,8 +245,7 @@ static unsigned int us2e_freq_get(unsigned int cpu)
245 return clock_tick / estar_to_divisor(estar); 245 return clock_tick / estar_to_divisor(estar);
246} 246}
247 247
248static void us2e_set_cpu_divider_index(struct cpufreq_policy *policy, 248static int us2e_freq_target(struct cpufreq_policy *policy, unsigned int index)
249 unsigned int index)
250{ 249{
251 unsigned int cpu = policy->cpu; 250 unsigned int cpu = policy->cpu;
252 unsigned long new_bits, new_freq; 251 unsigned long new_bits, new_freq;
@@ -277,20 +276,6 @@ static void us2e_set_cpu_divider_index(struct cpufreq_policy *policy,
277 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 276 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
278 277
279 set_cpus_allowed_ptr(current, &cpus_allowed); 278 set_cpus_allowed_ptr(current, &cpus_allowed);
280}
281
282static int us2e_freq_target(struct cpufreq_policy *policy,
283 unsigned int target_freq,
284 unsigned int relation)
285{
286 unsigned int new_index = 0;
287
288 if (cpufreq_frequency_table_target(policy,
289 &us2e_freq_table[policy->cpu].table[0],
290 target_freq, relation, &new_index))
291 return -EINVAL;
292
293 us2e_set_cpu_divider_index(policy, new_index);
294 279
295 return 0; 280 return 0;
296} 281}
@@ -325,7 +310,7 @@ static int us2e_freq_cpu_exit(struct cpufreq_policy *policy)
325{ 310{
326 if (cpufreq_us2e_driver) { 311 if (cpufreq_us2e_driver) {
327 cpufreq_frequency_table_put_attr(policy->cpu); 312 cpufreq_frequency_table_put_attr(policy->cpu);
328 us2e_set_cpu_divider_index(policy, 0); 313 us2e_freq_target(policy, 0);
329 } 314 }
330 315
331 return 0; 316 return 0;
@@ -358,7 +343,7 @@ static int __init us2e_freq_init(void)
358 343
359 driver->init = us2e_freq_cpu_init; 344 driver->init = us2e_freq_cpu_init;
360 driver->verify = cpufreq_generic_frequency_table_verify; 345 driver->verify = cpufreq_generic_frequency_table_verify;
361 driver->target = us2e_freq_target; 346 driver->target_index = us2e_freq_target;
362 driver->get = us2e_freq_get; 347 driver->get = us2e_freq_get;
363 driver->exit = us2e_freq_cpu_exit; 348 driver->exit = us2e_freq_cpu_exit;
364 strcpy(driver->name, "UltraSPARC-IIe"); 349 strcpy(driver->name, "UltraSPARC-IIe");
diff --git a/drivers/cpufreq/sparc-us3-cpufreq.c b/drivers/cpufreq/sparc-us3-cpufreq.c
index 9b3dbd31362e..2e54d55915df 100644
--- a/drivers/cpufreq/sparc-us3-cpufreq.c
+++ b/drivers/cpufreq/sparc-us3-cpufreq.c
@@ -93,8 +93,7 @@ static unsigned int us3_freq_get(unsigned int cpu)
93 return ret; 93 return ret;
94} 94}
95 95
96static void us3_set_cpu_divider_index(struct cpufreq_policy *policy, 96static int us3_freq_target(struct cpufreq_policy *policy, unsigned int index)
97 unsigned int index)
98{ 97{
99 unsigned int cpu = policy->cpu; 98 unsigned int cpu = policy->cpu;
100 unsigned long new_bits, new_freq, reg; 99 unsigned long new_bits, new_freq, reg;
@@ -136,22 +135,6 @@ static void us3_set_cpu_divider_index(struct cpufreq_policy *policy,
136 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 135 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
137 136
138 set_cpus_allowed_ptr(current, &cpus_allowed); 137 set_cpus_allowed_ptr(current, &cpus_allowed);
139}
140
141static int us3_freq_target(struct cpufreq_policy *policy,
142 unsigned int target_freq,
143 unsigned int relation)
144{
145 unsigned int new_index = 0;
146
147 if (cpufreq_frequency_table_target(policy,
148 &us3_freq_table[policy->cpu].table[0],
149 target_freq,
150 relation,
151 &new_index))
152 return -EINVAL;
153
154 us3_set_cpu_divider_index(policy, new_index);
155 138
156 return 0; 139 return 0;
157} 140}
@@ -182,7 +165,7 @@ static int us3_freq_cpu_exit(struct cpufreq_policy *policy)
182{ 165{
183 if (cpufreq_us3_driver) { 166 if (cpufreq_us3_driver) {
184 cpufreq_frequency_table_put_attr(policy->cpu); 167 cpufreq_frequency_table_put_attr(policy->cpu);
185 us3_set_cpu_divider_index(policy, 0); 168 us3_freq_target(policy, 0);
186 } 169 }
187 170
188 return 0; 171 return 0;
@@ -219,7 +202,7 @@ static int __init us3_freq_init(void)
219 202
220 driver->init = us3_freq_cpu_init; 203 driver->init = us3_freq_cpu_init;
221 driver->verify = cpufreq_generic_frequency_table_verify; 204 driver->verify = cpufreq_generic_frequency_table_verify;
222 driver->target = us3_freq_target; 205 driver->target_index = us3_freq_target;
223 driver->get = us3_freq_get; 206 driver->get = us3_freq_get;
224 driver->exit = us3_freq_cpu_exit; 207 driver->exit = us3_freq_cpu_exit;
225 strcpy(driver->name, "UltraSPARC-III"); 208 strcpy(driver->name, "UltraSPARC-III");
diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c
index 8841366a2068..11a65be3fd76 100644
--- a/drivers/cpufreq/spear-cpufreq.c
+++ b/drivers/cpufreq/spear-cpufreq.c
@@ -105,20 +105,16 @@ static int spear1340_set_cpu_rate(struct clk *sys_pclk, unsigned long newfreq)
105} 105}
106 106
107static int spear_cpufreq_target(struct cpufreq_policy *policy, 107static int spear_cpufreq_target(struct cpufreq_policy *policy,
108 unsigned int target_freq, unsigned int relation) 108 unsigned int index)
109{ 109{
110 struct cpufreq_freqs freqs; 110 struct cpufreq_freqs freqs;
111 long newfreq; 111 long newfreq;
112 struct clk *srcclk; 112 struct clk *srcclk;
113 int index, ret, mult = 1; 113 int ret, mult = 1;
114
115 if (cpufreq_frequency_table_target(policy, spear_cpufreq.freq_tbl,
116 target_freq, relation, &index))
117 return -EINVAL;
118 114
119 freqs.old = spear_cpufreq_get(0); 115 freqs.old = spear_cpufreq_get(0);
120
121 newfreq = spear_cpufreq.freq_tbl[index].frequency * 1000; 116 newfreq = spear_cpufreq.freq_tbl[index].frequency * 1000;
117
122 if (of_machine_is_compatible("st,spear1340")) { 118 if (of_machine_is_compatible("st,spear1340")) {
123 /* 119 /*
124 * SPEAr1340 is special in the sense that due to the possibility 120 * SPEAr1340 is special in the sense that due to the possibility
@@ -179,7 +175,7 @@ static struct cpufreq_driver spear_cpufreq_driver = {
179 .name = "cpufreq-spear", 175 .name = "cpufreq-spear",
180 .flags = CPUFREQ_STICKY, 176 .flags = CPUFREQ_STICKY,
181 .verify = cpufreq_generic_frequency_table_verify, 177 .verify = cpufreq_generic_frequency_table_verify,
182 .target = spear_cpufreq_target, 178 .target_index = spear_cpufreq_target,
183 .get = spear_cpufreq_get, 179 .get = spear_cpufreq_get,
184 .init = spear_cpufreq_init, 180 .init = spear_cpufreq_init,
185 .exit = cpufreq_generic_exit, 181 .exit = cpufreq_generic_exit,
diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c
index 25e45f89acac..c51ec8c0e3a8 100644
--- a/drivers/cpufreq/speedstep-centrino.c
+++ b/drivers/cpufreq/speedstep-centrino.c
@@ -416,21 +416,17 @@ static int centrino_cpu_exit(struct cpufreq_policy *policy)
416/** 416/**
417 * centrino_setpolicy - set a new CPUFreq policy 417 * centrino_setpolicy - set a new CPUFreq policy
418 * @policy: new policy 418 * @policy: new policy
419 * @target_freq: the target frequency 419 * @index: index of target frequency
420 * @relation: how that frequency relates to achieved frequency
421 * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
422 * 420 *
423 * Sets a new CPUFreq policy. 421 * Sets a new CPUFreq policy.
424 */ 422 */
425static int centrino_target (struct cpufreq_policy *policy, 423static int centrino_target(struct cpufreq_policy *policy, unsigned int index)
426 unsigned int target_freq,
427 unsigned int relation)
428{ 424{
429 unsigned int newstate = 0;
430 unsigned int msr, oldmsr = 0, h = 0, cpu = policy->cpu; 425 unsigned int msr, oldmsr = 0, h = 0, cpu = policy->cpu;
431 struct cpufreq_freqs freqs; 426 struct cpufreq_freqs freqs;
432 int retval = 0; 427 int retval = 0;
433 unsigned int j, first_cpu, tmp; 428 unsigned int j, first_cpu, tmp;
429 struct cpufreq_frequency_table *op_points;
434 cpumask_var_t covered_cpus; 430 cpumask_var_t covered_cpus;
435 431
436 if (unlikely(!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL))) 432 if (unlikely(!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL)))
@@ -441,16 +437,8 @@ static int centrino_target (struct cpufreq_policy *policy,
441 goto out; 437 goto out;
442 } 438 }
443 439
444 if (unlikely(cpufreq_frequency_table_target(policy,
445 per_cpu(centrino_model, cpu)->op_points,
446 target_freq,
447 relation,
448 &newstate))) {
449 retval = -EINVAL;
450 goto out;
451 }
452
453 first_cpu = 1; 440 first_cpu = 1;
441 op_points = &per_cpu(centrino_model, cpu)->op_points[index];
454 for_each_cpu(j, policy->cpus) { 442 for_each_cpu(j, policy->cpus) {
455 int good_cpu; 443 int good_cpu;
456 444
@@ -474,7 +462,7 @@ static int centrino_target (struct cpufreq_policy *policy,
474 break; 462 break;
475 } 463 }
476 464
477 msr = per_cpu(centrino_model, cpu)->op_points[newstate].driver_data; 465 msr = op_points->driver_data;
478 466
479 if (first_cpu) { 467 if (first_cpu) {
480 rdmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, &oldmsr, &h); 468 rdmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, &oldmsr, &h);
@@ -489,7 +477,8 @@ static int centrino_target (struct cpufreq_policy *policy,
489 freqs.new = extract_clock(msr, cpu, 0); 477 freqs.new = extract_clock(msr, cpu, 0);
490 478
491 pr_debug("target=%dkHz old=%d new=%d msr=%04x\n", 479 pr_debug("target=%dkHz old=%d new=%d msr=%04x\n",
492 target_freq, freqs.old, freqs.new, msr); 480 op_points->frequency, freqs.old, freqs.new,
481 msr);
493 482
494 cpufreq_notify_transition(policy, &freqs, 483 cpufreq_notify_transition(policy, &freqs,
495 CPUFREQ_PRECHANGE); 484 CPUFREQ_PRECHANGE);
@@ -540,7 +529,7 @@ static struct cpufreq_driver centrino_driver = {
540 .init = centrino_cpu_init, 529 .init = centrino_cpu_init,
541 .exit = centrino_cpu_exit, 530 .exit = centrino_cpu_exit,
542 .verify = cpufreq_generic_frequency_table_verify, 531 .verify = cpufreq_generic_frequency_table_verify,
543 .target = centrino_target, 532 .target_index = centrino_target,
544 .get = get_cur_freq, 533 .get = get_cur_freq,
545 .attr = cpufreq_generic_attr, 534 .attr = cpufreq_generic_attr,
546}; 535};
diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c
index 1a8b01bd0fec..707721ebb853 100644
--- a/drivers/cpufreq/speedstep-ich.c
+++ b/drivers/cpufreq/speedstep-ich.c
@@ -251,36 +251,24 @@ static unsigned int speedstep_get(unsigned int cpu)
251/** 251/**
252 * speedstep_target - set a new CPUFreq policy 252 * speedstep_target - set a new CPUFreq policy
253 * @policy: new policy 253 * @policy: new policy
254 * @target_freq: the target frequency 254 * @index: index of target frequency
255 * @relation: how that frequency relates to achieved frequency
256 * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
257 * 255 *
258 * Sets a new CPUFreq policy. 256 * Sets a new CPUFreq policy.
259 */ 257 */
260static int speedstep_target(struct cpufreq_policy *policy, 258static int speedstep_target(struct cpufreq_policy *policy, unsigned int index)
261 unsigned int target_freq,
262 unsigned int relation)
263{ 259{
264 unsigned int newstate = 0, policy_cpu; 260 unsigned int policy_cpu;
265 struct cpufreq_freqs freqs; 261 struct cpufreq_freqs freqs;
266 262
267 if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0],
268 target_freq, relation, &newstate))
269 return -EINVAL;
270
271 policy_cpu = cpumask_any_and(policy->cpus, cpu_online_mask); 263 policy_cpu = cpumask_any_and(policy->cpus, cpu_online_mask);
272 freqs.old = speedstep_get(policy_cpu); 264 freqs.old = speedstep_get(policy_cpu);
273 freqs.new = speedstep_freqs[newstate].frequency; 265 freqs.new = speedstep_freqs[index].frequency;
274 266
275 pr_debug("transiting from %u to %u kHz\n", freqs.old, freqs.new); 267 pr_debug("transiting from %u to %u kHz\n", freqs.old, freqs.new);
276 268
277 /* no transition necessary */
278 if (freqs.old == freqs.new)
279 return 0;
280
281 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 269 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
282 270
283 smp_call_function_single(policy_cpu, _speedstep_set_state, &newstate, 271 smp_call_function_single(policy_cpu, _speedstep_set_state, &index,
284 true); 272 true);
285 273
286 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 274 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
@@ -330,7 +318,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
330static struct cpufreq_driver speedstep_driver = { 318static struct cpufreq_driver speedstep_driver = {
331 .name = "speedstep-ich", 319 .name = "speedstep-ich",
332 .verify = cpufreq_generic_frequency_table_verify, 320 .verify = cpufreq_generic_frequency_table_verify,
333 .target = speedstep_target, 321 .target_index = speedstep_target,
334 .init = speedstep_cpu_init, 322 .init = speedstep_cpu_init,
335 .exit = cpufreq_generic_exit, 323 .exit = cpufreq_generic_exit,
336 .get = speedstep_get, 324 .get = speedstep_get,
diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c
index a02b649c9647..19446e479ccc 100644
--- a/drivers/cpufreq/speedstep-smi.c
+++ b/drivers/cpufreq/speedstep-smi.c
@@ -235,29 +235,19 @@ static void speedstep_set_state(unsigned int state)
235/** 235/**
236 * speedstep_target - set a new CPUFreq policy 236 * speedstep_target - set a new CPUFreq policy
237 * @policy: new policy 237 * @policy: new policy
238 * @target_freq: new freq 238 * @index: index of new freq
239 * @relation:
240 * 239 *
241 * Sets a new CPUFreq policy/freq. 240 * Sets a new CPUFreq policy/freq.
242 */ 241 */
243static int speedstep_target(struct cpufreq_policy *policy, 242static int speedstep_target(struct cpufreq_policy *policy, unsigned int index)
244 unsigned int target_freq, unsigned int relation)
245{ 243{
246 unsigned int newstate = 0;
247 struct cpufreq_freqs freqs; 244 struct cpufreq_freqs freqs;
248 245
249 if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0],
250 target_freq, relation, &newstate))
251 return -EINVAL;
252
253 freqs.old = speedstep_freqs[speedstep_get_state()].frequency; 246 freqs.old = speedstep_freqs[speedstep_get_state()].frequency;
254 freqs.new = speedstep_freqs[newstate].frequency; 247 freqs.new = speedstep_freqs[index].frequency;
255
256 if (freqs.old == freqs.new)
257 return 0;
258 248
259 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 249 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
260 speedstep_set_state(newstate); 250 speedstep_set_state(index);
261 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 251 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
262 252
263 return 0; 253 return 0;
@@ -327,7 +317,7 @@ static int speedstep_resume(struct cpufreq_policy *policy)
327static struct cpufreq_driver speedstep_driver = { 317static struct cpufreq_driver speedstep_driver = {
328 .name = "speedstep-smi", 318 .name = "speedstep-smi",
329 .verify = cpufreq_generic_frequency_table_verify, 319 .verify = cpufreq_generic_frequency_table_verify,
330 .target = speedstep_target, 320 .target_index = speedstep_target,
331 .init = speedstep_cpu_init, 321 .init = speedstep_cpu_init,
332 .exit = cpufreq_generic_exit, 322 .exit = cpufreq_generic_exit,
333 .get = speedstep_get, 323 .get = speedstep_get,
diff --git a/drivers/cpufreq/tegra-cpufreq.c b/drivers/cpufreq/tegra-cpufreq.c
index 32483ef63d53..bd7d89c013a5 100644
--- a/drivers/cpufreq/tegra-cpufreq.c
+++ b/drivers/cpufreq/tegra-cpufreq.c
@@ -150,11 +150,8 @@ static unsigned long tegra_cpu_highest_speed(void)
150 return rate; 150 return rate;
151} 151}
152 152
153static int tegra_target(struct cpufreq_policy *policy, 153static int tegra_target(struct cpufreq_policy *policy, unsigned int index)
154 unsigned int target_freq,
155 unsigned int relation)
156{ 154{
157 unsigned int idx;
158 unsigned int freq; 155 unsigned int freq;
159 int ret = 0; 156 int ret = 0;
160 157
@@ -165,10 +162,7 @@ static int tegra_target(struct cpufreq_policy *policy,
165 goto out; 162 goto out;
166 } 163 }
167 164
168 cpufreq_frequency_table_target(policy, freq_table, target_freq, 165 freq = freq_table[index].frequency;
169 relation, &idx);
170
171 freq = freq_table[idx].frequency;
172 166
173 target_cpu_speed[policy->cpu] = freq; 167 target_cpu_speed[policy->cpu] = freq;
174 168
@@ -238,7 +232,7 @@ static int tegra_cpu_exit(struct cpufreq_policy *policy)
238 232
239static struct cpufreq_driver tegra_cpufreq_driver = { 233static struct cpufreq_driver tegra_cpufreq_driver = {
240 .verify = cpufreq_generic_frequency_table_verify, 234 .verify = cpufreq_generic_frequency_table_verify,
241 .target = tegra_target, 235 .target_index = tegra_target,
242 .get = tegra_getspeed, 236 .get = tegra_getspeed,
243 .init = tegra_cpu_init, 237 .init = tegra_cpu_init,
244 .exit = tegra_cpu_exit, 238 .exit = tegra_cpu_exit,
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 0aba2a6cadaf..e8c77d330479 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -187,9 +187,11 @@ struct cpufreq_driver {
187 187
188 /* define one out of two */ 188 /* define one out of two */
189 int (*setpolicy) (struct cpufreq_policy *policy); 189 int (*setpolicy) (struct cpufreq_policy *policy);
190 int (*target) (struct cpufreq_policy *policy, 190 int (*target) (struct cpufreq_policy *policy, /* Deprecated */
191 unsigned int target_freq, 191 unsigned int target_freq,
192 unsigned int relation); 192 unsigned int relation);
193 int (*target_index) (struct cpufreq_policy *policy,
194 unsigned int index);
193 195
194 /* should be defined, if possible */ 196 /* should be defined, if possible */
195 unsigned int (*get) (unsigned int cpu); 197 unsigned int (*get) (unsigned int cpu);