aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-01-14 17:12:08 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-01-14 17:12:08 -0500
commit51c4c4ce1df49b14bbfc334c6388cc9efe32c631 (patch)
treeb33a9a905b9b646c78be7df7c189e7f9c0f28f77 /drivers/cpufreq
parent6cbd7ee10e2842a3d1f9b60abede1c8f3d1f1130 (diff)
parent22c73795b101597051924556dce019385a1e2fa0 (diff)
Merge back earlier 'pm-cpufreq' material.
Diffstat (limited to 'drivers/cpufreq')
-rw-r--r--drivers/cpufreq/Kconfig3
-rw-r--r--drivers/cpufreq/Kconfig.arm12
-rw-r--r--drivers/cpufreq/arm_big_little.c3
-rw-r--r--drivers/cpufreq/cpufreq-cpu0.c2
-rw-r--r--drivers/cpufreq/cpufreq.c69
-rw-r--r--drivers/cpufreq/cpufreq_governor.c6
-rw-r--r--drivers/cpufreq/cpufreq_governor.h2
-rw-r--r--drivers/cpufreq/davinci-cpufreq.c2
-rw-r--r--drivers/cpufreq/dbx500-cpufreq.c3
-rw-r--r--drivers/cpufreq/exynos-cpufreq.c15
-rw-r--r--drivers/cpufreq/exynos5250-cpufreq.c74
-rw-r--r--drivers/cpufreq/exynos5440-cpufreq.c3
-rw-r--r--drivers/cpufreq/freq_table.c22
-rw-r--r--drivers/cpufreq/imx6q-cpufreq.c128
-rw-r--r--drivers/cpufreq/integrator-cpufreq.c1
-rw-r--r--drivers/cpufreq/intel_pstate.c69
-rw-r--r--drivers/cpufreq/kirkwood-cpufreq.c1
-rw-r--r--drivers/cpufreq/omap-cpufreq.c2
-rw-r--r--drivers/cpufreq/pcc-cpufreq.c18
-rw-r--r--drivers/cpufreq/powernow-k6.c147
-rw-r--r--drivers/cpufreq/powernow-k8.c7
-rw-r--r--drivers/cpufreq/pxa2xx-cpufreq.c1
-rw-r--r--drivers/cpufreq/pxa3xx-cpufreq.c1
-rw-r--r--drivers/cpufreq/s3c2416-cpufreq.c2
-rw-r--r--drivers/cpufreq/s3c2440-cpufreq.c6
-rw-r--r--drivers/cpufreq/s3c24xx-cpufreq.c4
-rw-r--r--drivers/cpufreq/s3c64xx-cpufreq.c2
-rw-r--r--drivers/cpufreq/s5pv210-cpufreq.c2
-rw-r--r--drivers/cpufreq/sa1100-cpufreq.c2
-rw-r--r--drivers/cpufreq/sa1110-cpufreq.c2
-rw-r--r--drivers/cpufreq/spear-cpufreq.c4
-rw-r--r--drivers/cpufreq/tegra-cpufreq.c1
-rw-r--r--drivers/cpufreq/unicore2-cpufreq.c16
33 files changed, 426 insertions, 206 deletions
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index 38093e272377..386dbc9ccdfd 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -181,7 +181,8 @@ config CPU_FREQ_GOV_CONSERVATIVE
181 181
182config GENERIC_CPUFREQ_CPU0 182config GENERIC_CPUFREQ_CPU0
183 tristate "Generic CPU0 cpufreq driver" 183 tristate "Generic CPU0 cpufreq driver"
184 depends on HAVE_CLK && REGULATOR && PM_OPP && OF 184 depends on HAVE_CLK && REGULATOR && OF
185 select PM_OPP
185 help 186 help
186 This adds a generic cpufreq driver for CPU0 frequency management. 187 This adds a generic cpufreq driver for CPU0 frequency management.
187 It supports both uniprocessor (UP) and symmetric multiprocessor (SMP) 188 It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index ce52ed949249..0468ad147301 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -4,7 +4,8 @@
4 4
5config ARM_BIG_LITTLE_CPUFREQ 5config ARM_BIG_LITTLE_CPUFREQ
6 tristate "Generic ARM big LITTLE CPUfreq driver" 6 tristate "Generic ARM big LITTLE CPUfreq driver"
7 depends on ARM_CPU_TOPOLOGY && PM_OPP && HAVE_CLK 7 depends on ARM && BIG_LITTLE && ARM_CPU_TOPOLOGY && HAVE_CLK
8 select PM_OPP
8 help 9 help
9 This enables the Generic CPUfreq driver for ARM big.LITTLE platforms. 10 This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
10 11
@@ -54,7 +55,8 @@ config ARM_EXYNOS5250_CPUFREQ
54config ARM_EXYNOS5440_CPUFREQ 55config ARM_EXYNOS5440_CPUFREQ
55 bool "SAMSUNG EXYNOS5440" 56 bool "SAMSUNG EXYNOS5440"
56 depends on SOC_EXYNOS5440 57 depends on SOC_EXYNOS5440
57 depends on HAVE_CLK && PM_OPP && OF 58 depends on HAVE_CLK && OF
59 select PM_OPP
58 default y 60 default y
59 help 61 help
60 This adds the CPUFreq driver for Samsung EXYNOS5440 62 This adds the CPUFreq driver for Samsung EXYNOS5440
@@ -79,11 +81,11 @@ config ARM_HIGHBANK_CPUFREQ
79 If in doubt, say N. 81 If in doubt, say N.
80 82
81config ARM_IMX6Q_CPUFREQ 83config ARM_IMX6Q_CPUFREQ
82 tristate "Freescale i.MX6Q cpufreq support" 84 tristate "Freescale i.MX6 cpufreq support"
83 depends on SOC_IMX6Q 85 depends on ARCH_MXC
84 depends on REGULATOR_ANATOP 86 depends on REGULATOR_ANATOP
85 help 87 help
86 This adds cpufreq driver support for Freescale i.MX6Q SOC. 88 This adds cpufreq driver support for Freescale i.MX6 series SoCs.
87 89
88 If in doubt, say N. 90 If in doubt, say N.
89 91
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c
index 5519933813ea..72f87e9317e3 100644
--- a/drivers/cpufreq/arm_big_little.c
+++ b/drivers/cpufreq/arm_big_little.c
@@ -488,7 +488,8 @@ static int bL_cpufreq_exit(struct cpufreq_policy *policy)
488static struct cpufreq_driver bL_cpufreq_driver = { 488static struct cpufreq_driver bL_cpufreq_driver = {
489 .name = "arm-big-little", 489 .name = "arm-big-little",
490 .flags = CPUFREQ_STICKY | 490 .flags = CPUFREQ_STICKY |
491 CPUFREQ_HAVE_GOVERNOR_PER_POLICY, 491 CPUFREQ_HAVE_GOVERNOR_PER_POLICY |
492 CPUFREQ_NEED_INITIAL_FREQ_CHECK,
492 .verify = cpufreq_generic_frequency_table_verify, 493 .verify = cpufreq_generic_frequency_table_verify,
493 .target_index = bL_cpufreq_set_target, 494 .target_index = bL_cpufreq_set_target,
494 .get = bL_cpufreq_get_rate, 495 .get = bL_cpufreq_get_rate,
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
index d4585ce2346c..0faf756f6197 100644
--- a/drivers/cpufreq/cpufreq-cpu0.c
+++ b/drivers/cpufreq/cpufreq-cpu0.c
@@ -44,7 +44,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
44 int ret; 44 int ret;
45 45
46 freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000); 46 freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
47 if (freq_Hz < 0) 47 if (freq_Hz <= 0)
48 freq_Hz = freq_table[index].frequency * 1000; 48 freq_Hz = freq_table[index].frequency * 1000;
49 49
50 freq_exact = freq_Hz; 50 freq_exact = freq_Hz;
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 8d19f7c06010..3509ca04b5bb 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -39,7 +39,7 @@ static struct cpufreq_driver *cpufreq_driver;
39static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); 39static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
40static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback); 40static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback);
41static DEFINE_RWLOCK(cpufreq_driver_lock); 41static DEFINE_RWLOCK(cpufreq_driver_lock);
42static DEFINE_MUTEX(cpufreq_governor_lock); 42DEFINE_MUTEX(cpufreq_governor_lock);
43static LIST_HEAD(cpufreq_policy_list); 43static LIST_HEAD(cpufreq_policy_list);
44 44
45#ifdef CONFIG_HOTPLUG_CPU 45#ifdef CONFIG_HOTPLUG_CPU
@@ -320,6 +320,20 @@ void cpufreq_notify_transition(struct cpufreq_policy *policy,
320} 320}
321EXPORT_SYMBOL_GPL(cpufreq_notify_transition); 321EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
322 322
323/* Do post notifications when there are chances that transition has failed */
324void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
325 struct cpufreq_freqs *freqs, int transition_failed)
326{
327 cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
328 if (!transition_failed)
329 return;
330
331 swap(freqs->old, freqs->new);
332 cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE);
333 cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
334}
335EXPORT_SYMBOL_GPL(cpufreq_notify_post_transition);
336
323 337
324/********************************************************************* 338/*********************************************************************
325 * SYSFS INTERFACE * 339 * SYSFS INTERFACE *
@@ -1059,6 +1073,46 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
1059 } 1073 }
1060 } 1074 }
1061 1075
1076 /*
1077 * Sometimes boot loaders set CPU frequency to a value outside of
1078 * frequency table present with cpufreq core. In such cases CPU might be
1079 * unstable if it has to run on that frequency for long duration of time
1080 * and so its better to set it to a frequency which is specified in
1081 * freq-table. This also makes cpufreq stats inconsistent as
1082 * cpufreq-stats would fail to register because current frequency of CPU
1083 * isn't found in freq-table.
1084 *
1085 * Because we don't want this change to effect boot process badly, we go
1086 * for the next freq which is >= policy->cur ('cur' must be set by now,
1087 * otherwise we will end up setting freq to lowest of the table as 'cur'
1088 * is initialized to zero).
1089 *
1090 * We are passing target-freq as "policy->cur - 1" otherwise
1091 * __cpufreq_driver_target() would simply fail, as policy->cur will be
1092 * equal to target-freq.
1093 */
1094 if ((cpufreq_driver->flags & CPUFREQ_NEED_INITIAL_FREQ_CHECK)
1095 && has_target()) {
1096 /* Are we running at unknown frequency ? */
1097 ret = cpufreq_frequency_table_get_index(policy, policy->cur);
1098 if (ret == -EINVAL) {
1099 /* Warn user and fix it */
1100 pr_warn("%s: CPU%d: Running at unlisted freq: %u KHz\n",
1101 __func__, policy->cpu, policy->cur);
1102 ret = __cpufreq_driver_target(policy, policy->cur - 1,
1103 CPUFREQ_RELATION_L);
1104
1105 /*
1106 * Reaching here after boot in a few seconds may not
1107 * mean that system will remain stable at "unknown"
1108 * frequency for longer duration. Hence, a BUG_ON().
1109 */
1110 BUG_ON(ret);
1111 pr_warn("%s: CPU%d: Unlisted initial frequency changed to: %u KHz\n",
1112 __func__, policy->cpu, policy->cur);
1113 }
1114 }
1115
1062 /* related cpus should atleast have policy->cpus */ 1116 /* related cpus should atleast have policy->cpus */
1063 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); 1117 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
1064 1118
@@ -1725,17 +1779,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
1725 pr_err("%s: Failed to change cpu frequency: %d\n", 1779 pr_err("%s: Failed to change cpu frequency: %d\n",
1726 __func__, retval); 1780 __func__, retval);
1727 1781
1728 if (notify) { 1782 if (notify)
1729 /* 1783 cpufreq_notify_post_transition(policy, &freqs, retval);
1730 * Notify with old freq in case we failed to change
1731 * frequency
1732 */
1733 if (retval)
1734 freqs.new = freqs.old;
1735
1736 cpufreq_notify_transition(policy, &freqs,
1737 CPUFREQ_POSTCHANGE);
1738 }
1739 } 1784 }
1740 1785
1741out: 1786out:
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
index e6be63561fa6..ba43991ba98a 100644
--- a/drivers/cpufreq/cpufreq_governor.c
+++ b/drivers/cpufreq/cpufreq_governor.c
@@ -119,8 +119,9 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy,
119{ 119{
120 int i; 120 int i;
121 121
122 mutex_lock(&cpufreq_governor_lock);
122 if (!policy->governor_enabled) 123 if (!policy->governor_enabled)
123 return; 124 goto out_unlock;
124 125
125 if (!all_cpus) { 126 if (!all_cpus) {
126 /* 127 /*
@@ -135,6 +136,9 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy,
135 for_each_cpu(i, policy->cpus) 136 for_each_cpu(i, policy->cpus)
136 __gov_queue_work(i, dbs_data, delay); 137 __gov_queue_work(i, dbs_data, delay);
137 } 138 }
139
140out_unlock:
141 mutex_unlock(&cpufreq_governor_lock);
138} 142}
139EXPORT_SYMBOL_GPL(gov_queue_work); 143EXPORT_SYMBOL_GPL(gov_queue_work);
140 144
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
index b5f2b8618949..bfb9ae14142c 100644
--- a/drivers/cpufreq/cpufreq_governor.h
+++ b/drivers/cpufreq/cpufreq_governor.h
@@ -257,6 +257,8 @@ static ssize_t show_sampling_rate_min_gov_pol \
257 return sprintf(buf, "%u\n", dbs_data->min_sampling_rate); \ 257 return sprintf(buf, "%u\n", dbs_data->min_sampling_rate); \
258} 258}
259 259
260extern struct mutex cpufreq_governor_lock;
261
260void dbs_check_cpu(struct dbs_data *dbs_data, int cpu); 262void dbs_check_cpu(struct dbs_data *dbs_data, int cpu);
261bool need_load_eval(struct cpu_dbs_common_info *cdbs, 263bool need_load_eval(struct cpu_dbs_common_info *cdbs,
262 unsigned int sampling_rate); 264 unsigned int sampling_rate);
diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c
index 5e8a854381b7..04f3390a7a2c 100644
--- a/drivers/cpufreq/davinci-cpufreq.c
+++ b/drivers/cpufreq/davinci-cpufreq.c
@@ -126,7 +126,7 @@ static int davinci_cpu_init(struct cpufreq_policy *policy)
126} 126}
127 127
128static struct cpufreq_driver davinci_driver = { 128static struct cpufreq_driver davinci_driver = {
129 .flags = CPUFREQ_STICKY, 129 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
130 .verify = davinci_verify_speed, 130 .verify = davinci_verify_speed,
131 .target_index = davinci_target, 131 .target_index = davinci_target,
132 .get = davinci_getspeed, 132 .get = davinci_getspeed,
diff --git a/drivers/cpufreq/dbx500-cpufreq.c b/drivers/cpufreq/dbx500-cpufreq.c
index 0e67ab96321a..21d9898e000c 100644
--- a/drivers/cpufreq/dbx500-cpufreq.c
+++ b/drivers/cpufreq/dbx500-cpufreq.c
@@ -48,7 +48,8 @@ static int dbx500_cpufreq_init(struct cpufreq_policy *policy)
48} 48}
49 49
50static struct cpufreq_driver dbx500_cpufreq_driver = { 50static struct cpufreq_driver dbx500_cpufreq_driver = {
51 .flags = CPUFREQ_STICKY | CPUFREQ_CONST_LOOPS, 51 .flags = CPUFREQ_STICKY | CPUFREQ_CONST_LOOPS |
52 CPUFREQ_NEED_INITIAL_FREQ_CHECK,
52 .verify = cpufreq_generic_frequency_table_verify, 53 .verify = cpufreq_generic_frequency_table_verify,
53 .target_index = dbx500_cpufreq_target, 54 .target_index = dbx500_cpufreq_target,
54 .get = dbx500_cpufreq_getspeed, 55 .get = dbx500_cpufreq_getspeed,
diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
index f3c22874da75..f7c322c7d7ed 100644
--- a/drivers/cpufreq/exynos-cpufreq.c
+++ b/drivers/cpufreq/exynos-cpufreq.c
@@ -17,6 +17,7 @@
17#include <linux/regulator/consumer.h> 17#include <linux/regulator/consumer.h>
18#include <linux/cpufreq.h> 18#include <linux/cpufreq.h>
19#include <linux/suspend.h> 19#include <linux/suspend.h>
20#include <linux/platform_device.h>
20 21
21#include <plat/cpu.h> 22#include <plat/cpu.h>
22 23
@@ -218,7 +219,7 @@ static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
218} 219}
219 220
220static struct cpufreq_driver exynos_driver = { 221static struct cpufreq_driver exynos_driver = {
221 .flags = CPUFREQ_STICKY, 222 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
222 .verify = cpufreq_generic_frequency_table_verify, 223 .verify = cpufreq_generic_frequency_table_verify,
223 .target_index = exynos_target, 224 .target_index = exynos_target,
224 .get = exynos_getspeed, 225 .get = exynos_getspeed,
@@ -232,7 +233,7 @@ static struct cpufreq_driver exynos_driver = {
232#endif 233#endif
233}; 234};
234 235
235static int __init exynos_cpufreq_init(void) 236static int exynos_cpufreq_probe(struct platform_device *pdev)
236{ 237{
237 int ret = -EINVAL; 238 int ret = -EINVAL;
238 239
@@ -281,4 +282,12 @@ err_vdd_arm:
281 kfree(exynos_info); 282 kfree(exynos_info);
282 return -EINVAL; 283 return -EINVAL;
283} 284}
284late_initcall(exynos_cpufreq_init); 285
286static struct platform_driver exynos_cpufreq_platdrv = {
287 .driver = {
288 .name = "exynos-cpufreq",
289 .owner = THIS_MODULE,
290 },
291 .probe = exynos_cpufreq_probe,
292};
293module_platform_driver(exynos_cpufreq_platdrv);
diff --git a/drivers/cpufreq/exynos5250-cpufreq.c b/drivers/cpufreq/exynos5250-cpufreq.c
index 8feda86fe42c..86fb1a105601 100644
--- a/drivers/cpufreq/exynos5250-cpufreq.c
+++ b/drivers/cpufreq/exynos5250-cpufreq.c
@@ -102,12 +102,12 @@ static void set_clkdiv(unsigned int div_index)
102 cpu_relax(); 102 cpu_relax();
103} 103}
104 104
105static void set_apll(unsigned int new_index, 105static void set_apll(unsigned int index)
106 unsigned int old_index)
107{ 106{
108 unsigned int tmp, pdiv; 107 unsigned int tmp;
108 unsigned int freq = apll_freq_5250[index].freq;
109 109
110 /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ 110 /* MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
111 clk_set_parent(moutcore, mout_mpll); 111 clk_set_parent(moutcore, mout_mpll);
112 112
113 do { 113 do {
@@ -116,24 +116,9 @@ static void set_apll(unsigned int new_index,
116 tmp &= 0x7; 116 tmp &= 0x7;
117 } while (tmp != 0x2); 117 } while (tmp != 0x2);
118 118
119 /* 2. Set APLL Lock time */ 119 clk_set_rate(mout_apll, freq * 1000);
120 pdiv = ((apll_freq_5250[new_index].mps >> 8) & 0x3f);
121
122 __raw_writel((pdiv * 250), EXYNOS5_APLL_LOCK);
123 120
124 /* 3. Change PLL PMS values */ 121 /* MUX_CORE_SEL = APLL */
125 tmp = __raw_readl(EXYNOS5_APLL_CON0);
126 tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
127 tmp |= apll_freq_5250[new_index].mps;
128 __raw_writel(tmp, EXYNOS5_APLL_CON0);
129
130 /* 4. wait_lock_time */
131 do {
132 cpu_relax();
133 tmp = __raw_readl(EXYNOS5_APLL_CON0);
134 } while (!(tmp & (0x1 << 29)));
135
136 /* 5. MUX_CORE_SEL = APLL */
137 clk_set_parent(moutcore, mout_apll); 122 clk_set_parent(moutcore, mout_apll);
138 123
139 do { 124 do {
@@ -141,55 +126,17 @@ static void set_apll(unsigned int new_index,
141 tmp = __raw_readl(EXYNOS5_CLKMUX_STATCPU); 126 tmp = __raw_readl(EXYNOS5_CLKMUX_STATCPU);
142 tmp &= (0x7 << 16); 127 tmp &= (0x7 << 16);
143 } while (tmp != (0x1 << 16)); 128 } while (tmp != (0x1 << 16));
144
145}
146
147static bool exynos5250_pms_change(unsigned int old_index, unsigned int new_index)
148{
149 unsigned int old_pm = apll_freq_5250[old_index].mps >> 8;
150 unsigned int new_pm = apll_freq_5250[new_index].mps >> 8;
151
152 return (old_pm == new_pm) ? 0 : 1;
153} 129}
154 130
155static void exynos5250_set_frequency(unsigned int old_index, 131static void exynos5250_set_frequency(unsigned int old_index,
156 unsigned int new_index) 132 unsigned int new_index)
157{ 133{
158 unsigned int tmp;
159
160 if (old_index > new_index) { 134 if (old_index > new_index) {
161 if (!exynos5250_pms_change(old_index, new_index)) { 135 set_clkdiv(new_index);
162 /* 1. Change the system clock divider values */ 136 set_apll(new_index);
163 set_clkdiv(new_index);
164 /* 2. Change just s value in apll m,p,s value */
165 tmp = __raw_readl(EXYNOS5_APLL_CON0);
166 tmp &= ~(0x7 << 0);
167 tmp |= apll_freq_5250[new_index].mps & 0x7;
168 __raw_writel(tmp, EXYNOS5_APLL_CON0);
169
170 } else {
171 /* Clock Configuration Procedure */
172 /* 1. Change the system clock divider values */
173 set_clkdiv(new_index);
174 /* 2. Change the apll m,p,s value */
175 set_apll(new_index, old_index);
176 }
177 } else if (old_index < new_index) { 137 } else if (old_index < new_index) {
178 if (!exynos5250_pms_change(old_index, new_index)) { 138 set_apll(new_index);
179 /* 1. Change just s value in apll m,p,s value */ 139 set_clkdiv(new_index);
180 tmp = __raw_readl(EXYNOS5_APLL_CON0);
181 tmp &= ~(0x7 << 0);
182 tmp |= apll_freq_5250[new_index].mps & 0x7;
183 __raw_writel(tmp, EXYNOS5_APLL_CON0);
184 /* 2. Change the system clock divider values */
185 set_clkdiv(new_index);
186 } else {
187 /* Clock Configuration Procedure */
188 /* 1. Change the apll m,p,s value */
189 set_apll(new_index, old_index);
190 /* 2. Change the system clock divider values */
191 set_clkdiv(new_index);
192 }
193 } 140 }
194} 141}
195 142
@@ -222,7 +169,6 @@ int exynos5250_cpufreq_init(struct exynos_dvfs_info *info)
222 info->volt_table = exynos5250_volt_table; 169 info->volt_table = exynos5250_volt_table;
223 info->freq_table = exynos5250_freq_table; 170 info->freq_table = exynos5250_freq_table;
224 info->set_freq = exynos5250_set_frequency; 171 info->set_freq = exynos5250_set_frequency;
225 info->need_apll_change = exynos5250_pms_change;
226 172
227 return 0; 173 return 0;
228 174
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c
index 76bef8b078cb..ffe6faea3a5f 100644
--- a/drivers/cpufreq/exynos5440-cpufreq.c
+++ b/drivers/cpufreq/exynos5440-cpufreq.c
@@ -312,7 +312,8 @@ static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
312} 312}
313 313
314static struct cpufreq_driver exynos_driver = { 314static struct cpufreq_driver exynos_driver = {
315 .flags = CPUFREQ_STICKY | CPUFREQ_ASYNC_NOTIFICATION, 315 .flags = CPUFREQ_STICKY | CPUFREQ_ASYNC_NOTIFICATION |
316 CPUFREQ_NEED_INITIAL_FREQ_CHECK,
316 .verify = cpufreq_generic_frequency_table_verify, 317 .verify = cpufreq_generic_frequency_table_verify,
317 .target_index = exynos_target, 318 .target_index = exynos_target,
318 .get = exynos_getspeed, 319 .get = exynos_getspeed,
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index 3458d27f63b4..a8ac0427fbfe 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -178,7 +178,29 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
178} 178}
179EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target); 179EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
180 180
181int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy,
182 unsigned int freq)
183{
184 struct cpufreq_frequency_table *table;
185 int i;
186
187 table = cpufreq_frequency_get_table(policy->cpu);
188 if (unlikely(!table)) {
189 pr_debug("%s: Unable to find frequency table\n", __func__);
190 return -ENOENT;
191 }
192
193 for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
194 if (table[i].frequency == freq)
195 return i;
196 }
197
198 return -EINVAL;
199}
200EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_index);
201
181static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table); 202static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table);
203
182/** 204/**
183 * show_available_freqs - show available frequencies for the specified CPU 205 * show_available_freqs - show available frequencies for the specified CPU
184 */ 206 */
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index 4b3f18e5f36b..2938257b8c19 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -35,6 +35,9 @@ static struct device *cpu_dev;
35static struct cpufreq_frequency_table *freq_table; 35static struct cpufreq_frequency_table *freq_table;
36static unsigned int transition_latency; 36static unsigned int transition_latency;
37 37
38static u32 *imx6_soc_volt;
39static u32 soc_opp_count;
40
38static unsigned int imx6q_get_speed(unsigned int cpu) 41static unsigned int imx6q_get_speed(unsigned int cpu)
39{ 42{
40 return clk_get_rate(arm_clk) / 1000; 43 return clk_get_rate(arm_clk) / 1000;
@@ -69,23 +72,22 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
69 72
70 /* scaling up? scale voltage before frequency */ 73 /* scaling up? scale voltage before frequency */
71 if (new_freq > old_freq) { 74 if (new_freq > old_freq) {
75 ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
76 if (ret) {
77 dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret);
78 return ret;
79 }
80 ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
81 if (ret) {
82 dev_err(cpu_dev, "failed to scale vddsoc up: %d\n", ret);
83 return ret;
84 }
72 ret = regulator_set_voltage_tol(arm_reg, volt, 0); 85 ret = regulator_set_voltage_tol(arm_reg, volt, 0);
73 if (ret) { 86 if (ret) {
74 dev_err(cpu_dev, 87 dev_err(cpu_dev,
75 "failed to scale vddarm up: %d\n", ret); 88 "failed to scale vddarm up: %d\n", ret);
76 return ret; 89 return ret;
77 } 90 }
78
79 /*
80 * Need to increase vddpu and vddsoc for safety
81 * if we are about to run at 1.2 GHz.
82 */
83 if (new_freq == FREQ_1P2_GHZ / 1000) {
84 regulator_set_voltage_tol(pu_reg,
85 PU_SOC_VOLTAGE_HIGH, 0);
86 regulator_set_voltage_tol(soc_reg,
87 PU_SOC_VOLTAGE_HIGH, 0);
88 }
89 } 91 }
90 92
91 /* 93 /*
@@ -120,12 +122,15 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
120 "failed to scale vddarm down: %d\n", ret); 122 "failed to scale vddarm down: %d\n", ret);
121 ret = 0; 123 ret = 0;
122 } 124 }
123 125 ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
124 if (old_freq == FREQ_1P2_GHZ / 1000) { 126 if (ret) {
125 regulator_set_voltage_tol(pu_reg, 127 dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", ret);
126 PU_SOC_VOLTAGE_NORMAL, 0); 128 ret = 0;
127 regulator_set_voltage_tol(soc_reg, 129 }
128 PU_SOC_VOLTAGE_NORMAL, 0); 130 ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
131 if (ret) {
132 dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret);
133 ret = 0;
129 } 134 }
130 } 135 }
131 136
@@ -138,6 +143,7 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
138} 143}
139 144
140static struct cpufreq_driver imx6q_cpufreq_driver = { 145static struct cpufreq_driver imx6q_cpufreq_driver = {
146 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
141 .verify = cpufreq_generic_frequency_table_verify, 147 .verify = cpufreq_generic_frequency_table_verify,
142 .target_index = imx6q_set_target, 148 .target_index = imx6q_set_target,
143 .get = imx6q_get_speed, 149 .get = imx6q_get_speed,
@@ -153,6 +159,9 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
153 struct dev_pm_opp *opp; 159 struct dev_pm_opp *opp;
154 unsigned long min_volt, max_volt; 160 unsigned long min_volt, max_volt;
155 int num, ret; 161 int num, ret;
162 const struct property *prop;
163 const __be32 *val;
164 u32 nr, i, j;
156 165
157 cpu_dev = get_cpu_device(0); 166 cpu_dev = get_cpu_device(0);
158 if (!cpu_dev) { 167 if (!cpu_dev) {
@@ -187,12 +196,25 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
187 goto put_node; 196 goto put_node;
188 } 197 }
189 198
190 /* We expect an OPP table supplied by platform */ 199 /*
200 * We expect an OPP table supplied by platform.
201 * Just, incase the platform did not supply the OPP
202 * table, it will try to get it.
203 */
191 num = dev_pm_opp_get_opp_count(cpu_dev); 204 num = dev_pm_opp_get_opp_count(cpu_dev);
192 if (num < 0) { 205 if (num < 0) {
193 ret = num; 206 ret = of_init_opp_table(cpu_dev);
194 dev_err(cpu_dev, "no OPP table is found: %d\n", ret); 207 if (ret < 0) {
195 goto put_node; 208 dev_err(cpu_dev, "failed to init OPP table: %d\n", ret);
209 goto put_node;
210 }
211
212 num = dev_pm_opp_get_opp_count(cpu_dev);
213 if (num < 0) {
214 ret = num;
215 dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
216 goto put_node;
217 }
196 } 218 }
197 219
198 ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); 220 ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
@@ -201,10 +223,62 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
201 goto put_node; 223 goto put_node;
202 } 224 }
203 225
226 /* Make imx6_soc_volt array's size same as arm opp number */
227 imx6_soc_volt = devm_kzalloc(cpu_dev, sizeof(*imx6_soc_volt) * num, GFP_KERNEL);
228 if (imx6_soc_volt == NULL) {
229 ret = -ENOMEM;
230 goto free_freq_table;
231 }
232
233 prop = of_find_property(np, "fsl,soc-operating-points", NULL);
234 if (!prop || !prop->value)
235 goto soc_opp_out;
236
237 /*
238 * Each OPP is a set of tuples consisting of frequency and
239 * voltage like <freq-kHz vol-uV>.
240 */
241 nr = prop->length / sizeof(u32);
242 if (nr % 2 || (nr / 2) < num)
243 goto soc_opp_out;
244
245 for (j = 0; j < num; j++) {
246 val = prop->value;
247 for (i = 0; i < nr / 2; i++) {
248 unsigned long freq = be32_to_cpup(val++);
249 unsigned long volt = be32_to_cpup(val++);
250 if (freq_table[j].frequency == freq) {
251 imx6_soc_volt[soc_opp_count++] = volt;
252 break;
253 }
254 }
255 }
256
257soc_opp_out:
258 /* use fixed soc opp volt if no valid soc opp info found in dtb */
259 if (soc_opp_count != num) {
260 dev_warn(cpu_dev, "can NOT find valid fsl,soc-operating-points property in dtb, use default value!\n");
261 for (j = 0; j < num; j++)
262 imx6_soc_volt[j] = PU_SOC_VOLTAGE_NORMAL;
263 if (freq_table[num - 1].frequency * 1000 == FREQ_1P2_GHZ)
264 imx6_soc_volt[num - 1] = PU_SOC_VOLTAGE_HIGH;
265 }
266
204 if (of_property_read_u32(np, "clock-latency", &transition_latency)) 267 if (of_property_read_u32(np, "clock-latency", &transition_latency))
205 transition_latency = CPUFREQ_ETERNAL; 268 transition_latency = CPUFREQ_ETERNAL;
206 269
207 /* 270 /*
271 * Calculate the ramp time for max voltage change in the
272 * VDDSOC and VDDPU regulators.
273 */
274 ret = regulator_set_voltage_time(soc_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
275 if (ret > 0)
276 transition_latency += ret * 1000;
277 ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
278 if (ret > 0)
279 transition_latency += ret * 1000;
280
281 /*
208 * OPP is maintained in order of increasing frequency, and 282 * OPP is maintained in order of increasing frequency, and
209 * freq_table initialised from OPP is therefore sorted in the 283 * freq_table initialised from OPP is therefore sorted in the
210 * same order. 284 * same order.
@@ -221,18 +295,6 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
221 if (ret > 0) 295 if (ret > 0)
222 transition_latency += ret * 1000; 296 transition_latency += ret * 1000;
223 297
224 /* Count vddpu and vddsoc latency in for 1.2 GHz support */
225 if (freq_table[num].frequency == FREQ_1P2_GHZ / 1000) {
226 ret = regulator_set_voltage_time(pu_reg, PU_SOC_VOLTAGE_NORMAL,
227 PU_SOC_VOLTAGE_HIGH);
228 if (ret > 0)
229 transition_latency += ret * 1000;
230 ret = regulator_set_voltage_time(soc_reg, PU_SOC_VOLTAGE_NORMAL,
231 PU_SOC_VOLTAGE_HIGH);
232 if (ret > 0)
233 transition_latency += ret * 1000;
234 }
235
236 ret = cpufreq_register_driver(&imx6q_cpufreq_driver); 298 ret = cpufreq_register_driver(&imx6q_cpufreq_driver);
237 if (ret) { 299 if (ret) {
238 dev_err(cpu_dev, "failed register driver: %d\n", ret); 300 dev_err(cpu_dev, "failed register driver: %d\n", ret);
diff --git a/drivers/cpufreq/integrator-cpufreq.c b/drivers/cpufreq/integrator-cpufreq.c
index 7d8ab000d317..0e27844e8c2d 100644
--- a/drivers/cpufreq/integrator-cpufreq.c
+++ b/drivers/cpufreq/integrator-cpufreq.c
@@ -190,6 +190,7 @@ static int integrator_cpufreq_init(struct cpufreq_policy *policy)
190} 190}
191 191
192static struct cpufreq_driver integrator_driver = { 192static struct cpufreq_driver integrator_driver = {
193 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
193 .verify = integrator_verify_policy, 194 .verify = integrator_verify_policy,
194 .target = integrator_set_target, 195 .target = integrator_set_target,
195 .get = integrator_get, 196 .get = integrator_get,
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index d51f17ed691e..fe91dad8f5e2 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -35,6 +35,7 @@
35#define SAMPLE_COUNT 3 35#define SAMPLE_COUNT 3
36 36
37#define BYT_RATIOS 0x66a 37#define BYT_RATIOS 0x66a
38#define BYT_VIDS 0x66b
38 39
39#define FRAC_BITS 8 40#define FRAC_BITS 8
40#define int_tofp(X) ((int64_t)(X) << FRAC_BITS) 41#define int_tofp(X) ((int64_t)(X) << FRAC_BITS)
@@ -64,6 +65,12 @@ struct pstate_data {
64 int turbo_pstate; 65 int turbo_pstate;
65}; 66};
66 67
68struct vid_data {
69 int32_t min;
70 int32_t max;
71 int32_t ratio;
72};
73
67struct _pid { 74struct _pid {
68 int setpoint; 75 int setpoint;
69 int32_t integral; 76 int32_t integral;
@@ -82,10 +89,9 @@ struct cpudata {
82 struct timer_list timer; 89 struct timer_list timer;
83 90
84 struct pstate_data pstate; 91 struct pstate_data pstate;
92 struct vid_data vid;
85 struct _pid pid; 93 struct _pid pid;
86 94
87 int min_pstate_count;
88
89 u64 prev_aperf; 95 u64 prev_aperf;
90 u64 prev_mperf; 96 u64 prev_mperf;
91 int sample_ptr; 97 int sample_ptr;
@@ -106,7 +112,8 @@ struct pstate_funcs {
106 int (*get_max)(void); 112 int (*get_max)(void);
107 int (*get_min)(void); 113 int (*get_min)(void);
108 int (*get_turbo)(void); 114 int (*get_turbo)(void);
109 void (*set)(int pstate); 115 void (*set)(struct cpudata*, int pstate);
116 void (*get_vid)(struct cpudata *);
110}; 117};
111 118
112struct cpu_defaults { 119struct cpu_defaults {
@@ -358,6 +365,42 @@ static int byt_get_max_pstate(void)
358 return (value >> 16) & 0xFF; 365 return (value >> 16) & 0xFF;
359} 366}
360 367
368static void byt_set_pstate(struct cpudata *cpudata, int pstate)
369{
370 u64 val;
371 int32_t vid_fp;
372 u32 vid;
373
374 val = pstate << 8;
375 if (limits.no_turbo)
376 val |= (u64)1 << 32;
377
378 vid_fp = cpudata->vid.min + mul_fp(
379 int_tofp(pstate - cpudata->pstate.min_pstate),
380 cpudata->vid.ratio);
381
382 vid_fp = clamp_t(int32_t, vid_fp, cpudata->vid.min, cpudata->vid.max);
383 vid = fp_toint(vid_fp);
384
385 val |= vid;
386
387 wrmsrl(MSR_IA32_PERF_CTL, val);
388}
389
390static void byt_get_vid(struct cpudata *cpudata)
391{
392 u64 value;
393
394 rdmsrl(BYT_VIDS, value);
395 cpudata->vid.min = int_tofp((value >> 8) & 0x7f);
396 cpudata->vid.max = int_tofp((value >> 16) & 0x7f);
397 cpudata->vid.ratio = div_fp(
398 cpudata->vid.max - cpudata->vid.min,
399 int_tofp(cpudata->pstate.max_pstate -
400 cpudata->pstate.min_pstate));
401}
402
403
361static int core_get_min_pstate(void) 404static int core_get_min_pstate(void)
362{ 405{
363 u64 value; 406 u64 value;
@@ -384,7 +427,7 @@ static int core_get_turbo_pstate(void)
384 return ret; 427 return ret;
385} 428}
386 429
387static void core_set_pstate(int pstate) 430static void core_set_pstate(struct cpudata *cpudata, int pstate)
388{ 431{
389 u64 val; 432 u64 val;
390 433
@@ -425,7 +468,8 @@ static struct cpu_defaults byt_params = {
425 .get_max = byt_get_max_pstate, 468 .get_max = byt_get_max_pstate,
426 .get_min = byt_get_min_pstate, 469 .get_min = byt_get_min_pstate,
427 .get_turbo = byt_get_max_pstate, 470 .get_turbo = byt_get_max_pstate,
428 .set = core_set_pstate, 471 .set = byt_set_pstate,
472 .get_vid = byt_get_vid,
429 }, 473 },
430}; 474};
431 475
@@ -462,7 +506,7 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
462 506
463 cpu->pstate.current_pstate = pstate; 507 cpu->pstate.current_pstate = pstate;
464 508
465 pstate_funcs.set(pstate); 509 pstate_funcs.set(cpu, pstate);
466} 510}
467 511
468static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps) 512static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps)
@@ -488,6 +532,9 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
488 cpu->pstate.max_pstate = pstate_funcs.get_max(); 532 cpu->pstate.max_pstate = pstate_funcs.get_max();
489 cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(); 533 cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
490 534
535 if (pstate_funcs.get_vid)
536 pstate_funcs.get_vid(cpu);
537
491 /* 538 /*
492 * goto max pstate so we don't slow up boot if we are built-in if we are 539 * goto max pstate so we don't slow up boot if we are built-in if we are
493 * a module we will take care of it during normal operation 540 * a module we will take care of it during normal operation
@@ -568,15 +615,6 @@ static void intel_pstate_timer_func(unsigned long __data)
568 615
569 intel_pstate_sample(cpu); 616 intel_pstate_sample(cpu);
570 intel_pstate_adjust_busy_pstate(cpu); 617 intel_pstate_adjust_busy_pstate(cpu);
571
572 if (cpu->pstate.current_pstate == cpu->pstate.min_pstate) {
573 cpu->min_pstate_count++;
574 if (!(cpu->min_pstate_count % 5)) {
575 intel_pstate_set_pstate(cpu, cpu->pstate.max_pstate);
576 }
577 } else
578 cpu->min_pstate_count = 0;
579
580 intel_pstate_set_sample_time(cpu); 618 intel_pstate_set_sample_time(cpu);
581} 619}
582 620
@@ -782,6 +820,7 @@ static void copy_cpu_funcs(struct pstate_funcs *funcs)
782 pstate_funcs.get_min = funcs->get_min; 820 pstate_funcs.get_min = funcs->get_min;
783 pstate_funcs.get_turbo = funcs->get_turbo; 821 pstate_funcs.get_turbo = funcs->get_turbo;
784 pstate_funcs.set = funcs->set; 822 pstate_funcs.set = funcs->set;
823 pstate_funcs.get_vid = funcs->get_vid;
785} 824}
786 825
787#if IS_ENABLED(CONFIG_ACPI) 826#if IS_ENABLED(CONFIG_ACPI)
diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c
index 0767a4e29dfe..eb7abe345b50 100644
--- a/drivers/cpufreq/kirkwood-cpufreq.c
+++ b/drivers/cpufreq/kirkwood-cpufreq.c
@@ -97,6 +97,7 @@ static int kirkwood_cpufreq_cpu_init(struct cpufreq_policy *policy)
97} 97}
98 98
99static struct cpufreq_driver kirkwood_cpufreq_driver = { 99static struct cpufreq_driver kirkwood_cpufreq_driver = {
100 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
100 .get = kirkwood_cpufreq_get_cpu_frequency, 101 .get = kirkwood_cpufreq_get_cpu_frequency,
101 .verify = cpufreq_generic_frequency_table_verify, 102 .verify = cpufreq_generic_frequency_table_verify,
102 .target_index = kirkwood_cpufreq_target, 103 .target_index = kirkwood_cpufreq_target,
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index a0acd0bfba40..5de1e5f73eca 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -162,7 +162,7 @@ static int omap_cpu_exit(struct cpufreq_policy *policy)
162} 162}
163 163
164static struct cpufreq_driver omap_driver = { 164static struct cpufreq_driver omap_driver = {
165 .flags = CPUFREQ_STICKY, 165 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
166 .verify = cpufreq_generic_frequency_table_verify, 166 .verify = cpufreq_generic_frequency_table_verify,
167 .target_index = omap_target, 167 .target_index = omap_target,
168 .get = omap_getspeed, 168 .get = omap_getspeed,
diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c
index e2b4f40ff69a..1c0f1067af73 100644
--- a/drivers/cpufreq/pcc-cpufreq.c
+++ b/drivers/cpufreq/pcc-cpufreq.c
@@ -213,6 +213,7 @@ static int pcc_cpufreq_target(struct cpufreq_policy *policy,
213 cpu, target_freq, 213 cpu, target_freq,
214 (pcch_virt_addr + pcc_cpu_data->input_offset)); 214 (pcch_virt_addr + pcc_cpu_data->input_offset));
215 215
216 freqs.old = policy->cur;
216 freqs.new = target_freq; 217 freqs.new = target_freq;
217 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 218 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
218 219
@@ -228,25 +229,20 @@ static int pcc_cpufreq_target(struct cpufreq_policy *policy,
228 memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ); 229 memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
229 230
230 status = ioread16(&pcch_hdr->status); 231 status = ioread16(&pcch_hdr->status);
232 iowrite16(0, &pcch_hdr->status);
233
234 cpufreq_notify_post_transition(policy, &freqs, status != CMD_COMPLETE);
235 spin_unlock(&pcc_lock);
236
231 if (status != CMD_COMPLETE) { 237 if (status != CMD_COMPLETE) {
232 pr_debug("target: FAILED for cpu %d, with status: 0x%x\n", 238 pr_debug("target: FAILED for cpu %d, with status: 0x%x\n",
233 cpu, status); 239 cpu, status);
234 goto cmd_incomplete; 240 return -EINVAL;
235 } 241 }
236 iowrite16(0, &pcch_hdr->status);
237 242
238 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
239 pr_debug("target: was SUCCESSFUL for cpu %d\n", cpu); 243 pr_debug("target: was SUCCESSFUL for cpu %d\n", cpu);
240 spin_unlock(&pcc_lock);
241 244
242 return 0; 245 return 0;
243
244cmd_incomplete:
245 freqs.new = freqs.old;
246 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
247 iowrite16(0, &pcch_hdr->status);
248 spin_unlock(&pcc_lock);
249 return -EINVAL;
250} 246}
251 247
252static int pcc_get_offset(int cpu) 248static int pcc_get_offset(int cpu)
diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c
index 643e7952cad3..b9a444e358b5 100644
--- a/drivers/cpufreq/powernow-k6.c
+++ b/drivers/cpufreq/powernow-k6.c
@@ -26,41 +26,108 @@
26static unsigned int busfreq; /* FSB, in 10 kHz */ 26static unsigned int busfreq; /* FSB, in 10 kHz */
27static unsigned int max_multiplier; 27static unsigned int max_multiplier;
28 28
29static unsigned int param_busfreq = 0;
30static unsigned int param_max_multiplier = 0;
31
32module_param_named(max_multiplier, param_max_multiplier, uint, S_IRUGO);
33MODULE_PARM_DESC(max_multiplier, "Maximum multiplier (allowed values: 20 30 35 40 45 50 55 60)");
34
35module_param_named(bus_frequency, param_busfreq, uint, S_IRUGO);
36MODULE_PARM_DESC(bus_frequency, "Bus frequency in kHz");
29 37
30/* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */ 38/* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */
31static struct cpufreq_frequency_table clock_ratio[] = { 39static struct cpufreq_frequency_table clock_ratio[] = {
32 {45, /* 000 -> 4.5x */ 0}, 40 {60, /* 110 -> 6.0x */ 0},
41 {55, /* 011 -> 5.5x */ 0},
33 {50, /* 001 -> 5.0x */ 0}, 42 {50, /* 001 -> 5.0x */ 0},
43 {45, /* 000 -> 4.5x */ 0},
34 {40, /* 010 -> 4.0x */ 0}, 44 {40, /* 010 -> 4.0x */ 0},
35 {55, /* 011 -> 5.5x */ 0},
36 {20, /* 100 -> 2.0x */ 0},
37 {30, /* 101 -> 3.0x */ 0},
38 {60, /* 110 -> 6.0x */ 0},
39 {35, /* 111 -> 3.5x */ 0}, 45 {35, /* 111 -> 3.5x */ 0},
46 {30, /* 101 -> 3.0x */ 0},
47 {20, /* 100 -> 2.0x */ 0},
40 {0, CPUFREQ_TABLE_END} 48 {0, CPUFREQ_TABLE_END}
41}; 49};
42 50
51static const u8 index_to_register[8] = { 6, 3, 1, 0, 2, 7, 5, 4 };
52static const u8 register_to_index[8] = { 3, 2, 4, 1, 7, 6, 0, 5 };
53
54static const struct {
55 unsigned freq;
56 unsigned mult;
57} usual_frequency_table[] = {
58 { 400000, 40 }, // 100 * 4
59 { 450000, 45 }, // 100 * 4.5
60 { 475000, 50 }, // 95 * 5
61 { 500000, 50 }, // 100 * 5
62 { 506250, 45 }, // 112.5 * 4.5
63 { 533500, 55 }, // 97 * 5.5
64 { 550000, 55 }, // 100 * 5.5
65 { 562500, 50 }, // 112.5 * 5
66 { 570000, 60 }, // 95 * 6
67 { 600000, 60 }, // 100 * 6
68 { 618750, 55 }, // 112.5 * 5.5
69 { 660000, 55 }, // 120 * 5.5
70 { 675000, 60 }, // 112.5 * 6
71 { 720000, 60 }, // 120 * 6
72};
73
74#define FREQ_RANGE 3000
43 75
44/** 76/**
45 * powernow_k6_get_cpu_multiplier - returns the current FSB multiplier 77 * powernow_k6_get_cpu_multiplier - returns the current FSB multiplier
46 * 78 *
47 * Returns the current setting of the frequency multiplier. Core clock 79 * Returns the current setting of the frequency multiplier. Core clock
48 * speed is frequency of the Front-Side Bus multiplied with this value. 80 * speed is frequency of the Front-Side Bus multiplied with this value.
49 */ 81 */
50static int powernow_k6_get_cpu_multiplier(void) 82static int powernow_k6_get_cpu_multiplier(void)
51{ 83{
52 u64 invalue = 0; 84 unsigned long invalue = 0;
53 u32 msrval; 85 u32 msrval;
54 86
87 local_irq_disable();
88
55 msrval = POWERNOW_IOPORT + 0x1; 89 msrval = POWERNOW_IOPORT + 0x1;
56 wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */ 90 wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
57 invalue = inl(POWERNOW_IOPORT + 0x8); 91 invalue = inl(POWERNOW_IOPORT + 0x8);
58 msrval = POWERNOW_IOPORT + 0x0; 92 msrval = POWERNOW_IOPORT + 0x0;
59 wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */ 93 wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
60 94
61 return clock_ratio[(invalue >> 5)&7].driver_data; 95 local_irq_enable();
96
97 return clock_ratio[register_to_index[(invalue >> 5)&7]].driver_data;
62} 98}
63 99
100static void powernow_k6_set_cpu_multiplier(unsigned int best_i)
101{
102 unsigned long outvalue, invalue;
103 unsigned long msrval;
104 unsigned long cr0;
105
106 /* we now need to transform best_i to the BVC format, see AMD#23446 */
107
108 /*
109 * The processor doesn't respond to inquiry cycles while changing the
110 * frequency, so we must disable cache.
111 */
112 local_irq_disable();
113 cr0 = read_cr0();
114 write_cr0(cr0 | X86_CR0_CD);
115 wbinvd();
116
117 outvalue = (1<<12) | (1<<10) | (1<<9) | (index_to_register[best_i]<<5);
118
119 msrval = POWERNOW_IOPORT + 0x1;
120 wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
121 invalue = inl(POWERNOW_IOPORT + 0x8);
122 invalue = invalue & 0x1f;
123 outvalue = outvalue | invalue;
124 outl(outvalue, (POWERNOW_IOPORT + 0x8));
125 msrval = POWERNOW_IOPORT + 0x0;
126 wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
127
128 write_cr0(cr0);
129 local_irq_enable();
130}
64 131
65/** 132/**
66 * powernow_k6_target - set the PowerNow! multiplier 133 * powernow_k6_target - set the PowerNow! multiplier
@@ -71,8 +138,6 @@ static int powernow_k6_get_cpu_multiplier(void)
71static int powernow_k6_target(struct cpufreq_policy *policy, 138static int powernow_k6_target(struct cpufreq_policy *policy,
72 unsigned int best_i) 139 unsigned int best_i)
73{ 140{
74 unsigned long outvalue = 0, invalue = 0;
75 unsigned long msrval;
76 struct cpufreq_freqs freqs; 141 struct cpufreq_freqs freqs;
77 142
78 if (clock_ratio[best_i].driver_data > max_multiplier) { 143 if (clock_ratio[best_i].driver_data > max_multiplier) {
@@ -85,35 +150,63 @@ static int powernow_k6_target(struct cpufreq_policy *policy,
85 150
86 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 151 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
87 152
88 /* we now need to transform best_i to the BVC format, see AMD#23446 */ 153 powernow_k6_set_cpu_multiplier(best_i);
89
90 outvalue = (1<<12) | (1<<10) | (1<<9) | (best_i<<5);
91
92 msrval = POWERNOW_IOPORT + 0x1;
93 wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
94 invalue = inl(POWERNOW_IOPORT + 0x8);
95 invalue = invalue & 0xf;
96 outvalue = outvalue | invalue;
97 outl(outvalue , (POWERNOW_IOPORT + 0x8));
98 msrval = POWERNOW_IOPORT + 0x0;
99 wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
100 154
101 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 155 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
102 156
103 return 0; 157 return 0;
104} 158}
105 159
106
107static int powernow_k6_cpu_init(struct cpufreq_policy *policy) 160static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
108{ 161{
109 unsigned int i, f; 162 unsigned int i, f;
163 unsigned khz;
110 164
111 if (policy->cpu != 0) 165 if (policy->cpu != 0)
112 return -ENODEV; 166 return -ENODEV;
113 167
114 /* get frequencies */ 168 max_multiplier = 0;
115 max_multiplier = powernow_k6_get_cpu_multiplier(); 169 khz = cpu_khz;
116 busfreq = cpu_khz / max_multiplier; 170 for (i = 0; i < ARRAY_SIZE(usual_frequency_table); i++) {
171 if (khz >= usual_frequency_table[i].freq - FREQ_RANGE &&
172 khz <= usual_frequency_table[i].freq + FREQ_RANGE) {
173 khz = usual_frequency_table[i].freq;
174 max_multiplier = usual_frequency_table[i].mult;
175 break;
176 }
177 }
178 if (param_max_multiplier) {
179 for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
180 if (clock_ratio[i].driver_data == param_max_multiplier) {
181 max_multiplier = param_max_multiplier;
182 goto have_max_multiplier;
183 }
184 }
185 printk(KERN_ERR "powernow-k6: invalid max_multiplier parameter, valid parameters 20, 30, 35, 40, 45, 50, 55, 60\n");
186 return -EINVAL;
187 }
188
189 if (!max_multiplier) {
190 printk(KERN_WARNING "powernow-k6: unknown frequency %u, cannot determine current multiplier\n", khz);
191 printk(KERN_WARNING "powernow-k6: use module parameters max_multiplier and bus_frequency\n");
192 return -EOPNOTSUPP;
193 }
194
195have_max_multiplier:
196 param_max_multiplier = max_multiplier;
197
198 if (param_busfreq) {
199 if (param_busfreq >= 50000 && param_busfreq <= 150000) {
200 busfreq = param_busfreq / 10;
201 goto have_busfreq;
202 }
203 printk(KERN_ERR "powernow-k6: invalid bus_frequency parameter, allowed range 50000 - 150000 kHz\n");
204 return -EINVAL;
205 }
206
207 busfreq = khz / max_multiplier;
208have_busfreq:
209 param_busfreq = busfreq * 10;
117 210
118 /* table init */ 211 /* table init */
119 for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { 212 for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
@@ -125,7 +218,7 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
125 } 218 }
126 219
127 /* cpuinfo and default policy values */ 220 /* cpuinfo and default policy values */
128 policy->cpuinfo.transition_latency = 200000; 221 policy->cpuinfo.transition_latency = 500000;
129 222
130 return cpufreq_table_validate_and_show(policy, clock_ratio); 223 return cpufreq_table_validate_and_show(policy, clock_ratio);
131} 224}
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index 0023c7d40a51..e10b646634d7 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -964,14 +964,9 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data,
964 cpufreq_cpu_put(policy); 964 cpufreq_cpu_put(policy);
965 965
966 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 966 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
967
968 res = transition_fid_vid(data, fid, vid); 967 res = transition_fid_vid(data, fid, vid);
969 if (res) 968 cpufreq_notify_post_transition(policy, &freqs, res);
970 freqs.new = freqs.old;
971 else
972 freqs.new = find_khz_freq_from_fid(data->currfid);
973 969
974 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
975 return res; 970 return res;
976} 971}
977 972
diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c
index 0a0f4369636a..a9195a86b069 100644
--- a/drivers/cpufreq/pxa2xx-cpufreq.c
+++ b/drivers/cpufreq/pxa2xx-cpufreq.c
@@ -423,6 +423,7 @@ static int pxa_cpufreq_init(struct cpufreq_policy *policy)
423} 423}
424 424
425static struct cpufreq_driver pxa_cpufreq_driver = { 425static struct cpufreq_driver pxa_cpufreq_driver = {
426 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
426 .verify = cpufreq_generic_frequency_table_verify, 427 .verify = cpufreq_generic_frequency_table_verify,
427 .target_index = pxa_set_target, 428 .target_index = pxa_set_target,
428 .init = pxa_cpufreq_init, 429 .init = pxa_cpufreq_init,
diff --git a/drivers/cpufreq/pxa3xx-cpufreq.c b/drivers/cpufreq/pxa3xx-cpufreq.c
index 93840048dd11..3785687e9d70 100644
--- a/drivers/cpufreq/pxa3xx-cpufreq.c
+++ b/drivers/cpufreq/pxa3xx-cpufreq.c
@@ -201,6 +201,7 @@ static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy)
201} 201}
202 202
203static struct cpufreq_driver pxa3xx_cpufreq_driver = { 203static struct cpufreq_driver pxa3xx_cpufreq_driver = {
204 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
204 .verify = cpufreq_generic_frequency_table_verify, 205 .verify = cpufreq_generic_frequency_table_verify,
205 .target_index = pxa3xx_cpufreq_set, 206 .target_index = pxa3xx_cpufreq_set,
206 .init = pxa3xx_cpufreq_init, 207 .init = pxa3xx_cpufreq_init,
diff --git a/drivers/cpufreq/s3c2416-cpufreq.c b/drivers/cpufreq/s3c2416-cpufreq.c
index 8d904a00027b..826b8be23099 100644
--- a/drivers/cpufreq/s3c2416-cpufreq.c
+++ b/drivers/cpufreq/s3c2416-cpufreq.c
@@ -481,7 +481,7 @@ err_hclk:
481} 481}
482 482
483static struct cpufreq_driver s3c2416_cpufreq_driver = { 483static struct cpufreq_driver s3c2416_cpufreq_driver = {
484 .flags = 0, 484 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
485 .verify = cpufreq_generic_frequency_table_verify, 485 .verify = cpufreq_generic_frequency_table_verify,
486 .target_index = s3c2416_cpufreq_set_target, 486 .target_index = s3c2416_cpufreq_set_target,
487 .get = s3c2416_cpufreq_get_speed, 487 .get = s3c2416_cpufreq_get_speed,
diff --git a/drivers/cpufreq/s3c2440-cpufreq.c b/drivers/cpufreq/s3c2440-cpufreq.c
index 72b2cc8a5a85..f84ed10755b5 100644
--- a/drivers/cpufreq/s3c2440-cpufreq.c
+++ b/drivers/cpufreq/s3c2440-cpufreq.c
@@ -22,8 +22,6 @@
22#include <linux/err.h> 22#include <linux/err.h>
23#include <linux/io.h> 23#include <linux/io.h>
24 24
25#include <mach/hardware.h>
26
27#include <asm/mach/arch.h> 25#include <asm/mach/arch.h>
28#include <asm/mach/map.h> 26#include <asm/mach/map.h>
29 27
@@ -55,7 +53,7 @@ static inline int within_khz(unsigned long a, unsigned long b)
55 * specified in @cfg. The values are stored in @cfg for later use 53 * specified in @cfg. The values are stored in @cfg for later use
56 * by the relevant set routine if the request settings can be reached. 54 * by the relevant set routine if the request settings can be reached.
57 */ 55 */
58int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg) 56static int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
59{ 57{
60 unsigned int hdiv, pdiv; 58 unsigned int hdiv, pdiv;
61 unsigned long hclk, fclk, armclk; 59 unsigned long hclk, fclk, armclk;
@@ -242,7 +240,7 @@ static int s3c2440_cpufreq_calctable(struct s3c_cpufreq_config *cfg,
242 return ret; 240 return ret;
243} 241}
244 242
245struct s3c_cpufreq_info s3c2440_cpufreq_info = { 243static struct s3c_cpufreq_info s3c2440_cpufreq_info = {
246 .max = { 244 .max = {
247 .fclk = 400000000, 245 .fclk = 400000000,
248 .hclk = 133333333, 246 .hclk = 133333333,
diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c
index 485088253358..6a1bf96deec0 100644
--- a/drivers/cpufreq/s3c24xx-cpufreq.c
+++ b/drivers/cpufreq/s3c24xx-cpufreq.c
@@ -448,7 +448,7 @@ static int s3c_cpufreq_resume(struct cpufreq_policy *policy)
448#endif 448#endif
449 449
450static struct cpufreq_driver s3c24xx_driver = { 450static struct cpufreq_driver s3c24xx_driver = {
451 .flags = CPUFREQ_STICKY, 451 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
452 .target = s3c_cpufreq_target, 452 .target = s3c_cpufreq_target,
453 .get = s3c_cpufreq_get, 453 .get = s3c_cpufreq_get,
454 .init = s3c_cpufreq_init, 454 .init = s3c_cpufreq_init,
@@ -509,7 +509,7 @@ int __init s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
509 return 0; 509 return 0;
510} 510}
511 511
512int __init s3c_cpufreq_auto_io(void) 512static int __init s3c_cpufreq_auto_io(void)
513{ 513{
514 int ret; 514 int ret;
515 515
diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c
index 67e302eeefec..8435f45d7e9d 100644
--- a/drivers/cpufreq/s3c64xx-cpufreq.c
+++ b/drivers/cpufreq/s3c64xx-cpufreq.c
@@ -226,7 +226,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
226} 226}
227 227
228static struct cpufreq_driver s3c64xx_cpufreq_driver = { 228static struct cpufreq_driver s3c64xx_cpufreq_driver = {
229 .flags = 0, 229 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
230 .verify = cpufreq_generic_frequency_table_verify, 230 .verify = cpufreq_generic_frequency_table_verify,
231 .target_index = s3c64xx_cpufreq_set_target, 231 .target_index = s3c64xx_cpufreq_set_target,
232 .get = s3c64xx_cpufreq_get_speed, 232 .get = s3c64xx_cpufreq_get_speed,
diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c
index e3973dae28a7..ccd548c6f0c1 100644
--- a/drivers/cpufreq/s5pv210-cpufreq.c
+++ b/drivers/cpufreq/s5pv210-cpufreq.c
@@ -560,7 +560,7 @@ static int s5pv210_cpufreq_reboot_notifier_event(struct notifier_block *this,
560} 560}
561 561
562static struct cpufreq_driver s5pv210_driver = { 562static struct cpufreq_driver s5pv210_driver = {
563 .flags = CPUFREQ_STICKY, 563 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
564 .verify = cpufreq_generic_frequency_table_verify, 564 .verify = cpufreq_generic_frequency_table_verify,
565 .target_index = s5pv210_target, 565 .target_index = s5pv210_target,
566 .get = s5pv210_getspeed, 566 .get = s5pv210_getspeed,
diff --git a/drivers/cpufreq/sa1100-cpufreq.c b/drivers/cpufreq/sa1100-cpufreq.c
index 623da742f8e7..728eab77e8e0 100644
--- a/drivers/cpufreq/sa1100-cpufreq.c
+++ b/drivers/cpufreq/sa1100-cpufreq.c
@@ -201,7 +201,7 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy)
201} 201}
202 202
203static struct cpufreq_driver sa1100_driver __refdata = { 203static struct cpufreq_driver sa1100_driver __refdata = {
204 .flags = CPUFREQ_STICKY, 204 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
205 .verify = cpufreq_generic_frequency_table_verify, 205 .verify = cpufreq_generic_frequency_table_verify,
206 .target_index = sa1100_target, 206 .target_index = sa1100_target,
207 .get = sa11x0_getspeed, 207 .get = sa11x0_getspeed,
diff --git a/drivers/cpufreq/sa1110-cpufreq.c b/drivers/cpufreq/sa1110-cpufreq.c
index 2c2b2e601d13..546376719d8f 100644
--- a/drivers/cpufreq/sa1110-cpufreq.c
+++ b/drivers/cpufreq/sa1110-cpufreq.c
@@ -312,7 +312,7 @@ static int __init sa1110_cpu_init(struct cpufreq_policy *policy)
312/* sa1110_driver needs __refdata because it must remain after init registers 312/* sa1110_driver needs __refdata because it must remain after init registers
313 * it with cpufreq_register_driver() */ 313 * it with cpufreq_register_driver() */
314static struct cpufreq_driver sa1110_driver __refdata = { 314static struct cpufreq_driver sa1110_driver __refdata = {
315 .flags = CPUFREQ_STICKY, 315 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
316 .verify = cpufreq_generic_frequency_table_verify, 316 .verify = cpufreq_generic_frequency_table_verify,
317 .target_index = sa1110_target, 317 .target_index = sa1110_target,
318 .get = sa11x0_getspeed, 318 .get = sa11x0_getspeed,
diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c
index d02ccd19c9c4..c7525fe33407 100644
--- a/drivers/cpufreq/spear-cpufreq.c
+++ b/drivers/cpufreq/spear-cpufreq.c
@@ -138,7 +138,7 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy,
138 } 138 }
139 139
140 newfreq = clk_round_rate(srcclk, newfreq * mult); 140 newfreq = clk_round_rate(srcclk, newfreq * mult);
141 if (newfreq < 0) { 141 if (newfreq <= 0) {
142 pr_err("clk_round_rate failed for cpu src clock\n"); 142 pr_err("clk_round_rate failed for cpu src clock\n");
143 return newfreq; 143 return newfreq;
144 } 144 }
@@ -162,7 +162,7 @@ static int spear_cpufreq_init(struct cpufreq_policy *policy)
162 162
163static struct cpufreq_driver spear_cpufreq_driver = { 163static struct cpufreq_driver spear_cpufreq_driver = {
164 .name = "cpufreq-spear", 164 .name = "cpufreq-spear",
165 .flags = CPUFREQ_STICKY, 165 .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
166 .verify = cpufreq_generic_frequency_table_verify, 166 .verify = cpufreq_generic_frequency_table_verify,
167 .target_index = spear_cpufreq_target, 167 .target_index = spear_cpufreq_target,
168 .get = spear_cpufreq_get, 168 .get = spear_cpufreq_get,
diff --git a/drivers/cpufreq/tegra-cpufreq.c b/drivers/cpufreq/tegra-cpufreq.c
index b7309c37033d..01b5578ffecf 100644
--- a/drivers/cpufreq/tegra-cpufreq.c
+++ b/drivers/cpufreq/tegra-cpufreq.c
@@ -214,6 +214,7 @@ static int tegra_cpu_exit(struct cpufreq_policy *policy)
214} 214}
215 215
216static struct cpufreq_driver tegra_cpufreq_driver = { 216static struct cpufreq_driver tegra_cpufreq_driver = {
217 .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
217 .verify = cpufreq_generic_frequency_table_verify, 218 .verify = cpufreq_generic_frequency_table_verify,
218 .target_index = tegra_target, 219 .target_index = tegra_target,
219 .get = tegra_getspeed, 220 .get = tegra_getspeed,
diff --git a/drivers/cpufreq/unicore2-cpufreq.c b/drivers/cpufreq/unicore2-cpufreq.c
index 653ae2955b55..86f6cfec2e09 100644
--- a/drivers/cpufreq/unicore2-cpufreq.c
+++ b/drivers/cpufreq/unicore2-cpufreq.c
@@ -46,20 +46,18 @@ static int ucv2_target(struct cpufreq_policy *policy,
46 unsigned int target_freq, 46 unsigned int target_freq,
47 unsigned int relation) 47 unsigned int relation)
48{ 48{
49 unsigned int cur = ucv2_getspeed(0);
50 struct cpufreq_freqs freqs; 49 struct cpufreq_freqs freqs;
51 struct clk *mclk = clk_get(NULL, "MAIN_CLK"); 50 struct clk *mclk = clk_get(NULL, "MAIN_CLK");
51 int ret;
52 52
53 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 53 freqs.old = policy->cur;
54 54 freqs.new = target_freq;
55 if (!clk_set_rate(mclk, target_freq * 1000)) {
56 freqs.old = cur;
57 freqs.new = target_freq;
58 }
59 55
60 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 56 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
57 ret = clk_set_rate(mclk, target_freq * 1000);
58 cpufreq_notify_post_transition(policy, &freqs, ret);
61 59
62 return 0; 60 return ret;
63} 61}
64 62
65static int __init ucv2_cpu_init(struct cpufreq_policy *policy) 63static int __init ucv2_cpu_init(struct cpufreq_policy *policy)