diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2014-01-09 10:08:43 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-01-16 20:00:44 -0500 |
commit | 652ed95d5fa6074b3c4ea245deb0691f1acb6656 (patch) | |
tree | 7b01079f3a582b0d6b08f541a8a344440bec8eae /drivers | |
parent | 0ad04fb30db0341d0b1134e2f592d9146c9abb64 (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.c | 17 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq-cpu0.c | 8 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 26 | ||||
-rw-r--r-- | drivers/cpufreq/davinci-cpufreq.c | 14 | ||||
-rw-r--r-- | drivers/cpufreq/dbx500-cpufreq.c | 19 | ||||
-rw-r--r-- | drivers/cpufreq/exynos-cpufreq.c | 10 | ||||
-rw-r--r-- | drivers/cpufreq/exynos5440-cpufreq.c | 33 | ||||
-rw-r--r-- | drivers/cpufreq/imx6q-cpufreq.c | 8 | ||||
-rw-r--r-- | drivers/cpufreq/loongson2_cpufreq.c | 15 | ||||
-rw-r--r-- | drivers/cpufreq/omap-cpufreq.c | 32 | ||||
-rw-r--r-- | drivers/cpufreq/ppc-corenet-cpufreq.c | 17 | ||||
-rw-r--r-- | drivers/cpufreq/s3c24xx-cpufreq.c | 10 | ||||
-rw-r--r-- | drivers/cpufreq/s3c64xx-cpufreq.c | 33 | ||||
-rw-r--r-- | drivers/cpufreq/s5pv210-cpufreq.c | 21 | ||||
-rw-r--r-- | drivers/cpufreq/spear-cpufreq.c | 8 | ||||
-rw-r--r-- | drivers/cpufreq/tegra-cpufreq.c | 48 | ||||
-rw-r--r-- | drivers/cpufreq/unicore2-cpufreq.c | 19 |
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 | ||
24 | static struct clk *cpuclk; | ||
25 | static struct cpufreq_frequency_table *freq_table; | 24 | static struct cpufreq_frequency_table *freq_table; |
26 | 25 | ||
27 | static 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 | |||
35 | static unsigned int ref_freq; | 26 | static unsigned int ref_freq; |
36 | static unsigned long loops_per_jiffy_ref; | 27 | static 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) | |||
61 | static int at32_cpufreq_driver_init(struct cpufreq_policy *policy) | 52 | static 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; | |||
30 | static struct regulator *cpu_reg; | 30 | static struct regulator *cpu_reg; |
31 | static struct cpufreq_frequency_table *freq_table; | 31 | static struct cpufreq_frequency_table *freq_table; |
32 | 32 | ||
33 | static unsigned int cpu0_get_speed(unsigned int cpu) | ||
34 | { | ||
35 | return clk_get_rate(cpu_clk) / 1000; | ||
36 | } | ||
37 | |||
38 | static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index) | 33 | static 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 | ||
101 | static int cpu0_cpufreq_init(struct cpufreq_policy *policy) | 96 | static 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 | } |
177 | EXPORT_SYMBOL_GPL(cpufreq_generic_init); | 177 | EXPORT_SYMBOL_GPL(cpufreq_generic_init); |
178 | 178 | ||
179 | unsigned 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 | } | ||
191 | EXPORT_SYMBOL_GPL(cpufreq_generic_get); | ||
192 | |||
179 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) | 193 | struct 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 | ||
1176 | err_out_unregister: | 1190 | err_out_unregister: |
1191 | err_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 | ||
1182 | err_get_freq: | ||
1183 | if (cpufreq_driver->exit) | 1197 | if (cpufreq_driver->exit) |
1184 | cpufreq_driver->exit(policy); | 1198 | cpufreq_driver->exit(policy); |
1185 | err_set_policy_cpu: | 1199 | err_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 | ||
61 | static 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 | |||
69 | static int davinci_target(struct cpufreq_policy *policy, unsigned int idx) | 61 | static 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 | ||
29 | static 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 | |||
45 | static int dbx500_cpufreq_init(struct cpufreq_policy *policy) | 29 | static 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; | |||
31 | static bool frequency_locked; | 31 | static bool frequency_locked; |
32 | static DEFINE_MUTEX(cpufreq_lock); | 32 | static DEFINE_MUTEX(cpufreq_lock); |
33 | 33 | ||
34 | static unsigned int exynos_getspeed(unsigned int cpu) | ||
35 | { | ||
36 | return clk_get_rate(exynos_info->cpu_clk) / 1000; | ||
37 | } | ||
38 | |||
39 | static int exynos_cpufreq_get_index(unsigned int freq) | 34 | static 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 | ||
216 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) | 211 | static 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 | ||
168 | static void exynos_enable_dvfs(void) | 167 | static 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 | ||
212 | static unsigned int exynos_getspeed(unsigned int cpu) | ||
213 | { | ||
214 | return dvfs_info->cur_frequency; | ||
215 | } | ||
216 | |||
217 | static int exynos_target(struct cpufreq_policy *policy, unsigned int index) | 211 | static 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 | ||
308 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) | 301 | static 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; | |||
38 | static u32 *imx6_soc_volt; | 38 | static u32 *imx6_soc_volt; |
39 | static u32 soc_opp_count; | 39 | static u32 soc_opp_count; |
40 | 40 | ||
41 | static unsigned int imx6q_get_speed(unsigned int cpu) | ||
42 | { | ||
43 | return clk_get_rate(arm_clk) / 1000; | ||
44 | } | ||
45 | |||
46 | static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) | 41 | static 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 | ||
140 | static int imx6q_cpufreq_init(struct cpufreq_policy *policy) | 135 | static 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 | ||
25 | static uint nowait; | 25 | static uint nowait; |
26 | 26 | ||
27 | static struct clk *cpuclk; | ||
28 | |||
29 | static void (*saved_cpu_wait) (void); | 27 | static void (*saved_cpu_wait) (void); |
30 | 28 | ||
31 | static int loongson2_cpu_freq_notifier(struct notifier_block *nb, | 29 | static 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 | ||
47 | static 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 | ||
77 | static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) | 70 | static 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 | ||
110 | static int loongson2_cpufreq_exit(struct cpufreq_policy *policy) | 105 | static 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 | ||
37 | static struct cpufreq_frequency_table *freq_table; | 37 | static struct cpufreq_frequency_table *freq_table; |
38 | static atomic_t freq_table_users = ATOMIC_INIT(0); | 38 | static atomic_t freq_table_users = ATOMIC_INIT(0); |
39 | static struct clk *mpu_clk; | ||
40 | static struct device *mpu_dev; | 39 | static struct device *mpu_dev; |
41 | static struct regulator *mpu_reg; | 40 | static struct regulator *mpu_reg; |
42 | 41 | ||
43 | static 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 | |||
54 | static int omap_target(struct cpufreq_policy *policy, unsigned int index) | 42 | static 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(); |
151 | fail: | 139 | fail: |
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 | */ |
31 | struct cpu_data { | 30 | struct 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 | ||
84 | static 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 */ |
92 | static void freq_table_redup(struct cpufreq_frequency_table *freq_table, | 83 | static 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 | ||
261 | static struct cpufreq_driver ppc_corenet_cpufreq_driver = { | 252 | static 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 | ||
358 | static unsigned int s3c_cpufreq_get(unsigned int cpu) | ||
359 | { | ||
360 | return clk_get_rate(clk_arm) / 1000; | ||
361 | } | ||
362 | |||
363 | struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) | 358 | struct 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 | ||
374 | static int s3c_cpufreq_init(struct cpufreq_policy *policy) | 369 | static 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) | |||
450 | static struct cpufreq_driver s3c24xx_driver = { | 446 | static 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 | ||
22 | static struct clk *armclk; | ||
23 | static struct regulator *vddarm; | 22 | static struct regulator *vddarm; |
24 | static unsigned long regulator_latency; | 23 | static 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 | ||
57 | static 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 | |||
65 | static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, | 56 | static 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 | ||
26 | static struct clk *cpu_clk; | ||
27 | static struct clk *dmc0_clk; | 26 | static struct clk *dmc0_clk; |
28 | static struct clk *dmc1_clk; | 27 | static struct clk *dmc1_clk; |
29 | static DEFINE_MUTEX(set_freq_lock); | 28 | static 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 | ||
167 | static 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 | |||
175 | static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index) | 166 | static 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) | |||
516 | out_dmc1: | 507 | out_dmc1: |
517 | clk_put(dmc0_clk); | 508 | clk_put(dmc0_clk); |
518 | out_dmc0: | 509 | out_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 | ||
33 | static unsigned int spear_cpufreq_get(unsigned int cpu) | ||
34 | { | ||
35 | return clk_get_rate(spear_cpufreq.clk) / 1000; | ||
36 | } | ||
37 | |||
38 | static struct clk *spear1340_cpu_get_possible_parent(unsigned long newfreq) | 33 | static 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 | ||
157 | static int spear_cpufreq_init(struct cpufreq_policy *policy) | 152 | static 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; | |||
47 | static struct clk *pll_p_clk; | 47 | static struct clk *pll_p_clk; |
48 | static struct clk *emc_clk; | 48 | static struct clk *emc_clk; |
49 | 49 | ||
50 | static unsigned long target_cpu_speed[NUM_CPUS]; | ||
51 | static DEFINE_MUTEX(tegra_cpu_lock); | 50 | static DEFINE_MUTEX(tegra_cpu_lock); |
52 | static bool is_suspended; | 51 | static bool is_suspended; |
53 | 52 | ||
54 | static 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 | |||
65 | static int tegra_cpu_clk_set_rate(unsigned long rate) | 53 | static 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 | ||
128 | static 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 | |||
138 | static int tegra_target(struct cpufreq_policy *policy, unsigned int index) | 113 | static 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 | |||
154 | out: | ||
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 | ||
36 | static 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 | |||
45 | static int ucv2_target(struct cpufreq_policy *policy, | 37 | static 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 | }; |