aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2014-01-09 10:08:43 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-01-16 20:00:44 -0500
commit652ed95d5fa6074b3c4ea245deb0691f1acb6656 (patch)
tree7b01079f3a582b0d6b08f541a8a344440bec8eae /drivers
parent0ad04fb30db0341d0b1134e2f592d9146c9abb64 (diff)
cpufreq: introduce cpufreq_generic_get() routine
CPUFreq drivers that use clock frameworks interface,i.e. clk_get_rate(), to get CPUs clk rate, have similar sort of code used in most of them. This patch adds a generic ->get() which will do the same thing for them. All those drivers are required to now is to set .get to cpufreq_generic_get() and set their clk pointer in policy->clk during ->init(). Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no> Acked-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/cpufreq/at32ap-cpufreq.c17
-rw-r--r--drivers/cpufreq/cpufreq-cpu0.c8
-rw-r--r--drivers/cpufreq/cpufreq.c26
-rw-r--r--drivers/cpufreq/davinci-cpufreq.c14
-rw-r--r--drivers/cpufreq/dbx500-cpufreq.c19
-rw-r--r--drivers/cpufreq/exynos-cpufreq.c10
-rw-r--r--drivers/cpufreq/exynos5440-cpufreq.c33
-rw-r--r--drivers/cpufreq/imx6q-cpufreq.c8
-rw-r--r--drivers/cpufreq/loongson2_cpufreq.c15
-rw-r--r--drivers/cpufreq/omap-cpufreq.c32
-rw-r--r--drivers/cpufreq/ppc-corenet-cpufreq.c17
-rw-r--r--drivers/cpufreq/s3c24xx-cpufreq.c10
-rw-r--r--drivers/cpufreq/s3c64xx-cpufreq.c33
-rw-r--r--drivers/cpufreq/s5pv210-cpufreq.c21
-rw-r--r--drivers/cpufreq/spear-cpufreq.c8
-rw-r--r--drivers/cpufreq/tegra-cpufreq.c48
-rw-r--r--drivers/cpufreq/unicore2-cpufreq.c19
17 files changed, 109 insertions, 229 deletions
diff --git a/drivers/cpufreq/at32ap-cpufreq.c b/drivers/cpufreq/at32ap-cpufreq.c
index 7c03dd84f66a..a1c79f549edb 100644
--- a/drivers/cpufreq/at32ap-cpufreq.c
+++ b/drivers/cpufreq/at32ap-cpufreq.c
@@ -21,17 +21,8 @@
21#include <linux/export.h> 21#include <linux/export.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23 23
24static struct clk *cpuclk;
25static struct cpufreq_frequency_table *freq_table; 24static struct cpufreq_frequency_table *freq_table;
26 25
27static unsigned int at32_get_speed(unsigned int cpu)
28{
29 /* No SMP support */
30 if (cpu)
31 return 0;
32 return (unsigned int)((clk_get_rate(cpuclk) + 500) / 1000);
33}
34
35static unsigned int ref_freq; 26static unsigned int ref_freq;
36static unsigned long loops_per_jiffy_ref; 27static unsigned long loops_per_jiffy_ref;
37 28
@@ -39,7 +30,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index)
39{ 30{
40 unsigned int old_freq, new_freq; 31 unsigned int old_freq, new_freq;
41 32
42 old_freq = at32_get_speed(0); 33 old_freq = policy->cur;
43 new_freq = freq_table[index].frequency; 34 new_freq = freq_table[index].frequency;
44 35
45 if (!ref_freq) { 36 if (!ref_freq) {
@@ -50,7 +41,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index)
50 if (old_freq < new_freq) 41 if (old_freq < new_freq)
51 boot_cpu_data.loops_per_jiffy = cpufreq_scale( 42 boot_cpu_data.loops_per_jiffy = cpufreq_scale(
52 loops_per_jiffy_ref, ref_freq, new_freq); 43 loops_per_jiffy_ref, ref_freq, new_freq);
53 clk_set_rate(cpuclk, new_freq * 1000); 44 clk_set_rate(policy->clk, new_freq * 1000);
54 if (new_freq < old_freq) 45 if (new_freq < old_freq)
55 boot_cpu_data.loops_per_jiffy = cpufreq_scale( 46 boot_cpu_data.loops_per_jiffy = cpufreq_scale(
56 loops_per_jiffy_ref, ref_freq, new_freq); 47 loops_per_jiffy_ref, ref_freq, new_freq);
@@ -61,6 +52,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index)
61static int at32_cpufreq_driver_init(struct cpufreq_policy *policy) 52static int at32_cpufreq_driver_init(struct cpufreq_policy *policy)
62{ 53{
63 unsigned int frequency, rate, min_freq; 54 unsigned int frequency, rate, min_freq;
55 static struct clk *cpuclk;
64 int retval, steps, i; 56 int retval, steps, i;
65 57
66 if (policy->cpu != 0) 58 if (policy->cpu != 0)
@@ -103,6 +95,7 @@ static int at32_cpufreq_driver_init(struct cpufreq_policy *policy)
103 frequency /= 2; 95 frequency /= 2;
104 } 96 }
105 97
98 policy->clk = cpuclk;
106 freq_table[steps - 1].frequency = CPUFREQ_TABLE_END; 99 freq_table[steps - 1].frequency = CPUFREQ_TABLE_END;
107 100
108 retval = cpufreq_table_validate_and_show(policy, freq_table); 101 retval = cpufreq_table_validate_and_show(policy, freq_table);
@@ -123,7 +116,7 @@ static struct cpufreq_driver at32_driver = {
123 .init = at32_cpufreq_driver_init, 116 .init = at32_cpufreq_driver_init,
124 .verify = cpufreq_generic_frequency_table_verify, 117 .verify = cpufreq_generic_frequency_table_verify,
125 .target_index = at32_set_target, 118 .target_index = at32_set_target,
126 .get = at32_get_speed, 119 .get = cpufreq_generic_get,
127 .flags = CPUFREQ_STICKY, 120 .flags = CPUFREQ_STICKY,
128}; 121};
129 122
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
index 0faf756f6197..bb7b3082efb3 100644
--- a/drivers/cpufreq/cpufreq-cpu0.c
+++ b/drivers/cpufreq/cpufreq-cpu0.c
@@ -30,11 +30,6 @@ static struct clk *cpu_clk;
30static struct regulator *cpu_reg; 30static struct regulator *cpu_reg;
31static struct cpufreq_frequency_table *freq_table; 31static struct cpufreq_frequency_table *freq_table;
32 32
33static unsigned int cpu0_get_speed(unsigned int cpu)
34{
35 return clk_get_rate(cpu_clk) / 1000;
36}
37
38static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index) 33static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
39{ 34{
40 struct dev_pm_opp *opp; 35 struct dev_pm_opp *opp;
@@ -100,6 +95,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
100 95
101static int cpu0_cpufreq_init(struct cpufreq_policy *policy) 96static int cpu0_cpufreq_init(struct cpufreq_policy *policy)
102{ 97{
98 policy->clk = cpu_clk;
103 return cpufreq_generic_init(policy, freq_table, transition_latency); 99 return cpufreq_generic_init(policy, freq_table, transition_latency);
104} 100}
105 101
@@ -107,7 +103,7 @@ static struct cpufreq_driver cpu0_cpufreq_driver = {
107 .flags = CPUFREQ_STICKY, 103 .flags = CPUFREQ_STICKY,
108 .verify = cpufreq_generic_frequency_table_verify, 104 .verify = cpufreq_generic_frequency_table_verify,
109 .target_index = cpu0_set_target, 105 .target_index = cpu0_set_target,
110 .get = cpu0_get_speed, 106 .get = cpufreq_generic_get,
111 .init = cpu0_cpufreq_init, 107 .init = cpu0_cpufreq_init,
112 .exit = cpufreq_generic_exit, 108 .exit = cpufreq_generic_exit,
113 .name = "generic_cpu0", 109 .name = "generic_cpu0",
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 1afbe52d6782..d7efdfe0c12c 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -176,6 +176,20 @@ int cpufreq_generic_init(struct cpufreq_policy *policy,
176} 176}
177EXPORT_SYMBOL_GPL(cpufreq_generic_init); 177EXPORT_SYMBOL_GPL(cpufreq_generic_init);
178 178
179unsigned int cpufreq_generic_get(unsigned int cpu)
180{
181 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
182
183 if (!policy || IS_ERR(policy->clk)) {
184 pr_err("%s: No %s associated to cpu: %d\n", __func__,
185 policy ? "clk" : "policy", cpu);
186 return 0;
187 }
188
189 return clk_get_rate(policy->clk) / 1000;
190}
191EXPORT_SYMBOL_GPL(cpufreq_generic_get);
192
179struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) 193struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
180{ 194{
181 struct cpufreq_policy *policy = NULL; 195 struct cpufreq_policy *policy = NULL;
@@ -1068,6 +1082,11 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
1068 goto err_set_policy_cpu; 1082 goto err_set_policy_cpu;
1069 } 1083 }
1070 1084
1085 write_lock_irqsave(&cpufreq_driver_lock, flags);
1086 for_each_cpu(j, policy->cpus)
1087 per_cpu(cpufreq_cpu_data, j) = policy;
1088 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1089
1071 if (cpufreq_driver->get) { 1090 if (cpufreq_driver->get) {
1072 policy->cur = cpufreq_driver->get(policy->cpu); 1091 policy->cur = cpufreq_driver->get(policy->cpu);
1073 if (!policy->cur) { 1092 if (!policy->cur) {
@@ -1142,11 +1161,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
1142 } 1161 }
1143#endif 1162#endif
1144 1163
1145 write_lock_irqsave(&cpufreq_driver_lock, flags);
1146 for_each_cpu(j, policy->cpus)
1147 per_cpu(cpufreq_cpu_data, j) = policy;
1148 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1149
1150 if (!frozen) { 1164 if (!frozen) {
1151 ret = cpufreq_add_dev_interface(policy, dev); 1165 ret = cpufreq_add_dev_interface(policy, dev);
1152 if (ret) 1166 if (ret)
@@ -1174,12 +1188,12 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
1174 return 0; 1188 return 0;
1175 1189
1176err_out_unregister: 1190err_out_unregister:
1191err_get_freq:
1177 write_lock_irqsave(&cpufreq_driver_lock, flags); 1192 write_lock_irqsave(&cpufreq_driver_lock, flags);
1178 for_each_cpu(j, policy->cpus) 1193 for_each_cpu(j, policy->cpus)
1179 per_cpu(cpufreq_cpu_data, j) = NULL; 1194 per_cpu(cpufreq_cpu_data, j) = NULL;
1180 write_unlock_irqrestore(&cpufreq_driver_lock, flags); 1195 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1181 1196
1182err_get_freq:
1183 if (cpufreq_driver->exit) 1197 if (cpufreq_driver->exit)
1184 cpufreq_driver->exit(policy); 1198 cpufreq_driver->exit(policy);
1185err_set_policy_cpu: 1199err_set_policy_cpu:
diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c
index 04f3390a7a2c..2cf33848d86e 100644
--- a/drivers/cpufreq/davinci-cpufreq.c
+++ b/drivers/cpufreq/davinci-cpufreq.c
@@ -58,14 +58,6 @@ static int davinci_verify_speed(struct cpufreq_policy *policy)
58 return 0; 58 return 0;
59} 59}
60 60
61static unsigned int davinci_getspeed(unsigned int cpu)
62{
63 if (cpu)
64 return 0;
65
66 return clk_get_rate(cpufreq.armclk) / 1000;
67}
68
69static int davinci_target(struct cpufreq_policy *policy, unsigned int idx) 61static int davinci_target(struct cpufreq_policy *policy, unsigned int idx)
70{ 62{
71 struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; 63 struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
@@ -73,7 +65,7 @@ static int davinci_target(struct cpufreq_policy *policy, unsigned int idx)
73 unsigned int old_freq, new_freq; 65 unsigned int old_freq, new_freq;
74 int ret = 0; 66 int ret = 0;
75 67
76 old_freq = davinci_getspeed(0); 68 old_freq = policy->cur;
77 new_freq = pdata->freq_table[idx].frequency; 69 new_freq = pdata->freq_table[idx].frequency;
78 70
79 /* if moving to higher frequency, up the voltage beforehand */ 71 /* if moving to higher frequency, up the voltage beforehand */
@@ -116,6 +108,8 @@ static int davinci_cpu_init(struct cpufreq_policy *policy)
116 return result; 108 return result;
117 } 109 }
118 110
111 policy->clk = cpufreq.armclk;
112
119 /* 113 /*
120 * Time measurement across the target() function yields ~1500-1800us 114 * Time measurement across the target() function yields ~1500-1800us
121 * time taken with no drivers on notification list. 115 * time taken with no drivers on notification list.
@@ -129,7 +123,7 @@ static struct cpufreq_driver davinci_driver = {
129 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, 123 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
130 .verify = davinci_verify_speed, 124 .verify = davinci_verify_speed,
131 .target_index = davinci_target, 125 .target_index = davinci_target,
132 .get = davinci_getspeed, 126 .get = cpufreq_generic_get,
133 .init = davinci_cpu_init, 127 .init = davinci_cpu_init,
134 .exit = cpufreq_generic_exit, 128 .exit = cpufreq_generic_exit,
135 .name = "davinci", 129 .name = "davinci",
diff --git a/drivers/cpufreq/dbx500-cpufreq.c b/drivers/cpufreq/dbx500-cpufreq.c
index 21d9898e000c..412a78bb0c94 100644
--- a/drivers/cpufreq/dbx500-cpufreq.c
+++ b/drivers/cpufreq/dbx500-cpufreq.c
@@ -26,24 +26,9 @@ static int dbx500_cpufreq_target(struct cpufreq_policy *policy,
26 return clk_set_rate(armss_clk, freq_table[index].frequency * 1000); 26 return clk_set_rate(armss_clk, freq_table[index].frequency * 1000);
27} 27}
28 28
29static unsigned int dbx500_cpufreq_getspeed(unsigned int cpu)
30{
31 int i = 0;
32 unsigned long freq = clk_get_rate(armss_clk) / 1000;
33
34 /* The value is rounded to closest frequency in the defined table. */
35 while (freq_table[i + 1].frequency != CPUFREQ_TABLE_END) {
36 if (freq < freq_table[i].frequency +
37 (freq_table[i + 1].frequency - freq_table[i].frequency) / 2)
38 return freq_table[i].frequency;
39 i++;
40 }
41
42 return freq_table[i].frequency;
43}
44
45static int dbx500_cpufreq_init(struct cpufreq_policy *policy) 29static int dbx500_cpufreq_init(struct cpufreq_policy *policy)
46{ 30{
31 policy->clk = armss_clk;
47 return cpufreq_generic_init(policy, freq_table, 20 * 1000); 32 return cpufreq_generic_init(policy, freq_table, 20 * 1000);
48} 33}
49 34
@@ -52,7 +37,7 @@ static struct cpufreq_driver dbx500_cpufreq_driver = {
52 CPUFREQ_NEED_INITIAL_FREQ_CHECK, 37 CPUFREQ_NEED_INITIAL_FREQ_CHECK,
53 .verify = cpufreq_generic_frequency_table_verify, 38 .verify = cpufreq_generic_frequency_table_verify,
54 .target_index = dbx500_cpufreq_target, 39 .target_index = dbx500_cpufreq_target,
55 .get = dbx500_cpufreq_getspeed, 40 .get = cpufreq_generic_get,
56 .init = dbx500_cpufreq_init, 41 .init = dbx500_cpufreq_init,
57 .name = "DBX500", 42 .name = "DBX500",
58 .attr = cpufreq_generic_attr, 43 .attr = cpufreq_generic_attr,
diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
index f7c322c7d7ed..4ee3804637be 100644
--- a/drivers/cpufreq/exynos-cpufreq.c
+++ b/drivers/cpufreq/exynos-cpufreq.c
@@ -31,11 +31,6 @@ static unsigned int locking_frequency;
31static bool frequency_locked; 31static bool frequency_locked;
32static DEFINE_MUTEX(cpufreq_lock); 32static DEFINE_MUTEX(cpufreq_lock);
33 33
34static unsigned int exynos_getspeed(unsigned int cpu)
35{
36 return clk_get_rate(exynos_info->cpu_clk) / 1000;
37}
38
39static int exynos_cpufreq_get_index(unsigned int freq) 34static int exynos_cpufreq_get_index(unsigned int freq)
40{ 35{
41 struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; 36 struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
@@ -215,6 +210,7 @@ static struct notifier_block exynos_cpufreq_nb = {
215 210
216static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) 211static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
217{ 212{
213 policy->clk = exynos_info->cpu_clk;
218 return cpufreq_generic_init(policy, exynos_info->freq_table, 100000); 214 return cpufreq_generic_init(policy, exynos_info->freq_table, 100000);
219} 215}
220 216
@@ -222,7 +218,7 @@ static struct cpufreq_driver exynos_driver = {
222 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, 218 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
223 .verify = cpufreq_generic_frequency_table_verify, 219 .verify = cpufreq_generic_frequency_table_verify,
224 .target_index = exynos_target, 220 .target_index = exynos_target,
225 .get = exynos_getspeed, 221 .get = cpufreq_generic_get,
226 .init = exynos_cpufreq_cpu_init, 222 .init = exynos_cpufreq_cpu_init,
227 .exit = cpufreq_generic_exit, 223 .exit = cpufreq_generic_exit,
228 .name = "exynos_cpufreq", 224 .name = "exynos_cpufreq",
@@ -264,7 +260,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev)
264 goto err_vdd_arm; 260 goto err_vdd_arm;
265 } 261 }
266 262
267 locking_frequency = exynos_getspeed(0); 263 locking_frequency = clk_get_rate(exynos_info->cpu_clk) / 1000;
268 264
269 register_pm_notifier(&exynos_cpufreq_nb); 265 register_pm_notifier(&exynos_cpufreq_nb);
270 266
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c
index ffe6faea3a5f..49b756015316 100644
--- a/drivers/cpufreq/exynos5440-cpufreq.c
+++ b/drivers/cpufreq/exynos5440-cpufreq.c
@@ -100,7 +100,6 @@ struct exynos_dvfs_data {
100 struct resource *mem; 100 struct resource *mem;
101 int irq; 101 int irq;
102 struct clk *cpu_clk; 102 struct clk *cpu_clk;
103 unsigned int cur_frequency;
104 unsigned int latency; 103 unsigned int latency;
105 struct cpufreq_frequency_table *freq_table; 104 struct cpufreq_frequency_table *freq_table;
106 unsigned int freq_count; 105 unsigned int freq_count;
@@ -165,7 +164,7 @@ static int init_div_table(void)
165 return 0; 164 return 0;
166} 165}
167 166
168static void exynos_enable_dvfs(void) 167static void exynos_enable_dvfs(unsigned int cur_frequency)
169{ 168{
170 unsigned int tmp, i, cpu; 169 unsigned int tmp, i, cpu;
171 struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; 170 struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table;
@@ -184,18 +183,18 @@ static void exynos_enable_dvfs(void)
184 183
185 /* Set initial performance index */ 184 /* Set initial performance index */
186 for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) 185 for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++)
187 if (freq_table[i].frequency == dvfs_info->cur_frequency) 186 if (freq_table[i].frequency == cur_frequency)
188 break; 187 break;
189 188
190 if (freq_table[i].frequency == CPUFREQ_TABLE_END) { 189 if (freq_table[i].frequency == CPUFREQ_TABLE_END) {
191 dev_crit(dvfs_info->dev, "Boot up frequency not supported\n"); 190 dev_crit(dvfs_info->dev, "Boot up frequency not supported\n");
192 /* Assign the highest frequency */ 191 /* Assign the highest frequency */
193 i = 0; 192 i = 0;
194 dvfs_info->cur_frequency = freq_table[i].frequency; 193 cur_frequency = freq_table[i].frequency;
195 } 194 }
196 195
197 dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ", 196 dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ",
198 dvfs_info->cur_frequency); 197 cur_frequency);
199 198
200 for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) { 199 for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) {
201 tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); 200 tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4);
@@ -209,11 +208,6 @@ static void exynos_enable_dvfs(void)
209 dvfs_info->base + XMU_DVFS_CTRL); 208 dvfs_info->base + XMU_DVFS_CTRL);
210} 209}
211 210
212static unsigned int exynos_getspeed(unsigned int cpu)
213{
214 return dvfs_info->cur_frequency;
215}
216
217static int exynos_target(struct cpufreq_policy *policy, unsigned int index) 211static int exynos_target(struct cpufreq_policy *policy, unsigned int index)
218{ 212{
219 unsigned int tmp; 213 unsigned int tmp;
@@ -222,7 +216,7 @@ static int exynos_target(struct cpufreq_policy *policy, unsigned int index)
222 216
223 mutex_lock(&cpufreq_lock); 217 mutex_lock(&cpufreq_lock);
224 218
225 freqs.old = dvfs_info->cur_frequency; 219 freqs.old = policy->cur;
226 freqs.new = freq_table[index].frequency; 220 freqs.new = freq_table[index].frequency;
227 221
228 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 222 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
@@ -250,7 +244,7 @@ static void exynos_cpufreq_work(struct work_struct *work)
250 goto skip_work; 244 goto skip_work;
251 245
252 mutex_lock(&cpufreq_lock); 246 mutex_lock(&cpufreq_lock);
253 freqs.old = dvfs_info->cur_frequency; 247 freqs.old = policy->cur;
254 248
255 cur_pstate = __raw_readl(dvfs_info->base + XMU_P_STATUS); 249 cur_pstate = __raw_readl(dvfs_info->base + XMU_P_STATUS);
256 if (cur_pstate >> C0_3_PSTATE_VALID_SHIFT & 0x1) 250 if (cur_pstate >> C0_3_PSTATE_VALID_SHIFT & 0x1)
@@ -260,10 +254,9 @@ static void exynos_cpufreq_work(struct work_struct *work)
260 254
261 if (likely(index < dvfs_info->freq_count)) { 255 if (likely(index < dvfs_info->freq_count)) {
262 freqs.new = freq_table[index].frequency; 256 freqs.new = freq_table[index].frequency;
263 dvfs_info->cur_frequency = freqs.new;
264 } else { 257 } else {
265 dev_crit(dvfs_info->dev, "New frequency out of range\n"); 258 dev_crit(dvfs_info->dev, "New frequency out of range\n");
266 freqs.new = dvfs_info->cur_frequency; 259 freqs.new = freqs.old;
267 } 260 }
268 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 261 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
269 262
@@ -307,6 +300,7 @@ static void exynos_sort_descend_freq_table(void)
307 300
308static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) 301static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
309{ 302{
303 policy->clk = dvfs_info->cpu_clk;
310 return cpufreq_generic_init(policy, dvfs_info->freq_table, 304 return cpufreq_generic_init(policy, dvfs_info->freq_table,
311 dvfs_info->latency); 305 dvfs_info->latency);
312} 306}
@@ -316,7 +310,7 @@ static struct cpufreq_driver exynos_driver = {
316 CPUFREQ_NEED_INITIAL_FREQ_CHECK, 310 CPUFREQ_NEED_INITIAL_FREQ_CHECK,
317 .verify = cpufreq_generic_frequency_table_verify, 311 .verify = cpufreq_generic_frequency_table_verify,
318 .target_index = exynos_target, 312 .target_index = exynos_target,
319 .get = exynos_getspeed, 313 .get = cpufreq_generic_get,
320 .init = exynos_cpufreq_cpu_init, 314 .init = exynos_cpufreq_cpu_init,
321 .exit = cpufreq_generic_exit, 315 .exit = cpufreq_generic_exit,
322 .name = CPUFREQ_NAME, 316 .name = CPUFREQ_NAME,
@@ -336,6 +330,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev)
336 int ret = -EINVAL; 330 int ret = -EINVAL;
337 struct device_node *np; 331 struct device_node *np;
338 struct resource res; 332 struct resource res;
333 unsigned int cur_frequency;
339 334
340 np = pdev->dev.of_node; 335 np = pdev->dev.of_node;
341 if (!np) 336 if (!np)
@@ -392,13 +387,13 @@ static int exynos_cpufreq_probe(struct platform_device *pdev)
392 goto err_free_table; 387 goto err_free_table;
393 } 388 }
394 389
395 dvfs_info->cur_frequency = clk_get_rate(dvfs_info->cpu_clk); 390 cur_frequency = clk_get_rate(dvfs_info->cpu_clk);
396 if (!dvfs_info->cur_frequency) { 391 if (!cur_frequency) {
397 dev_err(dvfs_info->dev, "Failed to get clock rate\n"); 392 dev_err(dvfs_info->dev, "Failed to get clock rate\n");
398 ret = -EINVAL; 393 ret = -EINVAL;
399 goto err_free_table; 394 goto err_free_table;
400 } 395 }
401 dvfs_info->cur_frequency /= 1000; 396 cur_frequency /= 1000;
402 397
403 INIT_WORK(&dvfs_info->irq_work, exynos_cpufreq_work); 398 INIT_WORK(&dvfs_info->irq_work, exynos_cpufreq_work);
404 ret = devm_request_irq(dvfs_info->dev, dvfs_info->irq, 399 ret = devm_request_irq(dvfs_info->dev, dvfs_info->irq,
@@ -415,7 +410,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev)
415 goto err_free_table; 410 goto err_free_table;
416 } 411 }
417 412
418 exynos_enable_dvfs(); 413 exynos_enable_dvfs(cur_frequency);
419 ret = cpufreq_register_driver(&exynos_driver); 414 ret = cpufreq_register_driver(&exynos_driver);
420 if (ret) { 415 if (ret) {
421 dev_err(dvfs_info->dev, 416 dev_err(dvfs_info->dev,
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index 2938257b8c19..ce69059be1fc 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -38,11 +38,6 @@ static unsigned int transition_latency;
38static u32 *imx6_soc_volt; 38static u32 *imx6_soc_volt;
39static u32 soc_opp_count; 39static u32 soc_opp_count;
40 40
41static unsigned int imx6q_get_speed(unsigned int cpu)
42{
43 return clk_get_rate(arm_clk) / 1000;
44}
45
46static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) 41static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
47{ 42{
48 struct dev_pm_opp *opp; 43 struct dev_pm_opp *opp;
@@ -139,6 +134,7 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
139 134
140static int imx6q_cpufreq_init(struct cpufreq_policy *policy) 135static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
141{ 136{
137 policy->clk = arm_clk;
142 return cpufreq_generic_init(policy, freq_table, transition_latency); 138 return cpufreq_generic_init(policy, freq_table, transition_latency);
143} 139}
144 140
@@ -146,7 +142,7 @@ static struct cpufreq_driver imx6q_cpufreq_driver = {
146 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, 142 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
147 .verify = cpufreq_generic_frequency_table_verify, 143 .verify = cpufreq_generic_frequency_table_verify,
148 .target_index = imx6q_set_target, 144 .target_index = imx6q_set_target,
149 .get = imx6q_get_speed, 145 .get = cpufreq_generic_get,
150 .init = imx6q_cpufreq_init, 146 .init = imx6q_cpufreq_init,
151 .exit = cpufreq_generic_exit, 147 .exit = cpufreq_generic_exit,
152 .name = "imx6q-cpufreq", 148 .name = "imx6q-cpufreq",
diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c
index a43609218105..b6581abc9207 100644
--- a/drivers/cpufreq/loongson2_cpufreq.c
+++ b/drivers/cpufreq/loongson2_cpufreq.c
@@ -24,8 +24,6 @@
24 24
25static uint nowait; 25static uint nowait;
26 26
27static struct clk *cpuclk;
28
29static void (*saved_cpu_wait) (void); 27static void (*saved_cpu_wait) (void);
30 28
31static int loongson2_cpu_freq_notifier(struct notifier_block *nb, 29static int loongson2_cpu_freq_notifier(struct notifier_block *nb,
@@ -44,11 +42,6 @@ static int loongson2_cpu_freq_notifier(struct notifier_block *nb,
44 return 0; 42 return 0;
45} 43}
46 44
47static unsigned int loongson2_cpufreq_get(unsigned int cpu)
48{
49 return clk_get_rate(cpuclk);
50}
51
52/* 45/*
53 * Here we notify other drivers of the proposed change and the final change. 46 * Here we notify other drivers of the proposed change and the final change.
54 */ 47 */
@@ -69,13 +62,14 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy,
69 set_cpus_allowed_ptr(current, &cpus_allowed); 62 set_cpus_allowed_ptr(current, &cpus_allowed);
70 63
71 /* setting the cpu frequency */ 64 /* setting the cpu frequency */
72 clk_set_rate(cpuclk, freq); 65 clk_set_rate(policy->clk, freq);
73 66
74 return 0; 67 return 0;
75} 68}
76 69
77static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) 70static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy)
78{ 71{
72 static struct clk *cpuclk;
79 int i; 73 int i;
80 unsigned long rate; 74 unsigned long rate;
81 int ret; 75 int ret;
@@ -104,13 +98,14 @@ static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy)
104 return ret; 98 return ret;
105 } 99 }
106 100
101 policy->clk = cpuclk;
107 return cpufreq_generic_init(policy, &loongson2_clockmod_table[0], 0); 102 return cpufreq_generic_init(policy, &loongson2_clockmod_table[0], 0);
108} 103}
109 104
110static int loongson2_cpufreq_exit(struct cpufreq_policy *policy) 105static int loongson2_cpufreq_exit(struct cpufreq_policy *policy)
111{ 106{
112 cpufreq_frequency_table_put_attr(policy->cpu); 107 cpufreq_frequency_table_put_attr(policy->cpu);
113 clk_put(cpuclk); 108 clk_put(policy->clk);
114 return 0; 109 return 0;
115} 110}
116 111
@@ -119,7 +114,7 @@ static struct cpufreq_driver loongson2_cpufreq_driver = {
119 .init = loongson2_cpufreq_cpu_init, 114 .init = loongson2_cpufreq_cpu_init,
120 .verify = cpufreq_generic_frequency_table_verify, 115 .verify = cpufreq_generic_frequency_table_verify,
121 .target_index = loongson2_cpufreq_target, 116 .target_index = loongson2_cpufreq_target,
122 .get = loongson2_cpufreq_get, 117 .get = cpufreq_generic_get,
123 .exit = loongson2_cpufreq_exit, 118 .exit = loongson2_cpufreq_exit,
124 .attr = cpufreq_generic_attr, 119 .attr = cpufreq_generic_attr,
125}; 120};
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 5de1e5f73eca..590f5b66d181 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -36,21 +36,9 @@
36 36
37static struct cpufreq_frequency_table *freq_table; 37static struct cpufreq_frequency_table *freq_table;
38static atomic_t freq_table_users = ATOMIC_INIT(0); 38static atomic_t freq_table_users = ATOMIC_INIT(0);
39static struct clk *mpu_clk;
40static struct device *mpu_dev; 39static struct device *mpu_dev;
41static struct regulator *mpu_reg; 40static struct regulator *mpu_reg;
42 41
43static unsigned int omap_getspeed(unsigned int cpu)
44{
45 unsigned long rate;
46
47 if (cpu >= NR_CPUS)
48 return 0;
49
50 rate = clk_get_rate(mpu_clk) / 1000;
51 return rate;
52}
53
54static int omap_target(struct cpufreq_policy *policy, unsigned int index) 42static int omap_target(struct cpufreq_policy *policy, unsigned int index)
55{ 43{
56 int r, ret; 44 int r, ret;
@@ -58,11 +46,11 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index)
58 unsigned long freq, volt = 0, volt_old = 0, tol = 0; 46 unsigned long freq, volt = 0, volt_old = 0, tol = 0;
59 unsigned int old_freq, new_freq; 47 unsigned int old_freq, new_freq;
60 48
61 old_freq = omap_getspeed(policy->cpu); 49 old_freq = policy->cur;
62 new_freq = freq_table[index].frequency; 50 new_freq = freq_table[index].frequency;
63 51
64 freq = new_freq * 1000; 52 freq = new_freq * 1000;
65 ret = clk_round_rate(mpu_clk, freq); 53 ret = clk_round_rate(policy->clk, freq);
66 if (IS_ERR_VALUE(ret)) { 54 if (IS_ERR_VALUE(ret)) {
67 dev_warn(mpu_dev, 55 dev_warn(mpu_dev,
68 "CPUfreq: Cannot find matching frequency for %lu\n", 56 "CPUfreq: Cannot find matching frequency for %lu\n",
@@ -100,7 +88,7 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index)
100 } 88 }
101 } 89 }
102 90
103 ret = clk_set_rate(mpu_clk, new_freq * 1000); 91 ret = clk_set_rate(policy->clk, new_freq * 1000);
104 92
105 /* scaling down? scale voltage after frequency */ 93 /* scaling down? scale voltage after frequency */
106 if (mpu_reg && (new_freq < old_freq)) { 94 if (mpu_reg && (new_freq < old_freq)) {
@@ -108,7 +96,7 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index)
108 if (r < 0) { 96 if (r < 0) {
109 dev_warn(mpu_dev, "%s: unable to scale voltage down.\n", 97 dev_warn(mpu_dev, "%s: unable to scale voltage down.\n",
110 __func__); 98 __func__);
111 clk_set_rate(mpu_clk, old_freq * 1000); 99 clk_set_rate(policy->clk, old_freq * 1000);
112 return r; 100 return r;
113 } 101 }
114 } 102 }
@@ -126,9 +114,9 @@ static int omap_cpu_init(struct cpufreq_policy *policy)
126{ 114{
127 int result; 115 int result;
128 116
129 mpu_clk = clk_get(NULL, "cpufreq_ck"); 117 policy->clk = clk_get(NULL, "cpufreq_ck");
130 if (IS_ERR(mpu_clk)) 118 if (IS_ERR(policy->clk))
131 return PTR_ERR(mpu_clk); 119 return PTR_ERR(policy->clk);
132 120
133 if (!freq_table) { 121 if (!freq_table) {
134 result = dev_pm_opp_init_cpufreq_table(mpu_dev, &freq_table); 122 result = dev_pm_opp_init_cpufreq_table(mpu_dev, &freq_table);
@@ -149,7 +137,7 @@ static int omap_cpu_init(struct cpufreq_policy *policy)
149 137
150 freq_table_free(); 138 freq_table_free();
151fail: 139fail:
152 clk_put(mpu_clk); 140 clk_put(policy->clk);
153 return result; 141 return result;
154} 142}
155 143
@@ -157,7 +145,7 @@ static int omap_cpu_exit(struct cpufreq_policy *policy)
157{ 145{
158 cpufreq_frequency_table_put_attr(policy->cpu); 146 cpufreq_frequency_table_put_attr(policy->cpu);
159 freq_table_free(); 147 freq_table_free();
160 clk_put(mpu_clk); 148 clk_put(policy->clk);
161 return 0; 149 return 0;
162} 150}
163 151
@@ -165,7 +153,7 @@ static struct cpufreq_driver omap_driver = {
165 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, 153 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
166 .verify = cpufreq_generic_frequency_table_verify, 154 .verify = cpufreq_generic_frequency_table_verify,
167 .target_index = omap_target, 155 .target_index = omap_target,
168 .get = omap_getspeed, 156 .get = cpufreq_generic_get,
169 .init = omap_cpu_init, 157 .init = omap_cpu_init,
170 .exit = omap_cpu_exit, 158 .exit = omap_cpu_exit,
171 .name = "omap", 159 .name = "omap",
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c
index 3f7be46d2b27..051000f44ca2 100644
--- a/drivers/cpufreq/ppc-corenet-cpufreq.c
+++ b/drivers/cpufreq/ppc-corenet-cpufreq.c
@@ -24,12 +24,10 @@
24 24
25/** 25/**
26 * struct cpu_data - per CPU data struct 26 * struct cpu_data - per CPU data struct
27 * @clk: the clk of CPU
28 * @parent: the parent node of cpu clock 27 * @parent: the parent node of cpu clock
29 * @table: frequency table 28 * @table: frequency table
30 */ 29 */
31struct cpu_data { 30struct cpu_data {
32 struct clk *clk;
33 struct device_node *parent; 31 struct device_node *parent;
34 struct cpufreq_frequency_table *table; 32 struct cpufreq_frequency_table *table;
35}; 33};
@@ -81,13 +79,6 @@ static inline const struct cpumask *cpu_core_mask(int cpu)
81} 79}
82#endif 80#endif
83 81
84static unsigned int corenet_cpufreq_get_speed(unsigned int cpu)
85{
86 struct cpu_data *data = per_cpu(cpu_data, cpu);
87
88 return clk_get_rate(data->clk) / 1000;
89}
90
91/* reduce the duplicated frequencies in frequency table */ 82/* reduce the duplicated frequencies in frequency table */
92static void freq_table_redup(struct cpufreq_frequency_table *freq_table, 83static void freq_table_redup(struct cpufreq_frequency_table *freq_table,
93 int count) 84 int count)
@@ -158,8 +149,8 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
158 goto err_np; 149 goto err_np;
159 } 150 }
160 151
161 data->clk = of_clk_get(np, 0); 152 policy->clk = of_clk_get(np, 0);
162 if (IS_ERR(data->clk)) { 153 if (IS_ERR(policy->clk)) {
163 pr_err("%s: no clock information\n", __func__); 154 pr_err("%s: no clock information\n", __func__);
164 goto err_nomem2; 155 goto err_nomem2;
165 } 156 }
@@ -255,7 +246,7 @@ static int corenet_cpufreq_target(struct cpufreq_policy *policy,
255 struct cpu_data *data = per_cpu(cpu_data, policy->cpu); 246 struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
256 247
257 parent = of_clk_get(data->parent, data->table[index].driver_data); 248 parent = of_clk_get(data->parent, data->table[index].driver_data);
258 return clk_set_parent(data->clk, parent); 249 return clk_set_parent(policy->clk, parent);
259} 250}
260 251
261static struct cpufreq_driver ppc_corenet_cpufreq_driver = { 252static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
@@ -265,7 +256,7 @@ static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
265 .exit = __exit_p(corenet_cpufreq_cpu_exit), 256 .exit = __exit_p(corenet_cpufreq_cpu_exit),
266 .verify = cpufreq_generic_frequency_table_verify, 257 .verify = cpufreq_generic_frequency_table_verify,
267 .target_index = corenet_cpufreq_target, 258 .target_index = corenet_cpufreq_target,
268 .get = corenet_cpufreq_get_speed, 259 .get = cpufreq_generic_get,
269 .attr = cpufreq_generic_attr, 260 .attr = cpufreq_generic_attr,
270}; 261};
271 262
diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c
index 6a1bf96deec0..25069741b507 100644
--- a/drivers/cpufreq/s3c24xx-cpufreq.c
+++ b/drivers/cpufreq/s3c24xx-cpufreq.c
@@ -355,11 +355,6 @@ static int s3c_cpufreq_target(struct cpufreq_policy *policy,
355 return -EINVAL; 355 return -EINVAL;
356} 356}
357 357
358static unsigned int s3c_cpufreq_get(unsigned int cpu)
359{
360 return clk_get_rate(clk_arm) / 1000;
361}
362
363struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) 358struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name)
364{ 359{
365 struct clk *clk; 360 struct clk *clk;
@@ -373,6 +368,7 @@ struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name)
373 368
374static int s3c_cpufreq_init(struct cpufreq_policy *policy) 369static int s3c_cpufreq_init(struct cpufreq_policy *policy)
375{ 370{
371 policy->clk = clk_arm;
376 return cpufreq_generic_init(policy, ftab, cpu_cur.info->latency); 372 return cpufreq_generic_init(policy, ftab, cpu_cur.info->latency);
377} 373}
378 374
@@ -408,7 +404,7 @@ static int s3c_cpufreq_suspend(struct cpufreq_policy *policy)
408{ 404{
409 suspend_pll.frequency = clk_get_rate(_clk_mpll); 405 suspend_pll.frequency = clk_get_rate(_clk_mpll);
410 suspend_pll.driver_data = __raw_readl(S3C2410_MPLLCON); 406 suspend_pll.driver_data = __raw_readl(S3C2410_MPLLCON);
411 suspend_freq = s3c_cpufreq_get(0) * 1000; 407 suspend_freq = clk_get_rate(clk_arm);
412 408
413 return 0; 409 return 0;
414} 410}
@@ -450,7 +446,7 @@ static int s3c_cpufreq_resume(struct cpufreq_policy *policy)
450static struct cpufreq_driver s3c24xx_driver = { 446static struct cpufreq_driver s3c24xx_driver = {
451 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, 447 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
452 .target = s3c_cpufreq_target, 448 .target = s3c_cpufreq_target,
453 .get = s3c_cpufreq_get, 449 .get = cpufreq_generic_get,
454 .init = s3c_cpufreq_init, 450 .init = s3c_cpufreq_init,
455 .suspend = s3c_cpufreq_suspend, 451 .suspend = s3c_cpufreq_suspend,
456 .resume = s3c_cpufreq_resume, 452 .resume = s3c_cpufreq_resume,
diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c
index 8435f45d7e9d..c4226de079ab 100644
--- a/drivers/cpufreq/s3c64xx-cpufreq.c
+++ b/drivers/cpufreq/s3c64xx-cpufreq.c
@@ -19,7 +19,6 @@
19#include <linux/regulator/consumer.h> 19#include <linux/regulator/consumer.h>
20#include <linux/module.h> 20#include <linux/module.h>
21 21
22static struct clk *armclk;
23static struct regulator *vddarm; 22static struct regulator *vddarm;
24static unsigned long regulator_latency; 23static unsigned long regulator_latency;
25 24
@@ -54,14 +53,6 @@ static struct cpufreq_frequency_table s3c64xx_freq_table[] = {
54}; 53};
55#endif 54#endif
56 55
57static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu)
58{
59 if (cpu != 0)
60 return 0;
61
62 return clk_get_rate(armclk) / 1000;
63}
64
65static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, 56static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
66 unsigned int index) 57 unsigned int index)
67{ 58{
@@ -69,7 +60,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
69 unsigned int old_freq, new_freq; 60 unsigned int old_freq, new_freq;
70 int ret; 61 int ret;
71 62
72 old_freq = clk_get_rate(armclk) / 1000; 63 old_freq = clk_get_rate(policy->clk) / 1000;
73 new_freq = s3c64xx_freq_table[index].frequency; 64 new_freq = s3c64xx_freq_table[index].frequency;
74 dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data]; 65 dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data];
75 66
@@ -86,7 +77,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
86 } 77 }
87#endif 78#endif
88 79
89 ret = clk_set_rate(armclk, new_freq * 1000); 80 ret = clk_set_rate(policy->clk, new_freq * 1000);
90 if (ret < 0) { 81 if (ret < 0) {
91 pr_err("Failed to set rate %dkHz: %d\n", 82 pr_err("Failed to set rate %dkHz: %d\n",
92 new_freq, ret); 83 new_freq, ret);
@@ -101,7 +92,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
101 if (ret != 0) { 92 if (ret != 0) {
102 pr_err("Failed to set VDDARM for %dkHz: %d\n", 93 pr_err("Failed to set VDDARM for %dkHz: %d\n",
103 new_freq, ret); 94 new_freq, ret);
104 if (clk_set_rate(armclk, old_freq * 1000) < 0) 95 if (clk_set_rate(policy->clk, old_freq * 1000) < 0)
105 pr_err("Failed to restore original clock rate\n"); 96 pr_err("Failed to restore original clock rate\n");
106 97
107 return ret; 98 return ret;
@@ -110,7 +101,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
110#endif 101#endif
111 102
112 pr_debug("Set actual frequency %lukHz\n", 103 pr_debug("Set actual frequency %lukHz\n",
113 clk_get_rate(armclk) / 1000); 104 clk_get_rate(policy->clk) / 1000);
114 105
115 return 0; 106 return 0;
116} 107}
@@ -169,11 +160,11 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
169 return -ENODEV; 160 return -ENODEV;
170 } 161 }
171 162
172 armclk = clk_get(NULL, "armclk"); 163 policy->clk = clk_get(NULL, "armclk");
173 if (IS_ERR(armclk)) { 164 if (IS_ERR(policy->clk)) {
174 pr_err("Unable to obtain ARMCLK: %ld\n", 165 pr_err("Unable to obtain ARMCLK: %ld\n",
175 PTR_ERR(armclk)); 166 PTR_ERR(policy->clk));
176 return PTR_ERR(armclk); 167 return PTR_ERR(policy->clk);
177 } 168 }
178 169
179#ifdef CONFIG_REGULATOR 170#ifdef CONFIG_REGULATOR
@@ -193,7 +184,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
193 unsigned long r; 184 unsigned long r;
194 185
195 /* Check for frequencies we can generate */ 186 /* Check for frequencies we can generate */
196 r = clk_round_rate(armclk, freq->frequency * 1000); 187 r = clk_round_rate(policy->clk, freq->frequency * 1000);
197 r /= 1000; 188 r /= 1000;
198 if (r != freq->frequency) { 189 if (r != freq->frequency) {
199 pr_debug("%dkHz unsupported by clock\n", 190 pr_debug("%dkHz unsupported by clock\n",
@@ -203,7 +194,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
203 194
204 /* If we have no regulator then assume startup 195 /* If we have no regulator then assume startup
205 * frequency is the maximum we can support. */ 196 * frequency is the maximum we can support. */
206 if (!vddarm && freq->frequency > s3c64xx_cpufreq_get_speed(0)) 197 if (!vddarm && freq->frequency > clk_get_rate(policy->clk) / 1000)
207 freq->frequency = CPUFREQ_ENTRY_INVALID; 198 freq->frequency = CPUFREQ_ENTRY_INVALID;
208 199
209 freq++; 200 freq++;
@@ -219,7 +210,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
219 pr_err("Failed to configure frequency table: %d\n", 210 pr_err("Failed to configure frequency table: %d\n",
220 ret); 211 ret);
221 regulator_put(vddarm); 212 regulator_put(vddarm);
222 clk_put(armclk); 213 clk_put(policy->clk);
223 } 214 }
224 215
225 return ret; 216 return ret;
@@ -229,7 +220,7 @@ static struct cpufreq_driver s3c64xx_cpufreq_driver = {
229 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, 220 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
230 .verify = cpufreq_generic_frequency_table_verify, 221 .verify = cpufreq_generic_frequency_table_verify,
231 .target_index = s3c64xx_cpufreq_set_target, 222 .target_index = s3c64xx_cpufreq_set_target,
232 .get = s3c64xx_cpufreq_get_speed, 223 .get = cpufreq_generic_get,
233 .init = s3c64xx_cpufreq_driver_init, 224 .init = s3c64xx_cpufreq_driver_init,
234 .name = "s3c", 225 .name = "s3c",
235}; 226};
diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c
index ccd548c6f0c1..55a8e9fa9435 100644
--- a/drivers/cpufreq/s5pv210-cpufreq.c
+++ b/drivers/cpufreq/s5pv210-cpufreq.c
@@ -23,7 +23,6 @@
23#include <mach/map.h> 23#include <mach/map.h>
24#include <mach/regs-clock.h> 24#include <mach/regs-clock.h>
25 25
26static struct clk *cpu_clk;
27static struct clk *dmc0_clk; 26static struct clk *dmc0_clk;
28static struct clk *dmc1_clk; 27static struct clk *dmc1_clk;
29static DEFINE_MUTEX(set_freq_lock); 28static DEFINE_MUTEX(set_freq_lock);
@@ -164,14 +163,6 @@ static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq)
164 __raw_writel(tmp1, reg); 163 __raw_writel(tmp1, reg);
165} 164}
166 165
167static unsigned int s5pv210_getspeed(unsigned int cpu)
168{
169 if (cpu)
170 return 0;
171
172 return clk_get_rate(cpu_clk) / 1000;
173}
174
175static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index) 166static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index)
176{ 167{
177 unsigned long reg; 168 unsigned long reg;
@@ -193,7 +184,7 @@ static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index)
193 goto exit; 184 goto exit;
194 } 185 }
195 186
196 old_freq = s5pv210_getspeed(0); 187 old_freq = policy->cur;
197 new_freq = s5pv210_freq_table[index].frequency; 188 new_freq = s5pv210_freq_table[index].frequency;
198 189
199 /* Finding current running level index */ 190 /* Finding current running level index */
@@ -471,9 +462,9 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy)
471 unsigned long mem_type; 462 unsigned long mem_type;
472 int ret; 463 int ret;
473 464
474 cpu_clk = clk_get(NULL, "armclk"); 465 policy->clk = clk_get(NULL, "armclk");
475 if (IS_ERR(cpu_clk)) 466 if (IS_ERR(policy->clk))
476 return PTR_ERR(cpu_clk); 467 return PTR_ERR(policy->clk);
477 468
478 dmc0_clk = clk_get(NULL, "sclk_dmc0"); 469 dmc0_clk = clk_get(NULL, "sclk_dmc0");
479 if (IS_ERR(dmc0_clk)) { 470 if (IS_ERR(dmc0_clk)) {
@@ -516,7 +507,7 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy)
516out_dmc1: 507out_dmc1:
517 clk_put(dmc0_clk); 508 clk_put(dmc0_clk);
518out_dmc0: 509out_dmc0:
519 clk_put(cpu_clk); 510 clk_put(policy->clk);
520 return ret; 511 return ret;
521} 512}
522 513
@@ -563,7 +554,7 @@ static struct cpufreq_driver s5pv210_driver = {
563 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, 554 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
564 .verify = cpufreq_generic_frequency_table_verify, 555 .verify = cpufreq_generic_frequency_table_verify,
565 .target_index = s5pv210_target, 556 .target_index = s5pv210_target,
566 .get = s5pv210_getspeed, 557 .get = cpufreq_generic_get,
567 .init = s5pv210_cpu_init, 558 .init = s5pv210_cpu_init,
568 .name = "s5pv210", 559 .name = "s5pv210",
569#ifdef CONFIG_PM 560#ifdef CONFIG_PM
diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c
index c7525fe33407..5c86e3fa5593 100644
--- a/drivers/cpufreq/spear-cpufreq.c
+++ b/drivers/cpufreq/spear-cpufreq.c
@@ -30,11 +30,6 @@ static struct {
30 u32 cnt; 30 u32 cnt;
31} spear_cpufreq; 31} spear_cpufreq;
32 32
33static unsigned int spear_cpufreq_get(unsigned int cpu)
34{
35 return clk_get_rate(spear_cpufreq.clk) / 1000;
36}
37
38static struct clk *spear1340_cpu_get_possible_parent(unsigned long newfreq) 33static struct clk *spear1340_cpu_get_possible_parent(unsigned long newfreq)
39{ 34{
40 struct clk *sys_pclk; 35 struct clk *sys_pclk;
@@ -156,6 +151,7 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy,
156 151
157static int spear_cpufreq_init(struct cpufreq_policy *policy) 152static int spear_cpufreq_init(struct cpufreq_policy *policy)
158{ 153{
154 policy->clk = spear_cpufreq.clk;
159 return cpufreq_generic_init(policy, spear_cpufreq.freq_tbl, 155 return cpufreq_generic_init(policy, spear_cpufreq.freq_tbl,
160 spear_cpufreq.transition_latency); 156 spear_cpufreq.transition_latency);
161} 157}
@@ -165,7 +161,7 @@ static struct cpufreq_driver spear_cpufreq_driver = {
165 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, 161 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
166 .verify = cpufreq_generic_frequency_table_verify, 162 .verify = cpufreq_generic_frequency_table_verify,
167 .target_index = spear_cpufreq_target, 163 .target_index = spear_cpufreq_target,
168 .get = spear_cpufreq_get, 164 .get = cpufreq_generic_get,
169 .init = spear_cpufreq_init, 165 .init = spear_cpufreq_init,
170 .exit = cpufreq_generic_exit, 166 .exit = cpufreq_generic_exit,
171 .attr = cpufreq_generic_attr, 167 .attr = cpufreq_generic_attr,
diff --git a/drivers/cpufreq/tegra-cpufreq.c b/drivers/cpufreq/tegra-cpufreq.c
index 01b5578ffecf..e652c1bd8d0f 100644
--- a/drivers/cpufreq/tegra-cpufreq.c
+++ b/drivers/cpufreq/tegra-cpufreq.c
@@ -47,21 +47,9 @@ static struct clk *pll_x_clk;
47static struct clk *pll_p_clk; 47static struct clk *pll_p_clk;
48static struct clk *emc_clk; 48static struct clk *emc_clk;
49 49
50static unsigned long target_cpu_speed[NUM_CPUS];
51static DEFINE_MUTEX(tegra_cpu_lock); 50static DEFINE_MUTEX(tegra_cpu_lock);
52static bool is_suspended; 51static bool is_suspended;
53 52
54static unsigned int tegra_getspeed(unsigned int cpu)
55{
56 unsigned long rate;
57
58 if (cpu >= NUM_CPUS)
59 return 0;
60
61 rate = clk_get_rate(cpu_clk) / 1000;
62 return rate;
63}
64
65static int tegra_cpu_clk_set_rate(unsigned long rate) 53static int tegra_cpu_clk_set_rate(unsigned long rate)
66{ 54{
67 int ret; 55 int ret;
@@ -103,9 +91,6 @@ static int tegra_update_cpu_speed(struct cpufreq_policy *policy,
103{ 91{
104 int ret = 0; 92 int ret = 0;
105 93
106 if (tegra_getspeed(0) == rate)
107 return ret;
108
109 /* 94 /*
110 * Vote on memory bus frequency based on cpu frequency 95 * Vote on memory bus frequency based on cpu frequency
111 * This sets the minimum frequency, display or avp may request higher 96 * This sets the minimum frequency, display or avp may request higher
@@ -125,33 +110,16 @@ static int tegra_update_cpu_speed(struct cpufreq_policy *policy,
125 return ret; 110 return ret;
126} 111}
127 112
128static unsigned long tegra_cpu_highest_speed(void)
129{
130 unsigned long rate = 0;
131 int i;
132
133 for_each_online_cpu(i)
134 rate = max(rate, target_cpu_speed[i]);
135 return rate;
136}
137
138static int tegra_target(struct cpufreq_policy *policy, unsigned int index) 113static int tegra_target(struct cpufreq_policy *policy, unsigned int index)
139{ 114{
140 unsigned int freq; 115 int ret = -EBUSY;
141 int ret = 0;
142 116
143 mutex_lock(&tegra_cpu_lock); 117 mutex_lock(&tegra_cpu_lock);
144 118
145 if (is_suspended) 119 if (!is_suspended)
146 goto out; 120 ret = tegra_update_cpu_speed(policy,
147 121 freq_table[index].frequency);
148 freq = freq_table[index].frequency;
149 122
150 target_cpu_speed[policy->cpu] = freq;
151
152 ret = tegra_update_cpu_speed(policy, tegra_cpu_highest_speed());
153
154out:
155 mutex_unlock(&tegra_cpu_lock); 123 mutex_unlock(&tegra_cpu_lock);
156 return ret; 124 return ret;
157} 125}
@@ -165,7 +133,8 @@ static int tegra_pm_notify(struct notifier_block *nb, unsigned long event,
165 is_suspended = true; 133 is_suspended = true;
166 pr_info("Tegra cpufreq suspend: setting frequency to %d kHz\n", 134 pr_info("Tegra cpufreq suspend: setting frequency to %d kHz\n",
167 freq_table[0].frequency); 135 freq_table[0].frequency);
168 tegra_update_cpu_speed(policy, freq_table[0].frequency); 136 if (clk_get_rate(cpu_clk) / 1000 != freq_table[0].frequency)
137 tegra_update_cpu_speed(policy, freq_table[0].frequency);
169 cpufreq_cpu_put(policy); 138 cpufreq_cpu_put(policy);
170 } else if (event == PM_POST_SUSPEND) { 139 } else if (event == PM_POST_SUSPEND) {
171 is_suspended = false; 140 is_suspended = false;
@@ -189,8 +158,6 @@ static int tegra_cpu_init(struct cpufreq_policy *policy)
189 clk_prepare_enable(emc_clk); 158 clk_prepare_enable(emc_clk);
190 clk_prepare_enable(cpu_clk); 159 clk_prepare_enable(cpu_clk);
191 160
192 target_cpu_speed[policy->cpu] = tegra_getspeed(policy->cpu);
193
194 /* FIXME: what's the actual transition time? */ 161 /* FIXME: what's the actual transition time? */
195 ret = cpufreq_generic_init(policy, freq_table, 300 * 1000); 162 ret = cpufreq_generic_init(policy, freq_table, 300 * 1000);
196 if (ret) { 163 if (ret) {
@@ -202,6 +169,7 @@ static int tegra_cpu_init(struct cpufreq_policy *policy)
202 if (policy->cpu == 0) 169 if (policy->cpu == 0)
203 register_pm_notifier(&tegra_cpu_pm_notifier); 170 register_pm_notifier(&tegra_cpu_pm_notifier);
204 171
172 policy->clk = cpu_clk;
205 return 0; 173 return 0;
206} 174}
207 175
@@ -217,7 +185,7 @@ static struct cpufreq_driver tegra_cpufreq_driver = {
217 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, 185 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
218 .verify = cpufreq_generic_frequency_table_verify, 186 .verify = cpufreq_generic_frequency_table_verify,
219 .target_index = tegra_target, 187 .target_index = tegra_target,
220 .get = tegra_getspeed, 188 .get = cpufreq_generic_get,
221 .init = tegra_cpu_init, 189 .init = tegra_cpu_init,
222 .exit = tegra_cpu_exit, 190 .exit = tegra_cpu_exit,
223 .name = "tegra", 191 .name = "tegra",
diff --git a/drivers/cpufreq/unicore2-cpufreq.c b/drivers/cpufreq/unicore2-cpufreq.c
index 86f6cfec2e09..36cc330b8747 100644
--- a/drivers/cpufreq/unicore2-cpufreq.c
+++ b/drivers/cpufreq/unicore2-cpufreq.c
@@ -11,6 +11,7 @@
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13 13
14#include <linux/err.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
15#include <linux/types.h> 16#include <linux/types.h>
16#include <linux/init.h> 17#include <linux/init.h>
@@ -33,28 +34,18 @@ static int ucv2_verify_speed(struct cpufreq_policy *policy)
33 return 0; 34 return 0;
34} 35}
35 36
36static unsigned int ucv2_getspeed(unsigned int cpu)
37{
38 struct clk *mclk = clk_get(NULL, "MAIN_CLK");
39
40 if (cpu)
41 return 0;
42 return clk_get_rate(mclk)/1000;
43}
44
45static int ucv2_target(struct cpufreq_policy *policy, 37static int ucv2_target(struct cpufreq_policy *policy,
46 unsigned int target_freq, 38 unsigned int target_freq,
47 unsigned int relation) 39 unsigned int relation)
48{ 40{
49 struct cpufreq_freqs freqs; 41 struct cpufreq_freqs freqs;
50 struct clk *mclk = clk_get(NULL, "MAIN_CLK");
51 int ret; 42 int ret;
52 43
53 freqs.old = policy->cur; 44 freqs.old = policy->cur;
54 freqs.new = target_freq; 45 freqs.new = target_freq;
55 46
56 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 47 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
57 ret = clk_set_rate(mclk, target_freq * 1000); 48 ret = clk_set_rate(policy->mclk, target_freq * 1000);
58 cpufreq_notify_post_transition(policy, &freqs, ret); 49 cpufreq_notify_post_transition(policy, &freqs, ret);
59 50
60 return ret; 51 return ret;
@@ -64,9 +55,13 @@ static int __init ucv2_cpu_init(struct cpufreq_policy *policy)
64{ 55{
65 if (policy->cpu != 0) 56 if (policy->cpu != 0)
66 return -EINVAL; 57 return -EINVAL;
58
67 policy->min = policy->cpuinfo.min_freq = 250000; 59 policy->min = policy->cpuinfo.min_freq = 250000;
68 policy->max = policy->cpuinfo.max_freq = 1000000; 60 policy->max = policy->cpuinfo.max_freq = 1000000;
69 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; 61 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
62 policy->clk = clk_get(NULL, "MAIN_CLK");
63 if (IS_ERR(policy->clk))
64 return PTR_ERR(policy->clk);
70 return 0; 65 return 0;
71} 66}
72 67
@@ -74,7 +69,7 @@ static struct cpufreq_driver ucv2_driver = {
74 .flags = CPUFREQ_STICKY, 69 .flags = CPUFREQ_STICKY,
75 .verify = ucv2_verify_speed, 70 .verify = ucv2_verify_speed,
76 .target = ucv2_target, 71 .target = ucv2_target,
77 .get = ucv2_getspeed, 72 .get = cpufreq_generic_get,
78 .init = ucv2_cpu_init, 73 .init = ucv2_cpu_init,
79 .name = "UniCore-II", 74 .name = "UniCore-II",
80}; 75};