diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-01-14 17:12:08 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-01-14 17:12:08 -0500 |
commit | 51c4c4ce1df49b14bbfc334c6388cc9efe32c631 (patch) | |
tree | b33a9a905b9b646c78be7df7c189e7f9c0f28f77 /drivers/cpufreq | |
parent | 6cbd7ee10e2842a3d1f9b60abede1c8f3d1f1130 (diff) | |
parent | 22c73795b101597051924556dce019385a1e2fa0 (diff) |
Merge back earlier 'pm-cpufreq' material.
Diffstat (limited to 'drivers/cpufreq')
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 | ||
182 | config GENERIC_CPUFREQ_CPU0 | 182 | config 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 | ||
5 | config ARM_BIG_LITTLE_CPUFREQ | 5 | config 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 | |||
54 | config ARM_EXYNOS5440_CPUFREQ | 55 | config 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 | ||
81 | config ARM_IMX6Q_CPUFREQ | 83 | config 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) | |||
488 | static struct cpufreq_driver bL_cpufreq_driver = { | 488 | static 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; | |||
39 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); | 39 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); |
40 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback); | 40 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback); |
41 | static DEFINE_RWLOCK(cpufreq_driver_lock); | 41 | static DEFINE_RWLOCK(cpufreq_driver_lock); |
42 | static DEFINE_MUTEX(cpufreq_governor_lock); | 42 | DEFINE_MUTEX(cpufreq_governor_lock); |
43 | static LIST_HEAD(cpufreq_policy_list); | 43 | static 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 | } |
321 | EXPORT_SYMBOL_GPL(cpufreq_notify_transition); | 321 | EXPORT_SYMBOL_GPL(cpufreq_notify_transition); |
322 | 322 | ||
323 | /* Do post notifications when there are chances that transition has failed */ | ||
324 | void 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 | } | ||
335 | EXPORT_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 | ||
1741 | out: | 1786 | out: |
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 | |||
140 | out_unlock: | ||
141 | mutex_unlock(&cpufreq_governor_lock); | ||
138 | } | 142 | } |
139 | EXPORT_SYMBOL_GPL(gov_queue_work); | 143 | EXPORT_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 | ||
260 | extern struct mutex cpufreq_governor_lock; | ||
261 | |||
260 | void dbs_check_cpu(struct dbs_data *dbs_data, int cpu); | 262 | void dbs_check_cpu(struct dbs_data *dbs_data, int cpu); |
261 | bool need_load_eval(struct cpu_dbs_common_info *cdbs, | 263 | bool 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 | ||
128 | static struct cpufreq_driver davinci_driver = { | 128 | static 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 | ||
50 | static struct cpufreq_driver dbx500_cpufreq_driver = { | 50 | static 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 | ||
220 | static struct cpufreq_driver exynos_driver = { | 221 | static 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 | ||
235 | static int __init exynos_cpufreq_init(void) | 236 | static 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 | } |
284 | late_initcall(exynos_cpufreq_init); | 285 | |
286 | static struct platform_driver exynos_cpufreq_platdrv = { | ||
287 | .driver = { | ||
288 | .name = "exynos-cpufreq", | ||
289 | .owner = THIS_MODULE, | ||
290 | }, | ||
291 | .probe = exynos_cpufreq_probe, | ||
292 | }; | ||
293 | module_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 | ||
105 | static void set_apll(unsigned int new_index, | 105 | static 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 | |||
147 | static 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 | ||
155 | static void exynos5250_set_frequency(unsigned int old_index, | 131 | static 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 | ||
314 | static struct cpufreq_driver exynos_driver = { | 314 | static 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 | } |
179 | EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target); | 179 | EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target); |
180 | 180 | ||
181 | int 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 | } | ||
200 | EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_index); | ||
201 | |||
181 | static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table); | 202 | static 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; | |||
35 | static struct cpufreq_frequency_table *freq_table; | 35 | static struct cpufreq_frequency_table *freq_table; |
36 | static unsigned int transition_latency; | 36 | static unsigned int transition_latency; |
37 | 37 | ||
38 | static u32 *imx6_soc_volt; | ||
39 | static u32 soc_opp_count; | ||
40 | |||
38 | static unsigned int imx6q_get_speed(unsigned int cpu) | 41 | static 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 | ||
140 | static struct cpufreq_driver imx6q_cpufreq_driver = { | 145 | static 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 | |||
257 | soc_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 | ||
192 | static struct cpufreq_driver integrator_driver = { | 192 | static 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 | ||
68 | struct vid_data { | ||
69 | int32_t min; | ||
70 | int32_t max; | ||
71 | int32_t ratio; | ||
72 | }; | ||
73 | |||
67 | struct _pid { | 74 | struct _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 | ||
112 | struct cpu_defaults { | 119 | struct 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 | ||
368 | static 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 | |||
390 | static 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 | |||
361 | static int core_get_min_pstate(void) | 404 | static 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 | ||
387 | static void core_set_pstate(int pstate) | 430 | static 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 | ||
468 | static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps) | 512 | static 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 | ||
99 | static struct cpufreq_driver kirkwood_cpufreq_driver = { | 99 | static 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 | ||
164 | static struct cpufreq_driver omap_driver = { | 164 | static 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 | |||
244 | cmd_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 | ||
252 | static int pcc_get_offset(int cpu) | 248 | static 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 @@ | |||
26 | static unsigned int busfreq; /* FSB, in 10 kHz */ | 26 | static unsigned int busfreq; /* FSB, in 10 kHz */ |
27 | static unsigned int max_multiplier; | 27 | static unsigned int max_multiplier; |
28 | 28 | ||
29 | static unsigned int param_busfreq = 0; | ||
30 | static unsigned int param_max_multiplier = 0; | ||
31 | |||
32 | module_param_named(max_multiplier, param_max_multiplier, uint, S_IRUGO); | ||
33 | MODULE_PARM_DESC(max_multiplier, "Maximum multiplier (allowed values: 20 30 35 40 45 50 55 60)"); | ||
34 | |||
35 | module_param_named(bus_frequency, param_busfreq, uint, S_IRUGO); | ||
36 | MODULE_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 */ |
31 | static struct cpufreq_frequency_table clock_ratio[] = { | 39 | static 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 | ||
51 | static const u8 index_to_register[8] = { 6, 3, 1, 0, 2, 7, 5, 4 }; | ||
52 | static const u8 register_to_index[8] = { 3, 2, 4, 1, 7, 6, 0, 5 }; | ||
53 | |||
54 | static 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 | */ |
50 | static int powernow_k6_get_cpu_multiplier(void) | 82 | static 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 | ||
100 | static 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) | |||
71 | static int powernow_k6_target(struct cpufreq_policy *policy, | 138 | static 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 | |||
107 | static int powernow_k6_cpu_init(struct cpufreq_policy *policy) | 160 | static 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 | |||
195 | have_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; | ||
208 | have_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 | ||
425 | static struct cpufreq_driver pxa_cpufreq_driver = { | 425 | static 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 | ||
203 | static struct cpufreq_driver pxa3xx_cpufreq_driver = { | 203 | static 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 | ||
483 | static struct cpufreq_driver s3c2416_cpufreq_driver = { | 483 | static 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 | */ |
58 | int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg) | 56 | static 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 | ||
245 | struct s3c_cpufreq_info s3c2440_cpufreq_info = { | 243 | static 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 | ||
450 | static struct cpufreq_driver s3c24xx_driver = { | 450 | static 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 | ||
512 | int __init s3c_cpufreq_auto_io(void) | 512 | static 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 | ||
228 | static struct cpufreq_driver s3c64xx_cpufreq_driver = { | 228 | static 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 | ||
562 | static struct cpufreq_driver s5pv210_driver = { | 562 | static 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 | ||
203 | static struct cpufreq_driver sa1100_driver __refdata = { | 203 | static 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() */ |
314 | static struct cpufreq_driver sa1110_driver __refdata = { | 314 | static 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 | ||
163 | static struct cpufreq_driver spear_cpufreq_driver = { | 163 | static 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 | ||
216 | static struct cpufreq_driver tegra_cpufreq_driver = { | 216 | static 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 | ||
65 | static int __init ucv2_cpu_init(struct cpufreq_policy *policy) | 63 | static int __init ucv2_cpu_init(struct cpufreq_policy *policy) |