diff options
Diffstat (limited to 'drivers/cpufreq')
70 files changed, 1517 insertions, 2936 deletions
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 534fcb825153..38093e272377 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig | |||
@@ -17,15 +17,11 @@ config CPU_FREQ | |||
17 | 17 | ||
18 | if CPU_FREQ | 18 | if CPU_FREQ |
19 | 19 | ||
20 | config CPU_FREQ_TABLE | ||
21 | tristate | ||
22 | |||
23 | config CPU_FREQ_GOV_COMMON | 20 | config CPU_FREQ_GOV_COMMON |
24 | bool | 21 | bool |
25 | 22 | ||
26 | config CPU_FREQ_STAT | 23 | config CPU_FREQ_STAT |
27 | tristate "CPU frequency translation statistics" | 24 | tristate "CPU frequency translation statistics" |
28 | select CPU_FREQ_TABLE | ||
29 | default y | 25 | default y |
30 | help | 26 | help |
31 | This driver exports CPU frequency statistics information through sysfs | 27 | This driver exports CPU frequency statistics information through sysfs |
@@ -143,7 +139,6 @@ config CPU_FREQ_GOV_USERSPACE | |||
143 | 139 | ||
144 | config CPU_FREQ_GOV_ONDEMAND | 140 | config CPU_FREQ_GOV_ONDEMAND |
145 | tristate "'ondemand' cpufreq policy governor" | 141 | tristate "'ondemand' cpufreq policy governor" |
146 | select CPU_FREQ_TABLE | ||
147 | select CPU_FREQ_GOV_COMMON | 142 | select CPU_FREQ_GOV_COMMON |
148 | help | 143 | help |
149 | 'ondemand' - This driver adds a dynamic cpufreq policy governor. | 144 | 'ondemand' - This driver adds a dynamic cpufreq policy governor. |
@@ -187,7 +182,6 @@ config CPU_FREQ_GOV_CONSERVATIVE | |||
187 | config GENERIC_CPUFREQ_CPU0 | 182 | config GENERIC_CPUFREQ_CPU0 |
188 | tristate "Generic CPU0 cpufreq driver" | 183 | tristate "Generic CPU0 cpufreq driver" |
189 | depends on HAVE_CLK && REGULATOR && PM_OPP && OF | 184 | depends on HAVE_CLK && REGULATOR && PM_OPP && OF |
190 | select CPU_FREQ_TABLE | ||
191 | help | 185 | help |
192 | This adds a generic cpufreq driver for CPU0 frequency management. | 186 | This adds a generic cpufreq driver for CPU0 frequency management. |
193 | It supports both uniprocessor (UP) and symmetric multiprocessor (SMP) | 187 | It supports both uniprocessor (UP) and symmetric multiprocessor (SMP) |
@@ -223,7 +217,6 @@ depends on IA64 | |||
223 | 217 | ||
224 | config IA64_ACPI_CPUFREQ | 218 | config IA64_ACPI_CPUFREQ |
225 | tristate "ACPI Processor P-States driver" | 219 | tristate "ACPI Processor P-States driver" |
226 | select CPU_FREQ_TABLE | ||
227 | depends on ACPI_PROCESSOR | 220 | depends on ACPI_PROCESSOR |
228 | help | 221 | help |
229 | This driver adds a CPUFreq driver which utilizes the ACPI | 222 | This driver adds a CPUFreq driver which utilizes the ACPI |
@@ -240,7 +233,6 @@ depends on MIPS | |||
240 | 233 | ||
241 | config LOONGSON2_CPUFREQ | 234 | config LOONGSON2_CPUFREQ |
242 | tristate "Loongson2 CPUFreq Driver" | 235 | tristate "Loongson2 CPUFreq Driver" |
243 | select CPU_FREQ_TABLE | ||
244 | help | 236 | help |
245 | This option adds a CPUFreq driver for loongson processors which | 237 | This option adds a CPUFreq driver for loongson processors which |
246 | support software configurable cpu frequency. | 238 | support software configurable cpu frequency. |
@@ -262,7 +254,6 @@ menu "SPARC CPU frequency scaling drivers" | |||
262 | depends on SPARC64 | 254 | depends on SPARC64 |
263 | config SPARC_US3_CPUFREQ | 255 | config SPARC_US3_CPUFREQ |
264 | tristate "UltraSPARC-III CPU Frequency driver" | 256 | tristate "UltraSPARC-III CPU Frequency driver" |
265 | select CPU_FREQ_TABLE | ||
266 | help | 257 | help |
267 | This adds the CPUFreq driver for UltraSPARC-III processors. | 258 | This adds the CPUFreq driver for UltraSPARC-III processors. |
268 | 259 | ||
@@ -272,7 +263,6 @@ config SPARC_US3_CPUFREQ | |||
272 | 263 | ||
273 | config SPARC_US2E_CPUFREQ | 264 | config SPARC_US2E_CPUFREQ |
274 | tristate "UltraSPARC-IIe CPU Frequency driver" | 265 | tristate "UltraSPARC-IIe CPU Frequency driver" |
275 | select CPU_FREQ_TABLE | ||
276 | help | 266 | help |
277 | This adds the CPUFreq driver for UltraSPARC-IIe processors. | 267 | This adds the CPUFreq driver for UltraSPARC-IIe processors. |
278 | 268 | ||
@@ -285,7 +275,6 @@ menu "SH CPU Frequency scaling" | |||
285 | depends on SUPERH | 275 | depends on SUPERH |
286 | config SH_CPU_FREQ | 276 | config SH_CPU_FREQ |
287 | tristate "SuperH CPU Frequency driver" | 277 | tristate "SuperH CPU Frequency driver" |
288 | select CPU_FREQ_TABLE | ||
289 | help | 278 | help |
290 | This adds the cpufreq driver for SuperH. Any CPU that supports | 279 | This adds the cpufreq driver for SuperH. Any CPU that supports |
291 | clock rate rounding through the clock framework can use this | 280 | clock rate rounding through the clock framework can use this |
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index 0fa204b244bd..ce52ed949249 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm | |||
@@ -5,7 +5,6 @@ | |||
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_CPU_TOPOLOGY && PM_OPP && HAVE_CLK |
8 | select CPU_FREQ_TABLE | ||
9 | help | 8 | help |
10 | This enables the Generic CPUfreq driver for ARM big.LITTLE platforms. | 9 | This enables the Generic CPUfreq driver for ARM big.LITTLE platforms. |
11 | 10 | ||
@@ -18,7 +17,6 @@ config ARM_DT_BL_CPUFREQ | |||
18 | 17 | ||
19 | config ARM_EXYNOS_CPUFREQ | 18 | config ARM_EXYNOS_CPUFREQ |
20 | bool | 19 | bool |
21 | select CPU_FREQ_TABLE | ||
22 | 20 | ||
23 | config ARM_EXYNOS4210_CPUFREQ | 21 | config ARM_EXYNOS4210_CPUFREQ |
24 | bool "SAMSUNG EXYNOS4210" | 22 | bool "SAMSUNG EXYNOS4210" |
@@ -58,7 +56,6 @@ config ARM_EXYNOS5440_CPUFREQ | |||
58 | depends on SOC_EXYNOS5440 | 56 | depends on SOC_EXYNOS5440 |
59 | depends on HAVE_CLK && PM_OPP && OF | 57 | depends on HAVE_CLK && PM_OPP && OF |
60 | default y | 58 | default y |
61 | select CPU_FREQ_TABLE | ||
62 | help | 59 | help |
63 | This adds the CPUFreq driver for Samsung EXYNOS5440 | 60 | This adds the CPUFreq driver for Samsung EXYNOS5440 |
64 | SoC. The nature of exynos5440 clock controller is | 61 | SoC. The nature of exynos5440 clock controller is |
@@ -85,7 +82,6 @@ config ARM_IMX6Q_CPUFREQ | |||
85 | tristate "Freescale i.MX6Q cpufreq support" | 82 | tristate "Freescale i.MX6Q cpufreq support" |
86 | depends on SOC_IMX6Q | 83 | depends on SOC_IMX6Q |
87 | depends on REGULATOR_ANATOP | 84 | depends on REGULATOR_ANATOP |
88 | select CPU_FREQ_TABLE | ||
89 | help | 85 | help |
90 | This adds cpufreq driver support for Freescale i.MX6Q SOC. | 86 | This adds cpufreq driver support for Freescale i.MX6Q SOC. |
91 | 87 | ||
@@ -101,7 +97,6 @@ config ARM_INTEGRATOR | |||
101 | 97 | ||
102 | config ARM_KIRKWOOD_CPUFREQ | 98 | config ARM_KIRKWOOD_CPUFREQ |
103 | def_bool ARCH_KIRKWOOD && OF | 99 | def_bool ARCH_KIRKWOOD && OF |
104 | select CPU_FREQ_TABLE | ||
105 | help | 100 | help |
106 | This adds the CPUFreq driver for Marvell Kirkwood | 101 | This adds the CPUFreq driver for Marvell Kirkwood |
107 | SoCs. | 102 | SoCs. |
@@ -110,7 +105,6 @@ config ARM_OMAP2PLUS_CPUFREQ | |||
110 | bool "TI OMAP2+" | 105 | bool "TI OMAP2+" |
111 | depends on ARCH_OMAP2PLUS | 106 | depends on ARCH_OMAP2PLUS |
112 | default ARCH_OMAP2PLUS | 107 | default ARCH_OMAP2PLUS |
113 | select CPU_FREQ_TABLE | ||
114 | 108 | ||
115 | config ARM_S3C_CPUFREQ | 109 | config ARM_S3C_CPUFREQ |
116 | bool | 110 | bool |
@@ -165,7 +159,6 @@ config ARM_S3C2412_CPUFREQ | |||
165 | config ARM_S3C2416_CPUFREQ | 159 | config ARM_S3C2416_CPUFREQ |
166 | bool "S3C2416 CPU Frequency scaling support" | 160 | bool "S3C2416 CPU Frequency scaling support" |
167 | depends on CPU_S3C2416 | 161 | depends on CPU_S3C2416 |
168 | select CPU_FREQ_TABLE | ||
169 | help | 162 | help |
170 | This adds the CPUFreq driver for the Samsung S3C2416 and | 163 | This adds the CPUFreq driver for the Samsung S3C2416 and |
171 | S3C2450 SoC. The S3C2416 supports changing the rate of the | 164 | S3C2450 SoC. The S3C2416 supports changing the rate of the |
@@ -196,7 +189,6 @@ config ARM_S3C2440_CPUFREQ | |||
196 | config ARM_S3C64XX_CPUFREQ | 189 | config ARM_S3C64XX_CPUFREQ |
197 | bool "Samsung S3C64XX" | 190 | bool "Samsung S3C64XX" |
198 | depends on CPU_S3C6410 | 191 | depends on CPU_S3C6410 |
199 | select CPU_FREQ_TABLE | ||
200 | default y | 192 | default y |
201 | help | 193 | help |
202 | This adds the CPUFreq driver for Samsung S3C6410 SoC. | 194 | This adds the CPUFreq driver for Samsung S3C6410 SoC. |
@@ -206,7 +198,6 @@ config ARM_S3C64XX_CPUFREQ | |||
206 | config ARM_S5PV210_CPUFREQ | 198 | config ARM_S5PV210_CPUFREQ |
207 | bool "Samsung S5PV210 and S5PC110" | 199 | bool "Samsung S5PV210 and S5PC110" |
208 | depends on CPU_S5PV210 | 200 | depends on CPU_S5PV210 |
209 | select CPU_FREQ_TABLE | ||
210 | default y | 201 | default y |
211 | help | 202 | help |
212 | This adds the CPUFreq driver for Samsung S5PV210 and | 203 | This adds the CPUFreq driver for Samsung S5PV210 and |
@@ -223,7 +214,6 @@ config ARM_SA1110_CPUFREQ | |||
223 | config ARM_SPEAR_CPUFREQ | 214 | config ARM_SPEAR_CPUFREQ |
224 | bool "SPEAr CPUFreq support" | 215 | bool "SPEAr CPUFreq support" |
225 | depends on PLAT_SPEAR | 216 | depends on PLAT_SPEAR |
226 | select CPU_FREQ_TABLE | ||
227 | default y | 217 | default y |
228 | help | 218 | help |
229 | This adds the CPUFreq driver support for SPEAr SOCs. | 219 | This adds the CPUFreq driver support for SPEAr SOCs. |
@@ -231,7 +221,14 @@ config ARM_SPEAR_CPUFREQ | |||
231 | config ARM_TEGRA_CPUFREQ | 221 | config ARM_TEGRA_CPUFREQ |
232 | bool "TEGRA CPUFreq support" | 222 | bool "TEGRA CPUFreq support" |
233 | depends on ARCH_TEGRA | 223 | depends on ARCH_TEGRA |
234 | select CPU_FREQ_TABLE | ||
235 | default y | 224 | default y |
236 | help | 225 | help |
237 | This adds the CPUFreq driver support for TEGRA SOCs. | 226 | This adds the CPUFreq driver support for TEGRA SOCs. |
227 | |||
228 | config ARM_VEXPRESS_SPC_CPUFREQ | ||
229 | tristate "Versatile Express SPC based CPUfreq driver" | ||
230 | select ARM_BIG_LITTLE_CPUFREQ | ||
231 | depends on ARCH_VEXPRESS_SPC | ||
232 | help | ||
233 | This add the CPUfreq driver support for Versatile Express | ||
234 | big.LITTLE platforms using SPC for power management. | ||
diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc index 25ca9db62e09..ca0021a96e19 100644 --- a/drivers/cpufreq/Kconfig.powerpc +++ b/drivers/cpufreq/Kconfig.powerpc | |||
@@ -1,7 +1,6 @@ | |||
1 | config CPU_FREQ_CBE | 1 | config CPU_FREQ_CBE |
2 | tristate "CBE frequency scaling" | 2 | tristate "CBE frequency scaling" |
3 | depends on CBE_RAS && PPC_CELL | 3 | depends on CBE_RAS && PPC_CELL |
4 | select CPU_FREQ_TABLE | ||
5 | default m | 4 | default m |
6 | help | 5 | help |
7 | This adds the cpufreq driver for Cell BE processors. | 6 | This adds the cpufreq driver for Cell BE processors. |
@@ -20,7 +19,6 @@ config CPU_FREQ_CBE_PMI | |||
20 | config CPU_FREQ_MAPLE | 19 | config CPU_FREQ_MAPLE |
21 | bool "Support for Maple 970FX Evaluation Board" | 20 | bool "Support for Maple 970FX Evaluation Board" |
22 | depends on PPC_MAPLE | 21 | depends on PPC_MAPLE |
23 | select CPU_FREQ_TABLE | ||
24 | help | 22 | help |
25 | This adds support for frequency switching on Maple 970FX | 23 | This adds support for frequency switching on Maple 970FX |
26 | Evaluation Board and compatible boards (IBM JS2x blades). | 24 | Evaluation Board and compatible boards (IBM JS2x blades). |
@@ -28,7 +26,6 @@ config CPU_FREQ_MAPLE | |||
28 | config PPC_CORENET_CPUFREQ | 26 | config PPC_CORENET_CPUFREQ |
29 | tristate "CPU frequency scaling driver for Freescale E500MC SoCs" | 27 | tristate "CPU frequency scaling driver for Freescale E500MC SoCs" |
30 | depends on PPC_E500MC && OF && COMMON_CLK | 28 | depends on PPC_E500MC && OF && COMMON_CLK |
31 | select CPU_FREQ_TABLE | ||
32 | select CLK_PPC_CORENET | 29 | select CLK_PPC_CORENET |
33 | help | 30 | help |
34 | This adds the CPUFreq driver support for Freescale e500mc, | 31 | This adds the CPUFreq driver support for Freescale e500mc, |
@@ -38,7 +35,6 @@ config PPC_CORENET_CPUFREQ | |||
38 | config CPU_FREQ_PMAC | 35 | config CPU_FREQ_PMAC |
39 | bool "Support for Apple PowerBooks" | 36 | bool "Support for Apple PowerBooks" |
40 | depends on ADB_PMU && PPC32 | 37 | depends on ADB_PMU && PPC32 |
41 | select CPU_FREQ_TABLE | ||
42 | help | 38 | help |
43 | This adds support for frequency switching on Apple PowerBooks, | 39 | This adds support for frequency switching on Apple PowerBooks, |
44 | this currently includes some models of iBook & Titanium | 40 | this currently includes some models of iBook & Titanium |
@@ -47,7 +43,6 @@ config CPU_FREQ_PMAC | |||
47 | config CPU_FREQ_PMAC64 | 43 | config CPU_FREQ_PMAC64 |
48 | bool "Support for some Apple G5s" | 44 | bool "Support for some Apple G5s" |
49 | depends on PPC_PMAC && PPC64 | 45 | depends on PPC_PMAC && PPC64 |
50 | select CPU_FREQ_TABLE | ||
51 | help | 46 | help |
52 | This adds support for frequency switching on Apple iMac G5, | 47 | This adds support for frequency switching on Apple iMac G5, |
53 | and some of the more recent desktop G5 machines as well. | 48 | and some of the more recent desktop G5 machines as well. |
@@ -55,7 +50,6 @@ config CPU_FREQ_PMAC64 | |||
55 | config PPC_PASEMI_CPUFREQ | 50 | config PPC_PASEMI_CPUFREQ |
56 | bool "Support for PA Semi PWRficient" | 51 | bool "Support for PA Semi PWRficient" |
57 | depends on PPC_PASEMI | 52 | depends on PPC_PASEMI |
58 | select CPU_FREQ_TABLE | ||
59 | default y | 53 | default y |
60 | help | 54 | help |
61 | This adds the support for frequency switching on PA Semi | 55 | This adds the support for frequency switching on PA Semi |
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86 index e2b6eabef221..6897ad85b046 100644 --- a/drivers/cpufreq/Kconfig.x86 +++ b/drivers/cpufreq/Kconfig.x86 | |||
@@ -31,7 +31,6 @@ config X86_PCC_CPUFREQ | |||
31 | 31 | ||
32 | config X86_ACPI_CPUFREQ | 32 | config X86_ACPI_CPUFREQ |
33 | tristate "ACPI Processor P-States driver" | 33 | tristate "ACPI Processor P-States driver" |
34 | select CPU_FREQ_TABLE | ||
35 | depends on ACPI_PROCESSOR | 34 | depends on ACPI_PROCESSOR |
36 | help | 35 | help |
37 | This driver adds a CPUFreq driver which utilizes the ACPI | 36 | This driver adds a CPUFreq driver which utilizes the ACPI |
@@ -60,7 +59,6 @@ config X86_ACPI_CPUFREQ_CPB | |||
60 | 59 | ||
61 | config ELAN_CPUFREQ | 60 | config ELAN_CPUFREQ |
62 | tristate "AMD Elan SC400 and SC410" | 61 | tristate "AMD Elan SC400 and SC410" |
63 | select CPU_FREQ_TABLE | ||
64 | depends on MELAN | 62 | depends on MELAN |
65 | ---help--- | 63 | ---help--- |
66 | This adds the CPUFreq driver for AMD Elan SC400 and SC410 | 64 | This adds the CPUFreq driver for AMD Elan SC400 and SC410 |
@@ -76,7 +74,6 @@ config ELAN_CPUFREQ | |||
76 | 74 | ||
77 | config SC520_CPUFREQ | 75 | config SC520_CPUFREQ |
78 | tristate "AMD Elan SC520" | 76 | tristate "AMD Elan SC520" |
79 | select CPU_FREQ_TABLE | ||
80 | depends on MELAN | 77 | depends on MELAN |
81 | ---help--- | 78 | ---help--- |
82 | This adds the CPUFreq driver for AMD Elan SC520 processor. | 79 | This adds the CPUFreq driver for AMD Elan SC520 processor. |
@@ -88,7 +85,6 @@ config SC520_CPUFREQ | |||
88 | 85 | ||
89 | config X86_POWERNOW_K6 | 86 | config X86_POWERNOW_K6 |
90 | tristate "AMD Mobile K6-2/K6-3 PowerNow!" | 87 | tristate "AMD Mobile K6-2/K6-3 PowerNow!" |
91 | select CPU_FREQ_TABLE | ||
92 | depends on X86_32 | 88 | depends on X86_32 |
93 | help | 89 | help |
94 | This adds the CPUFreq driver for mobile AMD K6-2+ and mobile | 90 | This adds the CPUFreq driver for mobile AMD K6-2+ and mobile |
@@ -100,7 +96,6 @@ config X86_POWERNOW_K6 | |||
100 | 96 | ||
101 | config X86_POWERNOW_K7 | 97 | config X86_POWERNOW_K7 |
102 | tristate "AMD Mobile Athlon/Duron PowerNow!" | 98 | tristate "AMD Mobile Athlon/Duron PowerNow!" |
103 | select CPU_FREQ_TABLE | ||
104 | depends on X86_32 | 99 | depends on X86_32 |
105 | help | 100 | help |
106 | This adds the CPUFreq driver for mobile AMD K7 mobile processors. | 101 | This adds the CPUFreq driver for mobile AMD K7 mobile processors. |
@@ -118,7 +113,6 @@ config X86_POWERNOW_K7_ACPI | |||
118 | 113 | ||
119 | config X86_POWERNOW_K8 | 114 | config X86_POWERNOW_K8 |
120 | tristate "AMD Opteron/Athlon64 PowerNow!" | 115 | tristate "AMD Opteron/Athlon64 PowerNow!" |
121 | select CPU_FREQ_TABLE | ||
122 | depends on ACPI && ACPI_PROCESSOR && X86_ACPI_CPUFREQ | 116 | depends on ACPI && ACPI_PROCESSOR && X86_ACPI_CPUFREQ |
123 | help | 117 | help |
124 | This adds the CPUFreq driver for K8/early Opteron/Athlon64 processors. | 118 | This adds the CPUFreq driver for K8/early Opteron/Athlon64 processors. |
@@ -132,7 +126,6 @@ config X86_POWERNOW_K8 | |||
132 | config X86_AMD_FREQ_SENSITIVITY | 126 | config X86_AMD_FREQ_SENSITIVITY |
133 | tristate "AMD frequency sensitivity feedback powersave bias" | 127 | tristate "AMD frequency sensitivity feedback powersave bias" |
134 | depends on CPU_FREQ_GOV_ONDEMAND && X86_ACPI_CPUFREQ && CPU_SUP_AMD | 128 | depends on CPU_FREQ_GOV_ONDEMAND && X86_ACPI_CPUFREQ && CPU_SUP_AMD |
135 | select CPU_FREQ_TABLE | ||
136 | help | 129 | help |
137 | This adds AMD-specific powersave bias function to the ondemand | 130 | This adds AMD-specific powersave bias function to the ondemand |
138 | governor, which allows it to make more power-conscious frequency | 131 | governor, which allows it to make more power-conscious frequency |
@@ -160,7 +153,6 @@ config X86_GX_SUSPMOD | |||
160 | 153 | ||
161 | config X86_SPEEDSTEP_CENTRINO | 154 | config X86_SPEEDSTEP_CENTRINO |
162 | tristate "Intel Enhanced SpeedStep (deprecated)" | 155 | tristate "Intel Enhanced SpeedStep (deprecated)" |
163 | select CPU_FREQ_TABLE | ||
164 | select X86_SPEEDSTEP_CENTRINO_TABLE if X86_32 | 156 | select X86_SPEEDSTEP_CENTRINO_TABLE if X86_32 |
165 | depends on X86_32 || (X86_64 && ACPI_PROCESSOR) | 157 | depends on X86_32 || (X86_64 && ACPI_PROCESSOR) |
166 | help | 158 | help |
@@ -190,7 +182,6 @@ config X86_SPEEDSTEP_CENTRINO_TABLE | |||
190 | 182 | ||
191 | config X86_SPEEDSTEP_ICH | 183 | config X86_SPEEDSTEP_ICH |
192 | tristate "Intel Speedstep on ICH-M chipsets (ioport interface)" | 184 | tristate "Intel Speedstep on ICH-M chipsets (ioport interface)" |
193 | select CPU_FREQ_TABLE | ||
194 | depends on X86_32 | 185 | depends on X86_32 |
195 | help | 186 | help |
196 | This adds the CPUFreq driver for certain mobile Intel Pentium III | 187 | This adds the CPUFreq driver for certain mobile Intel Pentium III |
@@ -204,7 +195,6 @@ config X86_SPEEDSTEP_ICH | |||
204 | 195 | ||
205 | config X86_SPEEDSTEP_SMI | 196 | config X86_SPEEDSTEP_SMI |
206 | tristate "Intel SpeedStep on 440BX/ZX/MX chipsets (SMI interface)" | 197 | tristate "Intel SpeedStep on 440BX/ZX/MX chipsets (SMI interface)" |
207 | select CPU_FREQ_TABLE | ||
208 | depends on X86_32 | 198 | depends on X86_32 |
209 | help | 199 | help |
210 | This adds the CPUFreq driver for certain mobile Intel Pentium III | 200 | This adds the CPUFreq driver for certain mobile Intel Pentium III |
@@ -217,7 +207,6 @@ config X86_SPEEDSTEP_SMI | |||
217 | 207 | ||
218 | config X86_P4_CLOCKMOD | 208 | config X86_P4_CLOCKMOD |
219 | tristate "Intel Pentium 4 clock modulation" | 209 | tristate "Intel Pentium 4 clock modulation" |
220 | select CPU_FREQ_TABLE | ||
221 | help | 210 | help |
222 | This adds the CPUFreq driver for Intel Pentium 4 / XEON | 211 | This adds the CPUFreq driver for Intel Pentium 4 / XEON |
223 | processors. When enabled it will lower CPU temperature by skipping | 212 | processors. When enabled it will lower CPU temperature by skipping |
@@ -259,7 +248,6 @@ config X86_LONGRUN | |||
259 | 248 | ||
260 | config X86_LONGHAUL | 249 | config X86_LONGHAUL |
261 | tristate "VIA Cyrix III Longhaul" | 250 | tristate "VIA Cyrix III Longhaul" |
262 | select CPU_FREQ_TABLE | ||
263 | depends on X86_32 && ACPI_PROCESSOR | 251 | depends on X86_32 && ACPI_PROCESSOR |
264 | help | 252 | help |
265 | This adds the CPUFreq driver for VIA Samuel/CyrixIII, | 253 | This adds the CPUFreq driver for VIA Samuel/CyrixIII, |
@@ -272,7 +260,6 @@ config X86_LONGHAUL | |||
272 | 260 | ||
273 | config X86_E_POWERSAVER | 261 | config X86_E_POWERSAVER |
274 | tristate "VIA C7 Enhanced PowerSaver (DANGEROUS)" | 262 | tristate "VIA C7 Enhanced PowerSaver (DANGEROUS)" |
275 | select CPU_FREQ_TABLE | ||
276 | depends on X86_32 && ACPI_PROCESSOR | 263 | depends on X86_32 && ACPI_PROCESSOR |
277 | help | 264 | help |
278 | This adds the CPUFreq driver for VIA C7 processors. However, this driver | 265 | This adds the CPUFreq driver for VIA C7 processors. However, this driver |
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index ad5866c2ada0..74945652dd7a 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | # CPUfreq core | 1 | # CPUfreq core |
2 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o | 2 | obj-$(CONFIG_CPU_FREQ) += cpufreq.o freq_table.o |
3 | # CPUfreq stats | 3 | # CPUfreq stats |
4 | obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o | 4 | obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o |
5 | 5 | ||
@@ -11,9 +11,6 @@ obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o | |||
11 | obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o | 11 | obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o |
12 | obj-$(CONFIG_CPU_FREQ_GOV_COMMON) += cpufreq_governor.o | 12 | obj-$(CONFIG_CPU_FREQ_GOV_COMMON) += cpufreq_governor.o |
13 | 13 | ||
14 | # CPUfreq cross-arch helpers | ||
15 | obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o | ||
16 | |||
17 | obj-$(CONFIG_GENERIC_CPUFREQ_CPU0) += cpufreq-cpu0.o | 14 | obj-$(CONFIG_GENERIC_CPUFREQ_CPU0) += cpufreq-cpu0.o |
18 | 15 | ||
19 | ################################################################################## | 16 | ################################################################################## |
@@ -77,6 +74,7 @@ obj-$(CONFIG_ARM_SA1100_CPUFREQ) += sa1100-cpufreq.o | |||
77 | obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o | 74 | obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o |
78 | obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o | 75 | obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o |
79 | obj-$(CONFIG_ARM_TEGRA_CPUFREQ) += tegra-cpufreq.o | 76 | obj-$(CONFIG_ARM_TEGRA_CPUFREQ) += tegra-cpufreq.o |
77 | obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o | ||
80 | 78 | ||
81 | ################################################################################## | 79 | ################################################################################## |
82 | # PowerPC platform drivers | 80 | # PowerPC platform drivers |
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 506fd23c7550..caf41ebea184 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
@@ -424,34 +424,21 @@ static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq, | |||
424 | } | 424 | } |
425 | 425 | ||
426 | static int acpi_cpufreq_target(struct cpufreq_policy *policy, | 426 | static int acpi_cpufreq_target(struct cpufreq_policy *policy, |
427 | unsigned int target_freq, unsigned int relation) | 427 | unsigned int index) |
428 | { | 428 | { |
429 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); | 429 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); |
430 | struct acpi_processor_performance *perf; | 430 | struct acpi_processor_performance *perf; |
431 | struct cpufreq_freqs freqs; | ||
432 | struct drv_cmd cmd; | 431 | struct drv_cmd cmd; |
433 | unsigned int next_state = 0; /* Index into freq_table */ | ||
434 | unsigned int next_perf_state = 0; /* Index into perf table */ | 432 | unsigned int next_perf_state = 0; /* Index into perf table */ |
435 | int result = 0; | 433 | int result = 0; |
436 | 434 | ||
437 | pr_debug("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu); | ||
438 | |||
439 | if (unlikely(data == NULL || | 435 | if (unlikely(data == NULL || |
440 | data->acpi_data == NULL || data->freq_table == NULL)) { | 436 | data->acpi_data == NULL || data->freq_table == NULL)) { |
441 | return -ENODEV; | 437 | return -ENODEV; |
442 | } | 438 | } |
443 | 439 | ||
444 | perf = data->acpi_data; | 440 | perf = data->acpi_data; |
445 | result = cpufreq_frequency_table_target(policy, | 441 | next_perf_state = data->freq_table[index].driver_data; |
446 | data->freq_table, | ||
447 | target_freq, | ||
448 | relation, &next_state); | ||
449 | if (unlikely(result)) { | ||
450 | result = -ENODEV; | ||
451 | goto out; | ||
452 | } | ||
453 | |||
454 | next_perf_state = data->freq_table[next_state].driver_data; | ||
455 | if (perf->state == next_perf_state) { | 442 | if (perf->state == next_perf_state) { |
456 | if (unlikely(data->resume)) { | 443 | if (unlikely(data->resume)) { |
457 | pr_debug("Called after resume, resetting to P%d\n", | 444 | pr_debug("Called after resume, resetting to P%d\n", |
@@ -492,23 +479,17 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, | |||
492 | else | 479 | else |
493 | cmd.mask = cpumask_of(policy->cpu); | 480 | cmd.mask = cpumask_of(policy->cpu); |
494 | 481 | ||
495 | freqs.old = perf->states[perf->state].core_frequency * 1000; | ||
496 | freqs.new = data->freq_table[next_state].frequency; | ||
497 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
498 | |||
499 | drv_write(&cmd); | 482 | drv_write(&cmd); |
500 | 483 | ||
501 | if (acpi_pstate_strict) { | 484 | if (acpi_pstate_strict) { |
502 | if (!check_freqs(cmd.mask, freqs.new, data)) { | 485 | if (!check_freqs(cmd.mask, data->freq_table[index].frequency, |
486 | data)) { | ||
503 | pr_debug("acpi_cpufreq_target failed (%d)\n", | 487 | pr_debug("acpi_cpufreq_target failed (%d)\n", |
504 | policy->cpu); | 488 | policy->cpu); |
505 | result = -EAGAIN; | 489 | result = -EAGAIN; |
506 | freqs.new = freqs.old; | ||
507 | } | 490 | } |
508 | } | 491 | } |
509 | 492 | ||
510 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
511 | |||
512 | if (!result) | 493 | if (!result) |
513 | perf->state = next_perf_state; | 494 | perf->state = next_perf_state; |
514 | 495 | ||
@@ -516,15 +497,6 @@ out: | |||
516 | return result; | 497 | return result; |
517 | } | 498 | } |
518 | 499 | ||
519 | static int acpi_cpufreq_verify(struct cpufreq_policy *policy) | ||
520 | { | ||
521 | struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); | ||
522 | |||
523 | pr_debug("acpi_cpufreq_verify\n"); | ||
524 | |||
525 | return cpufreq_frequency_table_verify(policy, data->freq_table); | ||
526 | } | ||
527 | |||
528 | static unsigned long | 500 | static unsigned long |
529 | acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu) | 501 | acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu) |
530 | { | 502 | { |
@@ -837,7 +809,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
837 | data->freq_table[valid_states].frequency = CPUFREQ_TABLE_END; | 809 | data->freq_table[valid_states].frequency = CPUFREQ_TABLE_END; |
838 | perf->state = 0; | 810 | perf->state = 0; |
839 | 811 | ||
840 | result = cpufreq_frequency_table_cpuinfo(policy, data->freq_table); | 812 | result = cpufreq_table_validate_and_show(policy, data->freq_table); |
841 | if (result) | 813 | if (result) |
842 | goto err_freqfree; | 814 | goto err_freqfree; |
843 | 815 | ||
@@ -846,12 +818,16 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
846 | 818 | ||
847 | switch (perf->control_register.space_id) { | 819 | switch (perf->control_register.space_id) { |
848 | case ACPI_ADR_SPACE_SYSTEM_IO: | 820 | case ACPI_ADR_SPACE_SYSTEM_IO: |
849 | /* Current speed is unknown and not detectable by IO port */ | 821 | /* |
822 | * The core will not set policy->cur, because | ||
823 | * cpufreq_driver->get is NULL, so we need to set it here. | ||
824 | * However, we have to guess it, because the current speed is | ||
825 | * unknown and not detectable via IO ports. | ||
826 | */ | ||
850 | policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu); | 827 | policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu); |
851 | break; | 828 | break; |
852 | case ACPI_ADR_SPACE_FIXED_HARDWARE: | 829 | case ACPI_ADR_SPACE_FIXED_HARDWARE: |
853 | acpi_cpufreq_driver.get = get_cur_freq_on_cpu; | 830 | acpi_cpufreq_driver.get = get_cur_freq_on_cpu; |
854 | policy->cur = get_cur_freq_on_cpu(cpu); | ||
855 | break; | 831 | break; |
856 | default: | 832 | default: |
857 | break; | 833 | break; |
@@ -868,8 +844,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
868 | (u32) perf->states[i].power, | 844 | (u32) perf->states[i].power, |
869 | (u32) perf->states[i].transition_latency); | 845 | (u32) perf->states[i].transition_latency); |
870 | 846 | ||
871 | cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu); | ||
872 | |||
873 | /* | 847 | /* |
874 | * the first call to ->target() should result in us actually | 848 | * the first call to ->target() should result in us actually |
875 | * writing something to the appropriate registers. | 849 | * writing something to the appropriate registers. |
@@ -929,8 +903,8 @@ static struct freq_attr *acpi_cpufreq_attr[] = { | |||
929 | }; | 903 | }; |
930 | 904 | ||
931 | static struct cpufreq_driver acpi_cpufreq_driver = { | 905 | static struct cpufreq_driver acpi_cpufreq_driver = { |
932 | .verify = acpi_cpufreq_verify, | 906 | .verify = cpufreq_generic_frequency_table_verify, |
933 | .target = acpi_cpufreq_target, | 907 | .target_index = acpi_cpufreq_target, |
934 | .bios_limit = acpi_processor_get_bios_limit, | 908 | .bios_limit = acpi_processor_get_bios_limit, |
935 | .init = acpi_cpufreq_cpu_init, | 909 | .init = acpi_cpufreq_cpu_init, |
936 | .exit = acpi_cpufreq_cpu_exit, | 910 | .exit = acpi_cpufreq_cpu_exit, |
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index 3549f0784af1..5519933813ea 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c | |||
@@ -24,110 +24,323 @@ | |||
24 | #include <linux/cpufreq.h> | 24 | #include <linux/cpufreq.h> |
25 | #include <linux/cpumask.h> | 25 | #include <linux/cpumask.h> |
26 | #include <linux/export.h> | 26 | #include <linux/export.h> |
27 | #include <linux/mutex.h> | ||
27 | #include <linux/of_platform.h> | 28 | #include <linux/of_platform.h> |
28 | #include <linux/opp.h> | 29 | #include <linux/pm_opp.h> |
29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
30 | #include <linux/topology.h> | 31 | #include <linux/topology.h> |
31 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <asm/bL_switcher.h> | ||
32 | 34 | ||
33 | #include "arm_big_little.h" | 35 | #include "arm_big_little.h" |
34 | 36 | ||
35 | /* Currently we support only two clusters */ | 37 | /* Currently we support only two clusters */ |
38 | #define A15_CLUSTER 0 | ||
39 | #define A7_CLUSTER 1 | ||
36 | #define MAX_CLUSTERS 2 | 40 | #define MAX_CLUSTERS 2 |
37 | 41 | ||
42 | #ifdef CONFIG_BL_SWITCHER | ||
43 | static bool bL_switching_enabled; | ||
44 | #define is_bL_switching_enabled() bL_switching_enabled | ||
45 | #define set_switching_enabled(x) (bL_switching_enabled = (x)) | ||
46 | #else | ||
47 | #define is_bL_switching_enabled() false | ||
48 | #define set_switching_enabled(x) do { } while (0) | ||
49 | #endif | ||
50 | |||
51 | #define ACTUAL_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq << 1 : freq) | ||
52 | #define VIRT_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq >> 1 : freq) | ||
53 | |||
38 | static struct cpufreq_arm_bL_ops *arm_bL_ops; | 54 | static struct cpufreq_arm_bL_ops *arm_bL_ops; |
39 | static struct clk *clk[MAX_CLUSTERS]; | 55 | static struct clk *clk[MAX_CLUSTERS]; |
40 | static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS]; | 56 | static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1]; |
41 | static atomic_t cluster_usage[MAX_CLUSTERS] = {ATOMIC_INIT(0), ATOMIC_INIT(0)}; | 57 | static atomic_t cluster_usage[MAX_CLUSTERS + 1]; |
58 | |||
59 | static unsigned int clk_big_min; /* (Big) clock frequencies */ | ||
60 | static unsigned int clk_little_max; /* Maximum clock frequency (Little) */ | ||
61 | |||
62 | static DEFINE_PER_CPU(unsigned int, physical_cluster); | ||
63 | static DEFINE_PER_CPU(unsigned int, cpu_last_req_freq); | ||
42 | 64 | ||
43 | static unsigned int bL_cpufreq_get(unsigned int cpu) | 65 | static struct mutex cluster_lock[MAX_CLUSTERS]; |
66 | |||
67 | static inline int raw_cpu_to_cluster(int cpu) | ||
44 | { | 68 | { |
45 | u32 cur_cluster = cpu_to_cluster(cpu); | 69 | return topology_physical_package_id(cpu); |
70 | } | ||
46 | 71 | ||
47 | return clk_get_rate(clk[cur_cluster]) / 1000; | 72 | static inline int cpu_to_cluster(int cpu) |
73 | { | ||
74 | return is_bL_switching_enabled() ? | ||
75 | MAX_CLUSTERS : raw_cpu_to_cluster(cpu); | ||
48 | } | 76 | } |
49 | 77 | ||
50 | /* Validate policy frequency range */ | 78 | static unsigned int find_cluster_maxfreq(int cluster) |
51 | static int bL_cpufreq_verify_policy(struct cpufreq_policy *policy) | ||
52 | { | 79 | { |
53 | u32 cur_cluster = cpu_to_cluster(policy->cpu); | 80 | int j; |
81 | u32 max_freq = 0, cpu_freq; | ||
82 | |||
83 | for_each_online_cpu(j) { | ||
84 | cpu_freq = per_cpu(cpu_last_req_freq, j); | ||
85 | |||
86 | if ((cluster == per_cpu(physical_cluster, j)) && | ||
87 | (max_freq < cpu_freq)) | ||
88 | max_freq = cpu_freq; | ||
89 | } | ||
90 | |||
91 | pr_debug("%s: cluster: %d, max freq: %d\n", __func__, cluster, | ||
92 | max_freq); | ||
93 | |||
94 | return max_freq; | ||
95 | } | ||
96 | |||
97 | static unsigned int clk_get_cpu_rate(unsigned int cpu) | ||
98 | { | ||
99 | u32 cur_cluster = per_cpu(physical_cluster, cpu); | ||
100 | u32 rate = clk_get_rate(clk[cur_cluster]) / 1000; | ||
101 | |||
102 | /* For switcher we use virtual A7 clock rates */ | ||
103 | if (is_bL_switching_enabled()) | ||
104 | rate = VIRT_FREQ(cur_cluster, rate); | ||
105 | |||
106 | pr_debug("%s: cpu: %d, cluster: %d, freq: %u\n", __func__, cpu, | ||
107 | cur_cluster, rate); | ||
108 | |||
109 | return rate; | ||
110 | } | ||
111 | |||
112 | static unsigned int bL_cpufreq_get_rate(unsigned int cpu) | ||
113 | { | ||
114 | if (is_bL_switching_enabled()) { | ||
115 | pr_debug("%s: freq: %d\n", __func__, per_cpu(cpu_last_req_freq, | ||
116 | cpu)); | ||
117 | |||
118 | return per_cpu(cpu_last_req_freq, cpu); | ||
119 | } else { | ||
120 | return clk_get_cpu_rate(cpu); | ||
121 | } | ||
122 | } | ||
123 | |||
124 | static unsigned int | ||
125 | bL_cpufreq_set_rate(u32 cpu, u32 old_cluster, u32 new_cluster, u32 rate) | ||
126 | { | ||
127 | u32 new_rate, prev_rate; | ||
128 | int ret; | ||
129 | bool bLs = is_bL_switching_enabled(); | ||
130 | |||
131 | mutex_lock(&cluster_lock[new_cluster]); | ||
54 | 132 | ||
55 | return cpufreq_frequency_table_verify(policy, freq_table[cur_cluster]); | 133 | if (bLs) { |
134 | prev_rate = per_cpu(cpu_last_req_freq, cpu); | ||
135 | per_cpu(cpu_last_req_freq, cpu) = rate; | ||
136 | per_cpu(physical_cluster, cpu) = new_cluster; | ||
137 | |||
138 | new_rate = find_cluster_maxfreq(new_cluster); | ||
139 | new_rate = ACTUAL_FREQ(new_cluster, new_rate); | ||
140 | } else { | ||
141 | new_rate = rate; | ||
142 | } | ||
143 | |||
144 | pr_debug("%s: cpu: %d, old cluster: %d, new cluster: %d, freq: %d\n", | ||
145 | __func__, cpu, old_cluster, new_cluster, new_rate); | ||
146 | |||
147 | ret = clk_set_rate(clk[new_cluster], new_rate * 1000); | ||
148 | if (WARN_ON(ret)) { | ||
149 | pr_err("clk_set_rate failed: %d, new cluster: %d\n", ret, | ||
150 | new_cluster); | ||
151 | if (bLs) { | ||
152 | per_cpu(cpu_last_req_freq, cpu) = prev_rate; | ||
153 | per_cpu(physical_cluster, cpu) = old_cluster; | ||
154 | } | ||
155 | |||
156 | mutex_unlock(&cluster_lock[new_cluster]); | ||
157 | |||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | mutex_unlock(&cluster_lock[new_cluster]); | ||
162 | |||
163 | /* Recalc freq for old cluster when switching clusters */ | ||
164 | if (old_cluster != new_cluster) { | ||
165 | pr_debug("%s: cpu: %d, old cluster: %d, new cluster: %d\n", | ||
166 | __func__, cpu, old_cluster, new_cluster); | ||
167 | |||
168 | /* Switch cluster */ | ||
169 | bL_switch_request(cpu, new_cluster); | ||
170 | |||
171 | mutex_lock(&cluster_lock[old_cluster]); | ||
172 | |||
173 | /* Set freq of old cluster if there are cpus left on it */ | ||
174 | new_rate = find_cluster_maxfreq(old_cluster); | ||
175 | new_rate = ACTUAL_FREQ(old_cluster, new_rate); | ||
176 | |||
177 | if (new_rate) { | ||
178 | pr_debug("%s: Updating rate of old cluster: %d, to freq: %d\n", | ||
179 | __func__, old_cluster, new_rate); | ||
180 | |||
181 | if (clk_set_rate(clk[old_cluster], new_rate * 1000)) | ||
182 | pr_err("%s: clk_set_rate failed: %d, old cluster: %d\n", | ||
183 | __func__, ret, old_cluster); | ||
184 | } | ||
185 | mutex_unlock(&cluster_lock[old_cluster]); | ||
186 | } | ||
187 | |||
188 | return 0; | ||
56 | } | 189 | } |
57 | 190 | ||
58 | /* Set clock frequency */ | 191 | /* Set clock frequency */ |
59 | static int bL_cpufreq_set_target(struct cpufreq_policy *policy, | 192 | static int bL_cpufreq_set_target(struct cpufreq_policy *policy, |
60 | unsigned int target_freq, unsigned int relation) | 193 | unsigned int index) |
61 | { | 194 | { |
62 | struct cpufreq_freqs freqs; | 195 | u32 cpu = policy->cpu, cur_cluster, new_cluster, actual_cluster; |
63 | u32 cpu = policy->cpu, freq_tab_idx, cur_cluster; | 196 | unsigned int freqs_new; |
64 | int ret = 0; | 197 | |
198 | cur_cluster = cpu_to_cluster(cpu); | ||
199 | new_cluster = actual_cluster = per_cpu(physical_cluster, cpu); | ||
200 | |||
201 | freqs_new = freq_table[cur_cluster][index].frequency; | ||
202 | |||
203 | if (is_bL_switching_enabled()) { | ||
204 | if ((actual_cluster == A15_CLUSTER) && | ||
205 | (freqs_new < clk_big_min)) { | ||
206 | new_cluster = A7_CLUSTER; | ||
207 | } else if ((actual_cluster == A7_CLUSTER) && | ||
208 | (freqs_new > clk_little_max)) { | ||
209 | new_cluster = A15_CLUSTER; | ||
210 | } | ||
211 | } | ||
65 | 212 | ||
66 | cur_cluster = cpu_to_cluster(policy->cpu); | 213 | return bL_cpufreq_set_rate(cpu, actual_cluster, new_cluster, freqs_new); |
214 | } | ||
67 | 215 | ||
68 | freqs.old = bL_cpufreq_get(policy->cpu); | 216 | static inline u32 get_table_count(struct cpufreq_frequency_table *table) |
217 | { | ||
218 | int count; | ||
69 | 219 | ||
70 | /* Determine valid target frequency using freq_table */ | 220 | for (count = 0; table[count].frequency != CPUFREQ_TABLE_END; count++) |
71 | cpufreq_frequency_table_target(policy, freq_table[cur_cluster], | 221 | ; |
72 | target_freq, relation, &freq_tab_idx); | ||
73 | freqs.new = freq_table[cur_cluster][freq_tab_idx].frequency; | ||
74 | 222 | ||
75 | pr_debug("%s: cpu: %d, cluster: %d, oldfreq: %d, target freq: %d, new freq: %d\n", | 223 | return count; |
76 | __func__, cpu, cur_cluster, freqs.old, target_freq, | 224 | } |
77 | freqs.new); | ||
78 | 225 | ||
79 | if (freqs.old == freqs.new) | 226 | /* get the minimum frequency in the cpufreq_frequency_table */ |
80 | return 0; | 227 | static inline u32 get_table_min(struct cpufreq_frequency_table *table) |
228 | { | ||
229 | int i; | ||
230 | uint32_t min_freq = ~0; | ||
231 | for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) | ||
232 | if (table[i].frequency < min_freq) | ||
233 | min_freq = table[i].frequency; | ||
234 | return min_freq; | ||
235 | } | ||
81 | 236 | ||
82 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 237 | /* get the maximum frequency in the cpufreq_frequency_table */ |
238 | static inline u32 get_table_max(struct cpufreq_frequency_table *table) | ||
239 | { | ||
240 | int i; | ||
241 | uint32_t max_freq = 0; | ||
242 | for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) | ||
243 | if (table[i].frequency > max_freq) | ||
244 | max_freq = table[i].frequency; | ||
245 | return max_freq; | ||
246 | } | ||
83 | 247 | ||
84 | ret = clk_set_rate(clk[cur_cluster], freqs.new * 1000); | 248 | static int merge_cluster_tables(void) |
85 | if (ret) { | 249 | { |
86 | pr_err("clk_set_rate failed: %d\n", ret); | 250 | int i, j, k = 0, count = 1; |
87 | freqs.new = freqs.old; | 251 | struct cpufreq_frequency_table *table; |
252 | |||
253 | for (i = 0; i < MAX_CLUSTERS; i++) | ||
254 | count += get_table_count(freq_table[i]); | ||
255 | |||
256 | table = kzalloc(sizeof(*table) * count, GFP_KERNEL); | ||
257 | if (!table) | ||
258 | return -ENOMEM; | ||
259 | |||
260 | freq_table[MAX_CLUSTERS] = table; | ||
261 | |||
262 | /* Add in reverse order to get freqs in increasing order */ | ||
263 | for (i = MAX_CLUSTERS - 1; i >= 0; i--) { | ||
264 | for (j = 0; freq_table[i][j].frequency != CPUFREQ_TABLE_END; | ||
265 | j++) { | ||
266 | table[k].frequency = VIRT_FREQ(i, | ||
267 | freq_table[i][j].frequency); | ||
268 | pr_debug("%s: index: %d, freq: %d\n", __func__, k, | ||
269 | table[k].frequency); | ||
270 | k++; | ||
271 | } | ||
88 | } | 272 | } |
89 | 273 | ||
90 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | 274 | table[k].driver_data = k; |
275 | table[k].frequency = CPUFREQ_TABLE_END; | ||
91 | 276 | ||
92 | return ret; | 277 | pr_debug("%s: End, table: %p, count: %d\n", __func__, table, k); |
278 | |||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | static void _put_cluster_clk_and_freq_table(struct device *cpu_dev) | ||
283 | { | ||
284 | u32 cluster = raw_cpu_to_cluster(cpu_dev->id); | ||
285 | |||
286 | if (!freq_table[cluster]) | ||
287 | return; | ||
288 | |||
289 | clk_put(clk[cluster]); | ||
290 | dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table[cluster]); | ||
291 | dev_dbg(cpu_dev, "%s: cluster: %d\n", __func__, cluster); | ||
93 | } | 292 | } |
94 | 293 | ||
95 | static void put_cluster_clk_and_freq_table(struct device *cpu_dev) | 294 | static void put_cluster_clk_and_freq_table(struct device *cpu_dev) |
96 | { | 295 | { |
97 | u32 cluster = cpu_to_cluster(cpu_dev->id); | 296 | u32 cluster = cpu_to_cluster(cpu_dev->id); |
297 | int i; | ||
298 | |||
299 | if (atomic_dec_return(&cluster_usage[cluster])) | ||
300 | return; | ||
301 | |||
302 | if (cluster < MAX_CLUSTERS) | ||
303 | return _put_cluster_clk_and_freq_table(cpu_dev); | ||
98 | 304 | ||
99 | if (!atomic_dec_return(&cluster_usage[cluster])) { | 305 | for_each_present_cpu(i) { |
100 | clk_put(clk[cluster]); | 306 | struct device *cdev = get_cpu_device(i); |
101 | opp_free_cpufreq_table(cpu_dev, &freq_table[cluster]); | 307 | if (!cdev) { |
102 | dev_dbg(cpu_dev, "%s: cluster: %d\n", __func__, cluster); | 308 | pr_err("%s: failed to get cpu%d device\n", __func__, i); |
309 | return; | ||
310 | } | ||
311 | |||
312 | _put_cluster_clk_and_freq_table(cdev); | ||
103 | } | 313 | } |
314 | |||
315 | /* free virtual table */ | ||
316 | kfree(freq_table[cluster]); | ||
104 | } | 317 | } |
105 | 318 | ||
106 | static int get_cluster_clk_and_freq_table(struct device *cpu_dev) | 319 | static int _get_cluster_clk_and_freq_table(struct device *cpu_dev) |
107 | { | 320 | { |
108 | u32 cluster = cpu_to_cluster(cpu_dev->id); | 321 | u32 cluster = raw_cpu_to_cluster(cpu_dev->id); |
109 | char name[14] = "cpu-cluster."; | 322 | char name[14] = "cpu-cluster."; |
110 | int ret; | 323 | int ret; |
111 | 324 | ||
112 | if (atomic_inc_return(&cluster_usage[cluster]) != 1) | 325 | if (freq_table[cluster]) |
113 | return 0; | 326 | return 0; |
114 | 327 | ||
115 | ret = arm_bL_ops->init_opp_table(cpu_dev); | 328 | ret = arm_bL_ops->init_opp_table(cpu_dev); |
116 | if (ret) { | 329 | if (ret) { |
117 | dev_err(cpu_dev, "%s: init_opp_table failed, cpu: %d, err: %d\n", | 330 | dev_err(cpu_dev, "%s: init_opp_table failed, cpu: %d, err: %d\n", |
118 | __func__, cpu_dev->id, ret); | 331 | __func__, cpu_dev->id, ret); |
119 | goto atomic_dec; | 332 | goto out; |
120 | } | 333 | } |
121 | 334 | ||
122 | ret = opp_init_cpufreq_table(cpu_dev, &freq_table[cluster]); | 335 | ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table[cluster]); |
123 | if (ret) { | 336 | if (ret) { |
124 | dev_err(cpu_dev, "%s: failed to init cpufreq table, cpu: %d, err: %d\n", | 337 | dev_err(cpu_dev, "%s: failed to init cpufreq table, cpu: %d, err: %d\n", |
125 | __func__, cpu_dev->id, ret); | 338 | __func__, cpu_dev->id, ret); |
126 | goto atomic_dec; | 339 | goto out; |
127 | } | 340 | } |
128 | 341 | ||
129 | name[12] = cluster + '0'; | 342 | name[12] = cluster + '0'; |
130 | clk[cluster] = clk_get_sys(name, NULL); | 343 | clk[cluster] = clk_get(cpu_dev, name); |
131 | if (!IS_ERR(clk[cluster])) { | 344 | if (!IS_ERR(clk[cluster])) { |
132 | dev_dbg(cpu_dev, "%s: clk: %p & freq table: %p, cluster: %d\n", | 345 | dev_dbg(cpu_dev, "%s: clk: %p & freq table: %p, cluster: %d\n", |
133 | __func__, clk[cluster], freq_table[cluster], | 346 | __func__, clk[cluster], freq_table[cluster], |
@@ -138,15 +351,74 @@ static int get_cluster_clk_and_freq_table(struct device *cpu_dev) | |||
138 | dev_err(cpu_dev, "%s: Failed to get clk for cpu: %d, cluster: %d\n", | 351 | dev_err(cpu_dev, "%s: Failed to get clk for cpu: %d, cluster: %d\n", |
139 | __func__, cpu_dev->id, cluster); | 352 | __func__, cpu_dev->id, cluster); |
140 | ret = PTR_ERR(clk[cluster]); | 353 | ret = PTR_ERR(clk[cluster]); |
141 | opp_free_cpufreq_table(cpu_dev, &freq_table[cluster]); | 354 | dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table[cluster]); |
142 | 355 | ||
143 | atomic_dec: | 356 | out: |
144 | atomic_dec(&cluster_usage[cluster]); | ||
145 | dev_err(cpu_dev, "%s: Failed to get data for cluster: %d\n", __func__, | 357 | dev_err(cpu_dev, "%s: Failed to get data for cluster: %d\n", __func__, |
146 | cluster); | 358 | cluster); |
147 | return ret; | 359 | return ret; |
148 | } | 360 | } |
149 | 361 | ||
362 | static int get_cluster_clk_and_freq_table(struct device *cpu_dev) | ||
363 | { | ||
364 | u32 cluster = cpu_to_cluster(cpu_dev->id); | ||
365 | int i, ret; | ||
366 | |||
367 | if (atomic_inc_return(&cluster_usage[cluster]) != 1) | ||
368 | return 0; | ||
369 | |||
370 | if (cluster < MAX_CLUSTERS) { | ||
371 | ret = _get_cluster_clk_and_freq_table(cpu_dev); | ||
372 | if (ret) | ||
373 | atomic_dec(&cluster_usage[cluster]); | ||
374 | return ret; | ||
375 | } | ||
376 | |||
377 | /* | ||
378 | * Get data for all clusters and fill virtual cluster with a merge of | ||
379 | * both | ||
380 | */ | ||
381 | for_each_present_cpu(i) { | ||
382 | struct device *cdev = get_cpu_device(i); | ||
383 | if (!cdev) { | ||
384 | pr_err("%s: failed to get cpu%d device\n", __func__, i); | ||
385 | return -ENODEV; | ||
386 | } | ||
387 | |||
388 | ret = _get_cluster_clk_and_freq_table(cdev); | ||
389 | if (ret) | ||
390 | goto put_clusters; | ||
391 | } | ||
392 | |||
393 | ret = merge_cluster_tables(); | ||
394 | if (ret) | ||
395 | goto put_clusters; | ||
396 | |||
397 | /* Assuming 2 cluster, set clk_big_min and clk_little_max */ | ||
398 | clk_big_min = get_table_min(freq_table[0]); | ||
399 | clk_little_max = VIRT_FREQ(1, get_table_max(freq_table[1])); | ||
400 | |||
401 | pr_debug("%s: cluster: %d, clk_big_min: %d, clk_little_max: %d\n", | ||
402 | __func__, cluster, clk_big_min, clk_little_max); | ||
403 | |||
404 | return 0; | ||
405 | |||
406 | put_clusters: | ||
407 | for_each_present_cpu(i) { | ||
408 | struct device *cdev = get_cpu_device(i); | ||
409 | if (!cdev) { | ||
410 | pr_err("%s: failed to get cpu%d device\n", __func__, i); | ||
411 | return -ENODEV; | ||
412 | } | ||
413 | |||
414 | _put_cluster_clk_and_freq_table(cdev); | ||
415 | } | ||
416 | |||
417 | atomic_dec(&cluster_usage[cluster]); | ||
418 | |||
419 | return ret; | ||
420 | } | ||
421 | |||
150 | /* Per-CPU initialization */ | 422 | /* Per-CPU initialization */ |
151 | static int bL_cpufreq_init(struct cpufreq_policy *policy) | 423 | static int bL_cpufreq_init(struct cpufreq_policy *policy) |
152 | { | 424 | { |
@@ -165,7 +437,7 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy) | |||
165 | if (ret) | 437 | if (ret) |
166 | return ret; | 438 | return ret; |
167 | 439 | ||
168 | ret = cpufreq_frequency_table_cpuinfo(policy, freq_table[cur_cluster]); | 440 | ret = cpufreq_table_validate_and_show(policy, freq_table[cur_cluster]); |
169 | if (ret) { | 441 | if (ret) { |
170 | dev_err(cpu_dev, "CPU %d, cluster: %d invalid freq table\n", | 442 | dev_err(cpu_dev, "CPU %d, cluster: %d invalid freq table\n", |
171 | policy->cpu, cur_cluster); | 443 | policy->cpu, cur_cluster); |
@@ -173,7 +445,14 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy) | |||
173 | return ret; | 445 | return ret; |
174 | } | 446 | } |
175 | 447 | ||
176 | cpufreq_frequency_table_get_attr(freq_table[cur_cluster], policy->cpu); | 448 | if (cur_cluster < MAX_CLUSTERS) { |
449 | cpumask_copy(policy->cpus, topology_core_cpumask(policy->cpu)); | ||
450 | |||
451 | per_cpu(physical_cluster, policy->cpu) = cur_cluster; | ||
452 | } else { | ||
453 | /* Assumption: during init, we are always running on A15 */ | ||
454 | per_cpu(physical_cluster, policy->cpu) = A15_CLUSTER; | ||
455 | } | ||
177 | 456 | ||
178 | if (arm_bL_ops->get_transition_latency) | 457 | if (arm_bL_ops->get_transition_latency) |
179 | policy->cpuinfo.transition_latency = | 458 | policy->cpuinfo.transition_latency = |
@@ -181,9 +460,8 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy) | |||
181 | else | 460 | else |
182 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 461 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; |
183 | 462 | ||
184 | policy->cur = bL_cpufreq_get(policy->cpu); | 463 | if (is_bL_switching_enabled()) |
185 | 464 | per_cpu(cpu_last_req_freq, policy->cpu) = clk_get_cpu_rate(policy->cpu); | |
186 | cpumask_copy(policy->cpus, topology_core_cpumask(policy->cpu)); | ||
187 | 465 | ||
188 | dev_info(cpu_dev, "%s: CPU %d initialized\n", __func__, policy->cpu); | 466 | dev_info(cpu_dev, "%s: CPU %d initialized\n", __func__, policy->cpu); |
189 | return 0; | 467 | return 0; |
@@ -200,33 +478,60 @@ static int bL_cpufreq_exit(struct cpufreq_policy *policy) | |||
200 | return -ENODEV; | 478 | return -ENODEV; |
201 | } | 479 | } |
202 | 480 | ||
481 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
203 | put_cluster_clk_and_freq_table(cpu_dev); | 482 | put_cluster_clk_and_freq_table(cpu_dev); |
204 | dev_dbg(cpu_dev, "%s: Exited, cpu: %d\n", __func__, policy->cpu); | 483 | dev_dbg(cpu_dev, "%s: Exited, cpu: %d\n", __func__, policy->cpu); |
205 | 484 | ||
206 | return 0; | 485 | return 0; |
207 | } | 486 | } |
208 | 487 | ||
209 | /* Export freq_table to sysfs */ | ||
210 | static struct freq_attr *bL_cpufreq_attr[] = { | ||
211 | &cpufreq_freq_attr_scaling_available_freqs, | ||
212 | NULL, | ||
213 | }; | ||
214 | |||
215 | static struct cpufreq_driver bL_cpufreq_driver = { | 488 | static struct cpufreq_driver bL_cpufreq_driver = { |
216 | .name = "arm-big-little", | 489 | .name = "arm-big-little", |
217 | .flags = CPUFREQ_STICKY, | 490 | .flags = CPUFREQ_STICKY | |
218 | .verify = bL_cpufreq_verify_policy, | 491 | CPUFREQ_HAVE_GOVERNOR_PER_POLICY, |
219 | .target = bL_cpufreq_set_target, | 492 | .verify = cpufreq_generic_frequency_table_verify, |
220 | .get = bL_cpufreq_get, | 493 | .target_index = bL_cpufreq_set_target, |
494 | .get = bL_cpufreq_get_rate, | ||
221 | .init = bL_cpufreq_init, | 495 | .init = bL_cpufreq_init, |
222 | .exit = bL_cpufreq_exit, | 496 | .exit = bL_cpufreq_exit, |
223 | .have_governor_per_policy = true, | 497 | .attr = cpufreq_generic_attr, |
224 | .attr = bL_cpufreq_attr, | 498 | }; |
499 | |||
500 | static int bL_cpufreq_switcher_notifier(struct notifier_block *nfb, | ||
501 | unsigned long action, void *_arg) | ||
502 | { | ||
503 | pr_debug("%s: action: %ld\n", __func__, action); | ||
504 | |||
505 | switch (action) { | ||
506 | case BL_NOTIFY_PRE_ENABLE: | ||
507 | case BL_NOTIFY_PRE_DISABLE: | ||
508 | cpufreq_unregister_driver(&bL_cpufreq_driver); | ||
509 | break; | ||
510 | |||
511 | case BL_NOTIFY_POST_ENABLE: | ||
512 | set_switching_enabled(true); | ||
513 | cpufreq_register_driver(&bL_cpufreq_driver); | ||
514 | break; | ||
515 | |||
516 | case BL_NOTIFY_POST_DISABLE: | ||
517 | set_switching_enabled(false); | ||
518 | cpufreq_register_driver(&bL_cpufreq_driver); | ||
519 | break; | ||
520 | |||
521 | default: | ||
522 | return NOTIFY_DONE; | ||
523 | } | ||
524 | |||
525 | return NOTIFY_OK; | ||
526 | } | ||
527 | |||
528 | static struct notifier_block bL_switcher_notifier = { | ||
529 | .notifier_call = bL_cpufreq_switcher_notifier, | ||
225 | }; | 530 | }; |
226 | 531 | ||
227 | int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops) | 532 | int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops) |
228 | { | 533 | { |
229 | int ret; | 534 | int ret, i; |
230 | 535 | ||
231 | if (arm_bL_ops) { | 536 | if (arm_bL_ops) { |
232 | pr_debug("%s: Already registered: %s, exiting\n", __func__, | 537 | pr_debug("%s: Already registered: %s, exiting\n", __func__, |
@@ -241,16 +546,29 @@ int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops) | |||
241 | 546 | ||
242 | arm_bL_ops = ops; | 547 | arm_bL_ops = ops; |
243 | 548 | ||
549 | ret = bL_switcher_get_enabled(); | ||
550 | set_switching_enabled(ret); | ||
551 | |||
552 | for (i = 0; i < MAX_CLUSTERS; i++) | ||
553 | mutex_init(&cluster_lock[i]); | ||
554 | |||
244 | ret = cpufreq_register_driver(&bL_cpufreq_driver); | 555 | ret = cpufreq_register_driver(&bL_cpufreq_driver); |
245 | if (ret) { | 556 | if (ret) { |
246 | pr_info("%s: Failed registering platform driver: %s, err: %d\n", | 557 | pr_info("%s: Failed registering platform driver: %s, err: %d\n", |
247 | __func__, ops->name, ret); | 558 | __func__, ops->name, ret); |
248 | arm_bL_ops = NULL; | 559 | arm_bL_ops = NULL; |
249 | } else { | 560 | } else { |
250 | pr_info("%s: Registered platform driver: %s\n", __func__, | 561 | ret = bL_switcher_register_notifier(&bL_switcher_notifier); |
251 | ops->name); | 562 | if (ret) { |
563 | cpufreq_unregister_driver(&bL_cpufreq_driver); | ||
564 | arm_bL_ops = NULL; | ||
565 | } else { | ||
566 | pr_info("%s: Registered platform driver: %s\n", | ||
567 | __func__, ops->name); | ||
568 | } | ||
252 | } | 569 | } |
253 | 570 | ||
571 | bL_switcher_put_enabled(); | ||
254 | return ret; | 572 | return ret; |
255 | } | 573 | } |
256 | EXPORT_SYMBOL_GPL(bL_cpufreq_register); | 574 | EXPORT_SYMBOL_GPL(bL_cpufreq_register); |
@@ -263,7 +581,10 @@ void bL_cpufreq_unregister(struct cpufreq_arm_bL_ops *ops) | |||
263 | return; | 581 | return; |
264 | } | 582 | } |
265 | 583 | ||
584 | bL_switcher_get_enabled(); | ||
585 | bL_switcher_unregister_notifier(&bL_switcher_notifier); | ||
266 | cpufreq_unregister_driver(&bL_cpufreq_driver); | 586 | cpufreq_unregister_driver(&bL_cpufreq_driver); |
587 | bL_switcher_put_enabled(); | ||
267 | pr_info("%s: Un-registered platform driver: %s\n", __func__, | 588 | pr_info("%s: Un-registered platform driver: %s\n", __func__, |
268 | arm_bL_ops->name); | 589 | arm_bL_ops->name); |
269 | arm_bL_ops = NULL; | 590 | arm_bL_ops = NULL; |
diff --git a/drivers/cpufreq/arm_big_little.h b/drivers/cpufreq/arm_big_little.h index 79b2ce17884d..70f18fc12d4a 100644 --- a/drivers/cpufreq/arm_big_little.h +++ b/drivers/cpufreq/arm_big_little.h | |||
@@ -34,11 +34,6 @@ struct cpufreq_arm_bL_ops { | |||
34 | int (*init_opp_table)(struct device *cpu_dev); | 34 | int (*init_opp_table)(struct device *cpu_dev); |
35 | }; | 35 | }; |
36 | 36 | ||
37 | static inline int cpu_to_cluster(int cpu) | ||
38 | { | ||
39 | return topology_physical_package_id(cpu); | ||
40 | } | ||
41 | |||
42 | int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops); | 37 | int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops); |
43 | void bL_cpufreq_unregister(struct cpufreq_arm_bL_ops *ops); | 38 | void bL_cpufreq_unregister(struct cpufreq_arm_bL_ops *ops); |
44 | 39 | ||
diff --git a/drivers/cpufreq/arm_big_little_dt.c b/drivers/cpufreq/arm_big_little_dt.c index 480c0bd0468d..8d9d59108906 100644 --- a/drivers/cpufreq/arm_big_little_dt.c +++ b/drivers/cpufreq/arm_big_little_dt.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/export.h> | 24 | #include <linux/export.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/of_device.h> | 26 | #include <linux/of_device.h> |
27 | #include <linux/opp.h> | 27 | #include <linux/pm_opp.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
diff --git a/drivers/cpufreq/at32ap-cpufreq.c b/drivers/cpufreq/at32ap-cpufreq.c index e0c38d938997..856ad80418ae 100644 --- a/drivers/cpufreq/at32ap-cpufreq.c +++ b/drivers/cpufreq/at32ap-cpufreq.c | |||
@@ -19,18 +19,10 @@ | |||
19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/export.h> | 21 | #include <linux/export.h> |
22 | #include <linux/slab.h> | ||
22 | 23 | ||
23 | static struct clk *cpuclk; | 24 | static struct clk *cpuclk; |
24 | 25 | static struct cpufreq_frequency_table *freq_table; | |
25 | static int at32_verify_speed(struct cpufreq_policy *policy) | ||
26 | { | ||
27 | if (policy->cpu != 0) | ||
28 | return -EINVAL; | ||
29 | |||
30 | cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | ||
31 | policy->cpuinfo.max_freq); | ||
32 | return 0; | ||
33 | } | ||
34 | 26 | ||
35 | static unsigned int at32_get_speed(unsigned int cpu) | 27 | static unsigned int at32_get_speed(unsigned int cpu) |
36 | { | 28 | { |
@@ -43,74 +35,94 @@ static unsigned int at32_get_speed(unsigned int cpu) | |||
43 | static unsigned int ref_freq; | 35 | static unsigned int ref_freq; |
44 | static unsigned long loops_per_jiffy_ref; | 36 | static unsigned long loops_per_jiffy_ref; |
45 | 37 | ||
46 | static int at32_set_target(struct cpufreq_policy *policy, | 38 | static int at32_set_target(struct cpufreq_policy *policy, unsigned int index) |
47 | unsigned int target_freq, | ||
48 | unsigned int relation) | ||
49 | { | 39 | { |
50 | struct cpufreq_freqs freqs; | 40 | unsigned int old_freq, new_freq; |
51 | long freq; | ||
52 | |||
53 | /* Convert target_freq from kHz to Hz */ | ||
54 | freq = clk_round_rate(cpuclk, target_freq * 1000); | ||
55 | |||
56 | /* Check if policy->min <= new_freq <= policy->max */ | ||
57 | if(freq < (policy->min * 1000) || freq > (policy->max * 1000)) | ||
58 | return -EINVAL; | ||
59 | |||
60 | pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000); | ||
61 | 41 | ||
62 | freqs.old = at32_get_speed(0); | 42 | old_freq = at32_get_speed(0); |
63 | freqs.new = (freq + 500) / 1000; | 43 | new_freq = freq_table[index].frequency; |
64 | freqs.flags = 0; | ||
65 | 44 | ||
66 | if (!ref_freq) { | 45 | if (!ref_freq) { |
67 | ref_freq = freqs.old; | 46 | ref_freq = old_freq; |
68 | loops_per_jiffy_ref = boot_cpu_data.loops_per_jiffy; | 47 | loops_per_jiffy_ref = boot_cpu_data.loops_per_jiffy; |
69 | } | 48 | } |
70 | 49 | ||
71 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 50 | if (old_freq < new_freq) |
72 | if (freqs.old < freqs.new) | ||
73 | boot_cpu_data.loops_per_jiffy = cpufreq_scale( | 51 | boot_cpu_data.loops_per_jiffy = cpufreq_scale( |
74 | loops_per_jiffy_ref, ref_freq, freqs.new); | 52 | loops_per_jiffy_ref, ref_freq, new_freq); |
75 | clk_set_rate(cpuclk, freq); | 53 | clk_set_rate(cpuclk, new_freq * 1000); |
76 | if (freqs.new < freqs.old) | 54 | if (new_freq < old_freq) |
77 | boot_cpu_data.loops_per_jiffy = cpufreq_scale( | 55 | boot_cpu_data.loops_per_jiffy = cpufreq_scale( |
78 | loops_per_jiffy_ref, ref_freq, freqs.new); | 56 | loops_per_jiffy_ref, ref_freq, new_freq); |
79 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
80 | |||
81 | pr_debug("cpufreq: set frequency %lu Hz\n", freq); | ||
82 | 57 | ||
83 | return 0; | 58 | return 0; |
84 | } | 59 | } |
85 | 60 | ||
86 | static int __init at32_cpufreq_driver_init(struct cpufreq_policy *policy) | 61 | static int __init at32_cpufreq_driver_init(struct cpufreq_policy *policy) |
87 | { | 62 | { |
63 | unsigned int frequency, rate, min_freq; | ||
64 | int retval, steps, i; | ||
65 | |||
88 | if (policy->cpu != 0) | 66 | if (policy->cpu != 0) |
89 | return -EINVAL; | 67 | return -EINVAL; |
90 | 68 | ||
91 | cpuclk = clk_get(NULL, "cpu"); | 69 | cpuclk = clk_get(NULL, "cpu"); |
92 | if (IS_ERR(cpuclk)) { | 70 | if (IS_ERR(cpuclk)) { |
93 | pr_debug("cpufreq: could not get CPU clk\n"); | 71 | pr_debug("cpufreq: could not get CPU clk\n"); |
94 | return PTR_ERR(cpuclk); | 72 | retval = PTR_ERR(cpuclk); |
73 | goto out_err; | ||
95 | } | 74 | } |
96 | 75 | ||
97 | policy->cpuinfo.min_freq = (clk_round_rate(cpuclk, 1) + 500) / 1000; | 76 | min_freq = (clk_round_rate(cpuclk, 1) + 500) / 1000; |
98 | policy->cpuinfo.max_freq = (clk_round_rate(cpuclk, ~0UL) + 500) / 1000; | 77 | frequency = (clk_round_rate(cpuclk, ~0UL) + 500) / 1000; |
99 | policy->cpuinfo.transition_latency = 0; | 78 | policy->cpuinfo.transition_latency = 0; |
100 | policy->cur = at32_get_speed(0); | ||
101 | policy->min = policy->cpuinfo.min_freq; | ||
102 | policy->max = policy->cpuinfo.max_freq; | ||
103 | 79 | ||
104 | printk("cpufreq: AT32AP CPU frequency driver\n"); | 80 | /* |
81 | * AVR32 CPU frequency rate scales in power of two between maximum and | ||
82 | * minimum, also add space for the table end marker. | ||
83 | * | ||
84 | * Further validate that the frequency is usable, and append it to the | ||
85 | * frequency table. | ||
86 | */ | ||
87 | steps = fls(frequency / min_freq) + 1; | ||
88 | freq_table = kzalloc(steps * sizeof(struct cpufreq_frequency_table), | ||
89 | GFP_KERNEL); | ||
90 | if (!freq_table) { | ||
91 | retval = -ENOMEM; | ||
92 | goto out_err_put_clk; | ||
93 | } | ||
105 | 94 | ||
106 | return 0; | 95 | for (i = 0; i < (steps - 1); i++) { |
96 | rate = clk_round_rate(cpuclk, frequency * 1000) / 1000; | ||
97 | |||
98 | if (rate != frequency) | ||
99 | freq_table[i].frequency = CPUFREQ_ENTRY_INVALID; | ||
100 | else | ||
101 | freq_table[i].frequency = frequency; | ||
102 | |||
103 | frequency /= 2; | ||
104 | } | ||
105 | |||
106 | freq_table[steps - 1].frequency = CPUFREQ_TABLE_END; | ||
107 | |||
108 | retval = cpufreq_table_validate_and_show(policy, freq_table); | ||
109 | if (!retval) { | ||
110 | printk("cpufreq: AT32AP CPU frequency driver\n"); | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | kfree(freq_table); | ||
115 | out_err_put_clk: | ||
116 | clk_put(cpuclk); | ||
117 | out_err: | ||
118 | return retval; | ||
107 | } | 119 | } |
108 | 120 | ||
109 | static struct cpufreq_driver at32_driver = { | 121 | static struct cpufreq_driver at32_driver = { |
110 | .name = "at32ap", | 122 | .name = "at32ap", |
111 | .init = at32_cpufreq_driver_init, | 123 | .init = at32_cpufreq_driver_init, |
112 | .verify = at32_verify_speed, | 124 | .verify = cpufreq_generic_frequency_table_verify, |
113 | .target = at32_set_target, | 125 | .target_index = at32_set_target, |
114 | .get = at32_get_speed, | 126 | .get = at32_get_speed, |
115 | .flags = CPUFREQ_STICKY, | 127 | .flags = CPUFREQ_STICKY, |
116 | }; | 128 | }; |
diff --git a/drivers/cpufreq/blackfin-cpufreq.c b/drivers/cpufreq/blackfin-cpufreq.c index ef05978a7237..e9e63fc9c2c9 100644 --- a/drivers/cpufreq/blackfin-cpufreq.c +++ b/drivers/cpufreq/blackfin-cpufreq.c | |||
@@ -127,41 +127,28 @@ unsigned long cpu_set_cclk(int cpu, unsigned long new) | |||
127 | } | 127 | } |
128 | #endif | 128 | #endif |
129 | 129 | ||
130 | static int bfin_target(struct cpufreq_policy *policy, | 130 | static int bfin_target(struct cpufreq_policy *policy, unsigned int index) |
131 | unsigned int target_freq, unsigned int relation) | ||
132 | { | 131 | { |
133 | #ifndef CONFIG_BF60x | 132 | #ifndef CONFIG_BF60x |
134 | unsigned int plldiv; | 133 | unsigned int plldiv; |
135 | #endif | 134 | #endif |
136 | unsigned int index; | ||
137 | unsigned long cclk_hz; | ||
138 | struct cpufreq_freqs freqs; | ||
139 | static unsigned long lpj_ref; | 135 | static unsigned long lpj_ref; |
140 | static unsigned int lpj_ref_freq; | 136 | static unsigned int lpj_ref_freq; |
137 | unsigned int old_freq, new_freq; | ||
141 | int ret = 0; | 138 | int ret = 0; |
142 | 139 | ||
143 | #if defined(CONFIG_CYCLES_CLOCKSOURCE) | 140 | #if defined(CONFIG_CYCLES_CLOCKSOURCE) |
144 | cycles_t cycles; | 141 | cycles_t cycles; |
145 | #endif | 142 | #endif |
146 | 143 | ||
147 | if (cpufreq_frequency_table_target(policy, bfin_freq_table, target_freq, | 144 | old_freq = bfin_getfreq_khz(0); |
148 | relation, &index)) | 145 | new_freq = bfin_freq_table[index].frequency; |
149 | return -EINVAL; | ||
150 | 146 | ||
151 | cclk_hz = bfin_freq_table[index].frequency; | ||
152 | |||
153 | freqs.old = bfin_getfreq_khz(0); | ||
154 | freqs.new = cclk_hz; | ||
155 | |||
156 | pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n", | ||
157 | cclk_hz, target_freq, freqs.old); | ||
158 | |||
159 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
160 | #ifndef CONFIG_BF60x | 147 | #ifndef CONFIG_BF60x |
161 | plldiv = (bfin_read_PLL_DIV() & SSEL) | dpm_state_table[index].csel; | 148 | plldiv = (bfin_read_PLL_DIV() & SSEL) | dpm_state_table[index].csel; |
162 | bfin_write_PLL_DIV(plldiv); | 149 | bfin_write_PLL_DIV(plldiv); |
163 | #else | 150 | #else |
164 | ret = cpu_set_cclk(policy->cpu, freqs.new * 1000); | 151 | ret = cpu_set_cclk(policy->cpu, new_freq * 1000); |
165 | if (ret != 0) { | 152 | if (ret != 0) { |
166 | WARN_ONCE(ret, "cpufreq set freq failed %d\n", ret); | 153 | WARN_ONCE(ret, "cpufreq set freq failed %d\n", ret); |
167 | return ret; | 154 | return ret; |
@@ -177,25 +164,16 @@ static int bfin_target(struct cpufreq_policy *policy, | |||
177 | #endif | 164 | #endif |
178 | if (!lpj_ref_freq) { | 165 | if (!lpj_ref_freq) { |
179 | lpj_ref = loops_per_jiffy; | 166 | lpj_ref = loops_per_jiffy; |
180 | lpj_ref_freq = freqs.old; | 167 | lpj_ref_freq = old_freq; |
181 | } | 168 | } |
182 | if (freqs.new != freqs.old) { | 169 | if (new_freq != old_freq) { |
183 | loops_per_jiffy = cpufreq_scale(lpj_ref, | 170 | loops_per_jiffy = cpufreq_scale(lpj_ref, |
184 | lpj_ref_freq, freqs.new); | 171 | lpj_ref_freq, new_freq); |
185 | } | 172 | } |
186 | 173 | ||
187 | /* TODO: just test case for cycles clock source, remove later */ | ||
188 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
189 | |||
190 | pr_debug("cpufreq: done\n"); | ||
191 | return ret; | 174 | return ret; |
192 | } | 175 | } |
193 | 176 | ||
194 | static int bfin_verify_speed(struct cpufreq_policy *policy) | ||
195 | { | ||
196 | return cpufreq_frequency_table_verify(policy, bfin_freq_table); | ||
197 | } | ||
198 | |||
199 | static int __bfin_cpu_init(struct cpufreq_policy *policy) | 177 | static int __bfin_cpu_init(struct cpufreq_policy *policy) |
200 | { | 178 | { |
201 | 179 | ||
@@ -209,23 +187,17 @@ static int __bfin_cpu_init(struct cpufreq_policy *policy) | |||
209 | 187 | ||
210 | policy->cpuinfo.transition_latency = 50000; /* 50us assumed */ | 188 | policy->cpuinfo.transition_latency = 50000; /* 50us assumed */ |
211 | 189 | ||
212 | policy->cur = cclk; | 190 | return cpufreq_table_validate_and_show(policy, bfin_freq_table); |
213 | cpufreq_frequency_table_get_attr(bfin_freq_table, policy->cpu); | ||
214 | return cpufreq_frequency_table_cpuinfo(policy, bfin_freq_table); | ||
215 | } | 191 | } |
216 | 192 | ||
217 | static struct freq_attr *bfin_freq_attr[] = { | ||
218 | &cpufreq_freq_attr_scaling_available_freqs, | ||
219 | NULL, | ||
220 | }; | ||
221 | |||
222 | static struct cpufreq_driver bfin_driver = { | 193 | static struct cpufreq_driver bfin_driver = { |
223 | .verify = bfin_verify_speed, | 194 | .verify = cpufreq_generic_frequency_table_verify, |
224 | .target = bfin_target, | 195 | .target_index = bfin_target, |
225 | .get = bfin_getfreq_khz, | 196 | .get = bfin_getfreq_khz, |
226 | .init = __bfin_cpu_init, | 197 | .init = __bfin_cpu_init, |
198 | .exit = cpufreq_generic_exit, | ||
227 | .name = "bfin cpufreq", | 199 | .name = "bfin cpufreq", |
228 | .attr = bfin_freq_attr, | 200 | .attr = cpufreq_generic_attr, |
229 | }; | 201 | }; |
230 | 202 | ||
231 | static int __init bfin_cpu_init(void) | 203 | static int __init bfin_cpu_init(void) |
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index c522a95c0e16..d4585ce2346c 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
20 | #include <linux/opp.h> | 20 | #include <linux/pm_opp.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/regulator/consumer.h> | 22 | #include <linux/regulator/consumer.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
@@ -30,73 +30,51 @@ static struct clk *cpu_clk; | |||
30 | static struct regulator *cpu_reg; | 30 | static struct regulator *cpu_reg; |
31 | static struct cpufreq_frequency_table *freq_table; | 31 | static struct cpufreq_frequency_table *freq_table; |
32 | 32 | ||
33 | static int cpu0_verify_speed(struct cpufreq_policy *policy) | ||
34 | { | ||
35 | return cpufreq_frequency_table_verify(policy, freq_table); | ||
36 | } | ||
37 | |||
38 | static unsigned int cpu0_get_speed(unsigned int cpu) | 33 | static unsigned int cpu0_get_speed(unsigned int cpu) |
39 | { | 34 | { |
40 | return clk_get_rate(cpu_clk) / 1000; | 35 | return clk_get_rate(cpu_clk) / 1000; |
41 | } | 36 | } |
42 | 37 | ||
43 | static int cpu0_set_target(struct cpufreq_policy *policy, | 38 | static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index) |
44 | unsigned int target_freq, unsigned int relation) | ||
45 | { | 39 | { |
46 | struct cpufreq_freqs freqs; | 40 | struct dev_pm_opp *opp; |
47 | struct opp *opp; | ||
48 | unsigned long volt = 0, volt_old = 0, tol = 0; | 41 | unsigned long volt = 0, volt_old = 0, tol = 0; |
42 | unsigned int old_freq, new_freq; | ||
49 | long freq_Hz, freq_exact; | 43 | long freq_Hz, freq_exact; |
50 | unsigned int index; | ||
51 | int ret; | 44 | int ret; |
52 | 45 | ||
53 | ret = cpufreq_frequency_table_target(policy, freq_table, target_freq, | ||
54 | relation, &index); | ||
55 | if (ret) { | ||
56 | pr_err("failed to match target freqency %d: %d\n", | ||
57 | target_freq, ret); | ||
58 | return ret; | ||
59 | } | ||
60 | |||
61 | 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); |
62 | if (freq_Hz < 0) | 47 | if (freq_Hz < 0) |
63 | freq_Hz = freq_table[index].frequency * 1000; | 48 | freq_Hz = freq_table[index].frequency * 1000; |
64 | freq_exact = freq_Hz; | ||
65 | freqs.new = freq_Hz / 1000; | ||
66 | freqs.old = clk_get_rate(cpu_clk) / 1000; | ||
67 | 49 | ||
68 | if (freqs.old == freqs.new) | 50 | freq_exact = freq_Hz; |
69 | return 0; | 51 | new_freq = freq_Hz / 1000; |
70 | 52 | old_freq = clk_get_rate(cpu_clk) / 1000; | |
71 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
72 | 53 | ||
73 | if (!IS_ERR(cpu_reg)) { | 54 | if (!IS_ERR(cpu_reg)) { |
74 | rcu_read_lock(); | 55 | rcu_read_lock(); |
75 | opp = opp_find_freq_ceil(cpu_dev, &freq_Hz); | 56 | opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_Hz); |
76 | if (IS_ERR(opp)) { | 57 | if (IS_ERR(opp)) { |
77 | rcu_read_unlock(); | 58 | rcu_read_unlock(); |
78 | pr_err("failed to find OPP for %ld\n", freq_Hz); | 59 | pr_err("failed to find OPP for %ld\n", freq_Hz); |
79 | freqs.new = freqs.old; | 60 | return PTR_ERR(opp); |
80 | ret = PTR_ERR(opp); | ||
81 | goto post_notify; | ||
82 | } | 61 | } |
83 | volt = opp_get_voltage(opp); | 62 | volt = dev_pm_opp_get_voltage(opp); |
84 | rcu_read_unlock(); | 63 | rcu_read_unlock(); |
85 | tol = volt * voltage_tolerance / 100; | 64 | tol = volt * voltage_tolerance / 100; |
86 | volt_old = regulator_get_voltage(cpu_reg); | 65 | volt_old = regulator_get_voltage(cpu_reg); |
87 | } | 66 | } |
88 | 67 | ||
89 | pr_debug("%u MHz, %ld mV --> %u MHz, %ld mV\n", | 68 | pr_debug("%u MHz, %ld mV --> %u MHz, %ld mV\n", |
90 | freqs.old / 1000, volt_old ? volt_old / 1000 : -1, | 69 | old_freq / 1000, volt_old ? volt_old / 1000 : -1, |
91 | freqs.new / 1000, volt ? volt / 1000 : -1); | 70 | new_freq / 1000, volt ? volt / 1000 : -1); |
92 | 71 | ||
93 | /* scaling up? scale voltage before frequency */ | 72 | /* scaling up? scale voltage before frequency */ |
94 | if (!IS_ERR(cpu_reg) && freqs.new > freqs.old) { | 73 | if (!IS_ERR(cpu_reg) && new_freq > old_freq) { |
95 | ret = regulator_set_voltage_tol(cpu_reg, volt, tol); | 74 | ret = regulator_set_voltage_tol(cpu_reg, volt, tol); |
96 | if (ret) { | 75 | if (ret) { |
97 | pr_err("failed to scale voltage up: %d\n", ret); | 76 | pr_err("failed to scale voltage up: %d\n", ret); |
98 | freqs.new = freqs.old; | 77 | return ret; |
99 | goto post_notify; | ||
100 | } | 78 | } |
101 | } | 79 | } |
102 | 80 | ||
@@ -105,72 +83,35 @@ static int cpu0_set_target(struct cpufreq_policy *policy, | |||
105 | pr_err("failed to set clock rate: %d\n", ret); | 83 | pr_err("failed to set clock rate: %d\n", ret); |
106 | if (!IS_ERR(cpu_reg)) | 84 | if (!IS_ERR(cpu_reg)) |
107 | regulator_set_voltage_tol(cpu_reg, volt_old, tol); | 85 | regulator_set_voltage_tol(cpu_reg, volt_old, tol); |
108 | freqs.new = freqs.old; | 86 | return ret; |
109 | goto post_notify; | ||
110 | } | 87 | } |
111 | 88 | ||
112 | /* scaling down? scale voltage after frequency */ | 89 | /* scaling down? scale voltage after frequency */ |
113 | if (!IS_ERR(cpu_reg) && freqs.new < freqs.old) { | 90 | if (!IS_ERR(cpu_reg) && new_freq < old_freq) { |
114 | ret = regulator_set_voltage_tol(cpu_reg, volt, tol); | 91 | ret = regulator_set_voltage_tol(cpu_reg, volt, tol); |
115 | if (ret) { | 92 | if (ret) { |
116 | pr_err("failed to scale voltage down: %d\n", ret); | 93 | pr_err("failed to scale voltage down: %d\n", ret); |
117 | clk_set_rate(cpu_clk, freqs.old * 1000); | 94 | clk_set_rate(cpu_clk, old_freq * 1000); |
118 | freqs.new = freqs.old; | ||
119 | } | 95 | } |
120 | } | 96 | } |
121 | 97 | ||
122 | post_notify: | ||
123 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
124 | |||
125 | return ret; | 98 | return ret; |
126 | } | 99 | } |
127 | 100 | ||
128 | static int cpu0_cpufreq_init(struct cpufreq_policy *policy) | 101 | static int cpu0_cpufreq_init(struct cpufreq_policy *policy) |
129 | { | 102 | { |
130 | int ret; | 103 | return cpufreq_generic_init(policy, freq_table, transition_latency); |
131 | |||
132 | ret = cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
133 | if (ret) { | ||
134 | pr_err("invalid frequency table: %d\n", ret); | ||
135 | return ret; | ||
136 | } | ||
137 | |||
138 | policy->cpuinfo.transition_latency = transition_latency; | ||
139 | policy->cur = clk_get_rate(cpu_clk) / 1000; | ||
140 | |||
141 | /* | ||
142 | * The driver only supports the SMP configuartion where all processors | ||
143 | * share the clock and voltage and clock. Use cpufreq affected_cpus | ||
144 | * interface to have all CPUs scaled together. | ||
145 | */ | ||
146 | cpumask_setall(policy->cpus); | ||
147 | |||
148 | cpufreq_frequency_table_get_attr(freq_table, policy->cpu); | ||
149 | |||
150 | return 0; | ||
151 | } | 104 | } |
152 | 105 | ||
153 | static int cpu0_cpufreq_exit(struct cpufreq_policy *policy) | ||
154 | { | ||
155 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static struct freq_attr *cpu0_cpufreq_attr[] = { | ||
161 | &cpufreq_freq_attr_scaling_available_freqs, | ||
162 | NULL, | ||
163 | }; | ||
164 | |||
165 | static struct cpufreq_driver cpu0_cpufreq_driver = { | 106 | static struct cpufreq_driver cpu0_cpufreq_driver = { |
166 | .flags = CPUFREQ_STICKY, | 107 | .flags = CPUFREQ_STICKY, |
167 | .verify = cpu0_verify_speed, | 108 | .verify = cpufreq_generic_frequency_table_verify, |
168 | .target = cpu0_set_target, | 109 | .target_index = cpu0_set_target, |
169 | .get = cpu0_get_speed, | 110 | .get = cpu0_get_speed, |
170 | .init = cpu0_cpufreq_init, | 111 | .init = cpu0_cpufreq_init, |
171 | .exit = cpu0_cpufreq_exit, | 112 | .exit = cpufreq_generic_exit, |
172 | .name = "generic_cpu0", | 113 | .name = "generic_cpu0", |
173 | .attr = cpu0_cpufreq_attr, | 114 | .attr = cpufreq_generic_attr, |
174 | }; | 115 | }; |
175 | 116 | ||
176 | static int cpu0_cpufreq_probe(struct platform_device *pdev) | 117 | static int cpu0_cpufreq_probe(struct platform_device *pdev) |
@@ -218,7 +159,7 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) | |||
218 | goto out_put_node; | 159 | goto out_put_node; |
219 | } | 160 | } |
220 | 161 | ||
221 | ret = opp_init_cpufreq_table(cpu_dev, &freq_table); | 162 | ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); |
222 | if (ret) { | 163 | if (ret) { |
223 | pr_err("failed to init cpufreq table: %d\n", ret); | 164 | pr_err("failed to init cpufreq table: %d\n", ret); |
224 | goto out_put_node; | 165 | goto out_put_node; |
@@ -230,7 +171,7 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) | |||
230 | transition_latency = CPUFREQ_ETERNAL; | 171 | transition_latency = CPUFREQ_ETERNAL; |
231 | 172 | ||
232 | if (!IS_ERR(cpu_reg)) { | 173 | if (!IS_ERR(cpu_reg)) { |
233 | struct opp *opp; | 174 | struct dev_pm_opp *opp; |
234 | unsigned long min_uV, max_uV; | 175 | unsigned long min_uV, max_uV; |
235 | int i; | 176 | int i; |
236 | 177 | ||
@@ -242,12 +183,12 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) | |||
242 | for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) | 183 | for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) |
243 | ; | 184 | ; |
244 | rcu_read_lock(); | 185 | rcu_read_lock(); |
245 | opp = opp_find_freq_exact(cpu_dev, | 186 | opp = dev_pm_opp_find_freq_exact(cpu_dev, |
246 | freq_table[0].frequency * 1000, true); | 187 | freq_table[0].frequency * 1000, true); |
247 | min_uV = opp_get_voltage(opp); | 188 | min_uV = dev_pm_opp_get_voltage(opp); |
248 | opp = opp_find_freq_exact(cpu_dev, | 189 | opp = dev_pm_opp_find_freq_exact(cpu_dev, |
249 | freq_table[i-1].frequency * 1000, true); | 190 | freq_table[i-1].frequency * 1000, true); |
250 | max_uV = opp_get_voltage(opp); | 191 | max_uV = dev_pm_opp_get_voltage(opp); |
251 | rcu_read_unlock(); | 192 | rcu_read_unlock(); |
252 | ret = regulator_set_voltage_time(cpu_reg, min_uV, max_uV); | 193 | ret = regulator_set_voltage_time(cpu_reg, min_uV, max_uV); |
253 | if (ret > 0) | 194 | if (ret > 0) |
@@ -264,7 +205,7 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) | |||
264 | return 0; | 205 | return 0; |
265 | 206 | ||
266 | out_free_table: | 207 | out_free_table: |
267 | opp_free_cpufreq_table(cpu_dev, &freq_table); | 208 | dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); |
268 | out_put_node: | 209 | out_put_node: |
269 | of_node_put(np); | 210 | of_node_put(np); |
270 | return ret; | 211 | return ret; |
@@ -273,7 +214,7 @@ out_put_node: | |||
273 | static int cpu0_cpufreq_remove(struct platform_device *pdev) | 214 | static int cpu0_cpufreq_remove(struct platform_device *pdev) |
274 | { | 215 | { |
275 | cpufreq_unregister_driver(&cpu0_cpufreq_driver); | 216 | cpufreq_unregister_driver(&cpu0_cpufreq_driver); |
276 | opp_free_cpufreq_table(cpu_dev, &freq_table); | 217 | dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); |
277 | 218 | ||
278 | return 0; | 219 | return 0; |
279 | } | 220 | } |
diff --git a/drivers/cpufreq/cpufreq-nforce2.c b/drivers/cpufreq/cpufreq-nforce2.c index b83d45f68574..a05b876f375e 100644 --- a/drivers/cpufreq/cpufreq-nforce2.c +++ b/drivers/cpufreq/cpufreq-nforce2.c | |||
@@ -303,9 +303,7 @@ static int nforce2_verify(struct cpufreq_policy *policy) | |||
303 | if (policy->min < (fsb_pol_max * fid * 100)) | 303 | if (policy->min < (fsb_pol_max * fid * 100)) |
304 | policy->max = (fsb_pol_max + 1) * fid * 100; | 304 | policy->max = (fsb_pol_max + 1) * fid * 100; |
305 | 305 | ||
306 | cpufreq_verify_within_limits(policy, | 306 | cpufreq_verify_within_cpu_limits(policy); |
307 | policy->cpuinfo.min_freq, | ||
308 | policy->cpuinfo.max_freq); | ||
309 | return 0; | 307 | return 0; |
310 | } | 308 | } |
311 | 309 | ||
@@ -362,7 +360,6 @@ static int nforce2_cpu_init(struct cpufreq_policy *policy) | |||
362 | policy->min = policy->cpuinfo.min_freq = min_fsb * fid * 100; | 360 | policy->min = policy->cpuinfo.min_freq = min_fsb * fid * 100; |
363 | policy->max = policy->cpuinfo.max_freq = max_fsb * fid * 100; | 361 | policy->max = policy->cpuinfo.max_freq = max_fsb * fid * 100; |
364 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 362 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; |
365 | policy->cur = nforce2_get(policy->cpu); | ||
366 | 363 | ||
367 | return 0; | 364 | return 0; |
368 | } | 365 | } |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 04548f7023af..02d534da22dd 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -47,49 +47,11 @@ static LIST_HEAD(cpufreq_policy_list); | |||
47 | static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); | 47 | static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | /* | 50 | static inline bool has_target(void) |
51 | * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure | 51 | { |
52 | * all cpufreq/hotplug/workqueue/etc related lock issues. | 52 | return cpufreq_driver->target_index || cpufreq_driver->target; |
53 | * | ||
54 | * The rules for this semaphore: | ||
55 | * - Any routine that wants to read from the policy structure will | ||
56 | * do a down_read on this semaphore. | ||
57 | * - Any routine that will write to the policy structure and/or may take away | ||
58 | * the policy altogether (eg. CPU hotplug), will hold this lock in write | ||
59 | * mode before doing so. | ||
60 | * | ||
61 | * Additional rules: | ||
62 | * - Governor routines that can be called in cpufreq hotplug path should not | ||
63 | * take this sem as top level hotplug notifier handler takes this. | ||
64 | * - Lock should not be held across | ||
65 | * __cpufreq_governor(data, CPUFREQ_GOV_STOP); | ||
66 | */ | ||
67 | static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem); | ||
68 | |||
69 | #define lock_policy_rwsem(mode, cpu) \ | ||
70 | static int lock_policy_rwsem_##mode(int cpu) \ | ||
71 | { \ | ||
72 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); \ | ||
73 | BUG_ON(!policy); \ | ||
74 | down_##mode(&per_cpu(cpu_policy_rwsem, policy->cpu)); \ | ||
75 | \ | ||
76 | return 0; \ | ||
77 | } | ||
78 | |||
79 | lock_policy_rwsem(read, cpu); | ||
80 | lock_policy_rwsem(write, cpu); | ||
81 | |||
82 | #define unlock_policy_rwsem(mode, cpu) \ | ||
83 | static void unlock_policy_rwsem_##mode(int cpu) \ | ||
84 | { \ | ||
85 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); \ | ||
86 | BUG_ON(!policy); \ | ||
87 | up_##mode(&per_cpu(cpu_policy_rwsem, policy->cpu)); \ | ||
88 | } | 53 | } |
89 | 54 | ||
90 | unlock_policy_rwsem(read, cpu); | ||
91 | unlock_policy_rwsem(write, cpu); | ||
92 | |||
93 | /* | 55 | /* |
94 | * rwsem to guarantee that cpufreq driver module doesn't unload during critical | 56 | * rwsem to guarantee that cpufreq driver module doesn't unload during critical |
95 | * sections | 57 | * sections |
@@ -135,7 +97,7 @@ static DEFINE_MUTEX(cpufreq_governor_mutex); | |||
135 | 97 | ||
136 | bool have_governor_per_policy(void) | 98 | bool have_governor_per_policy(void) |
137 | { | 99 | { |
138 | return cpufreq_driver->have_governor_per_policy; | 100 | return !!(cpufreq_driver->flags & CPUFREQ_HAVE_GOVERNOR_PER_POLICY); |
139 | } | 101 | } |
140 | EXPORT_SYMBOL_GPL(have_governor_per_policy); | 102 | EXPORT_SYMBOL_GPL(have_governor_per_policy); |
141 | 103 | ||
@@ -183,6 +145,37 @@ u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy) | |||
183 | } | 145 | } |
184 | EXPORT_SYMBOL_GPL(get_cpu_idle_time); | 146 | EXPORT_SYMBOL_GPL(get_cpu_idle_time); |
185 | 147 | ||
148 | /* | ||
149 | * This is a generic cpufreq init() routine which can be used by cpufreq | ||
150 | * drivers of SMP systems. It will do following: | ||
151 | * - validate & show freq table passed | ||
152 | * - set policies transition latency | ||
153 | * - policy->cpus with all possible CPUs | ||
154 | */ | ||
155 | int cpufreq_generic_init(struct cpufreq_policy *policy, | ||
156 | struct cpufreq_frequency_table *table, | ||
157 | unsigned int transition_latency) | ||
158 | { | ||
159 | int ret; | ||
160 | |||
161 | ret = cpufreq_table_validate_and_show(policy, table); | ||
162 | if (ret) { | ||
163 | pr_err("%s: invalid frequency table: %d\n", __func__, ret); | ||
164 | return ret; | ||
165 | } | ||
166 | |||
167 | policy->cpuinfo.transition_latency = transition_latency; | ||
168 | |||
169 | /* | ||
170 | * The driver only supports the SMP configuartion where all processors | ||
171 | * share the clock and voltage and clock. | ||
172 | */ | ||
173 | cpumask_setall(policy->cpus); | ||
174 | |||
175 | return 0; | ||
176 | } | ||
177 | EXPORT_SYMBOL_GPL(cpufreq_generic_init); | ||
178 | |||
186 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) | 179 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) |
187 | { | 180 | { |
188 | struct cpufreq_policy *policy = NULL; | 181 | struct cpufreq_policy *policy = NULL; |
@@ -363,7 +356,7 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy, | |||
363 | *policy = CPUFREQ_POLICY_POWERSAVE; | 356 | *policy = CPUFREQ_POLICY_POWERSAVE; |
364 | err = 0; | 357 | err = 0; |
365 | } | 358 | } |
366 | } else if (cpufreq_driver->target) { | 359 | } else if (has_target()) { |
367 | struct cpufreq_governor *t; | 360 | struct cpufreq_governor *t; |
368 | 361 | ||
369 | mutex_lock(&cpufreq_governor_mutex); | 362 | mutex_lock(&cpufreq_governor_mutex); |
@@ -414,7 +407,7 @@ show_one(scaling_min_freq, min); | |||
414 | show_one(scaling_max_freq, max); | 407 | show_one(scaling_max_freq, max); |
415 | show_one(scaling_cur_freq, cur); | 408 | show_one(scaling_cur_freq, cur); |
416 | 409 | ||
417 | static int __cpufreq_set_policy(struct cpufreq_policy *policy, | 410 | static int cpufreq_set_policy(struct cpufreq_policy *policy, |
418 | struct cpufreq_policy *new_policy); | 411 | struct cpufreq_policy *new_policy); |
419 | 412 | ||
420 | /** | 413 | /** |
@@ -435,7 +428,7 @@ static ssize_t store_##file_name \ | |||
435 | if (ret != 1) \ | 428 | if (ret != 1) \ |
436 | return -EINVAL; \ | 429 | return -EINVAL; \ |
437 | \ | 430 | \ |
438 | ret = __cpufreq_set_policy(policy, &new_policy); \ | 431 | ret = cpufreq_set_policy(policy, &new_policy); \ |
439 | policy->user_policy.object = policy->object; \ | 432 | policy->user_policy.object = policy->object; \ |
440 | \ | 433 | \ |
441 | return ret ? ret : count; \ | 434 | return ret ? ret : count; \ |
@@ -493,11 +486,7 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy, | |||
493 | &new_policy.governor)) | 486 | &new_policy.governor)) |
494 | return -EINVAL; | 487 | return -EINVAL; |
495 | 488 | ||
496 | /* | 489 | ret = cpufreq_set_policy(policy, &new_policy); |
497 | * Do not use cpufreq_set_policy here or the user_policy.max | ||
498 | * will be wrongly overridden | ||
499 | */ | ||
500 | ret = __cpufreq_set_policy(policy, &new_policy); | ||
501 | 490 | ||
502 | policy->user_policy.policy = policy->policy; | 491 | policy->user_policy.policy = policy->policy; |
503 | policy->user_policy.governor = policy->governor; | 492 | policy->user_policy.governor = policy->governor; |
@@ -525,7 +514,7 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy, | |||
525 | ssize_t i = 0; | 514 | ssize_t i = 0; |
526 | struct cpufreq_governor *t; | 515 | struct cpufreq_governor *t; |
527 | 516 | ||
528 | if (!cpufreq_driver->target) { | 517 | if (!has_target()) { |
529 | i += sprintf(buf, "performance powersave"); | 518 | i += sprintf(buf, "performance powersave"); |
530 | goto out; | 519 | goto out; |
531 | } | 520 | } |
@@ -653,24 +642,21 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) | |||
653 | { | 642 | { |
654 | struct cpufreq_policy *policy = to_policy(kobj); | 643 | struct cpufreq_policy *policy = to_policy(kobj); |
655 | struct freq_attr *fattr = to_attr(attr); | 644 | struct freq_attr *fattr = to_attr(attr); |
656 | ssize_t ret = -EINVAL; | 645 | ssize_t ret; |
657 | 646 | ||
658 | if (!down_read_trylock(&cpufreq_rwsem)) | 647 | if (!down_read_trylock(&cpufreq_rwsem)) |
659 | goto exit; | 648 | return -EINVAL; |
660 | 649 | ||
661 | if (lock_policy_rwsem_read(policy->cpu) < 0) | 650 | down_read(&policy->rwsem); |
662 | goto up_read; | ||
663 | 651 | ||
664 | if (fattr->show) | 652 | if (fattr->show) |
665 | ret = fattr->show(policy, buf); | 653 | ret = fattr->show(policy, buf); |
666 | else | 654 | else |
667 | ret = -EIO; | 655 | ret = -EIO; |
668 | 656 | ||
669 | unlock_policy_rwsem_read(policy->cpu); | 657 | up_read(&policy->rwsem); |
670 | |||
671 | up_read: | ||
672 | up_read(&cpufreq_rwsem); | 658 | up_read(&cpufreq_rwsem); |
673 | exit: | 659 | |
674 | return ret; | 660 | return ret; |
675 | } | 661 | } |
676 | 662 | ||
@@ -689,17 +675,15 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, | |||
689 | if (!down_read_trylock(&cpufreq_rwsem)) | 675 | if (!down_read_trylock(&cpufreq_rwsem)) |
690 | goto unlock; | 676 | goto unlock; |
691 | 677 | ||
692 | if (lock_policy_rwsem_write(policy->cpu) < 0) | 678 | down_write(&policy->rwsem); |
693 | goto up_read; | ||
694 | 679 | ||
695 | if (fattr->store) | 680 | if (fattr->store) |
696 | ret = fattr->store(policy, buf, count); | 681 | ret = fattr->store(policy, buf, count); |
697 | else | 682 | else |
698 | ret = -EIO; | 683 | ret = -EIO; |
699 | 684 | ||
700 | unlock_policy_rwsem_write(policy->cpu); | 685 | up_write(&policy->rwsem); |
701 | 686 | ||
702 | up_read: | ||
703 | up_read(&cpufreq_rwsem); | 687 | up_read(&cpufreq_rwsem); |
704 | unlock: | 688 | unlock: |
705 | put_online_cpus(); | 689 | put_online_cpus(); |
@@ -815,7 +799,7 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy, | |||
815 | if (ret) | 799 | if (ret) |
816 | goto err_out_kobj_put; | 800 | goto err_out_kobj_put; |
817 | } | 801 | } |
818 | if (cpufreq_driver->target) { | 802 | if (has_target()) { |
819 | ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); | 803 | ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); |
820 | if (ret) | 804 | if (ret) |
821 | goto err_out_kobj_put; | 805 | goto err_out_kobj_put; |
@@ -844,11 +828,11 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy) | |||
844 | int ret = 0; | 828 | int ret = 0; |
845 | 829 | ||
846 | memcpy(&new_policy, policy, sizeof(*policy)); | 830 | memcpy(&new_policy, policy, sizeof(*policy)); |
847 | /* assure that the starting sequence is run in __cpufreq_set_policy */ | 831 | /* assure that the starting sequence is run in cpufreq_set_policy */ |
848 | policy->governor = NULL; | 832 | policy->governor = NULL; |
849 | 833 | ||
850 | /* set default policy */ | 834 | /* set default policy */ |
851 | ret = __cpufreq_set_policy(policy, &new_policy); | 835 | ret = cpufreq_set_policy(policy, &new_policy); |
852 | policy->user_policy.policy = policy->policy; | 836 | policy->user_policy.policy = policy->policy; |
853 | policy->user_policy.governor = policy->governor; | 837 | policy->user_policy.governor = policy->governor; |
854 | 838 | ||
@@ -864,10 +848,10 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, | |||
864 | unsigned int cpu, struct device *dev, | 848 | unsigned int cpu, struct device *dev, |
865 | bool frozen) | 849 | bool frozen) |
866 | { | 850 | { |
867 | int ret = 0, has_target = !!cpufreq_driver->target; | 851 | int ret = 0; |
868 | unsigned long flags; | 852 | unsigned long flags; |
869 | 853 | ||
870 | if (has_target) { | 854 | if (has_target()) { |
871 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); | 855 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); |
872 | if (ret) { | 856 | if (ret) { |
873 | pr_err("%s: Failed to stop governor\n", __func__); | 857 | pr_err("%s: Failed to stop governor\n", __func__); |
@@ -875,7 +859,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, | |||
875 | } | 859 | } |
876 | } | 860 | } |
877 | 861 | ||
878 | lock_policy_rwsem_write(policy->cpu); | 862 | down_write(&policy->rwsem); |
879 | 863 | ||
880 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 864 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
881 | 865 | ||
@@ -883,9 +867,9 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, | |||
883 | per_cpu(cpufreq_cpu_data, cpu) = policy; | 867 | per_cpu(cpufreq_cpu_data, cpu) = policy; |
884 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 868 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
885 | 869 | ||
886 | unlock_policy_rwsem_write(policy->cpu); | 870 | up_write(&policy->rwsem); |
887 | 871 | ||
888 | if (has_target) { | 872 | if (has_target()) { |
889 | if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || | 873 | if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || |
890 | (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) { | 874 | (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) { |
891 | pr_err("%s: Failed to start governor\n", __func__); | 875 | pr_err("%s: Failed to start governor\n", __func__); |
@@ -930,6 +914,8 @@ static struct cpufreq_policy *cpufreq_policy_alloc(void) | |||
930 | goto err_free_cpumask; | 914 | goto err_free_cpumask; |
931 | 915 | ||
932 | INIT_LIST_HEAD(&policy->policy_list); | 916 | INIT_LIST_HEAD(&policy->policy_list); |
917 | init_rwsem(&policy->rwsem); | ||
918 | |||
933 | return policy; | 919 | return policy; |
934 | 920 | ||
935 | err_free_cpumask: | 921 | err_free_cpumask: |
@@ -949,26 +935,17 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy) | |||
949 | 935 | ||
950 | static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) | 936 | static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) |
951 | { | 937 | { |
952 | if (cpu == policy->cpu) | 938 | if (WARN_ON(cpu == policy->cpu)) |
953 | return; | 939 | return; |
954 | 940 | ||
955 | /* | 941 | down_write(&policy->rwsem); |
956 | * Take direct locks as lock_policy_rwsem_write wouldn't work here. | ||
957 | * Also lock for last cpu is enough here as contention will happen only | ||
958 | * after policy->cpu is changed and after it is changed, other threads | ||
959 | * will try to acquire lock for new cpu. And policy is already updated | ||
960 | * by then. | ||
961 | */ | ||
962 | down_write(&per_cpu(cpu_policy_rwsem, policy->cpu)); | ||
963 | 942 | ||
964 | policy->last_cpu = policy->cpu; | 943 | policy->last_cpu = policy->cpu; |
965 | policy->cpu = cpu; | 944 | policy->cpu = cpu; |
966 | 945 | ||
967 | up_write(&per_cpu(cpu_policy_rwsem, policy->last_cpu)); | 946 | up_write(&policy->rwsem); |
968 | 947 | ||
969 | #ifdef CONFIG_CPU_FREQ_TABLE | ||
970 | cpufreq_frequency_table_update_policy_cpu(policy); | 948 | cpufreq_frequency_table_update_policy_cpu(policy); |
971 | #endif | ||
972 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | 949 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
973 | CPUFREQ_UPDATE_POLICY_CPU, policy); | 950 | CPUFREQ_UPDATE_POLICY_CPU, policy); |
974 | } | 951 | } |
@@ -1053,6 +1030,14 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, | |||
1053 | goto err_set_policy_cpu; | 1030 | goto err_set_policy_cpu; |
1054 | } | 1031 | } |
1055 | 1032 | ||
1033 | if (cpufreq_driver->get) { | ||
1034 | policy->cur = cpufreq_driver->get(policy->cpu); | ||
1035 | if (!policy->cur) { | ||
1036 | pr_err("%s: ->get() failed\n", __func__); | ||
1037 | goto err_get_freq; | ||
1038 | } | ||
1039 | } | ||
1040 | |||
1056 | /* related cpus should atleast have policy->cpus */ | 1041 | /* related cpus should atleast have policy->cpus */ |
1057 | cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); | 1042 | cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); |
1058 | 1043 | ||
@@ -1107,6 +1092,9 @@ err_out_unregister: | |||
1107 | per_cpu(cpufreq_cpu_data, j) = NULL; | 1092 | per_cpu(cpufreq_cpu_data, j) = NULL; |
1108 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1093 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1109 | 1094 | ||
1095 | err_get_freq: | ||
1096 | if (cpufreq_driver->exit) | ||
1097 | cpufreq_driver->exit(policy); | ||
1110 | err_set_policy_cpu: | 1098 | err_set_policy_cpu: |
1111 | cpufreq_policy_free(policy); | 1099 | cpufreq_policy_free(policy); |
1112 | nomem_out: | 1100 | nomem_out: |
@@ -1147,9 +1135,9 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy, | |||
1147 | if (ret) { | 1135 | if (ret) { |
1148 | pr_err("%s: Failed to move kobj: %d", __func__, ret); | 1136 | pr_err("%s: Failed to move kobj: %d", __func__, ret); |
1149 | 1137 | ||
1150 | WARN_ON(lock_policy_rwsem_write(old_cpu)); | 1138 | down_write(&policy->rwsem); |
1151 | cpumask_set_cpu(old_cpu, policy->cpus); | 1139 | cpumask_set_cpu(old_cpu, policy->cpus); |
1152 | unlock_policy_rwsem_write(old_cpu); | 1140 | up_write(&policy->rwsem); |
1153 | 1141 | ||
1154 | ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj, | 1142 | ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj, |
1155 | "cpufreq"); | 1143 | "cpufreq"); |
@@ -1186,7 +1174,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, | |||
1186 | return -EINVAL; | 1174 | return -EINVAL; |
1187 | } | 1175 | } |
1188 | 1176 | ||
1189 | if (cpufreq_driver->target) { | 1177 | if (has_target()) { |
1190 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); | 1178 | ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); |
1191 | if (ret) { | 1179 | if (ret) { |
1192 | pr_err("%s: Failed to stop governor\n", __func__); | 1180 | pr_err("%s: Failed to stop governor\n", __func__); |
@@ -1200,22 +1188,21 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, | |||
1200 | policy->governor->name, CPUFREQ_NAME_LEN); | 1188 | policy->governor->name, CPUFREQ_NAME_LEN); |
1201 | #endif | 1189 | #endif |
1202 | 1190 | ||
1203 | lock_policy_rwsem_read(cpu); | 1191 | down_read(&policy->rwsem); |
1204 | cpus = cpumask_weight(policy->cpus); | 1192 | cpus = cpumask_weight(policy->cpus); |
1205 | unlock_policy_rwsem_read(cpu); | 1193 | up_read(&policy->rwsem); |
1206 | 1194 | ||
1207 | if (cpu != policy->cpu) { | 1195 | if (cpu != policy->cpu) { |
1208 | if (!frozen) | 1196 | if (!frozen) |
1209 | sysfs_remove_link(&dev->kobj, "cpufreq"); | 1197 | sysfs_remove_link(&dev->kobj, "cpufreq"); |
1210 | } else if (cpus > 1) { | 1198 | } else if (cpus > 1) { |
1211 | |||
1212 | new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu, frozen); | 1199 | new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu, frozen); |
1213 | if (new_cpu >= 0) { | 1200 | if (new_cpu >= 0) { |
1214 | update_policy_cpu(policy, new_cpu); | 1201 | update_policy_cpu(policy, new_cpu); |
1215 | 1202 | ||
1216 | if (!frozen) { | 1203 | if (!frozen) { |
1217 | pr_debug("%s: policy Kobject moved to cpu: %d " | 1204 | pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n", |
1218 | "from: %d\n",__func__, new_cpu, cpu); | 1205 | __func__, new_cpu, cpu); |
1219 | } | 1206 | } |
1220 | } | 1207 | } |
1221 | } | 1208 | } |
@@ -1243,16 +1230,16 @@ static int __cpufreq_remove_dev_finish(struct device *dev, | |||
1243 | return -EINVAL; | 1230 | return -EINVAL; |
1244 | } | 1231 | } |
1245 | 1232 | ||
1246 | WARN_ON(lock_policy_rwsem_write(cpu)); | 1233 | down_write(&policy->rwsem); |
1247 | cpus = cpumask_weight(policy->cpus); | 1234 | cpus = cpumask_weight(policy->cpus); |
1248 | 1235 | ||
1249 | if (cpus > 1) | 1236 | if (cpus > 1) |
1250 | cpumask_clear_cpu(cpu, policy->cpus); | 1237 | cpumask_clear_cpu(cpu, policy->cpus); |
1251 | unlock_policy_rwsem_write(cpu); | 1238 | up_write(&policy->rwsem); |
1252 | 1239 | ||
1253 | /* If cpu is last user of policy, free policy */ | 1240 | /* If cpu is last user of policy, free policy */ |
1254 | if (cpus == 1) { | 1241 | if (cpus == 1) { |
1255 | if (cpufreq_driver->target) { | 1242 | if (has_target()) { |
1256 | ret = __cpufreq_governor(policy, | 1243 | ret = __cpufreq_governor(policy, |
1257 | CPUFREQ_GOV_POLICY_EXIT); | 1244 | CPUFREQ_GOV_POLICY_EXIT); |
1258 | if (ret) { | 1245 | if (ret) { |
@@ -1263,10 +1250,10 @@ static int __cpufreq_remove_dev_finish(struct device *dev, | |||
1263 | } | 1250 | } |
1264 | 1251 | ||
1265 | if (!frozen) { | 1252 | if (!frozen) { |
1266 | lock_policy_rwsem_read(cpu); | 1253 | down_read(&policy->rwsem); |
1267 | kobj = &policy->kobj; | 1254 | kobj = &policy->kobj; |
1268 | cmp = &policy->kobj_unregister; | 1255 | cmp = &policy->kobj_unregister; |
1269 | unlock_policy_rwsem_read(cpu); | 1256 | up_read(&policy->rwsem); |
1270 | kobject_put(kobj); | 1257 | kobject_put(kobj); |
1271 | 1258 | ||
1272 | /* | 1259 | /* |
@@ -1295,7 +1282,7 @@ static int __cpufreq_remove_dev_finish(struct device *dev, | |||
1295 | if (!frozen) | 1282 | if (!frozen) |
1296 | cpufreq_policy_free(policy); | 1283 | cpufreq_policy_free(policy); |
1297 | } else { | 1284 | } else { |
1298 | if (cpufreq_driver->target) { | 1285 | if (has_target()) { |
1299 | if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || | 1286 | if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || |
1300 | (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) { | 1287 | (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) { |
1301 | pr_err("%s: Failed to start governor\n", | 1288 | pr_err("%s: Failed to start governor\n", |
@@ -1310,36 +1297,24 @@ static int __cpufreq_remove_dev_finish(struct device *dev, | |||
1310 | } | 1297 | } |
1311 | 1298 | ||
1312 | /** | 1299 | /** |
1313 | * __cpufreq_remove_dev - remove a CPU device | 1300 | * cpufreq_remove_dev - remove a CPU device |
1314 | * | 1301 | * |
1315 | * Removes the cpufreq interface for a CPU device. | 1302 | * Removes the cpufreq interface for a CPU device. |
1316 | * Caller should already have policy_rwsem in write mode for this CPU. | ||
1317 | * This routine frees the rwsem before returning. | ||
1318 | */ | 1303 | */ |
1319 | static inline int __cpufreq_remove_dev(struct device *dev, | ||
1320 | struct subsys_interface *sif, | ||
1321 | bool frozen) | ||
1322 | { | ||
1323 | int ret; | ||
1324 | |||
1325 | ret = __cpufreq_remove_dev_prepare(dev, sif, frozen); | ||
1326 | |||
1327 | if (!ret) | ||
1328 | ret = __cpufreq_remove_dev_finish(dev, sif, frozen); | ||
1329 | |||
1330 | return ret; | ||
1331 | } | ||
1332 | |||
1333 | static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) | 1304 | static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) |
1334 | { | 1305 | { |
1335 | unsigned int cpu = dev->id; | 1306 | unsigned int cpu = dev->id; |
1336 | int retval; | 1307 | int ret; |
1337 | 1308 | ||
1338 | if (cpu_is_offline(cpu)) | 1309 | if (cpu_is_offline(cpu)) |
1339 | return 0; | 1310 | return 0; |
1340 | 1311 | ||
1341 | retval = __cpufreq_remove_dev(dev, sif, false); | 1312 | ret = __cpufreq_remove_dev_prepare(dev, sif, false); |
1342 | return retval; | 1313 | |
1314 | if (!ret) | ||
1315 | ret = __cpufreq_remove_dev_finish(dev, sif, false); | ||
1316 | |||
1317 | return ret; | ||
1343 | } | 1318 | } |
1344 | 1319 | ||
1345 | static void handle_update(struct work_struct *work) | 1320 | static void handle_update(struct work_struct *work) |
@@ -1458,22 +1433,22 @@ static unsigned int __cpufreq_get(unsigned int cpu) | |||
1458 | */ | 1433 | */ |
1459 | unsigned int cpufreq_get(unsigned int cpu) | 1434 | unsigned int cpufreq_get(unsigned int cpu) |
1460 | { | 1435 | { |
1436 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); | ||
1461 | unsigned int ret_freq = 0; | 1437 | unsigned int ret_freq = 0; |
1462 | 1438 | ||
1463 | if (cpufreq_disabled() || !cpufreq_driver) | 1439 | if (cpufreq_disabled() || !cpufreq_driver) |
1464 | return -ENOENT; | 1440 | return -ENOENT; |
1465 | 1441 | ||
1442 | BUG_ON(!policy); | ||
1443 | |||
1466 | if (!down_read_trylock(&cpufreq_rwsem)) | 1444 | if (!down_read_trylock(&cpufreq_rwsem)) |
1467 | return 0; | 1445 | return 0; |
1468 | 1446 | ||
1469 | if (unlikely(lock_policy_rwsem_read(cpu))) | 1447 | down_read(&policy->rwsem); |
1470 | goto out_policy; | ||
1471 | 1448 | ||
1472 | ret_freq = __cpufreq_get(cpu); | 1449 | ret_freq = __cpufreq_get(cpu); |
1473 | 1450 | ||
1474 | unlock_policy_rwsem_read(cpu); | 1451 | up_read(&policy->rwsem); |
1475 | |||
1476 | out_policy: | ||
1477 | up_read(&cpufreq_rwsem); | 1452 | up_read(&cpufreq_rwsem); |
1478 | 1453 | ||
1479 | return ret_freq; | 1454 | return ret_freq; |
@@ -1681,12 +1656,75 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, | |||
1681 | pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n", | 1656 | pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n", |
1682 | policy->cpu, target_freq, relation, old_target_freq); | 1657 | policy->cpu, target_freq, relation, old_target_freq); |
1683 | 1658 | ||
1659 | /* | ||
1660 | * This might look like a redundant call as we are checking it again | ||
1661 | * after finding index. But it is left intentionally for cases where | ||
1662 | * exactly same freq is called again and so we can save on few function | ||
1663 | * calls. | ||
1664 | */ | ||
1684 | if (target_freq == policy->cur) | 1665 | if (target_freq == policy->cur) |
1685 | return 0; | 1666 | return 0; |
1686 | 1667 | ||
1687 | if (cpufreq_driver->target) | 1668 | if (cpufreq_driver->target) |
1688 | retval = cpufreq_driver->target(policy, target_freq, relation); | 1669 | retval = cpufreq_driver->target(policy, target_freq, relation); |
1670 | else if (cpufreq_driver->target_index) { | ||
1671 | struct cpufreq_frequency_table *freq_table; | ||
1672 | struct cpufreq_freqs freqs; | ||
1673 | bool notify; | ||
1674 | int index; | ||
1675 | |||
1676 | freq_table = cpufreq_frequency_get_table(policy->cpu); | ||
1677 | if (unlikely(!freq_table)) { | ||
1678 | pr_err("%s: Unable to find freq_table\n", __func__); | ||
1679 | goto out; | ||
1680 | } | ||
1681 | |||
1682 | retval = cpufreq_frequency_table_target(policy, freq_table, | ||
1683 | target_freq, relation, &index); | ||
1684 | if (unlikely(retval)) { | ||
1685 | pr_err("%s: Unable to find matching freq\n", __func__); | ||
1686 | goto out; | ||
1687 | } | ||
1688 | |||
1689 | if (freq_table[index].frequency == policy->cur) { | ||
1690 | retval = 0; | ||
1691 | goto out; | ||
1692 | } | ||
1693 | |||
1694 | notify = !(cpufreq_driver->flags & CPUFREQ_ASYNC_NOTIFICATION); | ||
1695 | |||
1696 | if (notify) { | ||
1697 | freqs.old = policy->cur; | ||
1698 | freqs.new = freq_table[index].frequency; | ||
1699 | freqs.flags = 0; | ||
1700 | |||
1701 | pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n", | ||
1702 | __func__, policy->cpu, freqs.old, | ||
1703 | freqs.new); | ||
1704 | |||
1705 | cpufreq_notify_transition(policy, &freqs, | ||
1706 | CPUFREQ_PRECHANGE); | ||
1707 | } | ||
1708 | |||
1709 | retval = cpufreq_driver->target_index(policy, index); | ||
1710 | if (retval) | ||
1711 | pr_err("%s: Failed to change cpu frequency: %d\n", | ||
1712 | __func__, retval); | ||
1713 | |||
1714 | if (notify) { | ||
1715 | /* | ||
1716 | * Notify with old freq in case we failed to change | ||
1717 | * frequency | ||
1718 | */ | ||
1719 | if (retval) | ||
1720 | freqs.new = freqs.old; | ||
1721 | |||
1722 | cpufreq_notify_transition(policy, &freqs, | ||
1723 | CPUFREQ_POSTCHANGE); | ||
1724 | } | ||
1725 | } | ||
1689 | 1726 | ||
1727 | out: | ||
1690 | return retval; | 1728 | return retval; |
1691 | } | 1729 | } |
1692 | EXPORT_SYMBOL_GPL(__cpufreq_driver_target); | 1730 | EXPORT_SYMBOL_GPL(__cpufreq_driver_target); |
@@ -1697,14 +1735,12 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, | |||
1697 | { | 1735 | { |
1698 | int ret = -EINVAL; | 1736 | int ret = -EINVAL; |
1699 | 1737 | ||
1700 | if (unlikely(lock_policy_rwsem_write(policy->cpu))) | 1738 | down_write(&policy->rwsem); |
1701 | goto fail; | ||
1702 | 1739 | ||
1703 | ret = __cpufreq_driver_target(policy, target_freq, relation); | 1740 | ret = __cpufreq_driver_target(policy, target_freq, relation); |
1704 | 1741 | ||
1705 | unlock_policy_rwsem_write(policy->cpu); | 1742 | up_write(&policy->rwsem); |
1706 | 1743 | ||
1707 | fail: | ||
1708 | return ret; | 1744 | return ret; |
1709 | } | 1745 | } |
1710 | EXPORT_SYMBOL_GPL(cpufreq_driver_target); | 1746 | EXPORT_SYMBOL_GPL(cpufreq_driver_target); |
@@ -1871,10 +1907,10 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu) | |||
1871 | EXPORT_SYMBOL(cpufreq_get_policy); | 1907 | EXPORT_SYMBOL(cpufreq_get_policy); |
1872 | 1908 | ||
1873 | /* | 1909 | /* |
1874 | * data : current policy. | 1910 | * policy : current policy. |
1875 | * policy : policy to be set. | 1911 | * new_policy: policy to be set. |
1876 | */ | 1912 | */ |
1877 | static int __cpufreq_set_policy(struct cpufreq_policy *policy, | 1913 | static int cpufreq_set_policy(struct cpufreq_policy *policy, |
1878 | struct cpufreq_policy *new_policy) | 1914 | struct cpufreq_policy *new_policy) |
1879 | { | 1915 | { |
1880 | int ret = 0, failed = 1; | 1916 | int ret = 0, failed = 1; |
@@ -1934,10 +1970,10 @@ static int __cpufreq_set_policy(struct cpufreq_policy *policy, | |||
1934 | /* end old governor */ | 1970 | /* end old governor */ |
1935 | if (policy->governor) { | 1971 | if (policy->governor) { |
1936 | __cpufreq_governor(policy, CPUFREQ_GOV_STOP); | 1972 | __cpufreq_governor(policy, CPUFREQ_GOV_STOP); |
1937 | unlock_policy_rwsem_write(new_policy->cpu); | 1973 | up_write(&policy->rwsem); |
1938 | __cpufreq_governor(policy, | 1974 | __cpufreq_governor(policy, |
1939 | CPUFREQ_GOV_POLICY_EXIT); | 1975 | CPUFREQ_GOV_POLICY_EXIT); |
1940 | lock_policy_rwsem_write(new_policy->cpu); | 1976 | down_write(&policy->rwsem); |
1941 | } | 1977 | } |
1942 | 1978 | ||
1943 | /* start new governor */ | 1979 | /* start new governor */ |
@@ -1946,10 +1982,10 @@ static int __cpufreq_set_policy(struct cpufreq_policy *policy, | |||
1946 | if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) { | 1982 | if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) { |
1947 | failed = 0; | 1983 | failed = 0; |
1948 | } else { | 1984 | } else { |
1949 | unlock_policy_rwsem_write(new_policy->cpu); | 1985 | up_write(&policy->rwsem); |
1950 | __cpufreq_governor(policy, | 1986 | __cpufreq_governor(policy, |
1951 | CPUFREQ_GOV_POLICY_EXIT); | 1987 | CPUFREQ_GOV_POLICY_EXIT); |
1952 | lock_policy_rwsem_write(new_policy->cpu); | 1988 | down_write(&policy->rwsem); |
1953 | } | 1989 | } |
1954 | } | 1990 | } |
1955 | 1991 | ||
@@ -1995,10 +2031,7 @@ int cpufreq_update_policy(unsigned int cpu) | |||
1995 | goto no_policy; | 2031 | goto no_policy; |
1996 | } | 2032 | } |
1997 | 2033 | ||
1998 | if (unlikely(lock_policy_rwsem_write(cpu))) { | 2034 | down_write(&policy->rwsem); |
1999 | ret = -EINVAL; | ||
2000 | goto fail; | ||
2001 | } | ||
2002 | 2035 | ||
2003 | pr_debug("updating policy for CPU %u\n", cpu); | 2036 | pr_debug("updating policy for CPU %u\n", cpu); |
2004 | memcpy(&new_policy, policy, sizeof(*policy)); | 2037 | memcpy(&new_policy, policy, sizeof(*policy)); |
@@ -2017,17 +2050,16 @@ int cpufreq_update_policy(unsigned int cpu) | |||
2017 | pr_debug("Driver did not initialize current freq"); | 2050 | pr_debug("Driver did not initialize current freq"); |
2018 | policy->cur = new_policy.cur; | 2051 | policy->cur = new_policy.cur; |
2019 | } else { | 2052 | } else { |
2020 | if (policy->cur != new_policy.cur && cpufreq_driver->target) | 2053 | if (policy->cur != new_policy.cur && has_target()) |
2021 | cpufreq_out_of_sync(cpu, policy->cur, | 2054 | cpufreq_out_of_sync(cpu, policy->cur, |
2022 | new_policy.cur); | 2055 | new_policy.cur); |
2023 | } | 2056 | } |
2024 | } | 2057 | } |
2025 | 2058 | ||
2026 | ret = __cpufreq_set_policy(policy, &new_policy); | 2059 | ret = cpufreq_set_policy(policy, &new_policy); |
2027 | 2060 | ||
2028 | unlock_policy_rwsem_write(cpu); | 2061 | up_write(&policy->rwsem); |
2029 | 2062 | ||
2030 | fail: | ||
2031 | cpufreq_cpu_put(policy); | 2063 | cpufreq_cpu_put(policy); |
2032 | no_policy: | 2064 | no_policy: |
2033 | return ret; | 2065 | return ret; |
@@ -2096,7 +2128,8 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) | |||
2096 | return -ENODEV; | 2128 | return -ENODEV; |
2097 | 2129 | ||
2098 | if (!driver_data || !driver_data->verify || !driver_data->init || | 2130 | if (!driver_data || !driver_data->verify || !driver_data->init || |
2099 | ((!driver_data->setpolicy) && (!driver_data->target))) | 2131 | !(driver_data->setpolicy || driver_data->target_index || |
2132 | driver_data->target)) | ||
2100 | return -EINVAL; | 2133 | return -EINVAL; |
2101 | 2134 | ||
2102 | pr_debug("trying to register driver %s\n", driver_data->name); | 2135 | pr_debug("trying to register driver %s\n", driver_data->name); |
@@ -2183,14 +2216,9 @@ EXPORT_SYMBOL_GPL(cpufreq_unregister_driver); | |||
2183 | 2216 | ||
2184 | static int __init cpufreq_core_init(void) | 2217 | static int __init cpufreq_core_init(void) |
2185 | { | 2218 | { |
2186 | int cpu; | ||
2187 | |||
2188 | if (cpufreq_disabled()) | 2219 | if (cpufreq_disabled()) |
2189 | return -ENODEV; | 2220 | return -ENODEV; |
2190 | 2221 | ||
2191 | for_each_possible_cpu(cpu) | ||
2192 | init_rwsem(&per_cpu(cpu_policy_rwsem, cpu)); | ||
2193 | |||
2194 | cpufreq_global_kobject = kobject_create(); | 2222 | cpufreq_global_kobject = kobject_create(); |
2195 | BUG_ON(!cpufreq_global_kobject); | 2223 | BUG_ON(!cpufreq_global_kobject); |
2196 | register_syscore_ops(&cpufreq_syscore_ops); | 2224 | register_syscore_ops(&cpufreq_syscore_ops); |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index f62d822048e6..218460fcd2e4 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
@@ -80,13 +80,18 @@ static void cs_check_cpu(int cpu, unsigned int load) | |||
80 | 80 | ||
81 | /* Check for frequency decrease */ | 81 | /* Check for frequency decrease */ |
82 | if (load < cs_tuners->down_threshold) { | 82 | if (load < cs_tuners->down_threshold) { |
83 | unsigned int freq_target; | ||
83 | /* | 84 | /* |
84 | * if we cannot reduce the frequency anymore, break out early | 85 | * if we cannot reduce the frequency anymore, break out early |
85 | */ | 86 | */ |
86 | if (policy->cur == policy->min) | 87 | if (policy->cur == policy->min) |
87 | return; | 88 | return; |
88 | 89 | ||
89 | dbs_info->requested_freq -= get_freq_target(cs_tuners, policy); | 90 | freq_target = get_freq_target(cs_tuners, policy); |
91 | if (dbs_info->requested_freq > freq_target) | ||
92 | dbs_info->requested_freq -= freq_target; | ||
93 | else | ||
94 | dbs_info->requested_freq = policy->min; | ||
90 | 95 | ||
91 | __cpufreq_driver_target(policy, dbs_info->requested_freq, | 96 | __cpufreq_driver_target(policy, dbs_info->requested_freq, |
92 | CPUFREQ_RELATION_L); | 97 | CPUFREQ_RELATION_L); |
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index 88cd39f7b0e9..b5f2b8618949 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h | |||
@@ -191,7 +191,10 @@ struct common_dbs_data { | |||
191 | struct attribute_group *attr_group_gov_sys; /* one governor - system */ | 191 | struct attribute_group *attr_group_gov_sys; /* one governor - system */ |
192 | struct attribute_group *attr_group_gov_pol; /* one governor - policy */ | 192 | struct attribute_group *attr_group_gov_pol; /* one governor - policy */ |
193 | 193 | ||
194 | /* Common data for platforms that don't set have_governor_per_policy */ | 194 | /* |
195 | * Common data for platforms that don't set | ||
196 | * CPUFREQ_HAVE_GOVERNOR_PER_POLICY | ||
197 | */ | ||
195 | struct dbs_data *gdbs_data; | 198 | struct dbs_data *gdbs_data; |
196 | 199 | ||
197 | struct cpu_dbs_common_info *(*get_cpu_cdbs)(int cpu); | 200 | struct cpu_dbs_common_info *(*get_cpu_cdbs)(int cpu); |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 32f26f6e17c5..18d409189092 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -168,7 +168,6 @@ static void od_check_cpu(int cpu, unsigned int load) | |||
168 | dbs_info->rate_mult = | 168 | dbs_info->rate_mult = |
169 | od_tuners->sampling_down_factor; | 169 | od_tuners->sampling_down_factor; |
170 | dbs_freq_increase(policy, policy->max); | 170 | dbs_freq_increase(policy, policy->max); |
171 | return; | ||
172 | } else { | 171 | } else { |
173 | /* Calculate the next frequency proportional to load */ | 172 | /* Calculate the next frequency proportional to load */ |
174 | unsigned int freq_next; | 173 | unsigned int freq_next; |
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index 03078090b5f7..4dbf1db16aca 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c | |||
@@ -38,18 +38,7 @@ static int cpufreq_set(struct cpufreq_policy *policy, unsigned int freq) | |||
38 | if (!per_cpu(cpu_is_managed, policy->cpu)) | 38 | if (!per_cpu(cpu_is_managed, policy->cpu)) |
39 | goto err; | 39 | goto err; |
40 | 40 | ||
41 | /* | ||
42 | * We're safe from concurrent calls to ->target() here | ||
43 | * as we hold the userspace_mutex lock. If we were calling | ||
44 | * cpufreq_driver_target, a deadlock situation might occur: | ||
45 | * A: cpufreq_set (lock userspace_mutex) -> | ||
46 | * cpufreq_driver_target(lock policy->lock) | ||
47 | * B: cpufreq_set_policy(lock policy->lock) -> | ||
48 | * __cpufreq_governor -> | ||
49 | * cpufreq_governor_userspace (lock userspace_mutex) | ||
50 | */ | ||
51 | ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L); | 41 | ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L); |
52 | |||
53 | err: | 42 | err: |
54 | mutex_unlock(&userspace_mutex); | 43 | mutex_unlock(&userspace_mutex); |
55 | return ret; | 44 | return ret; |
diff --git a/drivers/cpufreq/cris-artpec3-cpufreq.c b/drivers/cpufreq/cris-artpec3-cpufreq.c index cb8276dd19ca..86559040c54c 100644 --- a/drivers/cpufreq/cris-artpec3-cpufreq.c +++ b/drivers/cpufreq/cris-artpec3-cpufreq.c | |||
@@ -27,18 +27,11 @@ static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu) | |||
27 | return clk_ctrl.pll ? 200000 : 6000; | 27 | return clk_ctrl.pll ? 200000 : 6000; |
28 | } | 28 | } |
29 | 29 | ||
30 | static void cris_freq_set_cpu_state(struct cpufreq_policy *policy, | 30 | static int cris_freq_target(struct cpufreq_policy *policy, unsigned int state) |
31 | unsigned int state) | ||
32 | { | 31 | { |
33 | struct cpufreq_freqs freqs; | ||
34 | reg_clkgen_rw_clk_ctrl clk_ctrl; | 32 | reg_clkgen_rw_clk_ctrl clk_ctrl; |
35 | clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl); | 33 | clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl); |
36 | 34 | ||
37 | freqs.old = cris_freq_get_cpu_frequency(policy->cpu); | ||
38 | freqs.new = cris_freq_table[state].frequency; | ||
39 | |||
40 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
41 | |||
42 | local_irq_disable(); | 35 | local_irq_disable(); |
43 | 36 | ||
44 | /* Even though we may be SMP they will share the same clock | 37 | /* Even though we may be SMP they will share the same clock |
@@ -51,67 +44,22 @@ static void cris_freq_set_cpu_state(struct cpufreq_policy *policy, | |||
51 | 44 | ||
52 | local_irq_enable(); | 45 | local_irq_enable(); |
53 | 46 | ||
54 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
55 | }; | ||
56 | |||
57 | static int cris_freq_verify(struct cpufreq_policy *policy) | ||
58 | { | ||
59 | return cpufreq_frequency_table_verify(policy, &cris_freq_table[0]); | ||
60 | } | ||
61 | |||
62 | static int cris_freq_target(struct cpufreq_policy *policy, | ||
63 | unsigned int target_freq, | ||
64 | unsigned int relation) | ||
65 | { | ||
66 | unsigned int newstate = 0; | ||
67 | |||
68 | if (cpufreq_frequency_table_target(policy, cris_freq_table, | ||
69 | target_freq, relation, &newstate)) | ||
70 | return -EINVAL; | ||
71 | |||
72 | cris_freq_set_cpu_state(policy, newstate); | ||
73 | |||
74 | return 0; | 47 | return 0; |
75 | } | 48 | } |
76 | 49 | ||
77 | static int cris_freq_cpu_init(struct cpufreq_policy *policy) | 50 | static int cris_freq_cpu_init(struct cpufreq_policy *policy) |
78 | { | 51 | { |
79 | int result; | 52 | return cpufreq_generic_init(policy, cris_freq_table, 1000000); |
80 | |||
81 | /* cpuinfo and default policy values */ | ||
82 | policy->cpuinfo.transition_latency = 1000000; /* 1ms */ | ||
83 | policy->cur = cris_freq_get_cpu_frequency(0); | ||
84 | |||
85 | result = cpufreq_frequency_table_cpuinfo(policy, cris_freq_table); | ||
86 | if (result) | ||
87 | return (result); | ||
88 | |||
89 | cpufreq_frequency_table_get_attr(cris_freq_table, policy->cpu); | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | |||
95 | static int cris_freq_cpu_exit(struct cpufreq_policy *policy) | ||
96 | { | ||
97 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
98 | return 0; | ||
99 | } | 53 | } |
100 | 54 | ||
101 | |||
102 | static struct freq_attr *cris_freq_attr[] = { | ||
103 | &cpufreq_freq_attr_scaling_available_freqs, | ||
104 | NULL, | ||
105 | }; | ||
106 | |||
107 | static struct cpufreq_driver cris_freq_driver = { | 55 | static struct cpufreq_driver cris_freq_driver = { |
108 | .get = cris_freq_get_cpu_frequency, | 56 | .get = cris_freq_get_cpu_frequency, |
109 | .verify = cris_freq_verify, | 57 | .verify = cpufreq_generic_frequency_table_verify, |
110 | .target = cris_freq_target, | 58 | .target_index = cris_freq_target, |
111 | .init = cris_freq_cpu_init, | 59 | .init = cris_freq_cpu_init, |
112 | .exit = cris_freq_cpu_exit, | 60 | .exit = cpufreq_generic_exit, |
113 | .name = "cris_freq", | 61 | .name = "cris_freq", |
114 | .attr = cris_freq_attr, | 62 | .attr = cpufreq_generic_attr, |
115 | }; | 63 | }; |
116 | 64 | ||
117 | static int __init cris_freq_init(void) | 65 | static int __init cris_freq_init(void) |
diff --git a/drivers/cpufreq/cris-etraxfs-cpufreq.c b/drivers/cpufreq/cris-etraxfs-cpufreq.c index 72328f77dc53..26d940d40b1d 100644 --- a/drivers/cpufreq/cris-etraxfs-cpufreq.c +++ b/drivers/cpufreq/cris-etraxfs-cpufreq.c | |||
@@ -27,18 +27,11 @@ static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu) | |||
27 | return clk_ctrl.pll ? 200000 : 6000; | 27 | return clk_ctrl.pll ? 200000 : 6000; |
28 | } | 28 | } |
29 | 29 | ||
30 | static void cris_freq_set_cpu_state(struct cpufreq_policy *policy, | 30 | static int cris_freq_target(struct cpufreq_policy *policy, unsigned int state) |
31 | unsigned int state) | ||
32 | { | 31 | { |
33 | struct cpufreq_freqs freqs; | ||
34 | reg_config_rw_clk_ctrl clk_ctrl; | 32 | reg_config_rw_clk_ctrl clk_ctrl; |
35 | clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl); | 33 | clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl); |
36 | 34 | ||
37 | freqs.old = cris_freq_get_cpu_frequency(policy->cpu); | ||
38 | freqs.new = cris_freq_table[state].frequency; | ||
39 | |||
40 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
41 | |||
42 | local_irq_disable(); | 35 | local_irq_disable(); |
43 | 36 | ||
44 | /* Even though we may be SMP they will share the same clock | 37 | /* Even though we may be SMP they will share the same clock |
@@ -51,64 +44,22 @@ static void cris_freq_set_cpu_state(struct cpufreq_policy *policy, | |||
51 | 44 | ||
52 | local_irq_enable(); | 45 | local_irq_enable(); |
53 | 46 | ||
54 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
55 | }; | ||
56 | |||
57 | static int cris_freq_verify(struct cpufreq_policy *policy) | ||
58 | { | ||
59 | return cpufreq_frequency_table_verify(policy, &cris_freq_table[0]); | ||
60 | } | ||
61 | |||
62 | static int cris_freq_target(struct cpufreq_policy *policy, | ||
63 | unsigned int target_freq, unsigned int relation) | ||
64 | { | ||
65 | unsigned int newstate = 0; | ||
66 | |||
67 | if (cpufreq_frequency_table_target | ||
68 | (policy, cris_freq_table, target_freq, relation, &newstate)) | ||
69 | return -EINVAL; | ||
70 | |||
71 | cris_freq_set_cpu_state(policy, newstate); | ||
72 | |||
73 | return 0; | 47 | return 0; |
74 | } | 48 | } |
75 | 49 | ||
76 | static int cris_freq_cpu_init(struct cpufreq_policy *policy) | 50 | static int cris_freq_cpu_init(struct cpufreq_policy *policy) |
77 | { | 51 | { |
78 | int result; | 52 | return cpufreq_generic_init(policy, cris_freq_table, 1000000); |
79 | |||
80 | /* cpuinfo and default policy values */ | ||
81 | policy->cpuinfo.transition_latency = 1000000; /* 1ms */ | ||
82 | policy->cur = cris_freq_get_cpu_frequency(0); | ||
83 | |||
84 | result = cpufreq_frequency_table_cpuinfo(policy, cris_freq_table); | ||
85 | if (result) | ||
86 | return (result); | ||
87 | |||
88 | cpufreq_frequency_table_get_attr(cris_freq_table, policy->cpu); | ||
89 | |||
90 | return 0; | ||
91 | } | 53 | } |
92 | 54 | ||
93 | static int cris_freq_cpu_exit(struct cpufreq_policy *policy) | ||
94 | { | ||
95 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static struct freq_attr *cris_freq_attr[] = { | ||
100 | &cpufreq_freq_attr_scaling_available_freqs, | ||
101 | NULL, | ||
102 | }; | ||
103 | |||
104 | static struct cpufreq_driver cris_freq_driver = { | 55 | static struct cpufreq_driver cris_freq_driver = { |
105 | .get = cris_freq_get_cpu_frequency, | 56 | .get = cris_freq_get_cpu_frequency, |
106 | .verify = cris_freq_verify, | 57 | .verify = cpufreq_generic_frequency_table_verify, |
107 | .target = cris_freq_target, | 58 | .target_index = cris_freq_target, |
108 | .init = cris_freq_cpu_init, | 59 | .init = cris_freq_cpu_init, |
109 | .exit = cris_freq_cpu_exit, | 60 | .exit = cpufreq_generic_exit, |
110 | .name = "cris_freq", | 61 | .name = "cris_freq", |
111 | .attr = cris_freq_attr, | 62 | .attr = cpufreq_generic_attr, |
112 | }; | 63 | }; |
113 | 64 | ||
114 | static int __init cris_freq_init(void) | 65 | static int __init cris_freq_init(void) |
diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c index 551dd655c6f2..5e8a854381b7 100644 --- a/drivers/cpufreq/davinci-cpufreq.c +++ b/drivers/cpufreq/davinci-cpufreq.c | |||
@@ -50,9 +50,7 @@ static int davinci_verify_speed(struct cpufreq_policy *policy) | |||
50 | if (policy->cpu) | 50 | if (policy->cpu) |
51 | return -EINVAL; | 51 | return -EINVAL; |
52 | 52 | ||
53 | cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | 53 | cpufreq_verify_within_cpu_limits(policy); |
54 | policy->cpuinfo.max_freq); | ||
55 | |||
56 | policy->min = clk_round_rate(armclk, policy->min * 1000) / 1000; | 54 | policy->min = clk_round_rate(armclk, policy->min * 1000) / 1000; |
57 | policy->max = clk_round_rate(armclk, policy->max * 1000) / 1000; | 55 | policy->max = clk_round_rate(armclk, policy->max * 1000) / 1000; |
58 | cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | 56 | cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, |
@@ -68,58 +66,38 @@ static unsigned int davinci_getspeed(unsigned int cpu) | |||
68 | return clk_get_rate(cpufreq.armclk) / 1000; | 66 | return clk_get_rate(cpufreq.armclk) / 1000; |
69 | } | 67 | } |
70 | 68 | ||
71 | static int davinci_target(struct cpufreq_policy *policy, | 69 | static int davinci_target(struct cpufreq_policy *policy, unsigned int idx) |
72 | unsigned int target_freq, unsigned int relation) | ||
73 | { | 70 | { |
74 | int ret = 0; | ||
75 | unsigned int idx; | ||
76 | struct cpufreq_freqs freqs; | ||
77 | struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; | 71 | struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; |
78 | struct clk *armclk = cpufreq.armclk; | 72 | struct clk *armclk = cpufreq.armclk; |
73 | unsigned int old_freq, new_freq; | ||
74 | int ret = 0; | ||
79 | 75 | ||
80 | freqs.old = davinci_getspeed(0); | 76 | old_freq = davinci_getspeed(0); |
81 | freqs.new = clk_round_rate(armclk, target_freq * 1000) / 1000; | 77 | new_freq = pdata->freq_table[idx].frequency; |
82 | |||
83 | if (freqs.old == freqs.new) | ||
84 | return ret; | ||
85 | |||
86 | dev_dbg(cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new); | ||
87 | |||
88 | ret = cpufreq_frequency_table_target(policy, pdata->freq_table, | ||
89 | freqs.new, relation, &idx); | ||
90 | if (ret) | ||
91 | return -EINVAL; | ||
92 | |||
93 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
94 | 78 | ||
95 | /* if moving to higher frequency, up the voltage beforehand */ | 79 | /* if moving to higher frequency, up the voltage beforehand */ |
96 | if (pdata->set_voltage && freqs.new > freqs.old) { | 80 | if (pdata->set_voltage && new_freq > old_freq) { |
97 | ret = pdata->set_voltage(idx); | 81 | ret = pdata->set_voltage(idx); |
98 | if (ret) | 82 | if (ret) |
99 | goto out; | 83 | return ret; |
100 | } | 84 | } |
101 | 85 | ||
102 | ret = clk_set_rate(armclk, idx); | 86 | ret = clk_set_rate(armclk, idx); |
103 | if (ret) | 87 | if (ret) |
104 | goto out; | 88 | return ret; |
105 | 89 | ||
106 | if (cpufreq.asyncclk) { | 90 | if (cpufreq.asyncclk) { |
107 | ret = clk_set_rate(cpufreq.asyncclk, cpufreq.asyncrate); | 91 | ret = clk_set_rate(cpufreq.asyncclk, cpufreq.asyncrate); |
108 | if (ret) | 92 | if (ret) |
109 | goto out; | 93 | return ret; |
110 | } | 94 | } |
111 | 95 | ||
112 | /* if moving to lower freq, lower the voltage after lowering freq */ | 96 | /* if moving to lower freq, lower the voltage after lowering freq */ |
113 | if (pdata->set_voltage && freqs.new < freqs.old) | 97 | if (pdata->set_voltage && new_freq < old_freq) |
114 | pdata->set_voltage(idx); | 98 | pdata->set_voltage(idx); |
115 | 99 | ||
116 | out: | 100 | return 0; |
117 | if (ret) | ||
118 | freqs.new = freqs.old; | ||
119 | |||
120 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
121 | |||
122 | return ret; | ||
123 | } | 101 | } |
124 | 102 | ||
125 | static int davinci_cpu_init(struct cpufreq_policy *policy) | 103 | static int davinci_cpu_init(struct cpufreq_policy *policy) |
@@ -138,47 +116,24 @@ static int davinci_cpu_init(struct cpufreq_policy *policy) | |||
138 | return result; | 116 | return result; |
139 | } | 117 | } |
140 | 118 | ||
141 | policy->cur = davinci_getspeed(0); | ||
142 | |||
143 | result = cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
144 | if (result) { | ||
145 | pr_err("%s: cpufreq_frequency_table_cpuinfo() failed", | ||
146 | __func__); | ||
147 | return result; | ||
148 | } | ||
149 | |||
150 | cpufreq_frequency_table_get_attr(freq_table, policy->cpu); | ||
151 | |||
152 | /* | 119 | /* |
153 | * Time measurement across the target() function yields ~1500-1800us | 120 | * Time measurement across the target() function yields ~1500-1800us |
154 | * time taken with no drivers on notification list. | 121 | * time taken with no drivers on notification list. |
155 | * Setting the latency to 2000 us to accommodate addition of drivers | 122 | * Setting the latency to 2000 us to accommodate addition of drivers |
156 | * to pre/post change notification list. | 123 | * to pre/post change notification list. |
157 | */ | 124 | */ |
158 | policy->cpuinfo.transition_latency = 2000 * 1000; | 125 | return cpufreq_generic_init(policy, freq_table, 2000 * 1000); |
159 | return 0; | ||
160 | } | 126 | } |
161 | 127 | ||
162 | static int davinci_cpu_exit(struct cpufreq_policy *policy) | ||
163 | { | ||
164 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static struct freq_attr *davinci_cpufreq_attr[] = { | ||
169 | &cpufreq_freq_attr_scaling_available_freqs, | ||
170 | NULL, | ||
171 | }; | ||
172 | |||
173 | static struct cpufreq_driver davinci_driver = { | 128 | static struct cpufreq_driver davinci_driver = { |
174 | .flags = CPUFREQ_STICKY, | 129 | .flags = CPUFREQ_STICKY, |
175 | .verify = davinci_verify_speed, | 130 | .verify = davinci_verify_speed, |
176 | .target = davinci_target, | 131 | .target_index = davinci_target, |
177 | .get = davinci_getspeed, | 132 | .get = davinci_getspeed, |
178 | .init = davinci_cpu_init, | 133 | .init = davinci_cpu_init, |
179 | .exit = davinci_cpu_exit, | 134 | .exit = cpufreq_generic_exit, |
180 | .name = "davinci", | 135 | .name = "davinci", |
181 | .attr = davinci_cpufreq_attr, | 136 | .attr = cpufreq_generic_attr, |
182 | }; | 137 | }; |
183 | 138 | ||
184 | static int __init davinci_cpufreq_probe(struct platform_device *pdev) | 139 | static int __init davinci_cpufreq_probe(struct platform_device *pdev) |
diff --git a/drivers/cpufreq/dbx500-cpufreq.c b/drivers/cpufreq/dbx500-cpufreq.c index 26321cdc1946..0e67ab96321a 100644 --- a/drivers/cpufreq/dbx500-cpufreq.c +++ b/drivers/cpufreq/dbx500-cpufreq.c | |||
@@ -19,51 +19,11 @@ | |||
19 | static struct cpufreq_frequency_table *freq_table; | 19 | static struct cpufreq_frequency_table *freq_table; |
20 | static struct clk *armss_clk; | 20 | static struct clk *armss_clk; |
21 | 21 | ||
22 | static struct freq_attr *dbx500_cpufreq_attr[] = { | ||
23 | &cpufreq_freq_attr_scaling_available_freqs, | ||
24 | NULL, | ||
25 | }; | ||
26 | |||
27 | static int dbx500_cpufreq_verify_speed(struct cpufreq_policy *policy) | ||
28 | { | ||
29 | return cpufreq_frequency_table_verify(policy, freq_table); | ||
30 | } | ||
31 | |||
32 | static int dbx500_cpufreq_target(struct cpufreq_policy *policy, | 22 | static int dbx500_cpufreq_target(struct cpufreq_policy *policy, |
33 | unsigned int target_freq, | 23 | unsigned int index) |
34 | unsigned int relation) | ||
35 | { | 24 | { |
36 | struct cpufreq_freqs freqs; | ||
37 | unsigned int idx; | ||
38 | int ret; | ||
39 | |||
40 | /* Lookup the next frequency */ | ||
41 | if (cpufreq_frequency_table_target(policy, freq_table, target_freq, | ||
42 | relation, &idx)) | ||
43 | return -EINVAL; | ||
44 | |||
45 | freqs.old = policy->cur; | ||
46 | freqs.new = freq_table[idx].frequency; | ||
47 | |||
48 | if (freqs.old == freqs.new) | ||
49 | return 0; | ||
50 | |||
51 | /* pre-change notification */ | ||
52 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
53 | |||
54 | /* update armss clk frequency */ | 25 | /* update armss clk frequency */ |
55 | ret = clk_set_rate(armss_clk, freqs.new * 1000); | 26 | return clk_set_rate(armss_clk, freq_table[index].frequency * 1000); |
56 | |||
57 | if (ret) { | ||
58 | pr_err("dbx500-cpufreq: Failed to set armss_clk to %d Hz: error %d\n", | ||
59 | freqs.new * 1000, ret); | ||
60 | freqs.new = freqs.old; | ||
61 | } | ||
62 | |||
63 | /* post change notification */ | ||
64 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
65 | |||
66 | return ret; | ||
67 | } | 27 | } |
68 | 28 | ||
69 | static unsigned int dbx500_cpufreq_getspeed(unsigned int cpu) | 29 | static unsigned int dbx500_cpufreq_getspeed(unsigned int cpu) |
@@ -84,43 +44,17 @@ static unsigned int dbx500_cpufreq_getspeed(unsigned int cpu) | |||
84 | 44 | ||
85 | static int dbx500_cpufreq_init(struct cpufreq_policy *policy) | 45 | static int dbx500_cpufreq_init(struct cpufreq_policy *policy) |
86 | { | 46 | { |
87 | int res; | 47 | return cpufreq_generic_init(policy, freq_table, 20 * 1000); |
88 | |||
89 | /* get policy fields based on the table */ | ||
90 | res = cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
91 | if (!res) | ||
92 | cpufreq_frequency_table_get_attr(freq_table, policy->cpu); | ||
93 | else { | ||
94 | pr_err("dbx500-cpufreq: Failed to read policy table\n"); | ||
95 | return res; | ||
96 | } | ||
97 | |||
98 | policy->min = policy->cpuinfo.min_freq; | ||
99 | policy->max = policy->cpuinfo.max_freq; | ||
100 | policy->cur = dbx500_cpufreq_getspeed(policy->cpu); | ||
101 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | ||
102 | |||
103 | /* | ||
104 | * FIXME : Need to take time measurement across the target() | ||
105 | * function with no/some/all drivers in the notification | ||
106 | * list. | ||
107 | */ | ||
108 | policy->cpuinfo.transition_latency = 20 * 1000; /* in ns */ | ||
109 | |||
110 | /* policy sharing between dual CPUs */ | ||
111 | cpumask_setall(policy->cpus); | ||
112 | |||
113 | return 0; | ||
114 | } | 48 | } |
115 | 49 | ||
116 | static struct cpufreq_driver dbx500_cpufreq_driver = { | 50 | static struct cpufreq_driver dbx500_cpufreq_driver = { |
117 | .flags = CPUFREQ_STICKY | CPUFREQ_CONST_LOOPS, | 51 | .flags = CPUFREQ_STICKY | CPUFREQ_CONST_LOOPS, |
118 | .verify = dbx500_cpufreq_verify_speed, | 52 | .verify = cpufreq_generic_frequency_table_verify, |
119 | .target = dbx500_cpufreq_target, | 53 | .target_index = dbx500_cpufreq_target, |
120 | .get = dbx500_cpufreq_getspeed, | 54 | .get = dbx500_cpufreq_getspeed, |
121 | .init = dbx500_cpufreq_init, | 55 | .init = dbx500_cpufreq_init, |
122 | .name = "DBX500", | 56 | .name = "DBX500", |
123 | .attr = dbx500_cpufreq_attr, | 57 | .attr = cpufreq_generic_attr, |
124 | }; | 58 | }; |
125 | 59 | ||
126 | static int dbx500_cpufreq_probe(struct platform_device *pdev) | 60 | static int dbx500_cpufreq_probe(struct platform_device *pdev) |
diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c index 09f64cc83019..9012b8bb6b64 100644 --- a/drivers/cpufreq/e_powersaver.c +++ b/drivers/cpufreq/e_powersaver.c | |||
@@ -107,15 +107,9 @@ static int eps_set_state(struct eps_cpu_data *centaur, | |||
107 | struct cpufreq_policy *policy, | 107 | struct cpufreq_policy *policy, |
108 | u32 dest_state) | 108 | u32 dest_state) |
109 | { | 109 | { |
110 | struct cpufreq_freqs freqs; | ||
111 | u32 lo, hi; | 110 | u32 lo, hi; |
112 | int err = 0; | ||
113 | int i; | 111 | int i; |
114 | 112 | ||
115 | freqs.old = eps_get(policy->cpu); | ||
116 | freqs.new = centaur->fsb * ((dest_state >> 8) & 0xff); | ||
117 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
118 | |||
119 | /* Wait while CPU is busy */ | 113 | /* Wait while CPU is busy */ |
120 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); | 114 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); |
121 | i = 0; | 115 | i = 0; |
@@ -124,8 +118,7 @@ static int eps_set_state(struct eps_cpu_data *centaur, | |||
124 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); | 118 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); |
125 | i++; | 119 | i++; |
126 | if (unlikely(i > 64)) { | 120 | if (unlikely(i > 64)) { |
127 | err = -ENODEV; | 121 | return -ENODEV; |
128 | goto postchange; | ||
129 | } | 122 | } |
130 | } | 123 | } |
131 | /* Set new multiplier and voltage */ | 124 | /* Set new multiplier and voltage */ |
@@ -137,16 +130,10 @@ static int eps_set_state(struct eps_cpu_data *centaur, | |||
137 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); | 130 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); |
138 | i++; | 131 | i++; |
139 | if (unlikely(i > 64)) { | 132 | if (unlikely(i > 64)) { |
140 | err = -ENODEV; | 133 | return -ENODEV; |
141 | goto postchange; | ||
142 | } | 134 | } |
143 | } while (lo & ((1 << 16) | (1 << 17))); | 135 | } while (lo & ((1 << 16) | (1 << 17))); |
144 | 136 | ||
145 | /* Return current frequency */ | ||
146 | postchange: | ||
147 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); | ||
148 | freqs.new = centaur->fsb * ((lo >> 8) & 0xff); | ||
149 | |||
150 | #ifdef DEBUG | 137 | #ifdef DEBUG |
151 | { | 138 | { |
152 | u8 current_multiplier, current_voltage; | 139 | u8 current_multiplier, current_voltage; |
@@ -161,19 +148,12 @@ postchange: | |||
161 | current_multiplier); | 148 | current_multiplier); |
162 | } | 149 | } |
163 | #endif | 150 | #endif |
164 | if (err) | 151 | return 0; |
165 | freqs.new = freqs.old; | ||
166 | |||
167 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
168 | return err; | ||
169 | } | 152 | } |
170 | 153 | ||
171 | static int eps_target(struct cpufreq_policy *policy, | 154 | static int eps_target(struct cpufreq_policy *policy, unsigned int index) |
172 | unsigned int target_freq, | ||
173 | unsigned int relation) | ||
174 | { | 155 | { |
175 | struct eps_cpu_data *centaur; | 156 | struct eps_cpu_data *centaur; |
176 | unsigned int newstate = 0; | ||
177 | unsigned int cpu = policy->cpu; | 157 | unsigned int cpu = policy->cpu; |
178 | unsigned int dest_state; | 158 | unsigned int dest_state; |
179 | int ret; | 159 | int ret; |
@@ -182,28 +162,14 @@ static int eps_target(struct cpufreq_policy *policy, | |||
182 | return -ENODEV; | 162 | return -ENODEV; |
183 | centaur = eps_cpu[cpu]; | 163 | centaur = eps_cpu[cpu]; |
184 | 164 | ||
185 | if (unlikely(cpufreq_frequency_table_target(policy, | ||
186 | &eps_cpu[cpu]->freq_table[0], | ||
187 | target_freq, | ||
188 | relation, | ||
189 | &newstate))) { | ||
190 | return -EINVAL; | ||
191 | } | ||
192 | |||
193 | /* Make frequency transition */ | 165 | /* Make frequency transition */ |
194 | dest_state = centaur->freq_table[newstate].driver_data & 0xffff; | 166 | dest_state = centaur->freq_table[index].driver_data & 0xffff; |
195 | ret = eps_set_state(centaur, policy, dest_state); | 167 | ret = eps_set_state(centaur, policy, dest_state); |
196 | if (ret) | 168 | if (ret) |
197 | printk(KERN_ERR "eps: Timeout!\n"); | 169 | printk(KERN_ERR "eps: Timeout!\n"); |
198 | return ret; | 170 | return ret; |
199 | } | 171 | } |
200 | 172 | ||
201 | static int eps_verify(struct cpufreq_policy *policy) | ||
202 | { | ||
203 | return cpufreq_frequency_table_verify(policy, | ||
204 | &eps_cpu[policy->cpu]->freq_table[0]); | ||
205 | } | ||
206 | |||
207 | static int eps_cpu_init(struct cpufreq_policy *policy) | 173 | static int eps_cpu_init(struct cpufreq_policy *policy) |
208 | { | 174 | { |
209 | unsigned int i; | 175 | unsigned int i; |
@@ -401,15 +367,13 @@ static int eps_cpu_init(struct cpufreq_policy *policy) | |||
401 | } | 367 | } |
402 | 368 | ||
403 | policy->cpuinfo.transition_latency = 140000; /* 844mV -> 700mV in ns */ | 369 | policy->cpuinfo.transition_latency = 140000; /* 844mV -> 700mV in ns */ |
404 | policy->cur = fsb * current_multiplier; | ||
405 | 370 | ||
406 | ret = cpufreq_frequency_table_cpuinfo(policy, ¢aur->freq_table[0]); | 371 | ret = cpufreq_table_validate_and_show(policy, ¢aur->freq_table[0]); |
407 | if (ret) { | 372 | if (ret) { |
408 | kfree(centaur); | 373 | kfree(centaur); |
409 | return ret; | 374 | return ret; |
410 | } | 375 | } |
411 | 376 | ||
412 | cpufreq_frequency_table_get_attr(¢aur->freq_table[0], policy->cpu); | ||
413 | return 0; | 377 | return 0; |
414 | } | 378 | } |
415 | 379 | ||
@@ -424,19 +388,14 @@ static int eps_cpu_exit(struct cpufreq_policy *policy) | |||
424 | return 0; | 388 | return 0; |
425 | } | 389 | } |
426 | 390 | ||
427 | static struct freq_attr *eps_attr[] = { | ||
428 | &cpufreq_freq_attr_scaling_available_freqs, | ||
429 | NULL, | ||
430 | }; | ||
431 | |||
432 | static struct cpufreq_driver eps_driver = { | 391 | static struct cpufreq_driver eps_driver = { |
433 | .verify = eps_verify, | 392 | .verify = cpufreq_generic_frequency_table_verify, |
434 | .target = eps_target, | 393 | .target_index = eps_target, |
435 | .init = eps_cpu_init, | 394 | .init = eps_cpu_init, |
436 | .exit = eps_cpu_exit, | 395 | .exit = eps_cpu_exit, |
437 | .get = eps_get, | 396 | .get = eps_get, |
438 | .name = "e_powersaver", | 397 | .name = "e_powersaver", |
439 | .attr = eps_attr, | 398 | .attr = cpufreq_generic_attr, |
440 | }; | 399 | }; |
441 | 400 | ||
442 | 401 | ||
diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c index 823a400d98fd..de08acff5101 100644 --- a/drivers/cpufreq/elanfreq.c +++ b/drivers/cpufreq/elanfreq.c | |||
@@ -105,32 +105,9 @@ static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu) | |||
105 | } | 105 | } |
106 | 106 | ||
107 | 107 | ||
108 | /** | 108 | static int elanfreq_target(struct cpufreq_policy *policy, |
109 | * elanfreq_set_cpu_frequency: Change the CPU core frequency | 109 | unsigned int state) |
110 | * @cpu: cpu number | ||
111 | * @freq: frequency in kHz | ||
112 | * | ||
113 | * This function takes a frequency value and changes the CPU frequency | ||
114 | * according to this. Note that the frequency has to be checked by | ||
115 | * elanfreq_validatespeed() for correctness! | ||
116 | * | ||
117 | * There is no return value. | ||
118 | */ | ||
119 | |||
120 | static void elanfreq_set_cpu_state(struct cpufreq_policy *policy, | ||
121 | unsigned int state) | ||
122 | { | 110 | { |
123 | struct cpufreq_freqs freqs; | ||
124 | |||
125 | freqs.old = elanfreq_get_cpu_frequency(0); | ||
126 | freqs.new = elan_multiplier[state].clock; | ||
127 | |||
128 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
129 | |||
130 | printk(KERN_INFO "elanfreq: attempting to set frequency to %i kHz\n", | ||
131 | elan_multiplier[state].clock); | ||
132 | |||
133 | |||
134 | /* | 111 | /* |
135 | * Access to the Elan's internal registers is indexed via | 112 | * Access to the Elan's internal registers is indexed via |
136 | * 0x22: Chip Setup & Control Register Index Register (CSCI) | 113 | * 0x22: Chip Setup & Control Register Index Register (CSCI) |
@@ -161,39 +138,8 @@ static void elanfreq_set_cpu_state(struct cpufreq_policy *policy, | |||
161 | udelay(10000); | 138 | udelay(10000); |
162 | local_irq_enable(); | 139 | local_irq_enable(); |
163 | 140 | ||
164 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
165 | }; | ||
166 | |||
167 | |||
168 | /** | ||
169 | * elanfreq_validatespeed: test if frequency range is valid | ||
170 | * @policy: the policy to validate | ||
171 | * | ||
172 | * This function checks if a given frequency range in kHz is valid | ||
173 | * for the hardware supported by the driver. | ||
174 | */ | ||
175 | |||
176 | static int elanfreq_verify(struct cpufreq_policy *policy) | ||
177 | { | ||
178 | return cpufreq_frequency_table_verify(policy, &elanfreq_table[0]); | ||
179 | } | ||
180 | |||
181 | static int elanfreq_target(struct cpufreq_policy *policy, | ||
182 | unsigned int target_freq, | ||
183 | unsigned int relation) | ||
184 | { | ||
185 | unsigned int newstate = 0; | ||
186 | |||
187 | if (cpufreq_frequency_table_target(policy, &elanfreq_table[0], | ||
188 | target_freq, relation, &newstate)) | ||
189 | return -EINVAL; | ||
190 | |||
191 | elanfreq_set_cpu_state(policy, newstate); | ||
192 | |||
193 | return 0; | 141 | return 0; |
194 | } | 142 | } |
195 | |||
196 | |||
197 | /* | 143 | /* |
198 | * Module init and exit code | 144 | * Module init and exit code |
199 | */ | 145 | */ |
@@ -202,7 +148,6 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy) | |||
202 | { | 148 | { |
203 | struct cpuinfo_x86 *c = &cpu_data(0); | 149 | struct cpuinfo_x86 *c = &cpu_data(0); |
204 | unsigned int i; | 150 | unsigned int i; |
205 | int result; | ||
206 | 151 | ||
207 | /* capability check */ | 152 | /* capability check */ |
208 | if ((c->x86_vendor != X86_VENDOR_AMD) || | 153 | if ((c->x86_vendor != X86_VENDOR_AMD) || |
@@ -221,21 +166,8 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy) | |||
221 | 166 | ||
222 | /* cpuinfo and default policy values */ | 167 | /* cpuinfo and default policy values */ |
223 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 168 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; |
224 | policy->cur = elanfreq_get_cpu_frequency(0); | ||
225 | |||
226 | result = cpufreq_frequency_table_cpuinfo(policy, elanfreq_table); | ||
227 | if (result) | ||
228 | return result; | ||
229 | 169 | ||
230 | cpufreq_frequency_table_get_attr(elanfreq_table, policy->cpu); | 170 | return cpufreq_table_validate_and_show(policy, elanfreq_table); |
231 | return 0; | ||
232 | } | ||
233 | |||
234 | |||
235 | static int elanfreq_cpu_exit(struct cpufreq_policy *policy) | ||
236 | { | ||
237 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
238 | return 0; | ||
239 | } | 171 | } |
240 | 172 | ||
241 | 173 | ||
@@ -261,20 +193,14 @@ __setup("elanfreq=", elanfreq_setup); | |||
261 | #endif | 193 | #endif |
262 | 194 | ||
263 | 195 | ||
264 | static struct freq_attr *elanfreq_attr[] = { | ||
265 | &cpufreq_freq_attr_scaling_available_freqs, | ||
266 | NULL, | ||
267 | }; | ||
268 | |||
269 | |||
270 | static struct cpufreq_driver elanfreq_driver = { | 196 | static struct cpufreq_driver elanfreq_driver = { |
271 | .get = elanfreq_get_cpu_frequency, | 197 | .get = elanfreq_get_cpu_frequency, |
272 | .verify = elanfreq_verify, | 198 | .verify = cpufreq_generic_frequency_table_verify, |
273 | .target = elanfreq_target, | 199 | .target_index = elanfreq_target, |
274 | .init = elanfreq_cpu_init, | 200 | .init = elanfreq_cpu_init, |
275 | .exit = elanfreq_cpu_exit, | 201 | .exit = cpufreq_generic_exit, |
276 | .name = "elanfreq", | 202 | .name = "elanfreq", |
277 | .attr = elanfreq_attr, | 203 | .attr = cpufreq_generic_attr, |
278 | }; | 204 | }; |
279 | 205 | ||
280 | static const struct x86_cpu_id elan_id[] = { | 206 | static const struct x86_cpu_id elan_id[] = { |
diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c index 0fac34439e31..7b6dc06b1bd4 100644 --- a/drivers/cpufreq/exynos-cpufreq.c +++ b/drivers/cpufreq/exynos-cpufreq.c | |||
@@ -25,18 +25,11 @@ | |||
25 | static struct exynos_dvfs_info *exynos_info; | 25 | static struct exynos_dvfs_info *exynos_info; |
26 | 26 | ||
27 | static struct regulator *arm_regulator; | 27 | static struct regulator *arm_regulator; |
28 | static struct cpufreq_freqs freqs; | ||
29 | 28 | ||
30 | static unsigned int locking_frequency; | 29 | static unsigned int locking_frequency; |
31 | static bool frequency_locked; | 30 | static bool frequency_locked; |
32 | static DEFINE_MUTEX(cpufreq_lock); | 31 | static DEFINE_MUTEX(cpufreq_lock); |
33 | 32 | ||
34 | static int exynos_verify_speed(struct cpufreq_policy *policy) | ||
35 | { | ||
36 | return cpufreq_frequency_table_verify(policy, | ||
37 | exynos_info->freq_table); | ||
38 | } | ||
39 | |||
40 | static unsigned int exynos_getspeed(unsigned int cpu) | 33 | static unsigned int exynos_getspeed(unsigned int cpu) |
41 | { | 34 | { |
42 | return clk_get_rate(exynos_info->cpu_clk) / 1000; | 35 | return clk_get_rate(exynos_info->cpu_clk) / 1000; |
@@ -65,21 +58,18 @@ static int exynos_cpufreq_scale(unsigned int target_freq) | |||
65 | struct cpufreq_policy *policy = cpufreq_cpu_get(0); | 58 | struct cpufreq_policy *policy = cpufreq_cpu_get(0); |
66 | unsigned int arm_volt, safe_arm_volt = 0; | 59 | unsigned int arm_volt, safe_arm_volt = 0; |
67 | unsigned int mpll_freq_khz = exynos_info->mpll_freq_khz; | 60 | unsigned int mpll_freq_khz = exynos_info->mpll_freq_khz; |
61 | unsigned int old_freq; | ||
68 | int index, old_index; | 62 | int index, old_index; |
69 | int ret = 0; | 63 | int ret = 0; |
70 | 64 | ||
71 | freqs.old = policy->cur; | 65 | old_freq = policy->cur; |
72 | freqs.new = target_freq; | ||
73 | |||
74 | if (freqs.new == freqs.old) | ||
75 | goto out; | ||
76 | 66 | ||
77 | /* | 67 | /* |
78 | * The policy max have been changed so that we cannot get proper | 68 | * The policy max have been changed so that we cannot get proper |
79 | * old_index with cpufreq_frequency_table_target(). Thus, ignore | 69 | * old_index with cpufreq_frequency_table_target(). Thus, ignore |
80 | * policy and get the index from the raw freqeuncy table. | 70 | * policy and get the index from the raw freqeuncy table. |
81 | */ | 71 | */ |
82 | old_index = exynos_cpufreq_get_index(freqs.old); | 72 | old_index = exynos_cpufreq_get_index(old_freq); |
83 | if (old_index < 0) { | 73 | if (old_index < 0) { |
84 | ret = old_index; | 74 | ret = old_index; |
85 | goto out; | 75 | goto out; |
@@ -104,17 +94,14 @@ static int exynos_cpufreq_scale(unsigned int target_freq) | |||
104 | } | 94 | } |
105 | arm_volt = volt_table[index]; | 95 | arm_volt = volt_table[index]; |
106 | 96 | ||
107 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
108 | |||
109 | /* When the new frequency is higher than current frequency */ | 97 | /* When the new frequency is higher than current frequency */ |
110 | if ((freqs.new > freqs.old) && !safe_arm_volt) { | 98 | if ((target_freq > old_freq) && !safe_arm_volt) { |
111 | /* Firstly, voltage up to increase frequency */ | 99 | /* Firstly, voltage up to increase frequency */ |
112 | ret = regulator_set_voltage(arm_regulator, arm_volt, arm_volt); | 100 | ret = regulator_set_voltage(arm_regulator, arm_volt, arm_volt); |
113 | if (ret) { | 101 | if (ret) { |
114 | pr_err("%s: failed to set cpu voltage to %d\n", | 102 | pr_err("%s: failed to set cpu voltage to %d\n", |
115 | __func__, arm_volt); | 103 | __func__, arm_volt); |
116 | freqs.new = freqs.old; | 104 | return ret; |
117 | goto post_notify; | ||
118 | } | 105 | } |
119 | } | 106 | } |
120 | 107 | ||
@@ -124,24 +111,17 @@ static int exynos_cpufreq_scale(unsigned int target_freq) | |||
124 | if (ret) { | 111 | if (ret) { |
125 | pr_err("%s: failed to set cpu voltage to %d\n", | 112 | pr_err("%s: failed to set cpu voltage to %d\n", |
126 | __func__, safe_arm_volt); | 113 | __func__, safe_arm_volt); |
127 | freqs.new = freqs.old; | 114 | return ret; |
128 | goto post_notify; | ||
129 | } | 115 | } |
130 | } | 116 | } |
131 | 117 | ||
132 | exynos_info->set_freq(old_index, index); | 118 | exynos_info->set_freq(old_index, index); |
133 | 119 | ||
134 | post_notify: | ||
135 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
136 | |||
137 | if (ret) | ||
138 | goto out; | ||
139 | |||
140 | /* When the new frequency is lower than current frequency */ | 120 | /* When the new frequency is lower than current frequency */ |
141 | if ((freqs.new < freqs.old) || | 121 | if ((target_freq < old_freq) || |
142 | ((freqs.new > freqs.old) && safe_arm_volt)) { | 122 | ((target_freq > old_freq) && safe_arm_volt)) { |
143 | /* down the voltage after frequency change */ | 123 | /* down the voltage after frequency change */ |
144 | regulator_set_voltage(arm_regulator, arm_volt, | 124 | ret = regulator_set_voltage(arm_regulator, arm_volt, |
145 | arm_volt); | 125 | arm_volt); |
146 | if (ret) { | 126 | if (ret) { |
147 | pr_err("%s: failed to set cpu voltage to %d\n", | 127 | pr_err("%s: failed to set cpu voltage to %d\n", |
@@ -151,19 +131,14 @@ post_notify: | |||
151 | } | 131 | } |
152 | 132 | ||
153 | out: | 133 | out: |
154 | |||
155 | cpufreq_cpu_put(policy); | 134 | cpufreq_cpu_put(policy); |
156 | 135 | ||
157 | return ret; | 136 | return ret; |
158 | } | 137 | } |
159 | 138 | ||
160 | static int exynos_target(struct cpufreq_policy *policy, | 139 | static int exynos_target(struct cpufreq_policy *policy, unsigned int index) |
161 | unsigned int target_freq, | ||
162 | unsigned int relation) | ||
163 | { | 140 | { |
164 | struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; | 141 | struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; |
165 | unsigned int index; | ||
166 | unsigned int new_freq; | ||
167 | int ret = 0; | 142 | int ret = 0; |
168 | 143 | ||
169 | mutex_lock(&cpufreq_lock); | 144 | mutex_lock(&cpufreq_lock); |
@@ -171,15 +146,7 @@ static int exynos_target(struct cpufreq_policy *policy, | |||
171 | if (frequency_locked) | 146 | if (frequency_locked) |
172 | goto out; | 147 | goto out; |
173 | 148 | ||
174 | if (cpufreq_frequency_table_target(policy, freq_table, | 149 | ret = exynos_cpufreq_scale(freq_table[index].frequency); |
175 | target_freq, relation, &index)) { | ||
176 | ret = -EINVAL; | ||
177 | goto out; | ||
178 | } | ||
179 | |||
180 | new_freq = freq_table[index].frequency; | ||
181 | |||
182 | ret = exynos_cpufreq_scale(new_freq); | ||
183 | 150 | ||
184 | out: | 151 | out: |
185 | mutex_unlock(&cpufreq_lock); | 152 | mutex_unlock(&cpufreq_lock); |
@@ -247,38 +214,18 @@ static struct notifier_block exynos_cpufreq_nb = { | |||
247 | 214 | ||
248 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) | 215 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) |
249 | { | 216 | { |
250 | policy->cur = policy->min = policy->max = exynos_getspeed(policy->cpu); | 217 | return cpufreq_generic_init(policy, exynos_info->freq_table, 100000); |
251 | |||
252 | cpufreq_frequency_table_get_attr(exynos_info->freq_table, policy->cpu); | ||
253 | |||
254 | /* set the transition latency value */ | ||
255 | policy->cpuinfo.transition_latency = 100000; | ||
256 | |||
257 | cpumask_setall(policy->cpus); | ||
258 | |||
259 | return cpufreq_frequency_table_cpuinfo(policy, exynos_info->freq_table); | ||
260 | } | ||
261 | |||
262 | static int exynos_cpufreq_cpu_exit(struct cpufreq_policy *policy) | ||
263 | { | ||
264 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
265 | return 0; | ||
266 | } | 218 | } |
267 | 219 | ||
268 | static struct freq_attr *exynos_cpufreq_attr[] = { | ||
269 | &cpufreq_freq_attr_scaling_available_freqs, | ||
270 | NULL, | ||
271 | }; | ||
272 | |||
273 | static struct cpufreq_driver exynos_driver = { | 220 | static struct cpufreq_driver exynos_driver = { |
274 | .flags = CPUFREQ_STICKY, | 221 | .flags = CPUFREQ_STICKY, |
275 | .verify = exynos_verify_speed, | 222 | .verify = cpufreq_generic_frequency_table_verify, |
276 | .target = exynos_target, | 223 | .target_index = exynos_target, |
277 | .get = exynos_getspeed, | 224 | .get = exynos_getspeed, |
278 | .init = exynos_cpufreq_cpu_init, | 225 | .init = exynos_cpufreq_cpu_init, |
279 | .exit = exynos_cpufreq_cpu_exit, | 226 | .exit = cpufreq_generic_exit, |
280 | .name = "exynos_cpufreq", | 227 | .name = "exynos_cpufreq", |
281 | .attr = exynos_cpufreq_attr, | 228 | .attr = cpufreq_generic_attr, |
282 | #ifdef CONFIG_PM | 229 | #ifdef CONFIG_PM |
283 | .suspend = exynos_cpufreq_suspend, | 230 | .suspend = exynos_cpufreq_suspend, |
284 | .resume = exynos_cpufreq_resume, | 231 | .resume = exynos_cpufreq_resume, |
diff --git a/drivers/cpufreq/exynos4210-cpufreq.c b/drivers/cpufreq/exynos4210-cpufreq.c index add7fbec4fc9..f2c75065ce19 100644 --- a/drivers/cpufreq/exynos4210-cpufreq.c +++ b/drivers/cpufreq/exynos4210-cpufreq.c | |||
@@ -81,9 +81,9 @@ static void exynos4210_set_clkdiv(unsigned int div_index) | |||
81 | 81 | ||
82 | static void exynos4210_set_apll(unsigned int index) | 82 | static void exynos4210_set_apll(unsigned int index) |
83 | { | 83 | { |
84 | unsigned int tmp; | 84 | unsigned int tmp, freq = apll_freq_4210[index].freq; |
85 | 85 | ||
86 | /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ | 86 | /* MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ |
87 | clk_set_parent(moutcore, mout_mpll); | 87 | clk_set_parent(moutcore, mout_mpll); |
88 | 88 | ||
89 | do { | 89 | do { |
@@ -92,21 +92,9 @@ static void exynos4210_set_apll(unsigned int index) | |||
92 | tmp &= 0x7; | 92 | tmp &= 0x7; |
93 | } while (tmp != 0x2); | 93 | } while (tmp != 0x2); |
94 | 94 | ||
95 | /* 2. Set APLL Lock time */ | 95 | clk_set_rate(mout_apll, freq * 1000); |
96 | __raw_writel(EXYNOS4_APLL_LOCKTIME, EXYNOS4_APLL_LOCK); | ||
97 | |||
98 | /* 3. Change PLL PMS values */ | ||
99 | tmp = __raw_readl(EXYNOS4_APLL_CON0); | ||
100 | tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0)); | ||
101 | tmp |= apll_freq_4210[index].mps; | ||
102 | __raw_writel(tmp, EXYNOS4_APLL_CON0); | ||
103 | 96 | ||
104 | /* 4. wait_lock_time */ | 97 | /* MUX_CORE_SEL = APLL */ |
105 | do { | ||
106 | tmp = __raw_readl(EXYNOS4_APLL_CON0); | ||
107 | } while (!(tmp & (0x1 << EXYNOS4_APLLCON0_LOCKED_SHIFT))); | ||
108 | |||
109 | /* 5. MUX_CORE_SEL = APLL */ | ||
110 | clk_set_parent(moutcore, mout_apll); | 98 | clk_set_parent(moutcore, mout_apll); |
111 | 99 | ||
112 | do { | 100 | do { |
@@ -115,53 +103,15 @@ static void exynos4210_set_apll(unsigned int index) | |||
115 | } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT)); | 103 | } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT)); |
116 | } | 104 | } |
117 | 105 | ||
118 | static bool exynos4210_pms_change(unsigned int old_index, unsigned int new_index) | ||
119 | { | ||
120 | unsigned int old_pm = apll_freq_4210[old_index].mps >> 8; | ||
121 | unsigned int new_pm = apll_freq_4210[new_index].mps >> 8; | ||
122 | |||
123 | return (old_pm == new_pm) ? 0 : 1; | ||
124 | } | ||
125 | |||
126 | static void exynos4210_set_frequency(unsigned int old_index, | 106 | static void exynos4210_set_frequency(unsigned int old_index, |
127 | unsigned int new_index) | 107 | unsigned int new_index) |
128 | { | 108 | { |
129 | unsigned int tmp; | ||
130 | |||
131 | if (old_index > new_index) { | 109 | if (old_index > new_index) { |
132 | if (!exynos4210_pms_change(old_index, new_index)) { | 110 | exynos4210_set_clkdiv(new_index); |
133 | /* 1. Change the system clock divider values */ | 111 | exynos4210_set_apll(new_index); |
134 | exynos4210_set_clkdiv(new_index); | ||
135 | |||
136 | /* 2. Change just s value in apll m,p,s value */ | ||
137 | tmp = __raw_readl(EXYNOS4_APLL_CON0); | ||
138 | tmp &= ~(0x7 << 0); | ||
139 | tmp |= apll_freq_4210[new_index].mps & 0x7; | ||
140 | __raw_writel(tmp, EXYNOS4_APLL_CON0); | ||
141 | } else { | ||
142 | /* Clock Configuration Procedure */ | ||
143 | /* 1. Change the system clock divider values */ | ||
144 | exynos4210_set_clkdiv(new_index); | ||
145 | /* 2. Change the apll m,p,s value */ | ||
146 | exynos4210_set_apll(new_index); | ||
147 | } | ||
148 | } else if (old_index < new_index) { | 112 | } else if (old_index < new_index) { |
149 | if (!exynos4210_pms_change(old_index, new_index)) { | 113 | exynos4210_set_apll(new_index); |
150 | /* 1. Change just s value in apll m,p,s value */ | 114 | exynos4210_set_clkdiv(new_index); |
151 | tmp = __raw_readl(EXYNOS4_APLL_CON0); | ||
152 | tmp &= ~(0x7 << 0); | ||
153 | tmp |= apll_freq_4210[new_index].mps & 0x7; | ||
154 | __raw_writel(tmp, EXYNOS4_APLL_CON0); | ||
155 | |||
156 | /* 2. Change the system clock divider values */ | ||
157 | exynos4210_set_clkdiv(new_index); | ||
158 | } else { | ||
159 | /* Clock Configuration Procedure */ | ||
160 | /* 1. Change the apll m,p,s value */ | ||
161 | exynos4210_set_apll(new_index); | ||
162 | /* 2. Change the system clock divider values */ | ||
163 | exynos4210_set_clkdiv(new_index); | ||
164 | } | ||
165 | } | 115 | } |
166 | } | 116 | } |
167 | 117 | ||
@@ -194,7 +144,6 @@ int exynos4210_cpufreq_init(struct exynos_dvfs_info *info) | |||
194 | info->volt_table = exynos4210_volt_table; | 144 | info->volt_table = exynos4210_volt_table; |
195 | info->freq_table = exynos4210_freq_table; | 145 | info->freq_table = exynos4210_freq_table; |
196 | info->set_freq = exynos4210_set_frequency; | 146 | info->set_freq = exynos4210_set_frequency; |
197 | info->need_apll_change = exynos4210_pms_change; | ||
198 | 147 | ||
199 | return 0; | 148 | return 0; |
200 | 149 | ||
diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c index 08b7477b0aa2..8683304ce62c 100644 --- a/drivers/cpufreq/exynos4x12-cpufreq.c +++ b/drivers/cpufreq/exynos4x12-cpufreq.c | |||
@@ -128,9 +128,9 @@ static void exynos4x12_set_clkdiv(unsigned int div_index) | |||
128 | 128 | ||
129 | static void exynos4x12_set_apll(unsigned int index) | 129 | static void exynos4x12_set_apll(unsigned int index) |
130 | { | 130 | { |
131 | unsigned int tmp, pdiv; | 131 | unsigned int tmp, freq = apll_freq_4x12[index].freq; |
132 | 132 | ||
133 | /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ | 133 | /* MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ |
134 | clk_set_parent(moutcore, mout_mpll); | 134 | clk_set_parent(moutcore, mout_mpll); |
135 | 135 | ||
136 | do { | 136 | do { |
@@ -140,24 +140,9 @@ static void exynos4x12_set_apll(unsigned int index) | |||
140 | tmp &= 0x7; | 140 | tmp &= 0x7; |
141 | } while (tmp != 0x2); | 141 | } while (tmp != 0x2); |
142 | 142 | ||
143 | /* 2. Set APLL Lock time */ | 143 | clk_set_rate(mout_apll, freq * 1000); |
144 | pdiv = ((apll_freq_4x12[index].mps >> 8) & 0x3f); | ||
145 | 144 | ||
146 | __raw_writel((pdiv * 250), EXYNOS4_APLL_LOCK); | 145 | /* MUX_CORE_SEL = APLL */ |
147 | |||
148 | /* 3. Change PLL PMS values */ | ||
149 | tmp = __raw_readl(EXYNOS4_APLL_CON0); | ||
150 | tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0)); | ||
151 | tmp |= apll_freq_4x12[index].mps; | ||
152 | __raw_writel(tmp, EXYNOS4_APLL_CON0); | ||
153 | |||
154 | /* 4. wait_lock_time */ | ||
155 | do { | ||
156 | cpu_relax(); | ||
157 | tmp = __raw_readl(EXYNOS4_APLL_CON0); | ||
158 | } while (!(tmp & (0x1 << EXYNOS4_APLLCON0_LOCKED_SHIFT))); | ||
159 | |||
160 | /* 5. MUX_CORE_SEL = APLL */ | ||
161 | clk_set_parent(moutcore, mout_apll); | 146 | clk_set_parent(moutcore, mout_apll); |
162 | 147 | ||
163 | do { | 148 | do { |
@@ -167,52 +152,15 @@ static void exynos4x12_set_apll(unsigned int index) | |||
167 | } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT)); | 152 | } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT)); |
168 | } | 153 | } |
169 | 154 | ||
170 | static bool exynos4x12_pms_change(unsigned int old_index, unsigned int new_index) | ||
171 | { | ||
172 | unsigned int old_pm = apll_freq_4x12[old_index].mps >> 8; | ||
173 | unsigned int new_pm = apll_freq_4x12[new_index].mps >> 8; | ||
174 | |||
175 | return (old_pm == new_pm) ? 0 : 1; | ||
176 | } | ||
177 | |||
178 | static void exynos4x12_set_frequency(unsigned int old_index, | 155 | static void exynos4x12_set_frequency(unsigned int old_index, |
179 | unsigned int new_index) | 156 | unsigned int new_index) |
180 | { | 157 | { |
181 | unsigned int tmp; | ||
182 | |||
183 | if (old_index > new_index) { | 158 | if (old_index > new_index) { |
184 | if (!exynos4x12_pms_change(old_index, new_index)) { | 159 | exynos4x12_set_clkdiv(new_index); |
185 | /* 1. Change the system clock divider values */ | 160 | exynos4x12_set_apll(new_index); |
186 | exynos4x12_set_clkdiv(new_index); | ||
187 | /* 2. Change just s value in apll m,p,s value */ | ||
188 | tmp = __raw_readl(EXYNOS4_APLL_CON0); | ||
189 | tmp &= ~(0x7 << 0); | ||
190 | tmp |= apll_freq_4x12[new_index].mps & 0x7; | ||
191 | __raw_writel(tmp, EXYNOS4_APLL_CON0); | ||
192 | |||
193 | } else { | ||
194 | /* Clock Configuration Procedure */ | ||
195 | /* 1. Change the system clock divider values */ | ||
196 | exynos4x12_set_clkdiv(new_index); | ||
197 | /* 2. Change the apll m,p,s value */ | ||
198 | exynos4x12_set_apll(new_index); | ||
199 | } | ||
200 | } else if (old_index < new_index) { | 161 | } else if (old_index < new_index) { |
201 | if (!exynos4x12_pms_change(old_index, new_index)) { | 162 | exynos4x12_set_apll(new_index); |
202 | /* 1. Change just s value in apll m,p,s value */ | 163 | exynos4x12_set_clkdiv(new_index); |
203 | tmp = __raw_readl(EXYNOS4_APLL_CON0); | ||
204 | tmp &= ~(0x7 << 0); | ||
205 | tmp |= apll_freq_4x12[new_index].mps & 0x7; | ||
206 | __raw_writel(tmp, EXYNOS4_APLL_CON0); | ||
207 | /* 2. Change the system clock divider values */ | ||
208 | exynos4x12_set_clkdiv(new_index); | ||
209 | } else { | ||
210 | /* Clock Configuration Procedure */ | ||
211 | /* 1. Change the apll m,p,s value */ | ||
212 | exynos4x12_set_apll(new_index); | ||
213 | /* 2. Change the system clock divider values */ | ||
214 | exynos4x12_set_clkdiv(new_index); | ||
215 | } | ||
216 | } | 164 | } |
217 | } | 165 | } |
218 | 166 | ||
@@ -250,7 +198,6 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info) | |||
250 | info->volt_table = exynos4x12_volt_table; | 198 | info->volt_table = exynos4x12_volt_table; |
251 | info->freq_table = exynos4x12_freq_table; | 199 | info->freq_table = exynos4x12_freq_table; |
252 | info->set_freq = exynos4x12_set_frequency; | 200 | info->set_freq = exynos4x12_set_frequency; |
253 | info->need_apll_change = exynos4x12_pms_change; | ||
254 | 201 | ||
255 | return 0; | 202 | return 0; |
256 | 203 | ||
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index be5380ecdcd4..76bef8b078cb 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
22 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
23 | #include <linux/opp.h> | 23 | #include <linux/pm_opp.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | 26 | ||
@@ -118,12 +118,12 @@ static int init_div_table(void) | |||
118 | struct cpufreq_frequency_table *freq_tbl = dvfs_info->freq_table; | 118 | struct cpufreq_frequency_table *freq_tbl = dvfs_info->freq_table; |
119 | unsigned int tmp, clk_div, ema_div, freq, volt_id; | 119 | unsigned int tmp, clk_div, ema_div, freq, volt_id; |
120 | int i = 0; | 120 | int i = 0; |
121 | struct opp *opp; | 121 | struct dev_pm_opp *opp; |
122 | 122 | ||
123 | rcu_read_lock(); | 123 | rcu_read_lock(); |
124 | for (i = 0; freq_tbl[i].frequency != CPUFREQ_TABLE_END; i++) { | 124 | for (i = 0; freq_tbl[i].frequency != CPUFREQ_TABLE_END; i++) { |
125 | 125 | ||
126 | opp = opp_find_freq_exact(dvfs_info->dev, | 126 | opp = dev_pm_opp_find_freq_exact(dvfs_info->dev, |
127 | freq_tbl[i].frequency * 1000, true); | 127 | freq_tbl[i].frequency * 1000, true); |
128 | if (IS_ERR(opp)) { | 128 | if (IS_ERR(opp)) { |
129 | rcu_read_unlock(); | 129 | rcu_read_unlock(); |
@@ -142,7 +142,7 @@ static int init_div_table(void) | |||
142 | << P0_7_CSCLKDEV_SHIFT; | 142 | << P0_7_CSCLKDEV_SHIFT; |
143 | 143 | ||
144 | /* Calculate EMA */ | 144 | /* Calculate EMA */ |
145 | volt_id = opp_get_voltage(opp); | 145 | volt_id = dev_pm_opp_get_voltage(opp); |
146 | volt_id = (MAX_VOLTAGE - volt_id) / VOLTAGE_STEP; | 146 | volt_id = (MAX_VOLTAGE - volt_id) / VOLTAGE_STEP; |
147 | if (volt_id < PMIC_HIGH_VOLT) { | 147 | if (volt_id < PMIC_HIGH_VOLT) { |
148 | ema_div = (CPUEMA_HIGH << P0_7_CPUEMA_SHIFT) | | 148 | ema_div = (CPUEMA_HIGH << P0_7_CPUEMA_SHIFT) | |
@@ -209,38 +209,22 @@ static void exynos_enable_dvfs(void) | |||
209 | dvfs_info->base + XMU_DVFS_CTRL); | 209 | dvfs_info->base + XMU_DVFS_CTRL); |
210 | } | 210 | } |
211 | 211 | ||
212 | static int exynos_verify_speed(struct cpufreq_policy *policy) | ||
213 | { | ||
214 | return cpufreq_frequency_table_verify(policy, | ||
215 | dvfs_info->freq_table); | ||
216 | } | ||
217 | |||
218 | static unsigned int exynos_getspeed(unsigned int cpu) | 212 | static unsigned int exynos_getspeed(unsigned int cpu) |
219 | { | 213 | { |
220 | return dvfs_info->cur_frequency; | 214 | return dvfs_info->cur_frequency; |
221 | } | 215 | } |
222 | 216 | ||
223 | static int exynos_target(struct cpufreq_policy *policy, | 217 | static int exynos_target(struct cpufreq_policy *policy, unsigned int index) |
224 | unsigned int target_freq, | ||
225 | unsigned int relation) | ||
226 | { | 218 | { |
227 | unsigned int index, tmp; | 219 | unsigned int tmp; |
228 | int ret = 0, i; | 220 | int i; |
229 | struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; | 221 | struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; |
230 | 222 | ||
231 | mutex_lock(&cpufreq_lock); | 223 | mutex_lock(&cpufreq_lock); |
232 | 224 | ||
233 | ret = cpufreq_frequency_table_target(policy, freq_table, | ||
234 | target_freq, relation, &index); | ||
235 | if (ret) | ||
236 | goto out; | ||
237 | |||
238 | freqs.old = dvfs_info->cur_frequency; | 225 | freqs.old = dvfs_info->cur_frequency; |
239 | freqs.new = freq_table[index].frequency; | 226 | freqs.new = freq_table[index].frequency; |
240 | 227 | ||
241 | if (freqs.old == freqs.new) | ||
242 | goto out; | ||
243 | |||
244 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 228 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); |
245 | 229 | ||
246 | /* Set the target frequency in all C0_3_PSTATE register */ | 230 | /* Set the target frequency in all C0_3_PSTATE register */ |
@@ -251,9 +235,8 @@ static int exynos_target(struct cpufreq_policy *policy, | |||
251 | 235 | ||
252 | __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + i * 4); | 236 | __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + i * 4); |
253 | } | 237 | } |
254 | out: | ||
255 | mutex_unlock(&cpufreq_lock); | 238 | mutex_unlock(&cpufreq_lock); |
256 | return ret; | 239 | return 0; |
257 | } | 240 | } |
258 | 241 | ||
259 | static void exynos_cpufreq_work(struct work_struct *work) | 242 | static void exynos_cpufreq_work(struct work_struct *work) |
@@ -324,30 +307,19 @@ static void exynos_sort_descend_freq_table(void) | |||
324 | 307 | ||
325 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) | 308 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) |
326 | { | 309 | { |
327 | int ret; | 310 | return cpufreq_generic_init(policy, dvfs_info->freq_table, |
328 | 311 | dvfs_info->latency); | |
329 | ret = cpufreq_frequency_table_cpuinfo(policy, dvfs_info->freq_table); | ||
330 | if (ret) { | ||
331 | dev_err(dvfs_info->dev, "Invalid frequency table: %d\n", ret); | ||
332 | return ret; | ||
333 | } | ||
334 | |||
335 | policy->cur = dvfs_info->cur_frequency; | ||
336 | policy->cpuinfo.transition_latency = dvfs_info->latency; | ||
337 | cpumask_setall(policy->cpus); | ||
338 | |||
339 | cpufreq_frequency_table_get_attr(dvfs_info->freq_table, policy->cpu); | ||
340 | |||
341 | return 0; | ||
342 | } | 312 | } |
343 | 313 | ||
344 | static struct cpufreq_driver exynos_driver = { | 314 | static struct cpufreq_driver exynos_driver = { |
345 | .flags = CPUFREQ_STICKY, | 315 | .flags = CPUFREQ_STICKY | CPUFREQ_ASYNC_NOTIFICATION, |
346 | .verify = exynos_verify_speed, | 316 | .verify = cpufreq_generic_frequency_table_verify, |
347 | .target = exynos_target, | 317 | .target_index = exynos_target, |
348 | .get = exynos_getspeed, | 318 | .get = exynos_getspeed, |
349 | .init = exynos_cpufreq_cpu_init, | 319 | .init = exynos_cpufreq_cpu_init, |
320 | .exit = cpufreq_generic_exit, | ||
350 | .name = CPUFREQ_NAME, | 321 | .name = CPUFREQ_NAME, |
322 | .attr = cpufreq_generic_attr, | ||
351 | }; | 323 | }; |
352 | 324 | ||
353 | static const struct of_device_id exynos_cpufreq_match[] = { | 325 | static const struct of_device_id exynos_cpufreq_match[] = { |
@@ -399,13 +371,14 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
399 | goto err_put_node; | 371 | goto err_put_node; |
400 | } | 372 | } |
401 | 373 | ||
402 | ret = opp_init_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); | 374 | ret = dev_pm_opp_init_cpufreq_table(dvfs_info->dev, |
375 | &dvfs_info->freq_table); | ||
403 | if (ret) { | 376 | if (ret) { |
404 | dev_err(dvfs_info->dev, | 377 | dev_err(dvfs_info->dev, |
405 | "failed to init cpufreq table: %d\n", ret); | 378 | "failed to init cpufreq table: %d\n", ret); |
406 | goto err_put_node; | 379 | goto err_put_node; |
407 | } | 380 | } |
408 | dvfs_info->freq_count = opp_get_opp_count(dvfs_info->dev); | 381 | dvfs_info->freq_count = dev_pm_opp_get_opp_count(dvfs_info->dev); |
409 | exynos_sort_descend_freq_table(); | 382 | exynos_sort_descend_freq_table(); |
410 | 383 | ||
411 | if (of_property_read_u32(np, "clock-latency", &dvfs_info->latency)) | 384 | if (of_property_read_u32(np, "clock-latency", &dvfs_info->latency)) |
@@ -454,7 +427,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
454 | return 0; | 427 | return 0; |
455 | 428 | ||
456 | err_free_table: | 429 | err_free_table: |
457 | opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); | 430 | dev_pm_opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); |
458 | err_put_node: | 431 | err_put_node: |
459 | of_node_put(np); | 432 | of_node_put(np); |
460 | dev_err(&pdev->dev, "%s: failed initialization\n", __func__); | 433 | dev_err(&pdev->dev, "%s: failed initialization\n", __func__); |
@@ -464,7 +437,7 @@ err_put_node: | |||
464 | static int exynos_cpufreq_remove(struct platform_device *pdev) | 437 | static int exynos_cpufreq_remove(struct platform_device *pdev) |
465 | { | 438 | { |
466 | cpufreq_unregister_driver(&exynos_driver); | 439 | cpufreq_unregister_driver(&exynos_driver); |
467 | opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); | 440 | dev_pm_opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); |
468 | return 0; | 441 | return 0; |
469 | } | 442 | } |
470 | 443 | ||
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index f111454a7aea..3458d27f63b4 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c | |||
@@ -54,31 +54,30 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_cpuinfo); | |||
54 | int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, | 54 | int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, |
55 | struct cpufreq_frequency_table *table) | 55 | struct cpufreq_frequency_table *table) |
56 | { | 56 | { |
57 | unsigned int next_larger = ~0; | 57 | unsigned int next_larger = ~0, freq, i = 0; |
58 | unsigned int i; | 58 | bool found = false; |
59 | unsigned int count = 0; | ||
60 | 59 | ||
61 | pr_debug("request for verification of policy (%u - %u kHz) for cpu %u\n", | 60 | pr_debug("request for verification of policy (%u - %u kHz) for cpu %u\n", |
62 | policy->min, policy->max, policy->cpu); | 61 | policy->min, policy->max, policy->cpu); |
63 | 62 | ||
64 | cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | 63 | cpufreq_verify_within_cpu_limits(policy); |
65 | policy->cpuinfo.max_freq); | ||
66 | 64 | ||
67 | for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { | 65 | for (; freq = table[i].frequency, freq != CPUFREQ_TABLE_END; i++) { |
68 | unsigned int freq = table[i].frequency; | ||
69 | if (freq == CPUFREQ_ENTRY_INVALID) | 66 | if (freq == CPUFREQ_ENTRY_INVALID) |
70 | continue; | 67 | continue; |
71 | if ((freq >= policy->min) && (freq <= policy->max)) | 68 | if ((freq >= policy->min) && (freq <= policy->max)) { |
72 | count++; | 69 | found = true; |
73 | else if ((next_larger > freq) && (freq > policy->max)) | 70 | break; |
71 | } | ||
72 | |||
73 | if ((next_larger > freq) && (freq > policy->max)) | ||
74 | next_larger = freq; | 74 | next_larger = freq; |
75 | } | 75 | } |
76 | 76 | ||
77 | if (!count) | 77 | if (!found) { |
78 | policy->max = next_larger; | 78 | policy->max = next_larger; |
79 | 79 | cpufreq_verify_within_cpu_limits(policy); | |
80 | cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | 80 | } |
81 | policy->cpuinfo.max_freq); | ||
82 | 81 | ||
83 | pr_debug("verification lead to (%u - %u kHz) for cpu %u\n", | 82 | pr_debug("verification lead to (%u - %u kHz) for cpu %u\n", |
84 | policy->min, policy->max, policy->cpu); | 83 | policy->min, policy->max, policy->cpu); |
@@ -87,6 +86,20 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, | |||
87 | } | 86 | } |
88 | EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify); | 87 | EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify); |
89 | 88 | ||
89 | /* | ||
90 | * Generic routine to verify policy & frequency table, requires driver to call | ||
91 | * cpufreq_frequency_table_get_attr() prior to it. | ||
92 | */ | ||
93 | int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy) | ||
94 | { | ||
95 | struct cpufreq_frequency_table *table = | ||
96 | cpufreq_frequency_get_table(policy->cpu); | ||
97 | if (!table) | ||
98 | return -ENODEV; | ||
99 | |||
100 | return cpufreq_frequency_table_verify(policy, table); | ||
101 | } | ||
102 | EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify); | ||
90 | 103 | ||
91 | int cpufreq_frequency_table_target(struct cpufreq_policy *policy, | 104 | int cpufreq_frequency_table_target(struct cpufreq_policy *policy, |
92 | struct cpufreq_frequency_table *table, | 105 | struct cpufreq_frequency_table *table, |
@@ -200,6 +213,12 @@ struct freq_attr cpufreq_freq_attr_scaling_available_freqs = { | |||
200 | }; | 213 | }; |
201 | EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs); | 214 | EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs); |
202 | 215 | ||
216 | struct freq_attr *cpufreq_generic_attr[] = { | ||
217 | &cpufreq_freq_attr_scaling_available_freqs, | ||
218 | NULL, | ||
219 | }; | ||
220 | EXPORT_SYMBOL_GPL(cpufreq_generic_attr); | ||
221 | |||
203 | /* | 222 | /* |
204 | * if you use these, you must assure that the frequency table is valid | 223 | * if you use these, you must assure that the frequency table is valid |
205 | * all the time between get_attr and put_attr! | 224 | * all the time between get_attr and put_attr! |
@@ -219,6 +238,18 @@ void cpufreq_frequency_table_put_attr(unsigned int cpu) | |||
219 | } | 238 | } |
220 | EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr); | 239 | EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr); |
221 | 240 | ||
241 | int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, | ||
242 | struct cpufreq_frequency_table *table) | ||
243 | { | ||
244 | int ret = cpufreq_frequency_table_cpuinfo(policy, table); | ||
245 | |||
246 | if (!ret) | ||
247 | cpufreq_frequency_table_get_attr(table, policy->cpu); | ||
248 | |||
249 | return ret; | ||
250 | } | ||
251 | EXPORT_SYMBOL_GPL(cpufreq_table_validate_and_show); | ||
252 | |||
222 | void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy) | 253 | void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy) |
223 | { | 254 | { |
224 | pr_debug("Updating show_table for new_cpu %u from last_cpu %u\n", | 255 | pr_debug("Updating show_table for new_cpu %u from last_cpu %u\n", |
diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c index 70442c7b5e71..d83e8266a58e 100644 --- a/drivers/cpufreq/gx-suspmod.c +++ b/drivers/cpufreq/gx-suspmod.c | |||
@@ -401,7 +401,7 @@ static int cpufreq_gx_target(struct cpufreq_policy *policy, | |||
401 | 401 | ||
402 | static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy) | 402 | static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy) |
403 | { | 403 | { |
404 | unsigned int maxfreq, curfreq; | 404 | unsigned int maxfreq; |
405 | 405 | ||
406 | if (!policy || policy->cpu != 0) | 406 | if (!policy || policy->cpu != 0) |
407 | return -ENODEV; | 407 | return -ENODEV; |
@@ -415,10 +415,8 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy) | |||
415 | maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; | 415 | maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f]; |
416 | 416 | ||
417 | stock_freq = maxfreq; | 417 | stock_freq = maxfreq; |
418 | curfreq = gx_get_cpuspeed(0); | ||
419 | 418 | ||
420 | pr_debug("cpu max frequency is %d.\n", maxfreq); | 419 | pr_debug("cpu max frequency is %d.\n", maxfreq); |
421 | pr_debug("cpu current frequency is %dkHz.\n", curfreq); | ||
422 | 420 | ||
423 | /* setup basic struct for cpufreq API */ | 421 | /* setup basic struct for cpufreq API */ |
424 | policy->cpu = 0; | 422 | policy->cpu = 0; |
@@ -428,7 +426,6 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy) | |||
428 | else | 426 | else |
429 | policy->min = maxfreq / POLICY_MIN_DIV; | 427 | policy->min = maxfreq / POLICY_MIN_DIV; |
430 | policy->max = maxfreq; | 428 | policy->max = maxfreq; |
431 | policy->cur = curfreq; | ||
432 | policy->cpuinfo.min_freq = maxfreq / max_duration; | 429 | policy->cpuinfo.min_freq = maxfreq / max_duration; |
433 | policy->cpuinfo.max_freq = maxfreq; | 430 | policy->cpuinfo.max_freq = maxfreq; |
434 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 431 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; |
diff --git a/drivers/cpufreq/highbank-cpufreq.c b/drivers/cpufreq/highbank-cpufreq.c index 794123fcf3e3..bf8902a0866d 100644 --- a/drivers/cpufreq/highbank-cpufreq.c +++ b/drivers/cpufreq/highbank-cpufreq.c | |||
@@ -66,7 +66,8 @@ static int hb_cpufreq_driver_init(void) | |||
66 | struct device_node *np; | 66 | struct device_node *np; |
67 | int ret; | 67 | int ret; |
68 | 68 | ||
69 | if (!of_machine_is_compatible("calxeda,highbank")) | 69 | if ((!of_machine_is_compatible("calxeda,highbank")) && |
70 | (!of_machine_is_compatible("calxeda,ecx-2000"))) | ||
70 | return -ENODEV; | 71 | return -ENODEV; |
71 | 72 | ||
72 | cpu_dev = get_cpu_device(0); | 73 | cpu_dev = get_cpu_device(0); |
diff --git a/drivers/cpufreq/ia64-acpi-cpufreq.c b/drivers/cpufreq/ia64-acpi-cpufreq.c index 3e14f0317175..53c6ac637e10 100644 --- a/drivers/cpufreq/ia64-acpi-cpufreq.c +++ b/drivers/cpufreq/ia64-acpi-cpufreq.c | |||
@@ -141,7 +141,6 @@ processor_set_freq ( | |||
141 | { | 141 | { |
142 | int ret = 0; | 142 | int ret = 0; |
143 | u32 value = 0; | 143 | u32 value = 0; |
144 | struct cpufreq_freqs cpufreq_freqs; | ||
145 | cpumask_t saved_mask; | 144 | cpumask_t saved_mask; |
146 | int retval; | 145 | int retval; |
147 | 146 | ||
@@ -168,13 +167,6 @@ processor_set_freq ( | |||
168 | pr_debug("Transitioning from P%d to P%d\n", | 167 | pr_debug("Transitioning from P%d to P%d\n", |
169 | data->acpi_data.state, state); | 168 | data->acpi_data.state, state); |
170 | 169 | ||
171 | /* cpufreq frequency struct */ | ||
172 | cpufreq_freqs.old = data->freq_table[data->acpi_data.state].frequency; | ||
173 | cpufreq_freqs.new = data->freq_table[state].frequency; | ||
174 | |||
175 | /* notify cpufreq */ | ||
176 | cpufreq_notify_transition(policy, &cpufreq_freqs, CPUFREQ_PRECHANGE); | ||
177 | |||
178 | /* | 170 | /* |
179 | * First we write the target state's 'control' value to the | 171 | * First we write the target state's 'control' value to the |
180 | * control_register. | 172 | * control_register. |
@@ -186,22 +178,11 @@ processor_set_freq ( | |||
186 | 178 | ||
187 | ret = processor_set_pstate(value); | 179 | ret = processor_set_pstate(value); |
188 | if (ret) { | 180 | if (ret) { |
189 | unsigned int tmp = cpufreq_freqs.new; | ||
190 | cpufreq_notify_transition(policy, &cpufreq_freqs, | ||
191 | CPUFREQ_POSTCHANGE); | ||
192 | cpufreq_freqs.new = cpufreq_freqs.old; | ||
193 | cpufreq_freqs.old = tmp; | ||
194 | cpufreq_notify_transition(policy, &cpufreq_freqs, | ||
195 | CPUFREQ_PRECHANGE); | ||
196 | cpufreq_notify_transition(policy, &cpufreq_freqs, | ||
197 | CPUFREQ_POSTCHANGE); | ||
198 | printk(KERN_WARNING "Transition failed with error %d\n", ret); | 181 | printk(KERN_WARNING "Transition failed with error %d\n", ret); |
199 | retval = -ENODEV; | 182 | retval = -ENODEV; |
200 | goto migrate_end; | 183 | goto migrate_end; |
201 | } | 184 | } |
202 | 185 | ||
203 | cpufreq_notify_transition(policy, &cpufreq_freqs, CPUFREQ_POSTCHANGE); | ||
204 | |||
205 | data->acpi_data.state = state; | 186 | data->acpi_data.state = state; |
206 | 187 | ||
207 | retval = 0; | 188 | retval = 0; |
@@ -227,42 +208,11 @@ acpi_cpufreq_get ( | |||
227 | static int | 208 | static int |
228 | acpi_cpufreq_target ( | 209 | acpi_cpufreq_target ( |
229 | struct cpufreq_policy *policy, | 210 | struct cpufreq_policy *policy, |
230 | unsigned int target_freq, | 211 | unsigned int index) |
231 | unsigned int relation) | ||
232 | { | ||
233 | struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu]; | ||
234 | unsigned int next_state = 0; | ||
235 | unsigned int result = 0; | ||
236 | |||
237 | pr_debug("acpi_cpufreq_setpolicy\n"); | ||
238 | |||
239 | result = cpufreq_frequency_table_target(policy, | ||
240 | data->freq_table, target_freq, relation, &next_state); | ||
241 | if (result) | ||
242 | return (result); | ||
243 | |||
244 | result = processor_set_freq(data, policy, next_state); | ||
245 | |||
246 | return (result); | ||
247 | } | ||
248 | |||
249 | |||
250 | static int | ||
251 | acpi_cpufreq_verify ( | ||
252 | struct cpufreq_policy *policy) | ||
253 | { | 212 | { |
254 | unsigned int result = 0; | 213 | return processor_set_freq(acpi_io_data[policy->cpu], policy, index); |
255 | struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu]; | ||
256 | |||
257 | pr_debug("acpi_cpufreq_verify\n"); | ||
258 | |||
259 | result = cpufreq_frequency_table_verify(policy, | ||
260 | data->freq_table); | ||
261 | |||
262 | return (result); | ||
263 | } | 214 | } |
264 | 215 | ||
265 | |||
266 | static int | 216 | static int |
267 | acpi_cpufreq_cpu_init ( | 217 | acpi_cpufreq_cpu_init ( |
268 | struct cpufreq_policy *policy) | 218 | struct cpufreq_policy *policy) |
@@ -321,7 +271,6 @@ acpi_cpufreq_cpu_init ( | |||
321 | data->acpi_data.states[i].transition_latency * 1000; | 271 | data->acpi_data.states[i].transition_latency * 1000; |
322 | } | 272 | } |
323 | } | 273 | } |
324 | policy->cur = processor_get_freq(data, policy->cpu); | ||
325 | 274 | ||
326 | /* table init */ | 275 | /* table init */ |
327 | for (i = 0; i <= data->acpi_data.state_count; i++) | 276 | for (i = 0; i <= data->acpi_data.state_count; i++) |
@@ -335,7 +284,7 @@ acpi_cpufreq_cpu_init ( | |||
335 | } | 284 | } |
336 | } | 285 | } |
337 | 286 | ||
338 | result = cpufreq_frequency_table_cpuinfo(policy, data->freq_table); | 287 | result = cpufreq_table_validate_and_show(policy, data->freq_table); |
339 | if (result) { | 288 | if (result) { |
340 | goto err_freqfree; | 289 | goto err_freqfree; |
341 | } | 290 | } |
@@ -356,8 +305,6 @@ acpi_cpufreq_cpu_init ( | |||
356 | (u32) data->acpi_data.states[i].status, | 305 | (u32) data->acpi_data.states[i].status, |
357 | (u32) data->acpi_data.states[i].control); | 306 | (u32) data->acpi_data.states[i].control); |
358 | 307 | ||
359 | cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu); | ||
360 | |||
361 | /* the first call to ->target() should result in us actually | 308 | /* the first call to ->target() should result in us actually |
362 | * writing something to the appropriate registers. */ | 309 | * writing something to the appropriate registers. */ |
363 | data->resume = 1; | 310 | data->resume = 1; |
@@ -396,20 +343,14 @@ acpi_cpufreq_cpu_exit ( | |||
396 | } | 343 | } |
397 | 344 | ||
398 | 345 | ||
399 | static struct freq_attr* acpi_cpufreq_attr[] = { | ||
400 | &cpufreq_freq_attr_scaling_available_freqs, | ||
401 | NULL, | ||
402 | }; | ||
403 | |||
404 | |||
405 | static struct cpufreq_driver acpi_cpufreq_driver = { | 346 | static struct cpufreq_driver acpi_cpufreq_driver = { |
406 | .verify = acpi_cpufreq_verify, | 347 | .verify = cpufreq_generic_frequency_table_verify, |
407 | .target = acpi_cpufreq_target, | 348 | .target_index = acpi_cpufreq_target, |
408 | .get = acpi_cpufreq_get, | 349 | .get = acpi_cpufreq_get, |
409 | .init = acpi_cpufreq_cpu_init, | 350 | .init = acpi_cpufreq_cpu_init, |
410 | .exit = acpi_cpufreq_cpu_exit, | 351 | .exit = acpi_cpufreq_cpu_exit, |
411 | .name = "acpi-cpufreq", | 352 | .name = "acpi-cpufreq", |
412 | .attr = acpi_cpufreq_attr, | 353 | .attr = cpufreq_generic_attr, |
413 | }; | 354 | }; |
414 | 355 | ||
415 | 356 | ||
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index c3fd2a101ca0..4b3f18e5f36b 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
16 | #include <linux/opp.h> | 16 | #include <linux/pm_opp.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/regulator/consumer.h> | 18 | #include <linux/regulator/consumer.h> |
19 | 19 | ||
@@ -35,73 +35,52 @@ 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 int imx6q_verify_speed(struct cpufreq_policy *policy) | ||
39 | { | ||
40 | return cpufreq_frequency_table_verify(policy, freq_table); | ||
41 | } | ||
42 | |||
43 | static unsigned int imx6q_get_speed(unsigned int cpu) | 38 | static unsigned int imx6q_get_speed(unsigned int cpu) |
44 | { | 39 | { |
45 | return clk_get_rate(arm_clk) / 1000; | 40 | return clk_get_rate(arm_clk) / 1000; |
46 | } | 41 | } |
47 | 42 | ||
48 | static int imx6q_set_target(struct cpufreq_policy *policy, | 43 | static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) |
49 | unsigned int target_freq, unsigned int relation) | ||
50 | { | 44 | { |
51 | struct cpufreq_freqs freqs; | 45 | struct dev_pm_opp *opp; |
52 | struct opp *opp; | ||
53 | unsigned long freq_hz, volt, volt_old; | 46 | unsigned long freq_hz, volt, volt_old; |
54 | unsigned int index; | 47 | unsigned int old_freq, new_freq; |
55 | int ret; | 48 | int ret; |
56 | 49 | ||
57 | ret = cpufreq_frequency_table_target(policy, freq_table, target_freq, | 50 | new_freq = freq_table[index].frequency; |
58 | relation, &index); | 51 | freq_hz = new_freq * 1000; |
59 | if (ret) { | 52 | old_freq = clk_get_rate(arm_clk) / 1000; |
60 | dev_err(cpu_dev, "failed to match target frequency %d: %d\n", | ||
61 | target_freq, ret); | ||
62 | return ret; | ||
63 | } | ||
64 | |||
65 | freqs.new = freq_table[index].frequency; | ||
66 | freq_hz = freqs.new * 1000; | ||
67 | freqs.old = clk_get_rate(arm_clk) / 1000; | ||
68 | |||
69 | if (freqs.old == freqs.new) | ||
70 | return 0; | ||
71 | 53 | ||
72 | rcu_read_lock(); | 54 | rcu_read_lock(); |
73 | opp = opp_find_freq_ceil(cpu_dev, &freq_hz); | 55 | opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz); |
74 | if (IS_ERR(opp)) { | 56 | if (IS_ERR(opp)) { |
75 | rcu_read_unlock(); | 57 | rcu_read_unlock(); |
76 | dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz); | 58 | dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz); |
77 | return PTR_ERR(opp); | 59 | return PTR_ERR(opp); |
78 | } | 60 | } |
79 | 61 | ||
80 | volt = opp_get_voltage(opp); | 62 | volt = dev_pm_opp_get_voltage(opp); |
81 | rcu_read_unlock(); | 63 | rcu_read_unlock(); |
82 | volt_old = regulator_get_voltage(arm_reg); | 64 | volt_old = regulator_get_voltage(arm_reg); |
83 | 65 | ||
84 | dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n", | 66 | dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n", |
85 | freqs.old / 1000, volt_old / 1000, | 67 | old_freq / 1000, volt_old / 1000, |
86 | freqs.new / 1000, volt / 1000); | 68 | new_freq / 1000, volt / 1000); |
87 | |||
88 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
89 | 69 | ||
90 | /* scaling up? scale voltage before frequency */ | 70 | /* scaling up? scale voltage before frequency */ |
91 | if (freqs.new > freqs.old) { | 71 | if (new_freq > old_freq) { |
92 | ret = regulator_set_voltage_tol(arm_reg, volt, 0); | 72 | ret = regulator_set_voltage_tol(arm_reg, volt, 0); |
93 | if (ret) { | 73 | if (ret) { |
94 | dev_err(cpu_dev, | 74 | dev_err(cpu_dev, |
95 | "failed to scale vddarm up: %d\n", ret); | 75 | "failed to scale vddarm up: %d\n", ret); |
96 | freqs.new = freqs.old; | 76 | return ret; |
97 | goto post_notify; | ||
98 | } | 77 | } |
99 | 78 | ||
100 | /* | 79 | /* |
101 | * Need to increase vddpu and vddsoc for safety | 80 | * Need to increase vddpu and vddsoc for safety |
102 | * if we are about to run at 1.2 GHz. | 81 | * if we are about to run at 1.2 GHz. |
103 | */ | 82 | */ |
104 | if (freqs.new == FREQ_1P2_GHZ / 1000) { | 83 | if (new_freq == FREQ_1P2_GHZ / 1000) { |
105 | regulator_set_voltage_tol(pu_reg, | 84 | regulator_set_voltage_tol(pu_reg, |
106 | PU_SOC_VOLTAGE_HIGH, 0); | 85 | PU_SOC_VOLTAGE_HIGH, 0); |
107 | regulator_set_voltage_tol(soc_reg, | 86 | regulator_set_voltage_tol(soc_reg, |
@@ -121,21 +100,20 @@ static int imx6q_set_target(struct cpufreq_policy *policy, | |||
121 | clk_set_parent(step_clk, pll2_pfd2_396m_clk); | 100 | clk_set_parent(step_clk, pll2_pfd2_396m_clk); |
122 | clk_set_parent(pll1_sw_clk, step_clk); | 101 | clk_set_parent(pll1_sw_clk, step_clk); |
123 | if (freq_hz > clk_get_rate(pll2_pfd2_396m_clk)) { | 102 | if (freq_hz > clk_get_rate(pll2_pfd2_396m_clk)) { |
124 | clk_set_rate(pll1_sys_clk, freqs.new * 1000); | 103 | clk_set_rate(pll1_sys_clk, new_freq * 1000); |
125 | clk_set_parent(pll1_sw_clk, pll1_sys_clk); | 104 | clk_set_parent(pll1_sw_clk, pll1_sys_clk); |
126 | } | 105 | } |
127 | 106 | ||
128 | /* Ensure the arm clock divider is what we expect */ | 107 | /* Ensure the arm clock divider is what we expect */ |
129 | ret = clk_set_rate(arm_clk, freqs.new * 1000); | 108 | ret = clk_set_rate(arm_clk, new_freq * 1000); |
130 | if (ret) { | 109 | if (ret) { |
131 | dev_err(cpu_dev, "failed to set clock rate: %d\n", ret); | 110 | dev_err(cpu_dev, "failed to set clock rate: %d\n", ret); |
132 | regulator_set_voltage_tol(arm_reg, volt_old, 0); | 111 | regulator_set_voltage_tol(arm_reg, volt_old, 0); |
133 | freqs.new = freqs.old; | 112 | return ret; |
134 | goto post_notify; | ||
135 | } | 113 | } |
136 | 114 | ||
137 | /* scaling down? scale voltage after frequency */ | 115 | /* scaling down? scale voltage after frequency */ |
138 | if (freqs.new < freqs.old) { | 116 | if (new_freq < old_freq) { |
139 | ret = regulator_set_voltage_tol(arm_reg, volt, 0); | 117 | ret = regulator_set_voltage_tol(arm_reg, volt, 0); |
140 | if (ret) { | 118 | if (ret) { |
141 | dev_warn(cpu_dev, | 119 | dev_warn(cpu_dev, |
@@ -143,7 +121,7 @@ static int imx6q_set_target(struct cpufreq_policy *policy, | |||
143 | ret = 0; | 121 | ret = 0; |
144 | } | 122 | } |
145 | 123 | ||
146 | if (freqs.old == FREQ_1P2_GHZ / 1000) { | 124 | if (old_freq == FREQ_1P2_GHZ / 1000) { |
147 | regulator_set_voltage_tol(pu_reg, | 125 | regulator_set_voltage_tol(pu_reg, |
148 | PU_SOC_VOLTAGE_NORMAL, 0); | 126 | PU_SOC_VOLTAGE_NORMAL, 0); |
149 | regulator_set_voltage_tol(soc_reg, | 127 | regulator_set_voltage_tol(soc_reg, |
@@ -151,55 +129,28 @@ static int imx6q_set_target(struct cpufreq_policy *policy, | |||
151 | } | 129 | } |
152 | } | 130 | } |
153 | 131 | ||
154 | post_notify: | ||
155 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
156 | |||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | static int imx6q_cpufreq_init(struct cpufreq_policy *policy) | ||
161 | { | ||
162 | int ret; | ||
163 | |||
164 | ret = cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
165 | if (ret) { | ||
166 | dev_err(cpu_dev, "invalid frequency table: %d\n", ret); | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | policy->cpuinfo.transition_latency = transition_latency; | ||
171 | policy->cur = clk_get_rate(arm_clk) / 1000; | ||
172 | cpumask_setall(policy->cpus); | ||
173 | cpufreq_frequency_table_get_attr(freq_table, policy->cpu); | ||
174 | |||
175 | return 0; | 132 | return 0; |
176 | } | 133 | } |
177 | 134 | ||
178 | static int imx6q_cpufreq_exit(struct cpufreq_policy *policy) | 135 | static int imx6q_cpufreq_init(struct cpufreq_policy *policy) |
179 | { | 136 | { |
180 | cpufreq_frequency_table_put_attr(policy->cpu); | 137 | return cpufreq_generic_init(policy, freq_table, transition_latency); |
181 | return 0; | ||
182 | } | 138 | } |
183 | 139 | ||
184 | static struct freq_attr *imx6q_cpufreq_attr[] = { | ||
185 | &cpufreq_freq_attr_scaling_available_freqs, | ||
186 | NULL, | ||
187 | }; | ||
188 | |||
189 | static struct cpufreq_driver imx6q_cpufreq_driver = { | 140 | static struct cpufreq_driver imx6q_cpufreq_driver = { |
190 | .verify = imx6q_verify_speed, | 141 | .verify = cpufreq_generic_frequency_table_verify, |
191 | .target = imx6q_set_target, | 142 | .target_index = imx6q_set_target, |
192 | .get = imx6q_get_speed, | 143 | .get = imx6q_get_speed, |
193 | .init = imx6q_cpufreq_init, | 144 | .init = imx6q_cpufreq_init, |
194 | .exit = imx6q_cpufreq_exit, | 145 | .exit = cpufreq_generic_exit, |
195 | .name = "imx6q-cpufreq", | 146 | .name = "imx6q-cpufreq", |
196 | .attr = imx6q_cpufreq_attr, | 147 | .attr = cpufreq_generic_attr, |
197 | }; | 148 | }; |
198 | 149 | ||
199 | static int imx6q_cpufreq_probe(struct platform_device *pdev) | 150 | static int imx6q_cpufreq_probe(struct platform_device *pdev) |
200 | { | 151 | { |
201 | struct device_node *np; | 152 | struct device_node *np; |
202 | struct opp *opp; | 153 | struct dev_pm_opp *opp; |
203 | unsigned long min_volt, max_volt; | 154 | unsigned long min_volt, max_volt; |
204 | int num, ret; | 155 | int num, ret; |
205 | 156 | ||
@@ -237,14 +188,14 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) | |||
237 | } | 188 | } |
238 | 189 | ||
239 | /* We expect an OPP table supplied by platform */ | 190 | /* We expect an OPP table supplied by platform */ |
240 | num = opp_get_opp_count(cpu_dev); | 191 | num = dev_pm_opp_get_opp_count(cpu_dev); |
241 | if (num < 0) { | 192 | if (num < 0) { |
242 | ret = num; | 193 | ret = num; |
243 | dev_err(cpu_dev, "no OPP table is found: %d\n", ret); | 194 | dev_err(cpu_dev, "no OPP table is found: %d\n", ret); |
244 | goto put_node; | 195 | goto put_node; |
245 | } | 196 | } |
246 | 197 | ||
247 | ret = opp_init_cpufreq_table(cpu_dev, &freq_table); | 198 | ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); |
248 | if (ret) { | 199 | if (ret) { |
249 | dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); | 200 | dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); |
250 | goto put_node; | 201 | goto put_node; |
@@ -259,12 +210,12 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) | |||
259 | * same order. | 210 | * same order. |
260 | */ | 211 | */ |
261 | rcu_read_lock(); | 212 | rcu_read_lock(); |
262 | opp = opp_find_freq_exact(cpu_dev, | 213 | opp = dev_pm_opp_find_freq_exact(cpu_dev, |
263 | freq_table[0].frequency * 1000, true); | 214 | freq_table[0].frequency * 1000, true); |
264 | min_volt = opp_get_voltage(opp); | 215 | min_volt = dev_pm_opp_get_voltage(opp); |
265 | opp = opp_find_freq_exact(cpu_dev, | 216 | opp = dev_pm_opp_find_freq_exact(cpu_dev, |
266 | freq_table[--num].frequency * 1000, true); | 217 | freq_table[--num].frequency * 1000, true); |
267 | max_volt = opp_get_voltage(opp); | 218 | max_volt = dev_pm_opp_get_voltage(opp); |
268 | rcu_read_unlock(); | 219 | rcu_read_unlock(); |
269 | ret = regulator_set_voltage_time(arm_reg, min_volt, max_volt); | 220 | ret = regulator_set_voltage_time(arm_reg, min_volt, max_volt); |
270 | if (ret > 0) | 221 | if (ret > 0) |
@@ -292,7 +243,7 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) | |||
292 | return 0; | 243 | return 0; |
293 | 244 | ||
294 | free_freq_table: | 245 | free_freq_table: |
295 | opp_free_cpufreq_table(cpu_dev, &freq_table); | 246 | dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); |
296 | put_node: | 247 | put_node: |
297 | of_node_put(np); | 248 | of_node_put(np); |
298 | return ret; | 249 | return ret; |
@@ -301,7 +252,7 @@ put_node: | |||
301 | static int imx6q_cpufreq_remove(struct platform_device *pdev) | 252 | static int imx6q_cpufreq_remove(struct platform_device *pdev) |
302 | { | 253 | { |
303 | cpufreq_unregister_driver(&imx6q_cpufreq_driver); | 254 | cpufreq_unregister_driver(&imx6q_cpufreq_driver); |
304 | opp_free_cpufreq_table(cpu_dev, &freq_table); | 255 | dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); |
305 | 256 | ||
306 | return 0; | 257 | return 0; |
307 | } | 258 | } |
diff --git a/drivers/cpufreq/integrator-cpufreq.c b/drivers/cpufreq/integrator-cpufreq.c index 3d79bca47433..7d8ab000d317 100644 --- a/drivers/cpufreq/integrator-cpufreq.c +++ b/drivers/cpufreq/integrator-cpufreq.c | |||
@@ -60,9 +60,7 @@ static int integrator_verify_policy(struct cpufreq_policy *policy) | |||
60 | { | 60 | { |
61 | struct icst_vco vco; | 61 | struct icst_vco vco; |
62 | 62 | ||
63 | cpufreq_verify_within_limits(policy, | 63 | cpufreq_verify_within_cpu_limits(policy); |
64 | policy->cpuinfo.min_freq, | ||
65 | policy->cpuinfo.max_freq); | ||
66 | 64 | ||
67 | vco = icst_hz_to_vco(&cclk_params, policy->max * 1000); | 65 | vco = icst_hz_to_vco(&cclk_params, policy->max * 1000); |
68 | policy->max = icst_hz(&cclk_params, vco) / 1000; | 66 | policy->max = icst_hz(&cclk_params, vco) / 1000; |
@@ -70,10 +68,7 @@ static int integrator_verify_policy(struct cpufreq_policy *policy) | |||
70 | vco = icst_hz_to_vco(&cclk_params, policy->min * 1000); | 68 | vco = icst_hz_to_vco(&cclk_params, policy->min * 1000); |
71 | policy->min = icst_hz(&cclk_params, vco) / 1000; | 69 | policy->min = icst_hz(&cclk_params, vco) / 1000; |
72 | 70 | ||
73 | cpufreq_verify_within_limits(policy, | 71 | cpufreq_verify_within_cpu_limits(policy); |
74 | policy->cpuinfo.min_freq, | ||
75 | policy->cpuinfo.max_freq); | ||
76 | |||
77 | return 0; | 72 | return 0; |
78 | } | 73 | } |
79 | 74 | ||
@@ -187,10 +182,9 @@ static int integrator_cpufreq_init(struct cpufreq_policy *policy) | |||
187 | { | 182 | { |
188 | 183 | ||
189 | /* set default policy and cpuinfo */ | 184 | /* set default policy and cpuinfo */ |
190 | policy->cpuinfo.max_freq = 160000; | 185 | policy->max = policy->cpuinfo.max_freq = 160000; |
191 | policy->cpuinfo.min_freq = 12000; | 186 | policy->min = policy->cpuinfo.min_freq = 12000; |
192 | policy->cpuinfo.transition_latency = 1000000; /* 1 ms, assumed */ | 187 | policy->cpuinfo.transition_latency = 1000000; /* 1 ms, assumed */ |
193 | policy->cur = policy->min = policy->max = integrator_get(policy->cpu); | ||
194 | 188 | ||
195 | return 0; | 189 | return 0; |
196 | } | 190 | } |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index eb3fdc755000..5f1cbae36961 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/types.h> | 25 | #include <linux/types.h> |
26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
27 | #include <linux/debugfs.h> | 27 | #include <linux/debugfs.h> |
28 | #include <linux/acpi.h> | ||
28 | #include <trace/events/power.h> | 29 | #include <trace/events/power.h> |
29 | 30 | ||
30 | #include <asm/div64.h> | 31 | #include <asm/div64.h> |
@@ -33,6 +34,8 @@ | |||
33 | 34 | ||
34 | #define SAMPLE_COUNT 3 | 35 | #define SAMPLE_COUNT 3 |
35 | 36 | ||
37 | #define BYT_RATIOS 0x66a | ||
38 | |||
36 | #define FRAC_BITS 8 | 39 | #define FRAC_BITS 8 |
37 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) | 40 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) |
38 | #define fp_toint(X) ((X) >> FRAC_BITS) | 41 | #define fp_toint(X) ((X) >> FRAC_BITS) |
@@ -78,7 +81,6 @@ struct cpudata { | |||
78 | 81 | ||
79 | struct timer_list timer; | 82 | struct timer_list timer; |
80 | 83 | ||
81 | struct pstate_adjust_policy *pstate_policy; | ||
82 | struct pstate_data pstate; | 84 | struct pstate_data pstate; |
83 | struct _pid pid; | 85 | struct _pid pid; |
84 | 86 | ||
@@ -100,15 +102,21 @@ struct pstate_adjust_policy { | |||
100 | int i_gain_pct; | 102 | int i_gain_pct; |
101 | }; | 103 | }; |
102 | 104 | ||
103 | static struct pstate_adjust_policy default_policy = { | 105 | struct pstate_funcs { |
104 | .sample_rate_ms = 10, | 106 | int (*get_max)(void); |
105 | .deadband = 0, | 107 | int (*get_min)(void); |
106 | .setpoint = 97, | 108 | int (*get_turbo)(void); |
107 | .p_gain_pct = 20, | 109 | void (*set)(int pstate); |
108 | .d_gain_pct = 0, | 110 | }; |
109 | .i_gain_pct = 0, | 111 | |
112 | struct cpu_defaults { | ||
113 | struct pstate_adjust_policy pid_policy; | ||
114 | struct pstate_funcs funcs; | ||
110 | }; | 115 | }; |
111 | 116 | ||
117 | static struct pstate_adjust_policy pid_params; | ||
118 | static struct pstate_funcs pstate_funcs; | ||
119 | |||
112 | struct perf_limits { | 120 | struct perf_limits { |
113 | int no_turbo; | 121 | int no_turbo; |
114 | int max_perf_pct; | 122 | int max_perf_pct; |
@@ -185,14 +193,14 @@ static signed int pid_calc(struct _pid *pid, int32_t busy) | |||
185 | 193 | ||
186 | static inline void intel_pstate_busy_pid_reset(struct cpudata *cpu) | 194 | static inline void intel_pstate_busy_pid_reset(struct cpudata *cpu) |
187 | { | 195 | { |
188 | pid_p_gain_set(&cpu->pid, cpu->pstate_policy->p_gain_pct); | 196 | pid_p_gain_set(&cpu->pid, pid_params.p_gain_pct); |
189 | pid_d_gain_set(&cpu->pid, cpu->pstate_policy->d_gain_pct); | 197 | pid_d_gain_set(&cpu->pid, pid_params.d_gain_pct); |
190 | pid_i_gain_set(&cpu->pid, cpu->pstate_policy->i_gain_pct); | 198 | pid_i_gain_set(&cpu->pid, pid_params.i_gain_pct); |
191 | 199 | ||
192 | pid_reset(&cpu->pid, | 200 | pid_reset(&cpu->pid, |
193 | cpu->pstate_policy->setpoint, | 201 | pid_params.setpoint, |
194 | 100, | 202 | 100, |
195 | cpu->pstate_policy->deadband, | 203 | pid_params.deadband, |
196 | 0); | 204 | 0); |
197 | } | 205 | } |
198 | 206 | ||
@@ -226,12 +234,12 @@ struct pid_param { | |||
226 | }; | 234 | }; |
227 | 235 | ||
228 | static struct pid_param pid_files[] = { | 236 | static struct pid_param pid_files[] = { |
229 | {"sample_rate_ms", &default_policy.sample_rate_ms}, | 237 | {"sample_rate_ms", &pid_params.sample_rate_ms}, |
230 | {"d_gain_pct", &default_policy.d_gain_pct}, | 238 | {"d_gain_pct", &pid_params.d_gain_pct}, |
231 | {"i_gain_pct", &default_policy.i_gain_pct}, | 239 | {"i_gain_pct", &pid_params.i_gain_pct}, |
232 | {"deadband", &default_policy.deadband}, | 240 | {"deadband", &pid_params.deadband}, |
233 | {"setpoint", &default_policy.setpoint}, | 241 | {"setpoint", &pid_params.setpoint}, |
234 | {"p_gain_pct", &default_policy.p_gain_pct}, | 242 | {"p_gain_pct", &pid_params.p_gain_pct}, |
235 | {NULL, NULL} | 243 | {NULL, NULL} |
236 | }; | 244 | }; |
237 | 245 | ||
@@ -336,33 +344,92 @@ static void intel_pstate_sysfs_expose_params(void) | |||
336 | } | 344 | } |
337 | 345 | ||
338 | /************************** sysfs end ************************/ | 346 | /************************** sysfs end ************************/ |
347 | static int byt_get_min_pstate(void) | ||
348 | { | ||
349 | u64 value; | ||
350 | rdmsrl(BYT_RATIOS, value); | ||
351 | return value & 0xFF; | ||
352 | } | ||
339 | 353 | ||
340 | static int intel_pstate_min_pstate(void) | 354 | static int byt_get_max_pstate(void) |
355 | { | ||
356 | u64 value; | ||
357 | rdmsrl(BYT_RATIOS, value); | ||
358 | return (value >> 16) & 0xFF; | ||
359 | } | ||
360 | |||
361 | static int core_get_min_pstate(void) | ||
341 | { | 362 | { |
342 | u64 value; | 363 | u64 value; |
343 | rdmsrl(MSR_PLATFORM_INFO, value); | 364 | rdmsrl(MSR_PLATFORM_INFO, value); |
344 | return (value >> 40) & 0xFF; | 365 | return (value >> 40) & 0xFF; |
345 | } | 366 | } |
346 | 367 | ||
347 | static int intel_pstate_max_pstate(void) | 368 | static int core_get_max_pstate(void) |
348 | { | 369 | { |
349 | u64 value; | 370 | u64 value; |
350 | rdmsrl(MSR_PLATFORM_INFO, value); | 371 | rdmsrl(MSR_PLATFORM_INFO, value); |
351 | return (value >> 8) & 0xFF; | 372 | return (value >> 8) & 0xFF; |
352 | } | 373 | } |
353 | 374 | ||
354 | static int intel_pstate_turbo_pstate(void) | 375 | static int core_get_turbo_pstate(void) |
355 | { | 376 | { |
356 | u64 value; | 377 | u64 value; |
357 | int nont, ret; | 378 | int nont, ret; |
358 | rdmsrl(MSR_NHM_TURBO_RATIO_LIMIT, value); | 379 | rdmsrl(MSR_NHM_TURBO_RATIO_LIMIT, value); |
359 | nont = intel_pstate_max_pstate(); | 380 | nont = core_get_max_pstate(); |
360 | ret = ((value) & 255); | 381 | ret = ((value) & 255); |
361 | if (ret <= nont) | 382 | if (ret <= nont) |
362 | ret = nont; | 383 | ret = nont; |
363 | return ret; | 384 | return ret; |
364 | } | 385 | } |
365 | 386 | ||
387 | static void core_set_pstate(int pstate) | ||
388 | { | ||
389 | u64 val; | ||
390 | |||
391 | val = pstate << 8; | ||
392 | if (limits.no_turbo) | ||
393 | val |= (u64)1 << 32; | ||
394 | |||
395 | wrmsrl(MSR_IA32_PERF_CTL, val); | ||
396 | } | ||
397 | |||
398 | static struct cpu_defaults core_params = { | ||
399 | .pid_policy = { | ||
400 | .sample_rate_ms = 10, | ||
401 | .deadband = 0, | ||
402 | .setpoint = 97, | ||
403 | .p_gain_pct = 20, | ||
404 | .d_gain_pct = 0, | ||
405 | .i_gain_pct = 0, | ||
406 | }, | ||
407 | .funcs = { | ||
408 | .get_max = core_get_max_pstate, | ||
409 | .get_min = core_get_min_pstate, | ||
410 | .get_turbo = core_get_turbo_pstate, | ||
411 | .set = core_set_pstate, | ||
412 | }, | ||
413 | }; | ||
414 | |||
415 | static struct cpu_defaults byt_params = { | ||
416 | .pid_policy = { | ||
417 | .sample_rate_ms = 10, | ||
418 | .deadband = 0, | ||
419 | .setpoint = 97, | ||
420 | .p_gain_pct = 14, | ||
421 | .d_gain_pct = 0, | ||
422 | .i_gain_pct = 4, | ||
423 | }, | ||
424 | .funcs = { | ||
425 | .get_max = byt_get_max_pstate, | ||
426 | .get_min = byt_get_min_pstate, | ||
427 | .get_turbo = byt_get_max_pstate, | ||
428 | .set = core_set_pstate, | ||
429 | }, | ||
430 | }; | ||
431 | |||
432 | |||
366 | static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max) | 433 | static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max) |
367 | { | 434 | { |
368 | int max_perf = cpu->pstate.turbo_pstate; | 435 | int max_perf = cpu->pstate.turbo_pstate; |
@@ -383,7 +450,6 @@ static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max) | |||
383 | static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate) | 450 | static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate) |
384 | { | 451 | { |
385 | int max_perf, min_perf; | 452 | int max_perf, min_perf; |
386 | u64 val; | ||
387 | 453 | ||
388 | intel_pstate_get_min_max(cpu, &min_perf, &max_perf); | 454 | intel_pstate_get_min_max(cpu, &min_perf, &max_perf); |
389 | 455 | ||
@@ -395,11 +461,8 @@ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate) | |||
395 | trace_cpu_frequency(pstate * 100000, cpu->cpu); | 461 | trace_cpu_frequency(pstate * 100000, cpu->cpu); |
396 | 462 | ||
397 | cpu->pstate.current_pstate = pstate; | 463 | cpu->pstate.current_pstate = pstate; |
398 | val = pstate << 8; | ||
399 | if (limits.no_turbo) | ||
400 | val |= (u64)1 << 32; | ||
401 | 464 | ||
402 | wrmsrl(MSR_IA32_PERF_CTL, val); | 465 | pstate_funcs.set(pstate); |
403 | } | 466 | } |
404 | 467 | ||
405 | static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps) | 468 | static inline void intel_pstate_pstate_increase(struct cpudata *cpu, int steps) |
@@ -421,9 +484,9 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) | |||
421 | { | 484 | { |
422 | sprintf(cpu->name, "Intel 2nd generation core"); | 485 | sprintf(cpu->name, "Intel 2nd generation core"); |
423 | 486 | ||
424 | cpu->pstate.min_pstate = intel_pstate_min_pstate(); | 487 | cpu->pstate.min_pstate = pstate_funcs.get_min(); |
425 | cpu->pstate.max_pstate = intel_pstate_max_pstate(); | 488 | cpu->pstate.max_pstate = pstate_funcs.get_max(); |
426 | cpu->pstate.turbo_pstate = intel_pstate_turbo_pstate(); | 489 | cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(); |
427 | 490 | ||
428 | /* | 491 | /* |
429 | * goto max pstate so we don't slow up boot if we are built-in if we are | 492 | * goto max pstate so we don't slow up boot if we are built-in if we are |
@@ -465,7 +528,7 @@ static inline void intel_pstate_set_sample_time(struct cpudata *cpu) | |||
465 | { | 528 | { |
466 | int sample_time, delay; | 529 | int sample_time, delay; |
467 | 530 | ||
468 | sample_time = cpu->pstate_policy->sample_rate_ms; | 531 | sample_time = pid_params.sample_rate_ms; |
469 | delay = msecs_to_jiffies(sample_time); | 532 | delay = msecs_to_jiffies(sample_time); |
470 | mod_timer_pinned(&cpu->timer, jiffies + delay); | 533 | mod_timer_pinned(&cpu->timer, jiffies + delay); |
471 | } | 534 | } |
@@ -521,14 +584,15 @@ static void intel_pstate_timer_func(unsigned long __data) | |||
521 | { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&policy } | 584 | { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&policy } |
522 | 585 | ||
523 | static const struct x86_cpu_id intel_pstate_cpu_ids[] = { | 586 | static const struct x86_cpu_id intel_pstate_cpu_ids[] = { |
524 | ICPU(0x2a, default_policy), | 587 | ICPU(0x2a, core_params), |
525 | ICPU(0x2d, default_policy), | 588 | ICPU(0x2d, core_params), |
526 | ICPU(0x3a, default_policy), | 589 | ICPU(0x37, byt_params), |
527 | ICPU(0x3c, default_policy), | 590 | ICPU(0x3a, core_params), |
528 | ICPU(0x3e, default_policy), | 591 | ICPU(0x3c, core_params), |
529 | ICPU(0x3f, default_policy), | 592 | ICPU(0x3e, core_params), |
530 | ICPU(0x45, default_policy), | 593 | ICPU(0x3f, core_params), |
531 | ICPU(0x46, default_policy), | 594 | ICPU(0x45, core_params), |
595 | ICPU(0x46, core_params), | ||
532 | {} | 596 | {} |
533 | }; | 597 | }; |
534 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); | 598 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); |
@@ -552,8 +616,7 @@ static int intel_pstate_init_cpu(unsigned int cpunum) | |||
552 | intel_pstate_get_cpu_pstates(cpu); | 616 | intel_pstate_get_cpu_pstates(cpu); |
553 | 617 | ||
554 | cpu->cpu = cpunum; | 618 | cpu->cpu = cpunum; |
555 | cpu->pstate_policy = | 619 | |
556 | (struct pstate_adjust_policy *)id->driver_data; | ||
557 | init_timer_deferrable(&cpu->timer); | 620 | init_timer_deferrable(&cpu->timer); |
558 | cpu->timer.function = intel_pstate_timer_func; | 621 | cpu->timer.function = intel_pstate_timer_func; |
559 | cpu->timer.data = | 622 | cpu->timer.data = |
@@ -613,9 +676,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) | |||
613 | 676 | ||
614 | static int intel_pstate_verify_policy(struct cpufreq_policy *policy) | 677 | static int intel_pstate_verify_policy(struct cpufreq_policy *policy) |
615 | { | 678 | { |
616 | cpufreq_verify_within_limits(policy, | 679 | cpufreq_verify_within_cpu_limits(policy); |
617 | policy->cpuinfo.min_freq, | ||
618 | policy->cpuinfo.max_freq); | ||
619 | 680 | ||
620 | if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) && | 681 | if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) && |
621 | (policy->policy != CPUFREQ_POLICY_PERFORMANCE)) | 682 | (policy->policy != CPUFREQ_POLICY_PERFORMANCE)) |
@@ -683,9 +744,9 @@ static int intel_pstate_msrs_not_valid(void) | |||
683 | rdmsrl(MSR_IA32_APERF, aperf); | 744 | rdmsrl(MSR_IA32_APERF, aperf); |
684 | rdmsrl(MSR_IA32_MPERF, mperf); | 745 | rdmsrl(MSR_IA32_MPERF, mperf); |
685 | 746 | ||
686 | if (!intel_pstate_min_pstate() || | 747 | if (!pstate_funcs.get_max() || |
687 | !intel_pstate_max_pstate() || | 748 | !pstate_funcs.get_min() || |
688 | !intel_pstate_turbo_pstate()) | 749 | !pstate_funcs.get_turbo()) |
689 | return -ENODEV; | 750 | return -ENODEV; |
690 | 751 | ||
691 | rdmsrl(MSR_IA32_APERF, tmp); | 752 | rdmsrl(MSR_IA32_APERF, tmp); |
@@ -698,10 +759,96 @@ static int intel_pstate_msrs_not_valid(void) | |||
698 | 759 | ||
699 | return 0; | 760 | return 0; |
700 | } | 761 | } |
762 | |||
763 | static void copy_pid_params(struct pstate_adjust_policy *policy) | ||
764 | { | ||
765 | pid_params.sample_rate_ms = policy->sample_rate_ms; | ||
766 | pid_params.p_gain_pct = policy->p_gain_pct; | ||
767 | pid_params.i_gain_pct = policy->i_gain_pct; | ||
768 | pid_params.d_gain_pct = policy->d_gain_pct; | ||
769 | pid_params.deadband = policy->deadband; | ||
770 | pid_params.setpoint = policy->setpoint; | ||
771 | } | ||
772 | |||
773 | static void copy_cpu_funcs(struct pstate_funcs *funcs) | ||
774 | { | ||
775 | pstate_funcs.get_max = funcs->get_max; | ||
776 | pstate_funcs.get_min = funcs->get_min; | ||
777 | pstate_funcs.get_turbo = funcs->get_turbo; | ||
778 | pstate_funcs.set = funcs->set; | ||
779 | } | ||
780 | |||
781 | #if IS_ENABLED(CONFIG_ACPI) | ||
782 | #include <acpi/processor.h> | ||
783 | |||
784 | static bool intel_pstate_no_acpi_pss(void) | ||
785 | { | ||
786 | int i; | ||
787 | |||
788 | for_each_possible_cpu(i) { | ||
789 | acpi_status status; | ||
790 | union acpi_object *pss; | ||
791 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
792 | struct acpi_processor *pr = per_cpu(processors, i); | ||
793 | |||
794 | if (!pr) | ||
795 | continue; | ||
796 | |||
797 | status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer); | ||
798 | if (ACPI_FAILURE(status)) | ||
799 | continue; | ||
800 | |||
801 | pss = buffer.pointer; | ||
802 | if (pss && pss->type == ACPI_TYPE_PACKAGE) { | ||
803 | kfree(pss); | ||
804 | return false; | ||
805 | } | ||
806 | |||
807 | kfree(pss); | ||
808 | } | ||
809 | |||
810 | return true; | ||
811 | } | ||
812 | |||
813 | struct hw_vendor_info { | ||
814 | u16 valid; | ||
815 | char oem_id[ACPI_OEM_ID_SIZE]; | ||
816 | char oem_table_id[ACPI_OEM_TABLE_ID_SIZE]; | ||
817 | }; | ||
818 | |||
819 | /* Hardware vendor-specific info that has its own power management modes */ | ||
820 | static struct hw_vendor_info vendor_info[] = { | ||
821 | {1, "HP ", "ProLiant"}, | ||
822 | {0, "", ""}, | ||
823 | }; | ||
824 | |||
825 | static bool intel_pstate_platform_pwr_mgmt_exists(void) | ||
826 | { | ||
827 | struct acpi_table_header hdr; | ||
828 | struct hw_vendor_info *v_info; | ||
829 | |||
830 | if (acpi_disabled | ||
831 | || ACPI_FAILURE(acpi_get_table_header(ACPI_SIG_FADT, 0, &hdr))) | ||
832 | return false; | ||
833 | |||
834 | for (v_info = vendor_info; v_info->valid; v_info++) { | ||
835 | if (!strncmp(hdr.oem_id, v_info->oem_id, ACPI_OEM_ID_SIZE) | ||
836 | && !strncmp(hdr.oem_table_id, v_info->oem_table_id, ACPI_OEM_TABLE_ID_SIZE) | ||
837 | && intel_pstate_no_acpi_pss()) | ||
838 | return true; | ||
839 | } | ||
840 | |||
841 | return false; | ||
842 | } | ||
843 | #else /* CONFIG_ACPI not enabled */ | ||
844 | static inline bool intel_pstate_platform_pwr_mgmt_exists(void) { return false; } | ||
845 | #endif /* CONFIG_ACPI */ | ||
846 | |||
701 | static int __init intel_pstate_init(void) | 847 | static int __init intel_pstate_init(void) |
702 | { | 848 | { |
703 | int cpu, rc = 0; | 849 | int cpu, rc = 0; |
704 | const struct x86_cpu_id *id; | 850 | const struct x86_cpu_id *id; |
851 | struct cpu_defaults *cpu_info; | ||
705 | 852 | ||
706 | if (no_load) | 853 | if (no_load) |
707 | return -ENODEV; | 854 | return -ENODEV; |
@@ -710,6 +857,18 @@ static int __init intel_pstate_init(void) | |||
710 | if (!id) | 857 | if (!id) |
711 | return -ENODEV; | 858 | return -ENODEV; |
712 | 859 | ||
860 | /* | ||
861 | * The Intel pstate driver will be ignored if the platform | ||
862 | * firmware has its own power management modes. | ||
863 | */ | ||
864 | if (intel_pstate_platform_pwr_mgmt_exists()) | ||
865 | return -ENODEV; | ||
866 | |||
867 | cpu_info = (struct cpu_defaults *)id->driver_data; | ||
868 | |||
869 | copy_pid_params(&cpu_info->pid_policy); | ||
870 | copy_cpu_funcs(&cpu_info->funcs); | ||
871 | |||
713 | if (intel_pstate_msrs_not_valid()) | 872 | if (intel_pstate_msrs_not_valid()) |
714 | return -ENODEV; | 873 | return -ENODEV; |
715 | 874 | ||
diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c index ba10658a9394..0767a4e29dfe 100644 --- a/drivers/cpufreq/kirkwood-cpufreq.c +++ b/drivers/cpufreq/kirkwood-cpufreq.c | |||
@@ -55,69 +55,37 @@ static unsigned int kirkwood_cpufreq_get_cpu_frequency(unsigned int cpu) | |||
55 | return kirkwood_freq_table[0].frequency; | 55 | return kirkwood_freq_table[0].frequency; |
56 | } | 56 | } |
57 | 57 | ||
58 | static void kirkwood_cpufreq_set_cpu_state(struct cpufreq_policy *policy, | 58 | static int kirkwood_cpufreq_target(struct cpufreq_policy *policy, |
59 | unsigned int index) | 59 | unsigned int index) |
60 | { | 60 | { |
61 | struct cpufreq_freqs freqs; | ||
62 | unsigned int state = kirkwood_freq_table[index].driver_data; | 61 | unsigned int state = kirkwood_freq_table[index].driver_data; |
63 | unsigned long reg; | 62 | unsigned long reg; |
64 | 63 | ||
65 | freqs.old = kirkwood_cpufreq_get_cpu_frequency(0); | 64 | local_irq_disable(); |
66 | freqs.new = kirkwood_freq_table[index].frequency; | ||
67 | |||
68 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
69 | |||
70 | dev_dbg(priv.dev, "Attempting to set frequency to %i KHz\n", | ||
71 | kirkwood_freq_table[index].frequency); | ||
72 | dev_dbg(priv.dev, "old frequency was %i KHz\n", | ||
73 | kirkwood_cpufreq_get_cpu_frequency(0)); | ||
74 | |||
75 | if (freqs.old != freqs.new) { | ||
76 | local_irq_disable(); | ||
77 | |||
78 | /* Disable interrupts to the CPU */ | ||
79 | reg = readl_relaxed(priv.base); | ||
80 | reg |= CPU_SW_INT_BLK; | ||
81 | writel_relaxed(reg, priv.base); | ||
82 | |||
83 | switch (state) { | ||
84 | case STATE_CPU_FREQ: | ||
85 | clk_disable(priv.powersave_clk); | ||
86 | break; | ||
87 | case STATE_DDR_FREQ: | ||
88 | clk_enable(priv.powersave_clk); | ||
89 | break; | ||
90 | } | ||
91 | 65 | ||
92 | /* Wait-for-Interrupt, while the hardware changes frequency */ | 66 | /* Disable interrupts to the CPU */ |
93 | cpu_do_idle(); | 67 | reg = readl_relaxed(priv.base); |
68 | reg |= CPU_SW_INT_BLK; | ||
69 | writel_relaxed(reg, priv.base); | ||
94 | 70 | ||
95 | /* Enable interrupts to the CPU */ | 71 | switch (state) { |
96 | reg = readl_relaxed(priv.base); | 72 | case STATE_CPU_FREQ: |
97 | reg &= ~CPU_SW_INT_BLK; | 73 | clk_disable(priv.powersave_clk); |
98 | writel_relaxed(reg, priv.base); | 74 | break; |
99 | 75 | case STATE_DDR_FREQ: | |
100 | local_irq_enable(); | 76 | clk_enable(priv.powersave_clk); |
77 | break; | ||
101 | } | 78 | } |
102 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
103 | }; | ||
104 | |||
105 | static int kirkwood_cpufreq_verify(struct cpufreq_policy *policy) | ||
106 | { | ||
107 | return cpufreq_frequency_table_verify(policy, kirkwood_freq_table); | ||
108 | } | ||
109 | 79 | ||
110 | static int kirkwood_cpufreq_target(struct cpufreq_policy *policy, | 80 | /* Wait-for-Interrupt, while the hardware changes frequency */ |
111 | unsigned int target_freq, | 81 | cpu_do_idle(); |
112 | unsigned int relation) | ||
113 | { | ||
114 | unsigned int index = 0; | ||
115 | 82 | ||
116 | if (cpufreq_frequency_table_target(policy, kirkwood_freq_table, | 83 | /* Enable interrupts to the CPU */ |
117 | target_freq, relation, &index)) | 84 | reg = readl_relaxed(priv.base); |
118 | return -EINVAL; | 85 | reg &= ~CPU_SW_INT_BLK; |
86 | writel_relaxed(reg, priv.base); | ||
119 | 87 | ||
120 | kirkwood_cpufreq_set_cpu_state(policy, index); | 88 | local_irq_enable(); |
121 | 89 | ||
122 | return 0; | 90 | return 0; |
123 | } | 91 | } |
@@ -125,40 +93,17 @@ static int kirkwood_cpufreq_target(struct cpufreq_policy *policy, | |||
125 | /* Module init and exit code */ | 93 | /* Module init and exit code */ |
126 | static int kirkwood_cpufreq_cpu_init(struct cpufreq_policy *policy) | 94 | static int kirkwood_cpufreq_cpu_init(struct cpufreq_policy *policy) |
127 | { | 95 | { |
128 | int result; | 96 | return cpufreq_generic_init(policy, kirkwood_freq_table, 5000); |
129 | |||
130 | /* cpuinfo and default policy values */ | ||
131 | policy->cpuinfo.transition_latency = 5000; /* 5uS */ | ||
132 | policy->cur = kirkwood_cpufreq_get_cpu_frequency(0); | ||
133 | |||
134 | result = cpufreq_frequency_table_cpuinfo(policy, kirkwood_freq_table); | ||
135 | if (result) | ||
136 | return result; | ||
137 | |||
138 | cpufreq_frequency_table_get_attr(kirkwood_freq_table, policy->cpu); | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static int kirkwood_cpufreq_cpu_exit(struct cpufreq_policy *policy) | ||
144 | { | ||
145 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
146 | return 0; | ||
147 | } | 97 | } |
148 | 98 | ||
149 | static struct freq_attr *kirkwood_cpufreq_attr[] = { | ||
150 | &cpufreq_freq_attr_scaling_available_freqs, | ||
151 | NULL, | ||
152 | }; | ||
153 | |||
154 | static struct cpufreq_driver kirkwood_cpufreq_driver = { | 99 | static struct cpufreq_driver kirkwood_cpufreq_driver = { |
155 | .get = kirkwood_cpufreq_get_cpu_frequency, | 100 | .get = kirkwood_cpufreq_get_cpu_frequency, |
156 | .verify = kirkwood_cpufreq_verify, | 101 | .verify = cpufreq_generic_frequency_table_verify, |
157 | .target = kirkwood_cpufreq_target, | 102 | .target_index = kirkwood_cpufreq_target, |
158 | .init = kirkwood_cpufreq_cpu_init, | 103 | .init = kirkwood_cpufreq_cpu_init, |
159 | .exit = kirkwood_cpufreq_cpu_exit, | 104 | .exit = cpufreq_generic_exit, |
160 | .name = "kirkwood-cpufreq", | 105 | .name = "kirkwood-cpufreq", |
161 | .attr = kirkwood_cpufreq_attr, | 106 | .attr = cpufreq_generic_attr, |
162 | }; | 107 | }; |
163 | 108 | ||
164 | static int kirkwood_cpufreq_probe(struct platform_device *pdev) | 109 | static int kirkwood_cpufreq_probe(struct platform_device *pdev) |
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index 4ada1cccb052..45bafddfd8ea 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c | |||
@@ -625,28 +625,13 @@ static void longhaul_setup_voltagescaling(void) | |||
625 | } | 625 | } |
626 | 626 | ||
627 | 627 | ||
628 | static int longhaul_verify(struct cpufreq_policy *policy) | ||
629 | { | ||
630 | return cpufreq_frequency_table_verify(policy, longhaul_table); | ||
631 | } | ||
632 | |||
633 | |||
634 | static int longhaul_target(struct cpufreq_policy *policy, | 628 | static int longhaul_target(struct cpufreq_policy *policy, |
635 | unsigned int target_freq, unsigned int relation) | 629 | unsigned int table_index) |
636 | { | 630 | { |
637 | unsigned int table_index = 0; | ||
638 | unsigned int i; | 631 | unsigned int i; |
639 | unsigned int dir = 0; | 632 | unsigned int dir = 0; |
640 | u8 vid, current_vid; | 633 | u8 vid, current_vid; |
641 | 634 | ||
642 | if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, | ||
643 | relation, &table_index)) | ||
644 | return -EINVAL; | ||
645 | |||
646 | /* Don't set same frequency again */ | ||
647 | if (longhaul_index == table_index) | ||
648 | return 0; | ||
649 | |||
650 | if (!can_scale_voltage) | 635 | if (!can_scale_voltage) |
651 | longhaul_setstate(policy, table_index); | 636 | longhaul_setstate(policy, table_index); |
652 | else { | 637 | else { |
@@ -919,36 +904,18 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy) | |||
919 | longhaul_setup_voltagescaling(); | 904 | longhaul_setup_voltagescaling(); |
920 | 905 | ||
921 | policy->cpuinfo.transition_latency = 200000; /* nsec */ | 906 | policy->cpuinfo.transition_latency = 200000; /* nsec */ |
922 | policy->cur = calc_speed(longhaul_get_cpu_mult()); | ||
923 | |||
924 | ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table); | ||
925 | if (ret) | ||
926 | return ret; | ||
927 | |||
928 | cpufreq_frequency_table_get_attr(longhaul_table, policy->cpu); | ||
929 | 907 | ||
930 | return 0; | 908 | return cpufreq_table_validate_and_show(policy, longhaul_table); |
931 | } | 909 | } |
932 | 910 | ||
933 | static int longhaul_cpu_exit(struct cpufreq_policy *policy) | ||
934 | { | ||
935 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
936 | return 0; | ||
937 | } | ||
938 | |||
939 | static struct freq_attr *longhaul_attr[] = { | ||
940 | &cpufreq_freq_attr_scaling_available_freqs, | ||
941 | NULL, | ||
942 | }; | ||
943 | |||
944 | static struct cpufreq_driver longhaul_driver = { | 911 | static struct cpufreq_driver longhaul_driver = { |
945 | .verify = longhaul_verify, | 912 | .verify = cpufreq_generic_frequency_table_verify, |
946 | .target = longhaul_target, | 913 | .target_index = longhaul_target, |
947 | .get = longhaul_get, | 914 | .get = longhaul_get, |
948 | .init = longhaul_cpu_init, | 915 | .init = longhaul_cpu_init, |
949 | .exit = longhaul_cpu_exit, | 916 | .exit = cpufreq_generic_exit, |
950 | .name = "longhaul", | 917 | .name = "longhaul", |
951 | .attr = longhaul_attr, | 918 | .attr = cpufreq_generic_attr, |
952 | }; | 919 | }; |
953 | 920 | ||
954 | static const struct x86_cpu_id longhaul_id[] = { | 921 | static const struct x86_cpu_id longhaul_id[] = { |
diff --git a/drivers/cpufreq/longrun.c b/drivers/cpufreq/longrun.c index 5aa031612d53..074971b12635 100644 --- a/drivers/cpufreq/longrun.c +++ b/drivers/cpufreq/longrun.c | |||
@@ -129,9 +129,7 @@ static int longrun_verify_policy(struct cpufreq_policy *policy) | |||
129 | return -EINVAL; | 129 | return -EINVAL; |
130 | 130 | ||
131 | policy->cpu = 0; | 131 | policy->cpu = 0; |
132 | cpufreq_verify_within_limits(policy, | 132 | cpufreq_verify_within_cpu_limits(policy); |
133 | policy->cpuinfo.min_freq, | ||
134 | policy->cpuinfo.max_freq); | ||
135 | 133 | ||
136 | if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) && | 134 | if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) && |
137 | (policy->policy != CPUFREQ_POLICY_PERFORMANCE)) | 135 | (policy->policy != CPUFREQ_POLICY_PERFORMANCE)) |
diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c index 7bc3c44d34e2..a43609218105 100644 --- a/drivers/cpufreq/loongson2_cpufreq.c +++ b/drivers/cpufreq/loongson2_cpufreq.c | |||
@@ -53,51 +53,24 @@ static unsigned int loongson2_cpufreq_get(unsigned int cpu) | |||
53 | * Here we notify other drivers of the proposed change and the final change. | 53 | * Here we notify other drivers of the proposed change and the final change. |
54 | */ | 54 | */ |
55 | static int loongson2_cpufreq_target(struct cpufreq_policy *policy, | 55 | static int loongson2_cpufreq_target(struct cpufreq_policy *policy, |
56 | unsigned int target_freq, | 56 | unsigned int index) |
57 | unsigned int relation) | ||
58 | { | 57 | { |
59 | unsigned int cpu = policy->cpu; | 58 | unsigned int cpu = policy->cpu; |
60 | unsigned int newstate = 0; | ||
61 | cpumask_t cpus_allowed; | 59 | cpumask_t cpus_allowed; |
62 | struct cpufreq_freqs freqs; | ||
63 | unsigned int freq; | 60 | unsigned int freq; |
64 | 61 | ||
65 | cpus_allowed = current->cpus_allowed; | 62 | cpus_allowed = current->cpus_allowed; |
66 | set_cpus_allowed_ptr(current, cpumask_of(cpu)); | 63 | set_cpus_allowed_ptr(current, cpumask_of(cpu)); |
67 | 64 | ||
68 | if (cpufreq_frequency_table_target | ||
69 | (policy, &loongson2_clockmod_table[0], target_freq, relation, | ||
70 | &newstate)) | ||
71 | return -EINVAL; | ||
72 | |||
73 | freq = | 65 | freq = |
74 | ((cpu_clock_freq / 1000) * | 66 | ((cpu_clock_freq / 1000) * |
75 | loongson2_clockmod_table[newstate].driver_data) / 8; | 67 | loongson2_clockmod_table[index].driver_data) / 8; |
76 | if (freq < policy->min || freq > policy->max) | ||
77 | return -EINVAL; | ||
78 | |||
79 | pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000); | ||
80 | |||
81 | freqs.old = loongson2_cpufreq_get(cpu); | ||
82 | freqs.new = freq; | ||
83 | freqs.flags = 0; | ||
84 | |||
85 | if (freqs.new == freqs.old) | ||
86 | return 0; | ||
87 | |||
88 | /* notifiers */ | ||
89 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
90 | 68 | ||
91 | set_cpus_allowed_ptr(current, &cpus_allowed); | 69 | set_cpus_allowed_ptr(current, &cpus_allowed); |
92 | 70 | ||
93 | /* setting the cpu frequency */ | 71 | /* setting the cpu frequency */ |
94 | clk_set_rate(cpuclk, freq); | 72 | clk_set_rate(cpuclk, freq); |
95 | 73 | ||
96 | /* notifiers */ | ||
97 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
98 | |||
99 | pr_debug("cpufreq: set frequency %u kHz\n", freq); | ||
100 | |||
101 | return 0; | 74 | return 0; |
102 | } | 75 | } |
103 | 76 | ||
@@ -131,40 +104,24 @@ static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
131 | return ret; | 104 | return ret; |
132 | } | 105 | } |
133 | 106 | ||
134 | policy->cur = loongson2_cpufreq_get(policy->cpu); | 107 | return cpufreq_generic_init(policy, &loongson2_clockmod_table[0], 0); |
135 | |||
136 | cpufreq_frequency_table_get_attr(&loongson2_clockmod_table[0], | ||
137 | policy->cpu); | ||
138 | |||
139 | return cpufreq_frequency_table_cpuinfo(policy, | ||
140 | &loongson2_clockmod_table[0]); | ||
141 | } | ||
142 | |||
143 | static int loongson2_cpufreq_verify(struct cpufreq_policy *policy) | ||
144 | { | ||
145 | return cpufreq_frequency_table_verify(policy, | ||
146 | &loongson2_clockmod_table[0]); | ||
147 | } | 108 | } |
148 | 109 | ||
149 | static int loongson2_cpufreq_exit(struct cpufreq_policy *policy) | 110 | static int loongson2_cpufreq_exit(struct cpufreq_policy *policy) |
150 | { | 111 | { |
112 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
151 | clk_put(cpuclk); | 113 | clk_put(cpuclk); |
152 | return 0; | 114 | return 0; |
153 | } | 115 | } |
154 | 116 | ||
155 | static struct freq_attr *loongson2_table_attr[] = { | ||
156 | &cpufreq_freq_attr_scaling_available_freqs, | ||
157 | NULL, | ||
158 | }; | ||
159 | |||
160 | static struct cpufreq_driver loongson2_cpufreq_driver = { | 117 | static struct cpufreq_driver loongson2_cpufreq_driver = { |
161 | .name = "loongson2", | 118 | .name = "loongson2", |
162 | .init = loongson2_cpufreq_cpu_init, | 119 | .init = loongson2_cpufreq_cpu_init, |
163 | .verify = loongson2_cpufreq_verify, | 120 | .verify = cpufreq_generic_frequency_table_verify, |
164 | .target = loongson2_cpufreq_target, | 121 | .target_index = loongson2_cpufreq_target, |
165 | .get = loongson2_cpufreq_get, | 122 | .get = loongson2_cpufreq_get, |
166 | .exit = loongson2_cpufreq_exit, | 123 | .exit = loongson2_cpufreq_exit, |
167 | .attr = loongson2_table_attr, | 124 | .attr = cpufreq_generic_attr, |
168 | }; | 125 | }; |
169 | 126 | ||
170 | static struct platform_device_id platform_device_ids[] = { | 127 | static struct platform_device_id platform_device_ids[] = { |
diff --git a/drivers/cpufreq/maple-cpufreq.c b/drivers/cpufreq/maple-cpufreq.c index 6168d77b296d..c4dfa42a75ac 100644 --- a/drivers/cpufreq/maple-cpufreq.c +++ b/drivers/cpufreq/maple-cpufreq.c | |||
@@ -64,18 +64,11 @@ static struct cpufreq_frequency_table maple_cpu_freqs[] = { | |||
64 | {0, CPUFREQ_TABLE_END}, | 64 | {0, CPUFREQ_TABLE_END}, |
65 | }; | 65 | }; |
66 | 66 | ||
67 | static struct freq_attr *maple_cpu_freqs_attr[] = { | ||
68 | &cpufreq_freq_attr_scaling_available_freqs, | ||
69 | NULL, | ||
70 | }; | ||
71 | |||
72 | /* Power mode data is an array of the 32 bits PCR values to use for | 67 | /* Power mode data is an array of the 32 bits PCR values to use for |
73 | * the various frequencies, retrieved from the device-tree | 68 | * the various frequencies, retrieved from the device-tree |
74 | */ | 69 | */ |
75 | static int maple_pmode_cur; | 70 | static int maple_pmode_cur; |
76 | 71 | ||
77 | static DEFINE_MUTEX(maple_switch_mutex); | ||
78 | |||
79 | static const u32 *maple_pmode_data; | 72 | static const u32 *maple_pmode_data; |
80 | static int maple_pmode_max; | 73 | static int maple_pmode_max; |
81 | 74 | ||
@@ -135,37 +128,10 @@ static int maple_scom_query_freq(void) | |||
135 | * Common interface to the cpufreq core | 128 | * Common interface to the cpufreq core |
136 | */ | 129 | */ |
137 | 130 | ||
138 | static int maple_cpufreq_verify(struct cpufreq_policy *policy) | ||
139 | { | ||
140 | return cpufreq_frequency_table_verify(policy, maple_cpu_freqs); | ||
141 | } | ||
142 | |||
143 | static int maple_cpufreq_target(struct cpufreq_policy *policy, | 131 | static int maple_cpufreq_target(struct cpufreq_policy *policy, |
144 | unsigned int target_freq, unsigned int relation) | 132 | unsigned int index) |
145 | { | 133 | { |
146 | unsigned int newstate = 0; | 134 | return maple_scom_switch_freq(index); |
147 | struct cpufreq_freqs freqs; | ||
148 | int rc; | ||
149 | |||
150 | if (cpufreq_frequency_table_target(policy, maple_cpu_freqs, | ||
151 | target_freq, relation, &newstate)) | ||
152 | return -EINVAL; | ||
153 | |||
154 | if (maple_pmode_cur == newstate) | ||
155 | return 0; | ||
156 | |||
157 | mutex_lock(&maple_switch_mutex); | ||
158 | |||
159 | freqs.old = maple_cpu_freqs[maple_pmode_cur].frequency; | ||
160 | freqs.new = maple_cpu_freqs[newstate].frequency; | ||
161 | |||
162 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
163 | rc = maple_scom_switch_freq(newstate); | ||
164 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
165 | |||
166 | mutex_unlock(&maple_switch_mutex); | ||
167 | |||
168 | return rc; | ||
169 | } | 135 | } |
170 | 136 | ||
171 | static unsigned int maple_cpufreq_get_speed(unsigned int cpu) | 137 | static unsigned int maple_cpufreq_get_speed(unsigned int cpu) |
@@ -175,27 +141,17 @@ static unsigned int maple_cpufreq_get_speed(unsigned int cpu) | |||
175 | 141 | ||
176 | static int maple_cpufreq_cpu_init(struct cpufreq_policy *policy) | 142 | static int maple_cpufreq_cpu_init(struct cpufreq_policy *policy) |
177 | { | 143 | { |
178 | policy->cpuinfo.transition_latency = 12000; | 144 | return cpufreq_generic_init(policy, maple_cpu_freqs, 12000); |
179 | policy->cur = maple_cpu_freqs[maple_scom_query_freq()].frequency; | ||
180 | /* secondary CPUs are tied to the primary one by the | ||
181 | * cpufreq core if in the secondary policy we tell it that | ||
182 | * it actually must be one policy together with all others. */ | ||
183 | cpumask_setall(policy->cpus); | ||
184 | cpufreq_frequency_table_get_attr(maple_cpu_freqs, policy->cpu); | ||
185 | |||
186 | return cpufreq_frequency_table_cpuinfo(policy, | ||
187 | maple_cpu_freqs); | ||
188 | } | 145 | } |
189 | 146 | ||
190 | |||
191 | static struct cpufreq_driver maple_cpufreq_driver = { | 147 | static struct cpufreq_driver maple_cpufreq_driver = { |
192 | .name = "maple", | 148 | .name = "maple", |
193 | .flags = CPUFREQ_CONST_LOOPS, | 149 | .flags = CPUFREQ_CONST_LOOPS, |
194 | .init = maple_cpufreq_cpu_init, | 150 | .init = maple_cpufreq_cpu_init, |
195 | .verify = maple_cpufreq_verify, | 151 | .verify = cpufreq_generic_frequency_table_verify, |
196 | .target = maple_cpufreq_target, | 152 | .target_index = maple_cpufreq_target, |
197 | .get = maple_cpufreq_get_speed, | 153 | .get = maple_cpufreq_get_speed, |
198 | .attr = maple_cpu_freqs_attr, | 154 | .attr = cpufreq_generic_attr, |
199 | }; | 155 | }; |
200 | 156 | ||
201 | static int __init maple_cpufreq_init(void) | 157 | static int __init maple_cpufreq_init(void) |
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index f31fcfcad514..be6d14307aa8 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/err.h> | 22 | #include <linux/err.h> |
23 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/opp.h> | 25 | #include <linux/pm_opp.h> |
26 | #include <linux/cpu.h> | 26 | #include <linux/cpu.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
@@ -40,13 +40,6 @@ static struct clk *mpu_clk; | |||
40 | static struct device *mpu_dev; | 40 | static struct device *mpu_dev; |
41 | static struct regulator *mpu_reg; | 41 | static struct regulator *mpu_reg; |
42 | 42 | ||
43 | static int omap_verify_speed(struct cpufreq_policy *policy) | ||
44 | { | ||
45 | if (!freq_table) | ||
46 | return -EINVAL; | ||
47 | return cpufreq_frequency_table_verify(policy, freq_table); | ||
48 | } | ||
49 | |||
50 | static unsigned int omap_getspeed(unsigned int cpu) | 43 | static unsigned int omap_getspeed(unsigned int cpu) |
51 | { | 44 | { |
52 | unsigned long rate; | 45 | unsigned long rate; |
@@ -58,42 +51,16 @@ static unsigned int omap_getspeed(unsigned int cpu) | |||
58 | return rate; | 51 | return rate; |
59 | } | 52 | } |
60 | 53 | ||
61 | static int omap_target(struct cpufreq_policy *policy, | 54 | static int omap_target(struct cpufreq_policy *policy, unsigned int index) |
62 | unsigned int target_freq, | ||
63 | unsigned int relation) | ||
64 | { | 55 | { |
65 | unsigned int i; | 56 | struct dev_pm_opp *opp; |
66 | int r, ret = 0; | ||
67 | struct cpufreq_freqs freqs; | ||
68 | struct opp *opp; | ||
69 | unsigned long freq, volt = 0, volt_old = 0, tol = 0; | 57 | unsigned long freq, volt = 0, volt_old = 0, tol = 0; |
58 | unsigned int old_freq, new_freq; | ||
70 | 59 | ||
71 | if (!freq_table) { | 60 | old_freq = omap_getspeed(policy->cpu); |
72 | dev_err(mpu_dev, "%s: cpu%d: no freq table!\n", __func__, | 61 | new_freq = freq_table[index].frequency; |
73 | policy->cpu); | ||
74 | return -EINVAL; | ||
75 | } | ||
76 | 62 | ||
77 | ret = cpufreq_frequency_table_target(policy, freq_table, target_freq, | 63 | freq = new_freq * 1000; |
78 | relation, &i); | ||
79 | if (ret) { | ||
80 | dev_dbg(mpu_dev, "%s: cpu%d: no freq match for %d(ret=%d)\n", | ||
81 | __func__, policy->cpu, target_freq, ret); | ||
82 | return ret; | ||
83 | } | ||
84 | freqs.new = freq_table[i].frequency; | ||
85 | if (!freqs.new) { | ||
86 | dev_err(mpu_dev, "%s: cpu%d: no match for freq %d\n", __func__, | ||
87 | policy->cpu, target_freq); | ||
88 | return -EINVAL; | ||
89 | } | ||
90 | |||
91 | freqs.old = omap_getspeed(policy->cpu); | ||
92 | |||
93 | if (freqs.old == freqs.new && policy->cur == freqs.new) | ||
94 | return ret; | ||
95 | |||
96 | freq = freqs.new * 1000; | ||
97 | ret = clk_round_rate(mpu_clk, freq); | 64 | ret = clk_round_rate(mpu_clk, freq); |
98 | if (IS_ERR_VALUE(ret)) { | 65 | if (IS_ERR_VALUE(ret)) { |
99 | dev_warn(mpu_dev, | 66 | dev_warn(mpu_dev, |
@@ -105,143 +72,103 @@ static int omap_target(struct cpufreq_policy *policy, | |||
105 | 72 | ||
106 | if (mpu_reg) { | 73 | if (mpu_reg) { |
107 | rcu_read_lock(); | 74 | rcu_read_lock(); |
108 | opp = opp_find_freq_ceil(mpu_dev, &freq); | 75 | opp = dev_pm_opp_find_freq_ceil(mpu_dev, &freq); |
109 | if (IS_ERR(opp)) { | 76 | if (IS_ERR(opp)) { |
110 | rcu_read_unlock(); | 77 | rcu_read_unlock(); |
111 | dev_err(mpu_dev, "%s: unable to find MPU OPP for %d\n", | 78 | dev_err(mpu_dev, "%s: unable to find MPU OPP for %d\n", |
112 | __func__, freqs.new); | 79 | __func__, new_freq); |
113 | return -EINVAL; | 80 | return -EINVAL; |
114 | } | 81 | } |
115 | volt = opp_get_voltage(opp); | 82 | volt = dev_pm_opp_get_voltage(opp); |
116 | rcu_read_unlock(); | 83 | rcu_read_unlock(); |
117 | tol = volt * OPP_TOLERANCE / 100; | 84 | tol = volt * OPP_TOLERANCE / 100; |
118 | volt_old = regulator_get_voltage(mpu_reg); | 85 | volt_old = regulator_get_voltage(mpu_reg); |
119 | } | 86 | } |
120 | 87 | ||
121 | dev_dbg(mpu_dev, "cpufreq-omap: %u MHz, %ld mV --> %u MHz, %ld mV\n", | 88 | dev_dbg(mpu_dev, "cpufreq-omap: %u MHz, %ld mV --> %u MHz, %ld mV\n", |
122 | freqs.old / 1000, volt_old ? volt_old / 1000 : -1, | 89 | old_freq / 1000, volt_old ? volt_old / 1000 : -1, |
123 | freqs.new / 1000, volt ? volt / 1000 : -1); | 90 | new_freq / 1000, volt ? volt / 1000 : -1); |
124 | |||
125 | /* notifiers */ | ||
126 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
127 | 91 | ||
128 | /* scaling up? scale voltage before frequency */ | 92 | /* scaling up? scale voltage before frequency */ |
129 | if (mpu_reg && (freqs.new > freqs.old)) { | 93 | if (mpu_reg && (new_freq > old_freq)) { |
130 | r = regulator_set_voltage(mpu_reg, volt - tol, volt + tol); | 94 | r = regulator_set_voltage(mpu_reg, volt - tol, volt + tol); |
131 | if (r < 0) { | 95 | if (r < 0) { |
132 | dev_warn(mpu_dev, "%s: unable to scale voltage up.\n", | 96 | dev_warn(mpu_dev, "%s: unable to scale voltage up.\n", |
133 | __func__); | 97 | __func__); |
134 | freqs.new = freqs.old; | 98 | return r; |
135 | goto done; | ||
136 | } | 99 | } |
137 | } | 100 | } |
138 | 101 | ||
139 | ret = clk_set_rate(mpu_clk, freqs.new * 1000); | 102 | ret = clk_set_rate(mpu_clk, new_freq * 1000); |
140 | 103 | ||
141 | /* scaling down? scale voltage after frequency */ | 104 | /* scaling down? scale voltage after frequency */ |
142 | if (mpu_reg && (freqs.new < freqs.old)) { | 105 | if (mpu_reg && (new_freq < old_freq)) { |
143 | r = regulator_set_voltage(mpu_reg, volt - tol, volt + tol); | 106 | r = regulator_set_voltage(mpu_reg, volt - tol, volt + tol); |
144 | if (r < 0) { | 107 | if (r < 0) { |
145 | dev_warn(mpu_dev, "%s: unable to scale voltage down.\n", | 108 | dev_warn(mpu_dev, "%s: unable to scale voltage down.\n", |
146 | __func__); | 109 | __func__); |
147 | ret = clk_set_rate(mpu_clk, freqs.old * 1000); | 110 | clk_set_rate(mpu_clk, old_freq * 1000); |
148 | freqs.new = freqs.old; | 111 | return r; |
149 | goto done; | ||
150 | } | 112 | } |
151 | } | 113 | } |
152 | 114 | ||
153 | freqs.new = omap_getspeed(policy->cpu); | ||
154 | |||
155 | done: | ||
156 | /* notifiers */ | ||
157 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
158 | |||
159 | return ret; | 115 | return ret; |
160 | } | 116 | } |
161 | 117 | ||
162 | static inline void freq_table_free(void) | 118 | static inline void freq_table_free(void) |
163 | { | 119 | { |
164 | if (atomic_dec_and_test(&freq_table_users)) | 120 | if (atomic_dec_and_test(&freq_table_users)) |
165 | opp_free_cpufreq_table(mpu_dev, &freq_table); | 121 | dev_pm_opp_free_cpufreq_table(mpu_dev, &freq_table); |
166 | } | 122 | } |
167 | 123 | ||
168 | static int omap_cpu_init(struct cpufreq_policy *policy) | 124 | static int omap_cpu_init(struct cpufreq_policy *policy) |
169 | { | 125 | { |
170 | int result = 0; | 126 | int result; |
171 | 127 | ||
172 | mpu_clk = clk_get(NULL, "cpufreq_ck"); | 128 | mpu_clk = clk_get(NULL, "cpufreq_ck"); |
173 | if (IS_ERR(mpu_clk)) | 129 | if (IS_ERR(mpu_clk)) |
174 | return PTR_ERR(mpu_clk); | 130 | return PTR_ERR(mpu_clk); |
175 | 131 | ||
176 | if (policy->cpu >= NR_CPUS) { | 132 | if (!freq_table) { |
177 | result = -EINVAL; | 133 | result = dev_pm_opp_init_cpufreq_table(mpu_dev, &freq_table); |
178 | goto fail_ck; | 134 | if (result) { |
179 | } | 135 | dev_err(mpu_dev, |
180 | 136 | "%s: cpu%d: failed creating freq table[%d]\n", | |
181 | policy->cur = omap_getspeed(policy->cpu); | ||
182 | |||
183 | if (!freq_table) | ||
184 | result = opp_init_cpufreq_table(mpu_dev, &freq_table); | ||
185 | |||
186 | if (result) { | ||
187 | dev_err(mpu_dev, "%s: cpu%d: failed creating freq table[%d]\n", | ||
188 | __func__, policy->cpu, result); | 137 | __func__, policy->cpu, result); |
189 | goto fail_ck; | 138 | goto fail; |
139 | } | ||
190 | } | 140 | } |
191 | 141 | ||
192 | atomic_inc_return(&freq_table_users); | 142 | atomic_inc_return(&freq_table_users); |
193 | 143 | ||
194 | result = cpufreq_frequency_table_cpuinfo(policy, freq_table); | ||
195 | if (result) | ||
196 | goto fail_table; | ||
197 | |||
198 | cpufreq_frequency_table_get_attr(freq_table, policy->cpu); | ||
199 | |||
200 | policy->cur = omap_getspeed(policy->cpu); | ||
201 | |||
202 | /* | ||
203 | * On OMAP SMP configuartion, both processors share the voltage | ||
204 | * and clock. So both CPUs needs to be scaled together and hence | ||
205 | * needs software co-ordination. Use cpufreq affected_cpus | ||
206 | * interface to handle this scenario. Additional is_smp() check | ||
207 | * is to keep SMP_ON_UP build working. | ||
208 | */ | ||
209 | if (is_smp()) | ||
210 | cpumask_setall(policy->cpus); | ||
211 | |||
212 | /* FIXME: what's the actual transition time? */ | 144 | /* FIXME: what's the actual transition time? */ |
213 | policy->cpuinfo.transition_latency = 300 * 1000; | 145 | result = cpufreq_generic_init(policy, freq_table, 300 * 1000); |
214 | 146 | if (!result) | |
215 | return 0; | 147 | return 0; |
216 | 148 | ||
217 | fail_table: | ||
218 | freq_table_free(); | 149 | freq_table_free(); |
219 | fail_ck: | 150 | fail: |
220 | clk_put(mpu_clk); | 151 | clk_put(mpu_clk); |
221 | return result; | 152 | return result; |
222 | } | 153 | } |
223 | 154 | ||
224 | static int omap_cpu_exit(struct cpufreq_policy *policy) | 155 | static int omap_cpu_exit(struct cpufreq_policy *policy) |
225 | { | 156 | { |
157 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
226 | freq_table_free(); | 158 | freq_table_free(); |
227 | clk_put(mpu_clk); | 159 | clk_put(mpu_clk); |
228 | return 0; | 160 | return 0; |
229 | } | 161 | } |
230 | 162 | ||
231 | static struct freq_attr *omap_cpufreq_attr[] = { | ||
232 | &cpufreq_freq_attr_scaling_available_freqs, | ||
233 | NULL, | ||
234 | }; | ||
235 | |||
236 | static struct cpufreq_driver omap_driver = { | 163 | static struct cpufreq_driver omap_driver = { |
237 | .flags = CPUFREQ_STICKY, | 164 | .flags = CPUFREQ_STICKY, |
238 | .verify = omap_verify_speed, | 165 | .verify = cpufreq_generic_frequency_table_verify, |
239 | .target = omap_target, | 166 | .target_index = omap_target, |
240 | .get = omap_getspeed, | 167 | .get = omap_getspeed, |
241 | .init = omap_cpu_init, | 168 | .init = omap_cpu_init, |
242 | .exit = omap_cpu_exit, | 169 | .exit = omap_cpu_exit, |
243 | .name = "omap", | 170 | .name = "omap", |
244 | .attr = omap_cpufreq_attr, | 171 | .attr = cpufreq_generic_attr, |
245 | }; | 172 | }; |
246 | 173 | ||
247 | static int omap_cpufreq_probe(struct platform_device *pdev) | 174 | static int omap_cpufreq_probe(struct platform_device *pdev) |
diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c index 2f0a2a65c37f..3d1cba9fd5f9 100644 --- a/drivers/cpufreq/p4-clockmod.c +++ b/drivers/cpufreq/p4-clockmod.c | |||
@@ -105,47 +105,21 @@ static struct cpufreq_frequency_table p4clockmod_table[] = { | |||
105 | }; | 105 | }; |
106 | 106 | ||
107 | 107 | ||
108 | static int cpufreq_p4_target(struct cpufreq_policy *policy, | 108 | static int cpufreq_p4_target(struct cpufreq_policy *policy, unsigned int index) |
109 | unsigned int target_freq, | ||
110 | unsigned int relation) | ||
111 | { | 109 | { |
112 | unsigned int newstate = DC_RESV; | ||
113 | struct cpufreq_freqs freqs; | ||
114 | int i; | 110 | int i; |
115 | 111 | ||
116 | if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0], | ||
117 | target_freq, relation, &newstate)) | ||
118 | return -EINVAL; | ||
119 | |||
120 | freqs.old = cpufreq_p4_get(policy->cpu); | ||
121 | freqs.new = stock_freq * p4clockmod_table[newstate].driver_data / 8; | ||
122 | |||
123 | if (freqs.new == freqs.old) | ||
124 | return 0; | ||
125 | |||
126 | /* notifiers */ | ||
127 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
128 | |||
129 | /* run on each logical CPU, | 112 | /* run on each logical CPU, |
130 | * see section 13.15.3 of IA32 Intel Architecture Software | 113 | * see section 13.15.3 of IA32 Intel Architecture Software |
131 | * Developer's Manual, Volume 3 | 114 | * Developer's Manual, Volume 3 |
132 | */ | 115 | */ |
133 | for_each_cpu(i, policy->cpus) | 116 | for_each_cpu(i, policy->cpus) |
134 | cpufreq_p4_setdc(i, p4clockmod_table[newstate].driver_data); | 117 | cpufreq_p4_setdc(i, p4clockmod_table[index].driver_data); |
135 | |||
136 | /* notifiers */ | ||
137 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
138 | 118 | ||
139 | return 0; | 119 | return 0; |
140 | } | 120 | } |
141 | 121 | ||
142 | 122 | ||
143 | static int cpufreq_p4_verify(struct cpufreq_policy *policy) | ||
144 | { | ||
145 | return cpufreq_frequency_table_verify(policy, &p4clockmod_table[0]); | ||
146 | } | ||
147 | |||
148 | |||
149 | static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c) | 123 | static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c) |
150 | { | 124 | { |
151 | if (c->x86 == 0x06) { | 125 | if (c->x86 == 0x06) { |
@@ -230,25 +204,17 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) | |||
230 | else | 204 | else |
231 | p4clockmod_table[i].frequency = (stock_freq * i)/8; | 205 | p4clockmod_table[i].frequency = (stock_freq * i)/8; |
232 | } | 206 | } |
233 | cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu); | ||
234 | 207 | ||
235 | /* cpuinfo and default policy values */ | 208 | /* cpuinfo and default policy values */ |
236 | 209 | ||
237 | /* the transition latency is set to be 1 higher than the maximum | 210 | /* the transition latency is set to be 1 higher than the maximum |
238 | * transition latency of the ondemand governor */ | 211 | * transition latency of the ondemand governor */ |
239 | policy->cpuinfo.transition_latency = 10000001; | 212 | policy->cpuinfo.transition_latency = 10000001; |
240 | policy->cur = stock_freq; | ||
241 | 213 | ||
242 | return cpufreq_frequency_table_cpuinfo(policy, &p4clockmod_table[0]); | 214 | return cpufreq_table_validate_and_show(policy, &p4clockmod_table[0]); |
243 | } | 215 | } |
244 | 216 | ||
245 | 217 | ||
246 | static int cpufreq_p4_cpu_exit(struct cpufreq_policy *policy) | ||
247 | { | ||
248 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static unsigned int cpufreq_p4_get(unsigned int cpu) | 218 | static unsigned int cpufreq_p4_get(unsigned int cpu) |
253 | { | 219 | { |
254 | u32 l, h; | 220 | u32 l, h; |
@@ -267,19 +233,14 @@ static unsigned int cpufreq_p4_get(unsigned int cpu) | |||
267 | return stock_freq; | 233 | return stock_freq; |
268 | } | 234 | } |
269 | 235 | ||
270 | static struct freq_attr *p4clockmod_attr[] = { | ||
271 | &cpufreq_freq_attr_scaling_available_freqs, | ||
272 | NULL, | ||
273 | }; | ||
274 | |||
275 | static struct cpufreq_driver p4clockmod_driver = { | 236 | static struct cpufreq_driver p4clockmod_driver = { |
276 | .verify = cpufreq_p4_verify, | 237 | .verify = cpufreq_generic_frequency_table_verify, |
277 | .target = cpufreq_p4_target, | 238 | .target_index = cpufreq_p4_target, |
278 | .init = cpufreq_p4_cpu_init, | 239 | .init = cpufreq_p4_cpu_init, |
279 | .exit = cpufreq_p4_cpu_exit, | 240 | .exit = cpufreq_generic_exit, |
280 | .get = cpufreq_p4_get, | 241 | .get = cpufreq_p4_get, |
281 | .name = "p4-clockmod", | 242 | .name = "p4-clockmod", |
282 | .attr = p4clockmod_attr, | 243 | .attr = cpufreq_generic_attr, |
283 | }; | 244 | }; |
284 | 245 | ||
285 | static const struct x86_cpu_id cpufreq_p4_id[] = { | 246 | static const struct x86_cpu_id cpufreq_p4_id[] = { |
diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c index f4ec8145b3d1..0426008380d8 100644 --- a/drivers/cpufreq/pasemi-cpufreq.c +++ b/drivers/cpufreq/pasemi-cpufreq.c | |||
@@ -52,8 +52,6 @@ | |||
52 | static void __iomem *sdcpwr_mapbase; | 52 | static void __iomem *sdcpwr_mapbase; |
53 | static void __iomem *sdcasr_mapbase; | 53 | static void __iomem *sdcasr_mapbase; |
54 | 54 | ||
55 | static DEFINE_MUTEX(pas_switch_mutex); | ||
56 | |||
57 | /* Current astate, is used when waking up from power savings on | 55 | /* Current astate, is used when waking up from power savings on |
58 | * one core, in case the other core has switched states during | 56 | * one core, in case the other core has switched states during |
59 | * the idle time. | 57 | * the idle time. |
@@ -70,11 +68,6 @@ static struct cpufreq_frequency_table pas_freqs[] = { | |||
70 | {0, CPUFREQ_TABLE_END}, | 68 | {0, CPUFREQ_TABLE_END}, |
71 | }; | 69 | }; |
72 | 70 | ||
73 | static struct freq_attr *pas_cpu_freqs_attr[] = { | ||
74 | &cpufreq_freq_attr_scaling_available_freqs, | ||
75 | NULL, | ||
76 | }; | ||
77 | |||
78 | /* | 71 | /* |
79 | * hardware specific functions | 72 | * hardware specific functions |
80 | */ | 73 | */ |
@@ -210,22 +203,13 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
210 | pr_debug("%d: %d\n", i, pas_freqs[i].frequency); | 203 | pr_debug("%d: %d\n", i, pas_freqs[i].frequency); |
211 | } | 204 | } |
212 | 205 | ||
213 | policy->cpuinfo.transition_latency = get_gizmo_latency(); | ||
214 | |||
215 | cur_astate = get_cur_astate(policy->cpu); | 206 | cur_astate = get_cur_astate(policy->cpu); |
216 | pr_debug("current astate is at %d\n",cur_astate); | 207 | pr_debug("current astate is at %d\n",cur_astate); |
217 | 208 | ||
218 | policy->cur = pas_freqs[cur_astate].frequency; | 209 | policy->cur = pas_freqs[cur_astate].frequency; |
219 | cpumask_copy(policy->cpus, cpu_online_mask); | ||
220 | |||
221 | ppc_proc_freq = policy->cur * 1000ul; | 210 | ppc_proc_freq = policy->cur * 1000ul; |
222 | 211 | ||
223 | cpufreq_frequency_table_get_attr(pas_freqs, policy->cpu); | 212 | return cpufreq_generic_init(policy, pas_freqs, get_gizmo_latency()); |
224 | |||
225 | /* this ensures that policy->cpuinfo_min and policy->cpuinfo_max | ||
226 | * are set correctly | ||
227 | */ | ||
228 | return cpufreq_frequency_table_cpuinfo(policy, pas_freqs); | ||
229 | 213 | ||
230 | out_unmap_sdcpwr: | 214 | out_unmap_sdcpwr: |
231 | iounmap(sdcpwr_mapbase); | 215 | iounmap(sdcpwr_mapbase); |
@@ -254,31 +238,11 @@ static int pas_cpufreq_cpu_exit(struct cpufreq_policy *policy) | |||
254 | return 0; | 238 | return 0; |
255 | } | 239 | } |
256 | 240 | ||
257 | static int pas_cpufreq_verify(struct cpufreq_policy *policy) | ||
258 | { | ||
259 | return cpufreq_frequency_table_verify(policy, pas_freqs); | ||
260 | } | ||
261 | |||
262 | static int pas_cpufreq_target(struct cpufreq_policy *policy, | 241 | static int pas_cpufreq_target(struct cpufreq_policy *policy, |
263 | unsigned int target_freq, | 242 | unsigned int pas_astate_new) |
264 | unsigned int relation) | ||
265 | { | 243 | { |
266 | struct cpufreq_freqs freqs; | ||
267 | int pas_astate_new; | ||
268 | int i; | 244 | int i; |
269 | 245 | ||
270 | cpufreq_frequency_table_target(policy, | ||
271 | pas_freqs, | ||
272 | target_freq, | ||
273 | relation, | ||
274 | &pas_astate_new); | ||
275 | |||
276 | freqs.old = policy->cur; | ||
277 | freqs.new = pas_freqs[pas_astate_new].frequency; | ||
278 | |||
279 | mutex_lock(&pas_switch_mutex); | ||
280 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
281 | |||
282 | pr_debug("setting frequency for cpu %d to %d kHz, 1/%d of max frequency\n", | 246 | pr_debug("setting frequency for cpu %d to %d kHz, 1/%d of max frequency\n", |
283 | policy->cpu, | 247 | policy->cpu, |
284 | pas_freqs[pas_astate_new].frequency, | 248 | pas_freqs[pas_astate_new].frequency, |
@@ -289,10 +253,7 @@ static int pas_cpufreq_target(struct cpufreq_policy *policy, | |||
289 | for_each_online_cpu(i) | 253 | for_each_online_cpu(i) |
290 | set_astate(i, pas_astate_new); | 254 | set_astate(i, pas_astate_new); |
291 | 255 | ||
292 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | 256 | ppc_proc_freq = pas_freqs[pas_astate_new].frequency * 1000ul; |
293 | mutex_unlock(&pas_switch_mutex); | ||
294 | |||
295 | ppc_proc_freq = freqs.new * 1000ul; | ||
296 | return 0; | 257 | return 0; |
297 | } | 258 | } |
298 | 259 | ||
@@ -301,9 +262,9 @@ static struct cpufreq_driver pas_cpufreq_driver = { | |||
301 | .flags = CPUFREQ_CONST_LOOPS, | 262 | .flags = CPUFREQ_CONST_LOOPS, |
302 | .init = pas_cpufreq_cpu_init, | 263 | .init = pas_cpufreq_cpu_init, |
303 | .exit = pas_cpufreq_cpu_exit, | 264 | .exit = pas_cpufreq_cpu_exit, |
304 | .verify = pas_cpufreq_verify, | 265 | .verify = cpufreq_generic_frequency_table_verify, |
305 | .target = pas_cpufreq_target, | 266 | .target_index = pas_cpufreq_target, |
306 | .attr = pas_cpu_freqs_attr, | 267 | .attr = cpufreq_generic_attr, |
307 | }; | 268 | }; |
308 | 269 | ||
309 | /* | 270 | /* |
diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c index d81c4e5ea0ad..e2b4f40ff69a 100644 --- a/drivers/cpufreq/pcc-cpufreq.c +++ b/drivers/cpufreq/pcc-cpufreq.c | |||
@@ -111,8 +111,7 @@ static struct pcc_cpu __percpu *pcc_cpu_info; | |||
111 | 111 | ||
112 | static int pcc_cpufreq_verify(struct cpufreq_policy *policy) | 112 | static int pcc_cpufreq_verify(struct cpufreq_policy *policy) |
113 | { | 113 | { |
114 | cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | 114 | cpufreq_verify_within_cpu_limits(policy); |
115 | policy->cpuinfo.max_freq); | ||
116 | return 0; | 115 | return 0; |
117 | } | 116 | } |
118 | 117 | ||
@@ -396,15 +395,14 @@ static int __init pcc_cpufreq_probe(void) | |||
396 | struct pcc_memory_resource *mem_resource; | 395 | struct pcc_memory_resource *mem_resource; |
397 | struct pcc_register_resource *reg_resource; | 396 | struct pcc_register_resource *reg_resource; |
398 | union acpi_object *out_obj, *member; | 397 | union acpi_object *out_obj, *member; |
399 | acpi_handle handle, osc_handle, pcch_handle; | 398 | acpi_handle handle, osc_handle; |
400 | int ret = 0; | 399 | int ret = 0; |
401 | 400 | ||
402 | status = acpi_get_handle(NULL, "\\_SB", &handle); | 401 | status = acpi_get_handle(NULL, "\\_SB", &handle); |
403 | if (ACPI_FAILURE(status)) | 402 | if (ACPI_FAILURE(status)) |
404 | return -ENODEV; | 403 | return -ENODEV; |
405 | 404 | ||
406 | status = acpi_get_handle(handle, "PCCH", &pcch_handle); | 405 | if (!acpi_has_method(handle, "PCCH")) |
407 | if (ACPI_FAILURE(status)) | ||
408 | return -ENODEV; | 406 | return -ENODEV; |
409 | 407 | ||
410 | status = acpi_get_handle(handle, "_OSC", &osc_handle); | 408 | status = acpi_get_handle(handle, "_OSC", &osc_handle); |
@@ -560,13 +558,6 @@ static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
560 | ioread32(&pcch_hdr->nominal) * 1000; | 558 | ioread32(&pcch_hdr->nominal) * 1000; |
561 | policy->min = policy->cpuinfo.min_freq = | 559 | policy->min = policy->cpuinfo.min_freq = |
562 | ioread32(&pcch_hdr->minimum_frequency) * 1000; | 560 | ioread32(&pcch_hdr->minimum_frequency) * 1000; |
563 | policy->cur = pcc_get_freq(cpu); | ||
564 | |||
565 | if (!policy->cur) { | ||
566 | pr_debug("init: Unable to get current CPU frequency\n"); | ||
567 | result = -EINVAL; | ||
568 | goto out; | ||
569 | } | ||
570 | 561 | ||
571 | pr_debug("init: policy->max is %d, policy->min is %d\n", | 562 | pr_debug("init: policy->max is %d, policy->min is %d\n", |
572 | policy->max, policy->min); | 563 | policy->max, policy->min); |
diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c index a096cd3fa23d..cf55d202f332 100644 --- a/drivers/cpufreq/pmac32-cpufreq.c +++ b/drivers/cpufreq/pmac32-cpufreq.c | |||
@@ -86,11 +86,6 @@ static struct cpufreq_frequency_table pmac_cpu_freqs[] = { | |||
86 | {0, CPUFREQ_TABLE_END}, | 86 | {0, CPUFREQ_TABLE_END}, |
87 | }; | 87 | }; |
88 | 88 | ||
89 | static struct freq_attr* pmac_cpu_freqs_attr[] = { | ||
90 | &cpufreq_freq_attr_scaling_available_freqs, | ||
91 | NULL, | ||
92 | }; | ||
93 | |||
94 | static inline void local_delay(unsigned long ms) | 89 | static inline void local_delay(unsigned long ms) |
95 | { | 90 | { |
96 | if (no_schedule) | 91 | if (no_schedule) |
@@ -336,21 +331,11 @@ static int pmu_set_cpu_speed(int low_speed) | |||
336 | return 0; | 331 | return 0; |
337 | } | 332 | } |
338 | 333 | ||
339 | static int do_set_cpu_speed(struct cpufreq_policy *policy, int speed_mode, | 334 | static int do_set_cpu_speed(struct cpufreq_policy *policy, int speed_mode) |
340 | int notify) | ||
341 | { | 335 | { |
342 | struct cpufreq_freqs freqs; | ||
343 | unsigned long l3cr; | 336 | unsigned long l3cr; |
344 | static unsigned long prev_l3cr; | 337 | static unsigned long prev_l3cr; |
345 | 338 | ||
346 | freqs.old = cur_freq; | ||
347 | freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; | ||
348 | |||
349 | if (freqs.old == freqs.new) | ||
350 | return 0; | ||
351 | |||
352 | if (notify) | ||
353 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
354 | if (speed_mode == CPUFREQ_LOW && | 339 | if (speed_mode == CPUFREQ_LOW && |
355 | cpu_has_feature(CPU_FTR_L3CR)) { | 340 | cpu_has_feature(CPU_FTR_L3CR)) { |
356 | l3cr = _get_L3CR(); | 341 | l3cr = _get_L3CR(); |
@@ -366,8 +351,6 @@ static int do_set_cpu_speed(struct cpufreq_policy *policy, int speed_mode, | |||
366 | if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr) | 351 | if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr) |
367 | _set_L3CR(prev_l3cr); | 352 | _set_L3CR(prev_l3cr); |
368 | } | 353 | } |
369 | if (notify) | ||
370 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
371 | cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; | 354 | cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; |
372 | 355 | ||
373 | return 0; | 356 | return 0; |
@@ -378,23 +361,12 @@ static unsigned int pmac_cpufreq_get_speed(unsigned int cpu) | |||
378 | return cur_freq; | 361 | return cur_freq; |
379 | } | 362 | } |
380 | 363 | ||
381 | static int pmac_cpufreq_verify(struct cpufreq_policy *policy) | ||
382 | { | ||
383 | return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs); | ||
384 | } | ||
385 | |||
386 | static int pmac_cpufreq_target( struct cpufreq_policy *policy, | 364 | static int pmac_cpufreq_target( struct cpufreq_policy *policy, |
387 | unsigned int target_freq, | 365 | unsigned int index) |
388 | unsigned int relation) | ||
389 | { | 366 | { |
390 | unsigned int newstate = 0; | ||
391 | int rc; | 367 | int rc; |
392 | 368 | ||
393 | if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs, | 369 | rc = do_set_cpu_speed(policy, index); |
394 | target_freq, relation, &newstate)) | ||
395 | return -EINVAL; | ||
396 | |||
397 | rc = do_set_cpu_speed(policy, newstate, 1); | ||
398 | 370 | ||
399 | ppc_proc_freq = cur_freq * 1000ul; | 371 | ppc_proc_freq = cur_freq * 1000ul; |
400 | return rc; | 372 | return rc; |
@@ -402,14 +374,7 @@ static int pmac_cpufreq_target( struct cpufreq_policy *policy, | |||
402 | 374 | ||
403 | static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) | 375 | static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) |
404 | { | 376 | { |
405 | if (policy->cpu != 0) | 377 | return cpufreq_generic_init(policy, pmac_cpu_freqs, transition_latency); |
406 | return -ENODEV; | ||
407 | |||
408 | policy->cpuinfo.transition_latency = transition_latency; | ||
409 | policy->cur = cur_freq; | ||
410 | |||
411 | cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu); | ||
412 | return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs); | ||
413 | } | 378 | } |
414 | 379 | ||
415 | static u32 read_gpio(struct device_node *np) | 380 | static u32 read_gpio(struct device_node *np) |
@@ -443,7 +408,7 @@ static int pmac_cpufreq_suspend(struct cpufreq_policy *policy) | |||
443 | no_schedule = 1; | 408 | no_schedule = 1; |
444 | sleep_freq = cur_freq; | 409 | sleep_freq = cur_freq; |
445 | if (cur_freq == low_freq && !is_pmu_based) | 410 | if (cur_freq == low_freq && !is_pmu_based) |
446 | do_set_cpu_speed(policy, CPUFREQ_HIGH, 0); | 411 | do_set_cpu_speed(policy, CPUFREQ_HIGH); |
447 | return 0; | 412 | return 0; |
448 | } | 413 | } |
449 | 414 | ||
@@ -460,7 +425,7 @@ static int pmac_cpufreq_resume(struct cpufreq_policy *policy) | |||
460 | * probably high speed due to our suspend() routine | 425 | * probably high speed due to our suspend() routine |
461 | */ | 426 | */ |
462 | do_set_cpu_speed(policy, sleep_freq == low_freq ? | 427 | do_set_cpu_speed(policy, sleep_freq == low_freq ? |
463 | CPUFREQ_LOW : CPUFREQ_HIGH, 0); | 428 | CPUFREQ_LOW : CPUFREQ_HIGH); |
464 | 429 | ||
465 | ppc_proc_freq = cur_freq * 1000ul; | 430 | ppc_proc_freq = cur_freq * 1000ul; |
466 | 431 | ||
@@ -469,14 +434,14 @@ static int pmac_cpufreq_resume(struct cpufreq_policy *policy) | |||
469 | } | 434 | } |
470 | 435 | ||
471 | static struct cpufreq_driver pmac_cpufreq_driver = { | 436 | static struct cpufreq_driver pmac_cpufreq_driver = { |
472 | .verify = pmac_cpufreq_verify, | 437 | .verify = cpufreq_generic_frequency_table_verify, |
473 | .target = pmac_cpufreq_target, | 438 | .target_index = pmac_cpufreq_target, |
474 | .get = pmac_cpufreq_get_speed, | 439 | .get = pmac_cpufreq_get_speed, |
475 | .init = pmac_cpufreq_cpu_init, | 440 | .init = pmac_cpufreq_cpu_init, |
476 | .suspend = pmac_cpufreq_suspend, | 441 | .suspend = pmac_cpufreq_suspend, |
477 | .resume = pmac_cpufreq_resume, | 442 | .resume = pmac_cpufreq_resume, |
478 | .flags = CPUFREQ_PM_NO_WARN, | 443 | .flags = CPUFREQ_PM_NO_WARN, |
479 | .attr = pmac_cpu_freqs_attr, | 444 | .attr = cpufreq_generic_attr, |
480 | .name = "powermac", | 445 | .name = "powermac", |
481 | }; | 446 | }; |
482 | 447 | ||
diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c index 3a51ad7e47c8..6a338f8c3860 100644 --- a/drivers/cpufreq/pmac64-cpufreq.c +++ b/drivers/cpufreq/pmac64-cpufreq.c | |||
@@ -70,11 +70,6 @@ static struct cpufreq_frequency_table g5_cpu_freqs[] = { | |||
70 | {0, CPUFREQ_TABLE_END}, | 70 | {0, CPUFREQ_TABLE_END}, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | static struct freq_attr* g5_cpu_freqs_attr[] = { | ||
74 | &cpufreq_freq_attr_scaling_available_freqs, | ||
75 | NULL, | ||
76 | }; | ||
77 | |||
78 | /* Power mode data is an array of the 32 bits PCR values to use for | 73 | /* Power mode data is an array of the 32 bits PCR values to use for |
79 | * the various frequencies, retrieved from the device-tree | 74 | * the various frequencies, retrieved from the device-tree |
80 | */ | 75 | */ |
@@ -84,8 +79,6 @@ static void (*g5_switch_volt)(int speed_mode); | |||
84 | static int (*g5_switch_freq)(int speed_mode); | 79 | static int (*g5_switch_freq)(int speed_mode); |
85 | static int (*g5_query_freq)(void); | 80 | static int (*g5_query_freq)(void); |
86 | 81 | ||
87 | static DEFINE_MUTEX(g5_switch_mutex); | ||
88 | |||
89 | static unsigned long transition_latency; | 82 | static unsigned long transition_latency; |
90 | 83 | ||
91 | #ifdef CONFIG_PMAC_SMU | 84 | #ifdef CONFIG_PMAC_SMU |
@@ -142,7 +135,7 @@ static void g5_vdnap_switch_volt(int speed_mode) | |||
142 | pmf_call_one(pfunc_vdnap0_complete, &args); | 135 | pmf_call_one(pfunc_vdnap0_complete, &args); |
143 | if (done) | 136 | if (done) |
144 | break; | 137 | break; |
145 | msleep(1); | 138 | usleep_range(1000, 1000); |
146 | } | 139 | } |
147 | if (done == 0) | 140 | if (done == 0) |
148 | printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n"); | 141 | printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n"); |
@@ -241,7 +234,7 @@ static void g5_pfunc_switch_volt(int speed_mode) | |||
241 | if (pfunc_cpu1_volt_low) | 234 | if (pfunc_cpu1_volt_low) |
242 | pmf_call_one(pfunc_cpu1_volt_low, NULL); | 235 | pmf_call_one(pfunc_cpu1_volt_low, NULL); |
243 | } | 236 | } |
244 | msleep(10); /* should be faster , to fix */ | 237 | usleep_range(10000, 10000); /* should be faster , to fix */ |
245 | } | 238 | } |
246 | 239 | ||
247 | /* | 240 | /* |
@@ -286,7 +279,7 @@ static int g5_pfunc_switch_freq(int speed_mode) | |||
286 | pmf_call_one(pfunc_slewing_done, &args); | 279 | pmf_call_one(pfunc_slewing_done, &args); |
287 | if (done) | 280 | if (done) |
288 | break; | 281 | break; |
289 | msleep(1); | 282 | usleep_range(500, 500); |
290 | } | 283 | } |
291 | if (done == 0) | 284 | if (done == 0) |
292 | printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n"); | 285 | printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n"); |
@@ -317,37 +310,9 @@ static int g5_pfunc_query_freq(void) | |||
317 | * Common interface to the cpufreq core | 310 | * Common interface to the cpufreq core |
318 | */ | 311 | */ |
319 | 312 | ||
320 | static int g5_cpufreq_verify(struct cpufreq_policy *policy) | 313 | static int g5_cpufreq_target(struct cpufreq_policy *policy, unsigned int index) |
321 | { | 314 | { |
322 | return cpufreq_frequency_table_verify(policy, g5_cpu_freqs); | 315 | return g5_switch_freq(index); |
323 | } | ||
324 | |||
325 | static int g5_cpufreq_target(struct cpufreq_policy *policy, | ||
326 | unsigned int target_freq, unsigned int relation) | ||
327 | { | ||
328 | unsigned int newstate = 0; | ||
329 | struct cpufreq_freqs freqs; | ||
330 | int rc; | ||
331 | |||
332 | if (cpufreq_frequency_table_target(policy, g5_cpu_freqs, | ||
333 | target_freq, relation, &newstate)) | ||
334 | return -EINVAL; | ||
335 | |||
336 | if (g5_pmode_cur == newstate) | ||
337 | return 0; | ||
338 | |||
339 | mutex_lock(&g5_switch_mutex); | ||
340 | |||
341 | freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency; | ||
342 | freqs.new = g5_cpu_freqs[newstate].frequency; | ||
343 | |||
344 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
345 | rc = g5_switch_freq(newstate); | ||
346 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
347 | |||
348 | mutex_unlock(&g5_switch_mutex); | ||
349 | |||
350 | return rc; | ||
351 | } | 316 | } |
352 | 317 | ||
353 | static unsigned int g5_cpufreq_get_speed(unsigned int cpu) | 318 | static unsigned int g5_cpufreq_get_speed(unsigned int cpu) |
@@ -357,27 +322,17 @@ static unsigned int g5_cpufreq_get_speed(unsigned int cpu) | |||
357 | 322 | ||
358 | static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy) | 323 | static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy) |
359 | { | 324 | { |
360 | policy->cpuinfo.transition_latency = transition_latency; | 325 | return cpufreq_generic_init(policy, g5_cpu_freqs, transition_latency); |
361 | policy->cur = g5_cpu_freqs[g5_query_freq()].frequency; | ||
362 | /* secondary CPUs are tied to the primary one by the | ||
363 | * cpufreq core if in the secondary policy we tell it that | ||
364 | * it actually must be one policy together with all others. */ | ||
365 | cpumask_copy(policy->cpus, cpu_online_mask); | ||
366 | cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu); | ||
367 | |||
368 | return cpufreq_frequency_table_cpuinfo(policy, | ||
369 | g5_cpu_freqs); | ||
370 | } | 326 | } |
371 | 327 | ||
372 | |||
373 | static struct cpufreq_driver g5_cpufreq_driver = { | 328 | static struct cpufreq_driver g5_cpufreq_driver = { |
374 | .name = "powermac", | 329 | .name = "powermac", |
375 | .flags = CPUFREQ_CONST_LOOPS, | 330 | .flags = CPUFREQ_CONST_LOOPS, |
376 | .init = g5_cpufreq_cpu_init, | 331 | .init = g5_cpufreq_cpu_init, |
377 | .verify = g5_cpufreq_verify, | 332 | .verify = cpufreq_generic_frequency_table_verify, |
378 | .target = g5_cpufreq_target, | 333 | .target_index = g5_cpufreq_target, |
379 | .get = g5_cpufreq_get_speed, | 334 | .get = g5_cpufreq_get_speed, |
380 | .attr = g5_cpu_freqs_attr, | 335 | .attr = cpufreq_generic_attr, |
381 | }; | 336 | }; |
382 | 337 | ||
383 | 338 | ||
@@ -397,7 +352,8 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpunode) | |||
397 | /* Check supported platforms */ | 352 | /* Check supported platforms */ |
398 | if (of_machine_is_compatible("PowerMac8,1") || | 353 | if (of_machine_is_compatible("PowerMac8,1") || |
399 | of_machine_is_compatible("PowerMac8,2") || | 354 | of_machine_is_compatible("PowerMac8,2") || |
400 | of_machine_is_compatible("PowerMac9,1")) | 355 | of_machine_is_compatible("PowerMac9,1") || |
356 | of_machine_is_compatible("PowerMac12,1")) | ||
401 | use_volts_smu = 1; | 357 | use_volts_smu = 1; |
402 | else if (of_machine_is_compatible("PowerMac11,2")) | 358 | else if (of_machine_is_compatible("PowerMac11,2")) |
403 | use_volts_vdnap = 1; | 359 | use_volts_vdnap = 1; |
@@ -647,8 +603,10 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpunode) | |||
647 | g5_cpu_freqs[0].frequency = max_freq; | 603 | g5_cpu_freqs[0].frequency = max_freq; |
648 | g5_cpu_freqs[1].frequency = min_freq; | 604 | g5_cpu_freqs[1].frequency = min_freq; |
649 | 605 | ||
606 | /* Based on a measurement on Xserve G5, rounded up. */ | ||
607 | transition_latency = 10 * NSEC_PER_MSEC; | ||
608 | |||
650 | /* Set callbacks */ | 609 | /* Set callbacks */ |
651 | transition_latency = CPUFREQ_ETERNAL; | ||
652 | g5_switch_volt = g5_pfunc_switch_volt; | 610 | g5_switch_volt = g5_pfunc_switch_volt; |
653 | g5_switch_freq = g5_pfunc_switch_freq; | 611 | g5_switch_freq = g5_pfunc_switch_freq; |
654 | g5_query_freq = g5_pfunc_query_freq; | 612 | g5_query_freq = g5_pfunc_query_freq; |
diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c index 85f1c8c25ddc..643e7952cad3 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c | |||
@@ -63,12 +63,12 @@ static int powernow_k6_get_cpu_multiplier(void) | |||
63 | 63 | ||
64 | 64 | ||
65 | /** | 65 | /** |
66 | * powernow_k6_set_state - set the PowerNow! multiplier | 66 | * powernow_k6_target - set the PowerNow! multiplier |
67 | * @best_i: clock_ratio[best_i] is the target multiplier | 67 | * @best_i: clock_ratio[best_i] is the target multiplier |
68 | * | 68 | * |
69 | * Tries to change the PowerNow! multiplier | 69 | * Tries to change the PowerNow! multiplier |
70 | */ | 70 | */ |
71 | static void powernow_k6_set_state(struct cpufreq_policy *policy, | 71 | static int powernow_k6_target(struct cpufreq_policy *policy, |
72 | unsigned int best_i) | 72 | unsigned int best_i) |
73 | { | 73 | { |
74 | unsigned long outvalue = 0, invalue = 0; | 74 | unsigned long outvalue = 0, invalue = 0; |
@@ -77,7 +77,7 @@ static void powernow_k6_set_state(struct cpufreq_policy *policy, | |||
77 | 77 | ||
78 | if (clock_ratio[best_i].driver_data > max_multiplier) { | 78 | if (clock_ratio[best_i].driver_data > max_multiplier) { |
79 | printk(KERN_ERR PFX "invalid target frequency\n"); | 79 | printk(KERN_ERR PFX "invalid target frequency\n"); |
80 | return; | 80 | return -EINVAL; |
81 | } | 81 | } |
82 | 82 | ||
83 | freqs.old = busfreq * powernow_k6_get_cpu_multiplier(); | 83 | freqs.old = busfreq * powernow_k6_get_cpu_multiplier(); |
@@ -100,44 +100,6 @@ static void powernow_k6_set_state(struct cpufreq_policy *policy, | |||
100 | 100 | ||
101 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | 101 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); |
102 | 102 | ||
103 | return; | ||
104 | } | ||
105 | |||
106 | |||
107 | /** | ||
108 | * powernow_k6_verify - verifies a new CPUfreq policy | ||
109 | * @policy: new policy | ||
110 | * | ||
111 | * Policy must be within lowest and highest possible CPU Frequency, | ||
112 | * and at least one possible state must be within min and max. | ||
113 | */ | ||
114 | static int powernow_k6_verify(struct cpufreq_policy *policy) | ||
115 | { | ||
116 | return cpufreq_frequency_table_verify(policy, &clock_ratio[0]); | ||
117 | } | ||
118 | |||
119 | |||
120 | /** | ||
121 | * powernow_k6_setpolicy - sets a new CPUFreq policy | ||
122 | * @policy: new policy | ||
123 | * @target_freq: the target frequency | ||
124 | * @relation: how that frequency relates to achieved frequency | ||
125 | * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) | ||
126 | * | ||
127 | * sets a new CPUFreq policy | ||
128 | */ | ||
129 | static int powernow_k6_target(struct cpufreq_policy *policy, | ||
130 | unsigned int target_freq, | ||
131 | unsigned int relation) | ||
132 | { | ||
133 | unsigned int newstate = 0; | ||
134 | |||
135 | if (cpufreq_frequency_table_target(policy, &clock_ratio[0], | ||
136 | target_freq, relation, &newstate)) | ||
137 | return -EINVAL; | ||
138 | |||
139 | powernow_k6_set_state(policy, newstate); | ||
140 | |||
141 | return 0; | 103 | return 0; |
142 | } | 104 | } |
143 | 105 | ||
@@ -145,7 +107,6 @@ static int powernow_k6_target(struct cpufreq_policy *policy, | |||
145 | static int powernow_k6_cpu_init(struct cpufreq_policy *policy) | 107 | static int powernow_k6_cpu_init(struct cpufreq_policy *policy) |
146 | { | 108 | { |
147 | unsigned int i, f; | 109 | unsigned int i, f; |
148 | int result; | ||
149 | 110 | ||
150 | if (policy->cpu != 0) | 111 | if (policy->cpu != 0) |
151 | return -ENODEV; | 112 | return -ENODEV; |
@@ -165,15 +126,8 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) | |||
165 | 126 | ||
166 | /* cpuinfo and default policy values */ | 127 | /* cpuinfo and default policy values */ |
167 | policy->cpuinfo.transition_latency = 200000; | 128 | policy->cpuinfo.transition_latency = 200000; |
168 | policy->cur = busfreq * max_multiplier; | ||
169 | |||
170 | result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio); | ||
171 | if (result) | ||
172 | return result; | ||
173 | |||
174 | cpufreq_frequency_table_get_attr(clock_ratio, policy->cpu); | ||
175 | 129 | ||
176 | return 0; | 130 | return cpufreq_table_validate_and_show(policy, clock_ratio); |
177 | } | 131 | } |
178 | 132 | ||
179 | 133 | ||
@@ -182,7 +136,7 @@ static int powernow_k6_cpu_exit(struct cpufreq_policy *policy) | |||
182 | unsigned int i; | 136 | unsigned int i; |
183 | for (i = 0; i < 8; i++) { | 137 | for (i = 0; i < 8; i++) { |
184 | if (i == max_multiplier) | 138 | if (i == max_multiplier) |
185 | powernow_k6_set_state(policy, i); | 139 | powernow_k6_target(policy, i); |
186 | } | 140 | } |
187 | cpufreq_frequency_table_put_attr(policy->cpu); | 141 | cpufreq_frequency_table_put_attr(policy->cpu); |
188 | return 0; | 142 | return 0; |
@@ -195,19 +149,14 @@ static unsigned int powernow_k6_get(unsigned int cpu) | |||
195 | return ret; | 149 | return ret; |
196 | } | 150 | } |
197 | 151 | ||
198 | static struct freq_attr *powernow_k6_attr[] = { | ||
199 | &cpufreq_freq_attr_scaling_available_freqs, | ||
200 | NULL, | ||
201 | }; | ||
202 | |||
203 | static struct cpufreq_driver powernow_k6_driver = { | 152 | static struct cpufreq_driver powernow_k6_driver = { |
204 | .verify = powernow_k6_verify, | 153 | .verify = cpufreq_generic_frequency_table_verify, |
205 | .target = powernow_k6_target, | 154 | .target_index = powernow_k6_target, |
206 | .init = powernow_k6_cpu_init, | 155 | .init = powernow_k6_cpu_init, |
207 | .exit = powernow_k6_cpu_exit, | 156 | .exit = powernow_k6_cpu_exit, |
208 | .get = powernow_k6_get, | 157 | .get = powernow_k6_get, |
209 | .name = "powernow-k6", | 158 | .name = "powernow-k6", |
210 | .attr = powernow_k6_attr, | 159 | .attr = cpufreq_generic_attr, |
211 | }; | 160 | }; |
212 | 161 | ||
213 | static const struct x86_cpu_id powernow_k6_ids[] = { | 162 | static const struct x86_cpu_id powernow_k6_ids[] = { |
diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index 14ce480be8ab..946708a1d745 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c | |||
@@ -248,7 +248,7 @@ static void change_VID(int vid) | |||
248 | } | 248 | } |
249 | 249 | ||
250 | 250 | ||
251 | static void change_speed(struct cpufreq_policy *policy, unsigned int index) | 251 | static int powernow_target(struct cpufreq_policy *policy, unsigned int index) |
252 | { | 252 | { |
253 | u8 fid, vid; | 253 | u8 fid, vid; |
254 | struct cpufreq_freqs freqs; | 254 | struct cpufreq_freqs freqs; |
@@ -291,6 +291,8 @@ static void change_speed(struct cpufreq_policy *policy, unsigned int index) | |||
291 | local_irq_enable(); | 291 | local_irq_enable(); |
292 | 292 | ||
293 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | 293 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); |
294 | |||
295 | return 0; | ||
294 | } | 296 | } |
295 | 297 | ||
296 | 298 | ||
@@ -533,27 +535,6 @@ static int powernow_decode_bios(int maxfid, int startvid) | |||
533 | } | 535 | } |
534 | 536 | ||
535 | 537 | ||
536 | static int powernow_target(struct cpufreq_policy *policy, | ||
537 | unsigned int target_freq, | ||
538 | unsigned int relation) | ||
539 | { | ||
540 | unsigned int newstate; | ||
541 | |||
542 | if (cpufreq_frequency_table_target(policy, powernow_table, target_freq, | ||
543 | relation, &newstate)) | ||
544 | return -EINVAL; | ||
545 | |||
546 | change_speed(policy, newstate); | ||
547 | |||
548 | return 0; | ||
549 | } | ||
550 | |||
551 | |||
552 | static int powernow_verify(struct cpufreq_policy *policy) | ||
553 | { | ||
554 | return cpufreq_frequency_table_verify(policy, powernow_table); | ||
555 | } | ||
556 | |||
557 | /* | 538 | /* |
558 | * We use the fact that the bus frequency is somehow | 539 | * We use the fact that the bus frequency is somehow |
559 | * a multiple of 100000/3 khz, then we compute sgtc according | 540 | * a multiple of 100000/3 khz, then we compute sgtc according |
@@ -678,11 +659,7 @@ static int powernow_cpu_init(struct cpufreq_policy *policy) | |||
678 | policy->cpuinfo.transition_latency = | 659 | policy->cpuinfo.transition_latency = |
679 | cpufreq_scale(2000000UL, fsb, latency); | 660 | cpufreq_scale(2000000UL, fsb, latency); |
680 | 661 | ||
681 | policy->cur = powernow_get(0); | 662 | return cpufreq_table_validate_and_show(policy, powernow_table); |
682 | |||
683 | cpufreq_frequency_table_get_attr(powernow_table, policy->cpu); | ||
684 | |||
685 | return cpufreq_frequency_table_cpuinfo(policy, powernow_table); | ||
686 | } | 663 | } |
687 | 664 | ||
688 | static int powernow_cpu_exit(struct cpufreq_policy *policy) | 665 | static int powernow_cpu_exit(struct cpufreq_policy *policy) |
@@ -701,14 +678,9 @@ static int powernow_cpu_exit(struct cpufreq_policy *policy) | |||
701 | return 0; | 678 | return 0; |
702 | } | 679 | } |
703 | 680 | ||
704 | static struct freq_attr *powernow_table_attr[] = { | ||
705 | &cpufreq_freq_attr_scaling_available_freqs, | ||
706 | NULL, | ||
707 | }; | ||
708 | |||
709 | static struct cpufreq_driver powernow_driver = { | 681 | static struct cpufreq_driver powernow_driver = { |
710 | .verify = powernow_verify, | 682 | .verify = cpufreq_generic_frequency_table_verify, |
711 | .target = powernow_target, | 683 | .target_index = powernow_target, |
712 | .get = powernow_get, | 684 | .get = powernow_get, |
713 | #ifdef CONFIG_X86_POWERNOW_K7_ACPI | 685 | #ifdef CONFIG_X86_POWERNOW_K7_ACPI |
714 | .bios_limit = acpi_processor_get_bios_limit, | 686 | .bios_limit = acpi_processor_get_bios_limit, |
@@ -716,7 +688,7 @@ static struct cpufreq_driver powernow_driver = { | |||
716 | .init = powernow_cpu_init, | 688 | .init = powernow_cpu_init, |
717 | .exit = powernow_cpu_exit, | 689 | .exit = powernow_cpu_exit, |
718 | .name = "powernow-k7", | 690 | .name = "powernow-k7", |
719 | .attr = powernow_table_attr, | 691 | .attr = cpufreq_generic_attr, |
720 | }; | 692 | }; |
721 | 693 | ||
722 | static int __init powernow_init(void) | 694 | static int __init powernow_init(void) |
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 2344a9ed17f3..0023c7d40a51 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c | |||
@@ -977,20 +977,17 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, | |||
977 | 977 | ||
978 | struct powernowk8_target_arg { | 978 | struct powernowk8_target_arg { |
979 | struct cpufreq_policy *pol; | 979 | struct cpufreq_policy *pol; |
980 | unsigned targfreq; | 980 | unsigned newstate; |
981 | unsigned relation; | ||
982 | }; | 981 | }; |
983 | 982 | ||
984 | static long powernowk8_target_fn(void *arg) | 983 | static long powernowk8_target_fn(void *arg) |
985 | { | 984 | { |
986 | struct powernowk8_target_arg *pta = arg; | 985 | struct powernowk8_target_arg *pta = arg; |
987 | struct cpufreq_policy *pol = pta->pol; | 986 | struct cpufreq_policy *pol = pta->pol; |
988 | unsigned targfreq = pta->targfreq; | 987 | unsigned newstate = pta->newstate; |
989 | unsigned relation = pta->relation; | ||
990 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); | 988 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); |
991 | u32 checkfid; | 989 | u32 checkfid; |
992 | u32 checkvid; | 990 | u32 checkvid; |
993 | unsigned int newstate; | ||
994 | int ret; | 991 | int ret; |
995 | 992 | ||
996 | if (!data) | 993 | if (!data) |
@@ -1004,8 +1001,9 @@ static long powernowk8_target_fn(void *arg) | |||
1004 | return -EIO; | 1001 | return -EIO; |
1005 | } | 1002 | } |
1006 | 1003 | ||
1007 | pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n", | 1004 | pr_debug("targ: cpu %d, %d kHz, min %d, max %d\n", |
1008 | pol->cpu, targfreq, pol->min, pol->max, relation); | 1005 | pol->cpu, data->powernow_table[newstate].frequency, pol->min, |
1006 | pol->max); | ||
1009 | 1007 | ||
1010 | if (query_current_values_with_pending_wait(data)) | 1008 | if (query_current_values_with_pending_wait(data)) |
1011 | return -EIO; | 1009 | return -EIO; |
@@ -1021,10 +1019,6 @@ static long powernowk8_target_fn(void *arg) | |||
1021 | checkvid, data->currvid); | 1019 | checkvid, data->currvid); |
1022 | } | 1020 | } |
1023 | 1021 | ||
1024 | if (cpufreq_frequency_table_target(pol, data->powernow_table, | ||
1025 | targfreq, relation, &newstate)) | ||
1026 | return -EIO; | ||
1027 | |||
1028 | mutex_lock(&fidvid_mutex); | 1022 | mutex_lock(&fidvid_mutex); |
1029 | 1023 | ||
1030 | powernow_k8_acpi_pst_values(data, newstate); | 1024 | powernow_k8_acpi_pst_values(data, newstate); |
@@ -1044,26 +1038,13 @@ static long powernowk8_target_fn(void *arg) | |||
1044 | } | 1038 | } |
1045 | 1039 | ||
1046 | /* Driver entry point to switch to the target frequency */ | 1040 | /* Driver entry point to switch to the target frequency */ |
1047 | static int powernowk8_target(struct cpufreq_policy *pol, | 1041 | static int powernowk8_target(struct cpufreq_policy *pol, unsigned index) |
1048 | unsigned targfreq, unsigned relation) | ||
1049 | { | 1042 | { |
1050 | struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq, | 1043 | struct powernowk8_target_arg pta = { .pol = pol, .newstate = index }; |
1051 | .relation = relation }; | ||
1052 | 1044 | ||
1053 | return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); | 1045 | return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); |
1054 | } | 1046 | } |
1055 | 1047 | ||
1056 | /* Driver entry point to verify the policy and range of frequencies */ | ||
1057 | static int powernowk8_verify(struct cpufreq_policy *pol) | ||
1058 | { | ||
1059 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); | ||
1060 | |||
1061 | if (!data) | ||
1062 | return -EINVAL; | ||
1063 | |||
1064 | return cpufreq_frequency_table_verify(pol, data->powernow_table); | ||
1065 | } | ||
1066 | |||
1067 | struct init_on_cpu { | 1048 | struct init_on_cpu { |
1068 | struct powernow_k8_data *data; | 1049 | struct powernow_k8_data *data; |
1069 | int rc; | 1050 | int rc; |
@@ -1152,11 +1133,8 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1152 | cpumask_copy(pol->cpus, cpu_core_mask(pol->cpu)); | 1133 | cpumask_copy(pol->cpus, cpu_core_mask(pol->cpu)); |
1153 | data->available_cores = pol->cpus; | 1134 | data->available_cores = pol->cpus; |
1154 | 1135 | ||
1155 | pol->cur = find_khz_freq_from_fid(data->currfid); | ||
1156 | pr_debug("policy current frequency %d kHz\n", pol->cur); | ||
1157 | |||
1158 | /* min/max the cpu is capable of */ | 1136 | /* min/max the cpu is capable of */ |
1159 | if (cpufreq_frequency_table_cpuinfo(pol, data->powernow_table)) { | 1137 | if (cpufreq_table_validate_and_show(pol, data->powernow_table)) { |
1160 | printk(KERN_ERR FW_BUG PFX "invalid powernow_table\n"); | 1138 | printk(KERN_ERR FW_BUG PFX "invalid powernow_table\n"); |
1161 | powernow_k8_cpu_exit_acpi(data); | 1139 | powernow_k8_cpu_exit_acpi(data); |
1162 | kfree(data->powernow_table); | 1140 | kfree(data->powernow_table); |
@@ -1164,8 +1142,6 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1164 | return -EINVAL; | 1142 | return -EINVAL; |
1165 | } | 1143 | } |
1166 | 1144 | ||
1167 | cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); | ||
1168 | |||
1169 | pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n", | 1145 | pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n", |
1170 | data->currfid, data->currvid); | 1146 | data->currfid, data->currvid); |
1171 | 1147 | ||
@@ -1227,20 +1203,16 @@ out: | |||
1227 | return khz; | 1203 | return khz; |
1228 | } | 1204 | } |
1229 | 1205 | ||
1230 | static struct freq_attr *powernow_k8_attr[] = { | ||
1231 | &cpufreq_freq_attr_scaling_available_freqs, | ||
1232 | NULL, | ||
1233 | }; | ||
1234 | |||
1235 | static struct cpufreq_driver cpufreq_amd64_driver = { | 1206 | static struct cpufreq_driver cpufreq_amd64_driver = { |
1236 | .verify = powernowk8_verify, | 1207 | .flags = CPUFREQ_ASYNC_NOTIFICATION, |
1237 | .target = powernowk8_target, | 1208 | .verify = cpufreq_generic_frequency_table_verify, |
1209 | .target_index = powernowk8_target, | ||
1238 | .bios_limit = acpi_processor_get_bios_limit, | 1210 | .bios_limit = acpi_processor_get_bios_limit, |
1239 | .init = powernowk8_cpu_init, | 1211 | .init = powernowk8_cpu_init, |
1240 | .exit = powernowk8_cpu_exit, | 1212 | .exit = powernowk8_cpu_exit, |
1241 | .get = powernowk8_get, | 1213 | .get = powernowk8_get, |
1242 | .name = "powernow-k8", | 1214 | .name = "powernow-k8", |
1243 | .attr = powernow_k8_attr, | 1215 | .attr = cpufreq_generic_attr, |
1244 | }; | 1216 | }; |
1245 | 1217 | ||
1246 | static void __request_acpi_cpufreq(void) | 1218 | static void __request_acpi_cpufreq(void) |
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c index 60e81d524ea8..3f7be46d2b27 100644 --- a/drivers/cpufreq/ppc-corenet-cpufreq.c +++ b/drivers/cpufreq/ppc-corenet-cpufreq.c | |||
@@ -69,8 +69,6 @@ static const struct soc_data sdata[] = { | |||
69 | static u32 min_cpufreq; | 69 | static u32 min_cpufreq; |
70 | static const u32 *fmask; | 70 | static const u32 *fmask; |
71 | 71 | ||
72 | /* serialize frequency changes */ | ||
73 | static DEFINE_MUTEX(cpufreq_lock); | ||
74 | static DEFINE_PER_CPU(struct cpu_data *, cpu_data); | 72 | static DEFINE_PER_CPU(struct cpu_data *, cpu_data); |
75 | 73 | ||
76 | /* cpumask in a cluster */ | 74 | /* cpumask in a cluster */ |
@@ -202,7 +200,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
202 | table[i].frequency = CPUFREQ_TABLE_END; | 200 | table[i].frequency = CPUFREQ_TABLE_END; |
203 | 201 | ||
204 | /* set the min and max frequency properly */ | 202 | /* set the min and max frequency properly */ |
205 | ret = cpufreq_frequency_table_cpuinfo(policy, table); | 203 | ret = cpufreq_table_validate_and_show(policy, table); |
206 | if (ret) { | 204 | if (ret) { |
207 | pr_err("invalid frequency table: %d\n", ret); | 205 | pr_err("invalid frequency table: %d\n", ret); |
208 | goto err_nomem1; | 206 | goto err_nomem1; |
@@ -217,9 +215,6 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
217 | per_cpu(cpu_data, i) = data; | 215 | per_cpu(cpu_data, i) = data; |
218 | 216 | ||
219 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 217 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; |
220 | policy->cur = corenet_cpufreq_get_speed(policy->cpu); | ||
221 | |||
222 | cpufreq_frequency_table_get_attr(table, cpu); | ||
223 | of_node_put(np); | 218 | of_node_put(np); |
224 | 219 | ||
225 | return 0; | 220 | return 0; |
@@ -253,60 +248,25 @@ static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy) | |||
253 | return 0; | 248 | return 0; |
254 | } | 249 | } |
255 | 250 | ||
256 | static int corenet_cpufreq_verify(struct cpufreq_policy *policy) | ||
257 | { | ||
258 | struct cpufreq_frequency_table *table = | ||
259 | per_cpu(cpu_data, policy->cpu)->table; | ||
260 | |||
261 | return cpufreq_frequency_table_verify(policy, table); | ||
262 | } | ||
263 | |||
264 | static int corenet_cpufreq_target(struct cpufreq_policy *policy, | 251 | static int corenet_cpufreq_target(struct cpufreq_policy *policy, |
265 | unsigned int target_freq, unsigned int relation) | 252 | unsigned int index) |
266 | { | 253 | { |
267 | struct cpufreq_freqs freqs; | ||
268 | unsigned int new; | ||
269 | struct clk *parent; | 254 | struct clk *parent; |
270 | int ret; | ||
271 | struct cpu_data *data = per_cpu(cpu_data, policy->cpu); | 255 | struct cpu_data *data = per_cpu(cpu_data, policy->cpu); |
272 | 256 | ||
273 | cpufreq_frequency_table_target(policy, data->table, | 257 | parent = of_clk_get(data->parent, data->table[index].driver_data); |
274 | target_freq, relation, &new); | 258 | return clk_set_parent(data->clk, parent); |
275 | |||
276 | if (policy->cur == data->table[new].frequency) | ||
277 | return 0; | ||
278 | |||
279 | freqs.old = policy->cur; | ||
280 | freqs.new = data->table[new].frequency; | ||
281 | |||
282 | mutex_lock(&cpufreq_lock); | ||
283 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
284 | |||
285 | parent = of_clk_get(data->parent, data->table[new].driver_data); | ||
286 | ret = clk_set_parent(data->clk, parent); | ||
287 | if (ret) | ||
288 | freqs.new = freqs.old; | ||
289 | |||
290 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
291 | mutex_unlock(&cpufreq_lock); | ||
292 | |||
293 | return ret; | ||
294 | } | 259 | } |
295 | 260 | ||
296 | static struct freq_attr *corenet_cpufreq_attr[] = { | ||
297 | &cpufreq_freq_attr_scaling_available_freqs, | ||
298 | NULL, | ||
299 | }; | ||
300 | |||
301 | static struct cpufreq_driver ppc_corenet_cpufreq_driver = { | 261 | static struct cpufreq_driver ppc_corenet_cpufreq_driver = { |
302 | .name = "ppc_cpufreq", | 262 | .name = "ppc_cpufreq", |
303 | .flags = CPUFREQ_CONST_LOOPS, | 263 | .flags = CPUFREQ_CONST_LOOPS, |
304 | .init = corenet_cpufreq_cpu_init, | 264 | .init = corenet_cpufreq_cpu_init, |
305 | .exit = __exit_p(corenet_cpufreq_cpu_exit), | 265 | .exit = __exit_p(corenet_cpufreq_cpu_exit), |
306 | .verify = corenet_cpufreq_verify, | 266 | .verify = cpufreq_generic_frequency_table_verify, |
307 | .target = corenet_cpufreq_target, | 267 | .target_index = corenet_cpufreq_target, |
308 | .get = corenet_cpufreq_get_speed, | 268 | .get = corenet_cpufreq_get_speed, |
309 | .attr = corenet_cpufreq_attr, | 269 | .attr = cpufreq_generic_attr, |
310 | }; | 270 | }; |
311 | 271 | ||
312 | static const struct of_device_id node_matches[] __initdata = { | 272 | static const struct of_device_id node_matches[] __initdata = { |
diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c index 2e448f0bbdc5..e42ca9c31cea 100644 --- a/drivers/cpufreq/ppc_cbe_cpufreq.c +++ b/drivers/cpufreq/ppc_cbe_cpufreq.c | |||
@@ -30,9 +30,6 @@ | |||
30 | 30 | ||
31 | #include "ppc_cbe_cpufreq.h" | 31 | #include "ppc_cbe_cpufreq.h" |
32 | 32 | ||
33 | static DEFINE_MUTEX(cbe_switch_mutex); | ||
34 | |||
35 | |||
36 | /* the CBE supports an 8 step frequency scaling */ | 33 | /* the CBE supports an 8 step frequency scaling */ |
37 | static struct cpufreq_frequency_table cbe_freqs[] = { | 34 | static struct cpufreq_frequency_table cbe_freqs[] = { |
38 | {1, 0}, | 35 | {1, 0}, |
@@ -123,63 +120,28 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
123 | cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu)); | 120 | cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu)); |
124 | #endif | 121 | #endif |
125 | 122 | ||
126 | cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu); | ||
127 | |||
128 | /* this ensures that policy->cpuinfo_min | 123 | /* this ensures that policy->cpuinfo_min |
129 | * and policy->cpuinfo_max are set correctly */ | 124 | * and policy->cpuinfo_max are set correctly */ |
130 | return cpufreq_frequency_table_cpuinfo(policy, cbe_freqs); | 125 | return cpufreq_table_validate_and_show(policy, cbe_freqs); |
131 | } | ||
132 | |||
133 | static int cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy) | ||
134 | { | ||
135 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static int cbe_cpufreq_verify(struct cpufreq_policy *policy) | ||
140 | { | ||
141 | return cpufreq_frequency_table_verify(policy, cbe_freqs); | ||
142 | } | 126 | } |
143 | 127 | ||
144 | static int cbe_cpufreq_target(struct cpufreq_policy *policy, | 128 | static int cbe_cpufreq_target(struct cpufreq_policy *policy, |
145 | unsigned int target_freq, | 129 | unsigned int cbe_pmode_new) |
146 | unsigned int relation) | ||
147 | { | 130 | { |
148 | int rc; | ||
149 | struct cpufreq_freqs freqs; | ||
150 | unsigned int cbe_pmode_new; | ||
151 | |||
152 | cpufreq_frequency_table_target(policy, | ||
153 | cbe_freqs, | ||
154 | target_freq, | ||
155 | relation, | ||
156 | &cbe_pmode_new); | ||
157 | |||
158 | freqs.old = policy->cur; | ||
159 | freqs.new = cbe_freqs[cbe_pmode_new].frequency; | ||
160 | |||
161 | mutex_lock(&cbe_switch_mutex); | ||
162 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
163 | |||
164 | pr_debug("setting frequency for cpu %d to %d kHz, " \ | 131 | pr_debug("setting frequency for cpu %d to %d kHz, " \ |
165 | "1/%d of max frequency\n", | 132 | "1/%d of max frequency\n", |
166 | policy->cpu, | 133 | policy->cpu, |
167 | cbe_freqs[cbe_pmode_new].frequency, | 134 | cbe_freqs[cbe_pmode_new].frequency, |
168 | cbe_freqs[cbe_pmode_new].driver_data); | 135 | cbe_freqs[cbe_pmode_new].driver_data); |
169 | 136 | ||
170 | rc = set_pmode(policy->cpu, cbe_pmode_new); | 137 | return set_pmode(policy->cpu, cbe_pmode_new); |
171 | |||
172 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
173 | mutex_unlock(&cbe_switch_mutex); | ||
174 | |||
175 | return rc; | ||
176 | } | 138 | } |
177 | 139 | ||
178 | static struct cpufreq_driver cbe_cpufreq_driver = { | 140 | static struct cpufreq_driver cbe_cpufreq_driver = { |
179 | .verify = cbe_cpufreq_verify, | 141 | .verify = cpufreq_generic_frequency_table_verify, |
180 | .target = cbe_cpufreq_target, | 142 | .target_index = cbe_cpufreq_target, |
181 | .init = cbe_cpufreq_cpu_init, | 143 | .init = cbe_cpufreq_cpu_init, |
182 | .exit = cbe_cpufreq_cpu_exit, | 144 | .exit = cpufreq_generic_exit, |
183 | .name = "cbe-cpufreq", | 145 | .name = "cbe-cpufreq", |
184 | .flags = CPUFREQ_CONST_LOOPS, | 146 | .flags = CPUFREQ_CONST_LOOPS, |
185 | }; | 147 | }; |
diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c index 8749eaf18793..0a0f4369636a 100644 --- a/drivers/cpufreq/pxa2xx-cpufreq.c +++ b/drivers/cpufreq/pxa2xx-cpufreq.c | |||
@@ -262,36 +262,15 @@ static u32 mdrefr_dri(unsigned int freq) | |||
262 | return (interval - (cpu_is_pxa27x() ? 31 : 0)) / 32; | 262 | return (interval - (cpu_is_pxa27x() ? 31 : 0)) / 32; |
263 | } | 263 | } |
264 | 264 | ||
265 | /* find a valid frequency point */ | ||
266 | static int pxa_verify_policy(struct cpufreq_policy *policy) | ||
267 | { | ||
268 | struct cpufreq_frequency_table *pxa_freqs_table; | ||
269 | pxa_freqs_t *pxa_freqs; | ||
270 | int ret; | ||
271 | |||
272 | find_freq_tables(&pxa_freqs_table, &pxa_freqs); | ||
273 | ret = cpufreq_frequency_table_verify(policy, pxa_freqs_table); | ||
274 | |||
275 | if (freq_debug) | ||
276 | pr_debug("Verified CPU policy: %dKhz min to %dKhz max\n", | ||
277 | policy->min, policy->max); | ||
278 | |||
279 | return ret; | ||
280 | } | ||
281 | |||
282 | static unsigned int pxa_cpufreq_get(unsigned int cpu) | 265 | static unsigned int pxa_cpufreq_get(unsigned int cpu) |
283 | { | 266 | { |
284 | return get_clk_frequency_khz(0); | 267 | return get_clk_frequency_khz(0); |
285 | } | 268 | } |
286 | 269 | ||
287 | static int pxa_set_target(struct cpufreq_policy *policy, | 270 | static int pxa_set_target(struct cpufreq_policy *policy, unsigned int idx) |
288 | unsigned int target_freq, | ||
289 | unsigned int relation) | ||
290 | { | 271 | { |
291 | struct cpufreq_frequency_table *pxa_freqs_table; | 272 | struct cpufreq_frequency_table *pxa_freqs_table; |
292 | pxa_freqs_t *pxa_freq_settings; | 273 | pxa_freqs_t *pxa_freq_settings; |
293 | struct cpufreq_freqs freqs; | ||
294 | unsigned int idx; | ||
295 | unsigned long flags; | 274 | unsigned long flags; |
296 | unsigned int new_freq_cpu, new_freq_mem; | 275 | unsigned int new_freq_cpu, new_freq_mem; |
297 | unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg; | 276 | unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg; |
@@ -300,32 +279,19 @@ static int pxa_set_target(struct cpufreq_policy *policy, | |||
300 | /* Get the current policy */ | 279 | /* Get the current policy */ |
301 | find_freq_tables(&pxa_freqs_table, &pxa_freq_settings); | 280 | find_freq_tables(&pxa_freqs_table, &pxa_freq_settings); |
302 | 281 | ||
303 | /* Lookup the next frequency */ | ||
304 | if (cpufreq_frequency_table_target(policy, pxa_freqs_table, | ||
305 | target_freq, relation, &idx)) { | ||
306 | return -EINVAL; | ||
307 | } | ||
308 | |||
309 | new_freq_cpu = pxa_freq_settings[idx].khz; | 282 | new_freq_cpu = pxa_freq_settings[idx].khz; |
310 | new_freq_mem = pxa_freq_settings[idx].membus; | 283 | new_freq_mem = pxa_freq_settings[idx].membus; |
311 | freqs.old = policy->cur; | ||
312 | freqs.new = new_freq_cpu; | ||
313 | 284 | ||
314 | if (freq_debug) | 285 | if (freq_debug) |
315 | pr_debug("Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n", | 286 | pr_debug("Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n", |
316 | freqs.new / 1000, (pxa_freq_settings[idx].div2) ? | 287 | new_freq_cpu / 1000, (pxa_freq_settings[idx].div2) ? |
317 | (new_freq_mem / 2000) : (new_freq_mem / 1000)); | 288 | (new_freq_mem / 2000) : (new_freq_mem / 1000)); |
318 | 289 | ||
319 | if (vcc_core && freqs.new > freqs.old) | 290 | if (vcc_core && new_freq_cpu > policy->cur) { |
320 | ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]); | 291 | ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]); |
321 | if (ret) | 292 | if (ret) |
322 | return ret; | 293 | return ret; |
323 | /* | 294 | } |
324 | * Tell everyone what we're about to do... | ||
325 | * you should add a notify client with any platform specific | ||
326 | * Vcc changing capability | ||
327 | */ | ||
328 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
329 | 295 | ||
330 | /* Calculate the next MDREFR. If we're slowing down the SDRAM clock | 296 | /* Calculate the next MDREFR. If we're slowing down the SDRAM clock |
331 | * we need to preset the smaller DRI before the change. If we're | 297 | * we need to preset the smaller DRI before the change. If we're |
@@ -376,13 +342,6 @@ static int pxa_set_target(struct cpufreq_policy *policy, | |||
376 | local_irq_restore(flags); | 342 | local_irq_restore(flags); |
377 | 343 | ||
378 | /* | 344 | /* |
379 | * Tell everyone what we've just done... | ||
380 | * you should add a notify client with any platform specific | ||
381 | * SDRAM refresh timer adjustments | ||
382 | */ | ||
383 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
384 | |||
385 | /* | ||
386 | * Even if voltage setting fails, we don't report it, as the frequency | 345 | * Even if voltage setting fails, we don't report it, as the frequency |
387 | * change succeeded. The voltage reduction is not a critical failure, | 346 | * change succeeded. The voltage reduction is not a critical failure, |
388 | * only power savings will suffer from this. | 347 | * only power savings will suffer from this. |
@@ -391,7 +350,7 @@ static int pxa_set_target(struct cpufreq_policy *policy, | |||
391 | * bug is triggered (seems a deadlock). Should anybody find out where, | 350 | * bug is triggered (seems a deadlock). Should anybody find out where, |
392 | * the "return 0" should become a "return ret". | 351 | * the "return 0" should become a "return ret". |
393 | */ | 352 | */ |
394 | if (vcc_core && freqs.new < freqs.old) | 353 | if (vcc_core && new_freq_cpu < policy->cur) |
395 | ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]); | 354 | ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]); |
396 | 355 | ||
397 | return 0; | 356 | return 0; |
@@ -414,8 +373,6 @@ static int pxa_cpufreq_init(struct cpufreq_policy *policy) | |||
414 | 373 | ||
415 | /* set default policy and cpuinfo */ | 374 | /* set default policy and cpuinfo */ |
416 | policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ | 375 | policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ |
417 | policy->cur = get_clk_frequency_khz(0); /* current freq */ | ||
418 | policy->min = policy->max = policy->cur; | ||
419 | 376 | ||
420 | /* Generate pxa25x the run cpufreq_frequency_table struct */ | 377 | /* Generate pxa25x the run cpufreq_frequency_table struct */ |
421 | for (i = 0; i < NUM_PXA25x_RUN_FREQS; i++) { | 378 | for (i = 0; i < NUM_PXA25x_RUN_FREQS; i++) { |
@@ -453,10 +410,12 @@ static int pxa_cpufreq_init(struct cpufreq_policy *policy) | |||
453 | find_freq_tables(&pxa255_freq_table, &pxa255_freqs); | 410 | find_freq_tables(&pxa255_freq_table, &pxa255_freqs); |
454 | pr_info("PXA255 cpufreq using %s frequency table\n", | 411 | pr_info("PXA255 cpufreq using %s frequency table\n", |
455 | pxa255_turbo_table ? "turbo" : "run"); | 412 | pxa255_turbo_table ? "turbo" : "run"); |
456 | cpufreq_frequency_table_cpuinfo(policy, pxa255_freq_table); | 413 | |
414 | cpufreq_table_validate_and_show(policy, pxa255_freq_table); | ||
415 | } | ||
416 | else if (cpu_is_pxa27x()) { | ||
417 | cpufreq_table_validate_and_show(policy, pxa27x_freq_table); | ||
457 | } | 418 | } |
458 | else if (cpu_is_pxa27x()) | ||
459 | cpufreq_frequency_table_cpuinfo(policy, pxa27x_freq_table); | ||
460 | 419 | ||
461 | printk(KERN_INFO "PXA CPU frequency change support initialized\n"); | 420 | printk(KERN_INFO "PXA CPU frequency change support initialized\n"); |
462 | 421 | ||
@@ -464,9 +423,10 @@ static int pxa_cpufreq_init(struct cpufreq_policy *policy) | |||
464 | } | 423 | } |
465 | 424 | ||
466 | static struct cpufreq_driver pxa_cpufreq_driver = { | 425 | static struct cpufreq_driver pxa_cpufreq_driver = { |
467 | .verify = pxa_verify_policy, | 426 | .verify = cpufreq_generic_frequency_table_verify, |
468 | .target = pxa_set_target, | 427 | .target_index = pxa_set_target, |
469 | .init = pxa_cpufreq_init, | 428 | .init = pxa_cpufreq_init, |
429 | .exit = cpufreq_generic_exit, | ||
470 | .get = pxa_cpufreq_get, | 430 | .get = pxa_cpufreq_get, |
471 | .name = "PXA2xx", | 431 | .name = "PXA2xx", |
472 | }; | 432 | }; |
diff --git a/drivers/cpufreq/pxa3xx-cpufreq.c b/drivers/cpufreq/pxa3xx-cpufreq.c index d26306fb00d2..93840048dd11 100644 --- a/drivers/cpufreq/pxa3xx-cpufreq.c +++ b/drivers/cpufreq/pxa3xx-cpufreq.c | |||
@@ -108,7 +108,7 @@ static int setup_freqs_table(struct cpufreq_policy *policy, | |||
108 | pxa3xx_freqs_num = num; | 108 | pxa3xx_freqs_num = num; |
109 | pxa3xx_freqs_table = table; | 109 | pxa3xx_freqs_table = table; |
110 | 110 | ||
111 | return cpufreq_frequency_table_cpuinfo(policy, table); | 111 | return cpufreq_table_validate_and_show(policy, table); |
112 | } | 112 | } |
113 | 113 | ||
114 | static void __update_core_freq(struct pxa3xx_freq_info *info) | 114 | static void __update_core_freq(struct pxa3xx_freq_info *info) |
@@ -150,54 +150,26 @@ static void __update_bus_freq(struct pxa3xx_freq_info *info) | |||
150 | cpu_relax(); | 150 | cpu_relax(); |
151 | } | 151 | } |
152 | 152 | ||
153 | static int pxa3xx_cpufreq_verify(struct cpufreq_policy *policy) | ||
154 | { | ||
155 | return cpufreq_frequency_table_verify(policy, pxa3xx_freqs_table); | ||
156 | } | ||
157 | |||
158 | static unsigned int pxa3xx_cpufreq_get(unsigned int cpu) | 153 | static unsigned int pxa3xx_cpufreq_get(unsigned int cpu) |
159 | { | 154 | { |
160 | return pxa3xx_get_clk_frequency_khz(0); | 155 | return pxa3xx_get_clk_frequency_khz(0); |
161 | } | 156 | } |
162 | 157 | ||
163 | static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy, | 158 | static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy, unsigned int index) |
164 | unsigned int target_freq, | ||
165 | unsigned int relation) | ||
166 | { | 159 | { |
167 | struct pxa3xx_freq_info *next; | 160 | struct pxa3xx_freq_info *next; |
168 | struct cpufreq_freqs freqs; | ||
169 | unsigned long flags; | 161 | unsigned long flags; |
170 | int idx; | ||
171 | 162 | ||
172 | if (policy->cpu != 0) | 163 | if (policy->cpu != 0) |
173 | return -EINVAL; | 164 | return -EINVAL; |
174 | 165 | ||
175 | /* Lookup the next frequency */ | 166 | next = &pxa3xx_freqs[index]; |
176 | if (cpufreq_frequency_table_target(policy, pxa3xx_freqs_table, | ||
177 | target_freq, relation, &idx)) | ||
178 | return -EINVAL; | ||
179 | |||
180 | next = &pxa3xx_freqs[idx]; | ||
181 | |||
182 | freqs.old = policy->cur; | ||
183 | freqs.new = next->cpufreq_mhz * 1000; | ||
184 | |||
185 | pr_debug("CPU frequency from %d MHz to %d MHz%s\n", | ||
186 | freqs.old / 1000, freqs.new / 1000, | ||
187 | (freqs.old == freqs.new) ? " (skipped)" : ""); | ||
188 | |||
189 | if (freqs.old == target_freq) | ||
190 | return 0; | ||
191 | |||
192 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
193 | 167 | ||
194 | local_irq_save(flags); | 168 | local_irq_save(flags); |
195 | __update_core_freq(next); | 169 | __update_core_freq(next); |
196 | __update_bus_freq(next); | 170 | __update_bus_freq(next); |
197 | local_irq_restore(flags); | 171 | local_irq_restore(flags); |
198 | 172 | ||
199 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
200 | |||
201 | return 0; | 173 | return 0; |
202 | } | 174 | } |
203 | 175 | ||
@@ -206,11 +178,10 @@ static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy) | |||
206 | int ret = -EINVAL; | 178 | int ret = -EINVAL; |
207 | 179 | ||
208 | /* set default policy and cpuinfo */ | 180 | /* set default policy and cpuinfo */ |
209 | policy->cpuinfo.min_freq = 104000; | 181 | policy->min = policy->cpuinfo.min_freq = 104000; |
210 | policy->cpuinfo.max_freq = (cpu_is_pxa320()) ? 806000 : 624000; | 182 | policy->max = policy->cpuinfo.max_freq = |
183 | (cpu_is_pxa320()) ? 806000 : 624000; | ||
211 | policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ | 184 | policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ |
212 | policy->max = pxa3xx_get_clk_frequency_khz(0); | ||
213 | policy->cur = policy->min = policy->max; | ||
214 | 185 | ||
215 | if (cpu_is_pxa300() || cpu_is_pxa310()) | 186 | if (cpu_is_pxa300() || cpu_is_pxa310()) |
216 | ret = setup_freqs_table(policy, pxa300_freqs, | 187 | ret = setup_freqs_table(policy, pxa300_freqs, |
@@ -230,9 +201,10 @@ static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy) | |||
230 | } | 201 | } |
231 | 202 | ||
232 | static struct cpufreq_driver pxa3xx_cpufreq_driver = { | 203 | static struct cpufreq_driver pxa3xx_cpufreq_driver = { |
233 | .verify = pxa3xx_cpufreq_verify, | 204 | .verify = cpufreq_generic_frequency_table_verify, |
234 | .target = pxa3xx_cpufreq_set, | 205 | .target_index = pxa3xx_cpufreq_set, |
235 | .init = pxa3xx_cpufreq_init, | 206 | .init = pxa3xx_cpufreq_init, |
207 | .exit = cpufreq_generic_exit, | ||
236 | .get = pxa3xx_cpufreq_get, | 208 | .get = pxa3xx_cpufreq_get, |
237 | .name = "pxa3xx-cpufreq", | 209 | .name = "pxa3xx-cpufreq", |
238 | }; | 210 | }; |
diff --git a/drivers/cpufreq/s3c2416-cpufreq.c b/drivers/cpufreq/s3c2416-cpufreq.c index 22dcb81ef9d0..8d904a00027b 100644 --- a/drivers/cpufreq/s3c2416-cpufreq.c +++ b/drivers/cpufreq/s3c2416-cpufreq.c | |||
@@ -87,16 +87,6 @@ static struct cpufreq_frequency_table s3c2450_freq_table[] = { | |||
87 | { 0, CPUFREQ_TABLE_END }, | 87 | { 0, CPUFREQ_TABLE_END }, |
88 | }; | 88 | }; |
89 | 89 | ||
90 | static int s3c2416_cpufreq_verify_speed(struct cpufreq_policy *policy) | ||
91 | { | ||
92 | struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; | ||
93 | |||
94 | if (policy->cpu != 0) | ||
95 | return -EINVAL; | ||
96 | |||
97 | return cpufreq_frequency_table_verify(policy, s3c_freq->freq_table); | ||
98 | } | ||
99 | |||
100 | static unsigned int s3c2416_cpufreq_get_speed(unsigned int cpu) | 90 | static unsigned int s3c2416_cpufreq_get_speed(unsigned int cpu) |
101 | { | 91 | { |
102 | struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; | 92 | struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; |
@@ -227,24 +217,15 @@ static int s3c2416_cpufreq_leave_dvs(struct s3c2416_data *s3c_freq, int idx) | |||
227 | } | 217 | } |
228 | 218 | ||
229 | static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy, | 219 | static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy, |
230 | unsigned int target_freq, | 220 | unsigned int index) |
231 | unsigned int relation) | ||
232 | { | 221 | { |
233 | struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; | 222 | struct s3c2416_data *s3c_freq = &s3c2416_cpufreq; |
234 | struct cpufreq_freqs freqs; | 223 | unsigned int new_freq; |
235 | int idx, ret, to_dvs = 0; | 224 | int idx, ret, to_dvs = 0; |
236 | unsigned int i; | ||
237 | 225 | ||
238 | mutex_lock(&cpufreq_lock); | 226 | mutex_lock(&cpufreq_lock); |
239 | 227 | ||
240 | pr_debug("cpufreq: to %dKHz, relation %d\n", target_freq, relation); | 228 | idx = s3c_freq->freq_table[index].driver_data; |
241 | |||
242 | ret = cpufreq_frequency_table_target(policy, s3c_freq->freq_table, | ||
243 | target_freq, relation, &i); | ||
244 | if (ret != 0) | ||
245 | goto out; | ||
246 | |||
247 | idx = s3c_freq->freq_table[i].driver_data; | ||
248 | 229 | ||
249 | if (idx == SOURCE_HCLK) | 230 | if (idx == SOURCE_HCLK) |
250 | to_dvs = 1; | 231 | to_dvs = 1; |
@@ -256,24 +237,13 @@ static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy, | |||
256 | goto out; | 237 | goto out; |
257 | } | 238 | } |
258 | 239 | ||
259 | freqs.flags = 0; | ||
260 | freqs.old = s3c_freq->is_dvs ? FREQ_DVS | ||
261 | : clk_get_rate(s3c_freq->armclk) / 1000; | ||
262 | |||
263 | /* When leavin dvs mode, always switch the armdiv to the hclk rate | 240 | /* When leavin dvs mode, always switch the armdiv to the hclk rate |
264 | * The S3C2416 has stability issues when switching directly to | 241 | * The S3C2416 has stability issues when switching directly to |
265 | * higher frequencies. | 242 | * higher frequencies. |
266 | */ | 243 | */ |
267 | freqs.new = (s3c_freq->is_dvs && !to_dvs) | 244 | new_freq = (s3c_freq->is_dvs && !to_dvs) |
268 | ? clk_get_rate(s3c_freq->hclk) / 1000 | 245 | ? clk_get_rate(s3c_freq->hclk) / 1000 |
269 | : s3c_freq->freq_table[i].frequency; | 246 | : s3c_freq->freq_table[index].frequency; |
270 | |||
271 | pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new); | ||
272 | |||
273 | if (!to_dvs && freqs.old == freqs.new) | ||
274 | goto out; | ||
275 | |||
276 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
277 | 247 | ||
278 | if (to_dvs) { | 248 | if (to_dvs) { |
279 | pr_debug("cpufreq: enter dvs\n"); | 249 | pr_debug("cpufreq: enter dvs\n"); |
@@ -282,12 +252,10 @@ static int s3c2416_cpufreq_set_target(struct cpufreq_policy *policy, | |||
282 | pr_debug("cpufreq: leave dvs\n"); | 252 | pr_debug("cpufreq: leave dvs\n"); |
283 | ret = s3c2416_cpufreq_leave_dvs(s3c_freq, idx); | 253 | ret = s3c2416_cpufreq_leave_dvs(s3c_freq, idx); |
284 | } else { | 254 | } else { |
285 | pr_debug("cpufreq: change armdiv to %dkHz\n", freqs.new); | 255 | pr_debug("cpufreq: change armdiv to %dkHz\n", new_freq); |
286 | ret = s3c2416_cpufreq_set_armdiv(s3c_freq, freqs.new); | 256 | ret = s3c2416_cpufreq_set_armdiv(s3c_freq, new_freq); |
287 | } | 257 | } |
288 | 258 | ||
289 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
290 | |||
291 | out: | 259 | out: |
292 | mutex_unlock(&cpufreq_lock); | 260 | mutex_unlock(&cpufreq_lock); |
293 | 261 | ||
@@ -486,20 +454,14 @@ static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
486 | freq++; | 454 | freq++; |
487 | } | 455 | } |
488 | 456 | ||
489 | policy->cur = clk_get_rate(s3c_freq->armclk) / 1000; | ||
490 | |||
491 | /* Datasheet says PLL stabalisation time must be at least 300us, | 457 | /* Datasheet says PLL stabalisation time must be at least 300us, |
492 | * so but add some fudge. (reference in LOCKCON0 register description) | 458 | * so but add some fudge. (reference in LOCKCON0 register description) |
493 | */ | 459 | */ |
494 | policy->cpuinfo.transition_latency = (500 * 1000) + | 460 | ret = cpufreq_generic_init(policy, s3c_freq->freq_table, |
495 | s3c_freq->regulator_latency; | 461 | (500 * 1000) + s3c_freq->regulator_latency); |
496 | |||
497 | ret = cpufreq_frequency_table_cpuinfo(policy, s3c_freq->freq_table); | ||
498 | if (ret) | 462 | if (ret) |
499 | goto err_freq_table; | 463 | goto err_freq_table; |
500 | 464 | ||
501 | cpufreq_frequency_table_get_attr(s3c_freq->freq_table, 0); | ||
502 | |||
503 | register_reboot_notifier(&s3c2416_cpufreq_reboot_notifier); | 465 | register_reboot_notifier(&s3c2416_cpufreq_reboot_notifier); |
504 | 466 | ||
505 | return 0; | 467 | return 0; |
@@ -518,19 +480,14 @@ err_hclk: | |||
518 | return ret; | 480 | return ret; |
519 | } | 481 | } |
520 | 482 | ||
521 | static struct freq_attr *s3c2416_cpufreq_attr[] = { | ||
522 | &cpufreq_freq_attr_scaling_available_freqs, | ||
523 | NULL, | ||
524 | }; | ||
525 | |||
526 | static struct cpufreq_driver s3c2416_cpufreq_driver = { | 483 | static struct cpufreq_driver s3c2416_cpufreq_driver = { |
527 | .flags = 0, | 484 | .flags = 0, |
528 | .verify = s3c2416_cpufreq_verify_speed, | 485 | .verify = cpufreq_generic_frequency_table_verify, |
529 | .target = s3c2416_cpufreq_set_target, | 486 | .target_index = s3c2416_cpufreq_set_target, |
530 | .get = s3c2416_cpufreq_get_speed, | 487 | .get = s3c2416_cpufreq_get_speed, |
531 | .init = s3c2416_cpufreq_driver_init, | 488 | .init = s3c2416_cpufreq_driver_init, |
532 | .name = "s3c2416", | 489 | .name = "s3c2416", |
533 | .attr = s3c2416_cpufreq_attr, | 490 | .attr = cpufreq_generic_attr, |
534 | }; | 491 | }; |
535 | 492 | ||
536 | static int __init s3c2416_cpufreq_init(void) | 493 | static int __init s3c2416_cpufreq_init(void) |
diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c index b0f343fcb7ee..485088253358 100644 --- a/drivers/cpufreq/s3c24xx-cpufreq.c +++ b/drivers/cpufreq/s3c24xx-cpufreq.c | |||
@@ -373,23 +373,7 @@ struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) | |||
373 | 373 | ||
374 | static int s3c_cpufreq_init(struct cpufreq_policy *policy) | 374 | static int s3c_cpufreq_init(struct cpufreq_policy *policy) |
375 | { | 375 | { |
376 | printk(KERN_INFO "%s: initialising policy %p\n", __func__, policy); | 376 | return cpufreq_generic_init(policy, ftab, cpu_cur.info->latency); |
377 | |||
378 | if (policy->cpu != 0) | ||
379 | return -EINVAL; | ||
380 | |||
381 | policy->cur = s3c_cpufreq_get(0); | ||
382 | policy->min = policy->cpuinfo.min_freq = 0; | ||
383 | policy->max = policy->cpuinfo.max_freq = cpu_cur.info->max.fclk / 1000; | ||
384 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | ||
385 | |||
386 | /* feed the latency information from the cpu driver */ | ||
387 | policy->cpuinfo.transition_latency = cpu_cur.info->latency; | ||
388 | |||
389 | if (ftab) | ||
390 | cpufreq_frequency_table_cpuinfo(policy, ftab); | ||
391 | |||
392 | return 0; | ||
393 | } | 377 | } |
394 | 378 | ||
395 | static int __init s3c_cpufreq_initclks(void) | 379 | static int __init s3c_cpufreq_initclks(void) |
@@ -416,14 +400,6 @@ static int __init s3c_cpufreq_initclks(void) | |||
416 | return 0; | 400 | return 0; |
417 | } | 401 | } |
418 | 402 | ||
419 | static int s3c_cpufreq_verify(struct cpufreq_policy *policy) | ||
420 | { | ||
421 | if (policy->cpu != 0) | ||
422 | return -EINVAL; | ||
423 | |||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | #ifdef CONFIG_PM | 403 | #ifdef CONFIG_PM |
428 | static struct cpufreq_frequency_table suspend_pll; | 404 | static struct cpufreq_frequency_table suspend_pll; |
429 | static unsigned int suspend_freq; | 405 | static unsigned int suspend_freq; |
@@ -473,7 +449,6 @@ static int s3c_cpufreq_resume(struct cpufreq_policy *policy) | |||
473 | 449 | ||
474 | static struct cpufreq_driver s3c24xx_driver = { | 450 | static struct cpufreq_driver s3c24xx_driver = { |
475 | .flags = CPUFREQ_STICKY, | 451 | .flags = CPUFREQ_STICKY, |
476 | .verify = s3c_cpufreq_verify, | ||
477 | .target = s3c_cpufreq_target, | 452 | .target = s3c_cpufreq_target, |
478 | .get = s3c_cpufreq_get, | 453 | .get = s3c_cpufreq_get, |
479 | .init = s3c_cpufreq_init, | 454 | .init = s3c_cpufreq_init, |
diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c index 15631f92ab7d..67e302eeefec 100644 --- a/drivers/cpufreq/s3c64xx-cpufreq.c +++ b/drivers/cpufreq/s3c64xx-cpufreq.c | |||
@@ -54,14 +54,6 @@ static struct cpufreq_frequency_table s3c64xx_freq_table[] = { | |||
54 | }; | 54 | }; |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | static int s3c64xx_cpufreq_verify_speed(struct cpufreq_policy *policy) | ||
58 | { | ||
59 | if (policy->cpu != 0) | ||
60 | return -EINVAL; | ||
61 | |||
62 | return cpufreq_frequency_table_verify(policy, s3c64xx_freq_table); | ||
63 | } | ||
64 | |||
65 | static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu) | 57 | static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu) |
66 | { | 58 | { |
67 | if (cpu != 0) | 59 | if (cpu != 0) |
@@ -71,66 +63,48 @@ static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu) | |||
71 | } | 63 | } |
72 | 64 | ||
73 | static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, | 65 | static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, |
74 | unsigned int target_freq, | 66 | unsigned int index) |
75 | unsigned int relation) | ||
76 | { | 67 | { |
77 | int ret; | ||
78 | unsigned int i; | ||
79 | struct cpufreq_freqs freqs; | ||
80 | struct s3c64xx_dvfs *dvfs; | 68 | struct s3c64xx_dvfs *dvfs; |
69 | unsigned int old_freq, new_freq; | ||
70 | int ret; | ||
81 | 71 | ||
82 | ret = cpufreq_frequency_table_target(policy, s3c64xx_freq_table, | 72 | old_freq = clk_get_rate(armclk) / 1000; |
83 | target_freq, relation, &i); | 73 | new_freq = s3c64xx_freq_table[index].frequency; |
84 | if (ret != 0) | 74 | dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data]; |
85 | return ret; | ||
86 | |||
87 | freqs.old = clk_get_rate(armclk) / 1000; | ||
88 | freqs.new = s3c64xx_freq_table[i].frequency; | ||
89 | freqs.flags = 0; | ||
90 | dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[i].driver_data]; | ||
91 | |||
92 | if (freqs.old == freqs.new) | ||
93 | return 0; | ||
94 | |||
95 | pr_debug("Transition %d-%dkHz\n", freqs.old, freqs.new); | ||
96 | |||
97 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
98 | 75 | ||
99 | #ifdef CONFIG_REGULATOR | 76 | #ifdef CONFIG_REGULATOR |
100 | if (vddarm && freqs.new > freqs.old) { | 77 | if (vddarm && new_freq > old_freq) { |
101 | ret = regulator_set_voltage(vddarm, | 78 | ret = regulator_set_voltage(vddarm, |
102 | dvfs->vddarm_min, | 79 | dvfs->vddarm_min, |
103 | dvfs->vddarm_max); | 80 | dvfs->vddarm_max); |
104 | if (ret != 0) { | 81 | if (ret != 0) { |
105 | pr_err("Failed to set VDDARM for %dkHz: %d\n", | 82 | pr_err("Failed to set VDDARM for %dkHz: %d\n", |
106 | freqs.new, ret); | 83 | new_freq, ret); |
107 | freqs.new = freqs.old; | 84 | return ret; |
108 | goto post_notify; | ||
109 | } | 85 | } |
110 | } | 86 | } |
111 | #endif | 87 | #endif |
112 | 88 | ||
113 | ret = clk_set_rate(armclk, freqs.new * 1000); | 89 | ret = clk_set_rate(armclk, new_freq * 1000); |
114 | if (ret < 0) { | 90 | if (ret < 0) { |
115 | pr_err("Failed to set rate %dkHz: %d\n", | 91 | pr_err("Failed to set rate %dkHz: %d\n", |
116 | freqs.new, ret); | 92 | new_freq, ret); |
117 | freqs.new = freqs.old; | 93 | return ret; |
118 | } | 94 | } |
119 | 95 | ||
120 | post_notify: | ||
121 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
122 | if (ret) | ||
123 | goto err; | ||
124 | |||
125 | #ifdef CONFIG_REGULATOR | 96 | #ifdef CONFIG_REGULATOR |
126 | if (vddarm && freqs.new < freqs.old) { | 97 | if (vddarm && new_freq < old_freq) { |
127 | ret = regulator_set_voltage(vddarm, | 98 | ret = regulator_set_voltage(vddarm, |
128 | dvfs->vddarm_min, | 99 | dvfs->vddarm_min, |
129 | dvfs->vddarm_max); | 100 | dvfs->vddarm_max); |
130 | if (ret != 0) { | 101 | if (ret != 0) { |
131 | pr_err("Failed to set VDDARM for %dkHz: %d\n", | 102 | pr_err("Failed to set VDDARM for %dkHz: %d\n", |
132 | freqs.new, ret); | 103 | new_freq, ret); |
133 | goto err_clk; | 104 | if (clk_set_rate(armclk, old_freq * 1000) < 0) |
105 | pr_err("Failed to restore original clock rate\n"); | ||
106 | |||
107 | return ret; | ||
134 | } | 108 | } |
135 | } | 109 | } |
136 | #endif | 110 | #endif |
@@ -139,14 +113,6 @@ post_notify: | |||
139 | clk_get_rate(armclk) / 1000); | 113 | clk_get_rate(armclk) / 1000); |
140 | 114 | ||
141 | return 0; | 115 | return 0; |
142 | |||
143 | err_clk: | ||
144 | if (clk_set_rate(armclk, freqs.old * 1000) < 0) | ||
145 | pr_err("Failed to restore original clock rate\n"); | ||
146 | err: | ||
147 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
148 | |||
149 | return ret; | ||
150 | } | 116 | } |
151 | 117 | ||
152 | #ifdef CONFIG_REGULATOR | 118 | #ifdef CONFIG_REGULATOR |
@@ -243,15 +209,12 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
243 | freq++; | 209 | freq++; |
244 | } | 210 | } |
245 | 211 | ||
246 | policy->cur = clk_get_rate(armclk) / 1000; | ||
247 | |||
248 | /* Datasheet says PLL stabalisation time (if we were to use | 212 | /* Datasheet says PLL stabalisation time (if we were to use |
249 | * the PLLs, which we don't currently) is ~300us worst case, | 213 | * the PLLs, which we don't currently) is ~300us worst case, |
250 | * but add some fudge. | 214 | * but add some fudge. |
251 | */ | 215 | */ |
252 | policy->cpuinfo.transition_latency = (500 * 1000) + regulator_latency; | 216 | ret = cpufreq_generic_init(policy, s3c64xx_freq_table, |
253 | 217 | (500 * 1000) + regulator_latency); | |
254 | ret = cpufreq_frequency_table_cpuinfo(policy, s3c64xx_freq_table); | ||
255 | if (ret != 0) { | 218 | if (ret != 0) { |
256 | pr_err("Failed to configure frequency table: %d\n", | 219 | pr_err("Failed to configure frequency table: %d\n", |
257 | ret); | 220 | ret); |
@@ -264,8 +227,8 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
264 | 227 | ||
265 | static struct cpufreq_driver s3c64xx_cpufreq_driver = { | 228 | static struct cpufreq_driver s3c64xx_cpufreq_driver = { |
266 | .flags = 0, | 229 | .flags = 0, |
267 | .verify = s3c64xx_cpufreq_verify_speed, | 230 | .verify = cpufreq_generic_frequency_table_verify, |
268 | .target = s3c64xx_cpufreq_set_target, | 231 | .target_index = s3c64xx_cpufreq_set_target, |
269 | .get = s3c64xx_cpufreq_get_speed, | 232 | .get = s3c64xx_cpufreq_get_speed, |
270 | .init = s3c64xx_cpufreq_driver_init, | 233 | .init = s3c64xx_cpufreq_driver_init, |
271 | .name = "s3c", | 234 | .name = "s3c", |
diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 5c7757073793..e3973dae28a7 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c | |||
@@ -26,7 +26,6 @@ | |||
26 | static struct clk *cpu_clk; | 26 | static struct clk *cpu_clk; |
27 | static struct clk *dmc0_clk; | 27 | static struct clk *dmc0_clk; |
28 | static struct clk *dmc1_clk; | 28 | static struct clk *dmc1_clk; |
29 | static struct cpufreq_freqs freqs; | ||
30 | static DEFINE_MUTEX(set_freq_lock); | 29 | static DEFINE_MUTEX(set_freq_lock); |
31 | 30 | ||
32 | /* APLL M,P,S values for 1G/800Mhz */ | 31 | /* APLL M,P,S values for 1G/800Mhz */ |
@@ -36,16 +35,7 @@ static DEFINE_MUTEX(set_freq_lock); | |||
36 | /* Use 800MHz when entering sleep mode */ | 35 | /* Use 800MHz when entering sleep mode */ |
37 | #define SLEEP_FREQ (800 * 1000) | 36 | #define SLEEP_FREQ (800 * 1000) |
38 | 37 | ||
39 | /* | 38 | /* Tracks if cpu freqency can be updated anymore */ |
40 | * relation has an additional symantics other than the standard of cpufreq | ||
41 | * DISALBE_FURTHER_CPUFREQ: disable further access to target | ||
42 | * ENABLE_FURTUER_CPUFREQ: enable access to target | ||
43 | */ | ||
44 | enum cpufreq_access { | ||
45 | DISABLE_FURTHER_CPUFREQ = 0x10, | ||
46 | ENABLE_FURTHER_CPUFREQ = 0x20, | ||
47 | }; | ||
48 | |||
49 | static bool no_cpufreq_access; | 39 | static bool no_cpufreq_access; |
50 | 40 | ||
51 | /* | 41 | /* |
@@ -174,14 +164,6 @@ static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq) | |||
174 | __raw_writel(tmp1, reg); | 164 | __raw_writel(tmp1, reg); |
175 | } | 165 | } |
176 | 166 | ||
177 | static int s5pv210_verify_speed(struct cpufreq_policy *policy) | ||
178 | { | ||
179 | if (policy->cpu) | ||
180 | return -EINVAL; | ||
181 | |||
182 | return cpufreq_frequency_table_verify(policy, s5pv210_freq_table); | ||
183 | } | ||
184 | |||
185 | static unsigned int s5pv210_getspeed(unsigned int cpu) | 167 | static unsigned int s5pv210_getspeed(unsigned int cpu) |
186 | { | 168 | { |
187 | if (cpu) | 169 | if (cpu) |
@@ -190,22 +172,18 @@ static unsigned int s5pv210_getspeed(unsigned int cpu) | |||
190 | return clk_get_rate(cpu_clk) / 1000; | 172 | return clk_get_rate(cpu_clk) / 1000; |
191 | } | 173 | } |
192 | 174 | ||
193 | static int s5pv210_target(struct cpufreq_policy *policy, | 175 | static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index) |
194 | unsigned int target_freq, | ||
195 | unsigned int relation) | ||
196 | { | 176 | { |
197 | unsigned long reg; | 177 | unsigned long reg; |
198 | unsigned int index, priv_index; | 178 | unsigned int priv_index; |
199 | unsigned int pll_changing = 0; | 179 | unsigned int pll_changing = 0; |
200 | unsigned int bus_speed_changing = 0; | 180 | unsigned int bus_speed_changing = 0; |
181 | unsigned int old_freq, new_freq; | ||
201 | int arm_volt, int_volt; | 182 | int arm_volt, int_volt; |
202 | int ret = 0; | 183 | int ret = 0; |
203 | 184 | ||
204 | mutex_lock(&set_freq_lock); | 185 | mutex_lock(&set_freq_lock); |
205 | 186 | ||
206 | if (relation & ENABLE_FURTHER_CPUFREQ) | ||
207 | no_cpufreq_access = false; | ||
208 | |||
209 | if (no_cpufreq_access) { | 187 | if (no_cpufreq_access) { |
210 | #ifdef CONFIG_PM_VERBOSE | 188 | #ifdef CONFIG_PM_VERBOSE |
211 | pr_err("%s:%d denied access to %s as it is disabled" | 189 | pr_err("%s:%d denied access to %s as it is disabled" |
@@ -215,27 +193,13 @@ static int s5pv210_target(struct cpufreq_policy *policy, | |||
215 | goto exit; | 193 | goto exit; |
216 | } | 194 | } |
217 | 195 | ||
218 | if (relation & DISABLE_FURTHER_CPUFREQ) | 196 | old_freq = s5pv210_getspeed(0); |
219 | no_cpufreq_access = true; | 197 | new_freq = s5pv210_freq_table[index].frequency; |
220 | |||
221 | relation &= ~(ENABLE_FURTHER_CPUFREQ | DISABLE_FURTHER_CPUFREQ); | ||
222 | |||
223 | freqs.old = s5pv210_getspeed(0); | ||
224 | |||
225 | if (cpufreq_frequency_table_target(policy, s5pv210_freq_table, | ||
226 | target_freq, relation, &index)) { | ||
227 | ret = -EINVAL; | ||
228 | goto exit; | ||
229 | } | ||
230 | |||
231 | freqs.new = s5pv210_freq_table[index].frequency; | ||
232 | |||
233 | if (freqs.new == freqs.old) | ||
234 | goto exit; | ||
235 | 198 | ||
236 | /* Finding current running level index */ | 199 | /* Finding current running level index */ |
237 | if (cpufreq_frequency_table_target(policy, s5pv210_freq_table, | 200 | if (cpufreq_frequency_table_target(policy, s5pv210_freq_table, |
238 | freqs.old, relation, &priv_index)) { | 201 | old_freq, CPUFREQ_RELATION_H, |
202 | &priv_index)) { | ||
239 | ret = -EINVAL; | 203 | ret = -EINVAL; |
240 | goto exit; | 204 | goto exit; |
241 | } | 205 | } |
@@ -243,7 +207,7 @@ static int s5pv210_target(struct cpufreq_policy *policy, | |||
243 | arm_volt = dvs_conf[index].arm_volt; | 207 | arm_volt = dvs_conf[index].arm_volt; |
244 | int_volt = dvs_conf[index].int_volt; | 208 | int_volt = dvs_conf[index].int_volt; |
245 | 209 | ||
246 | if (freqs.new > freqs.old) { | 210 | if (new_freq > old_freq) { |
247 | ret = regulator_set_voltage(arm_regulator, | 211 | ret = regulator_set_voltage(arm_regulator, |
248 | arm_volt, arm_volt_max); | 212 | arm_volt, arm_volt_max); |
249 | if (ret) | 213 | if (ret) |
@@ -255,8 +219,6 @@ static int s5pv210_target(struct cpufreq_policy *policy, | |||
255 | goto exit; | 219 | goto exit; |
256 | } | 220 | } |
257 | 221 | ||
258 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
259 | |||
260 | /* Check if there need to change PLL */ | 222 | /* Check if there need to change PLL */ |
261 | if ((index == L0) || (priv_index == L0)) | 223 | if ((index == L0) || (priv_index == L0)) |
262 | pll_changing = 1; | 224 | pll_changing = 1; |
@@ -467,9 +429,7 @@ static int s5pv210_target(struct cpufreq_policy *policy, | |||
467 | } | 429 | } |
468 | } | 430 | } |
469 | 431 | ||
470 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | 432 | if (new_freq < old_freq) { |
471 | |||
472 | if (freqs.new < freqs.old) { | ||
473 | regulator_set_voltage(int_regulator, | 433 | regulator_set_voltage(int_regulator, |
474 | int_volt, int_volt_max); | 434 | int_volt, int_volt_max); |
475 | 435 | ||
@@ -551,13 +511,7 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy) | |||
551 | s5pv210_dram_conf[1].refresh = (__raw_readl(S5P_VA_DMC1 + 0x30) * 1000); | 511 | s5pv210_dram_conf[1].refresh = (__raw_readl(S5P_VA_DMC1 + 0x30) * 1000); |
552 | s5pv210_dram_conf[1].freq = clk_get_rate(dmc1_clk); | 512 | s5pv210_dram_conf[1].freq = clk_get_rate(dmc1_clk); |
553 | 513 | ||
554 | policy->cur = policy->min = policy->max = s5pv210_getspeed(0); | 514 | return cpufreq_generic_init(policy, s5pv210_freq_table, 40000); |
555 | |||
556 | cpufreq_frequency_table_get_attr(s5pv210_freq_table, policy->cpu); | ||
557 | |||
558 | policy->cpuinfo.transition_latency = 40000; | ||
559 | |||
560 | return cpufreq_frequency_table_cpuinfo(policy, s5pv210_freq_table); | ||
561 | 515 | ||
562 | out_dmc1: | 516 | out_dmc1: |
563 | clk_put(dmc0_clk); | 517 | clk_put(dmc0_clk); |
@@ -573,16 +527,18 @@ static int s5pv210_cpufreq_notifier_event(struct notifier_block *this, | |||
573 | 527 | ||
574 | switch (event) { | 528 | switch (event) { |
575 | case PM_SUSPEND_PREPARE: | 529 | case PM_SUSPEND_PREPARE: |
576 | ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, | 530 | ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0); |
577 | DISABLE_FURTHER_CPUFREQ); | ||
578 | if (ret < 0) | 531 | if (ret < 0) |
579 | return NOTIFY_BAD; | 532 | return NOTIFY_BAD; |
580 | 533 | ||
534 | /* Disable updation of cpu frequency */ | ||
535 | no_cpufreq_access = true; | ||
581 | return NOTIFY_OK; | 536 | return NOTIFY_OK; |
582 | case PM_POST_RESTORE: | 537 | case PM_POST_RESTORE: |
583 | case PM_POST_SUSPEND: | 538 | case PM_POST_SUSPEND: |
584 | cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, | 539 | /* Enable updation of cpu frequency */ |
585 | ENABLE_FURTHER_CPUFREQ); | 540 | no_cpufreq_access = false; |
541 | cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0); | ||
586 | 542 | ||
587 | return NOTIFY_OK; | 543 | return NOTIFY_OK; |
588 | } | 544 | } |
@@ -595,18 +551,18 @@ static int s5pv210_cpufreq_reboot_notifier_event(struct notifier_block *this, | |||
595 | { | 551 | { |
596 | int ret; | 552 | int ret; |
597 | 553 | ||
598 | ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, | 554 | ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0); |
599 | DISABLE_FURTHER_CPUFREQ); | ||
600 | if (ret < 0) | 555 | if (ret < 0) |
601 | return NOTIFY_BAD; | 556 | return NOTIFY_BAD; |
602 | 557 | ||
558 | no_cpufreq_access = true; | ||
603 | return NOTIFY_DONE; | 559 | return NOTIFY_DONE; |
604 | } | 560 | } |
605 | 561 | ||
606 | static struct cpufreq_driver s5pv210_driver = { | 562 | static struct cpufreq_driver s5pv210_driver = { |
607 | .flags = CPUFREQ_STICKY, | 563 | .flags = CPUFREQ_STICKY, |
608 | .verify = s5pv210_verify_speed, | 564 | .verify = cpufreq_generic_frequency_table_verify, |
609 | .target = s5pv210_target, | 565 | .target_index = s5pv210_target, |
610 | .get = s5pv210_getspeed, | 566 | .get = s5pv210_getspeed, |
611 | .init = s5pv210_cpu_init, | 567 | .init = s5pv210_cpu_init, |
612 | .name = "s5pv210", | 568 | .name = "s5pv210", |
diff --git a/drivers/cpufreq/sa1100-cpufreq.c b/drivers/cpufreq/sa1100-cpufreq.c index cff18e87ca58..623da742f8e7 100644 --- a/drivers/cpufreq/sa1100-cpufreq.c +++ b/drivers/cpufreq/sa1100-cpufreq.c | |||
@@ -177,60 +177,33 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed) | |||
177 | } | 177 | } |
178 | } | 178 | } |
179 | 179 | ||
180 | static int sa1100_target(struct cpufreq_policy *policy, | 180 | static int sa1100_target(struct cpufreq_policy *policy, unsigned int ppcr) |
181 | unsigned int target_freq, | ||
182 | unsigned int relation) | ||
183 | { | 181 | { |
184 | unsigned int cur = sa11x0_getspeed(0); | 182 | unsigned int cur = sa11x0_getspeed(0); |
185 | unsigned int new_ppcr; | 183 | unsigned int new_freq; |
186 | struct cpufreq_freqs freqs; | ||
187 | |||
188 | new_ppcr = sa11x0_freq_to_ppcr(target_freq); | ||
189 | switch (relation) { | ||
190 | case CPUFREQ_RELATION_L: | ||
191 | if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max) | ||
192 | new_ppcr--; | ||
193 | break; | ||
194 | case CPUFREQ_RELATION_H: | ||
195 | if ((sa11x0_ppcr_to_freq(new_ppcr) > target_freq) && | ||
196 | (sa11x0_ppcr_to_freq(new_ppcr - 1) >= policy->min)) | ||
197 | new_ppcr--; | ||
198 | break; | ||
199 | } | ||
200 | |||
201 | freqs.old = cur; | ||
202 | freqs.new = sa11x0_ppcr_to_freq(new_ppcr); | ||
203 | 184 | ||
204 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 185 | new_freq = sa11x0_freq_table[ppcr].frequency; |
205 | 186 | ||
206 | if (freqs.new > cur) | 187 | if (new_freq > cur) |
207 | sa1100_update_dram_timings(cur, freqs.new); | 188 | sa1100_update_dram_timings(cur, new_freq); |
208 | 189 | ||
209 | PPCR = new_ppcr; | 190 | PPCR = ppcr; |
210 | 191 | ||
211 | if (freqs.new < cur) | 192 | if (new_freq < cur) |
212 | sa1100_update_dram_timings(cur, freqs.new); | 193 | sa1100_update_dram_timings(cur, new_freq); |
213 | |||
214 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
215 | 194 | ||
216 | return 0; | 195 | return 0; |
217 | } | 196 | } |
218 | 197 | ||
219 | static int __init sa1100_cpu_init(struct cpufreq_policy *policy) | 198 | static int __init sa1100_cpu_init(struct cpufreq_policy *policy) |
220 | { | 199 | { |
221 | if (policy->cpu != 0) | 200 | return cpufreq_generic_init(policy, sa11x0_freq_table, CPUFREQ_ETERNAL); |
222 | return -EINVAL; | ||
223 | policy->cur = policy->min = policy->max = sa11x0_getspeed(0); | ||
224 | policy->cpuinfo.min_freq = 59000; | ||
225 | policy->cpuinfo.max_freq = 287000; | ||
226 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | ||
227 | return 0; | ||
228 | } | 201 | } |
229 | 202 | ||
230 | static struct cpufreq_driver sa1100_driver __refdata = { | 203 | static struct cpufreq_driver sa1100_driver __refdata = { |
231 | .flags = CPUFREQ_STICKY, | 204 | .flags = CPUFREQ_STICKY, |
232 | .verify = sa11x0_verify_speed, | 205 | .verify = cpufreq_generic_frequency_table_verify, |
233 | .target = sa1100_target, | 206 | .target_index = sa1100_target, |
234 | .get = sa11x0_getspeed, | 207 | .get = sa11x0_getspeed, |
235 | .init = sa1100_cpu_init, | 208 | .init = sa1100_cpu_init, |
236 | .name = "sa1100", | 209 | .name = "sa1100", |
diff --git a/drivers/cpufreq/sa1110-cpufreq.c b/drivers/cpufreq/sa1110-cpufreq.c index 39c90b6f4286..2c2b2e601d13 100644 --- a/drivers/cpufreq/sa1110-cpufreq.c +++ b/drivers/cpufreq/sa1110-cpufreq.c | |||
@@ -229,36 +229,14 @@ sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram) | |||
229 | /* | 229 | /* |
230 | * Ok, set the CPU frequency. | 230 | * Ok, set the CPU frequency. |
231 | */ | 231 | */ |
232 | static int sa1110_target(struct cpufreq_policy *policy, | 232 | static int sa1110_target(struct cpufreq_policy *policy, unsigned int ppcr) |
233 | unsigned int target_freq, | ||
234 | unsigned int relation) | ||
235 | { | 233 | { |
236 | struct sdram_params *sdram = &sdram_params; | 234 | struct sdram_params *sdram = &sdram_params; |
237 | struct cpufreq_freqs freqs; | ||
238 | struct sdram_info sd; | 235 | struct sdram_info sd; |
239 | unsigned long flags; | 236 | unsigned long flags; |
240 | unsigned int ppcr, unused; | 237 | unsigned int unused; |
241 | |||
242 | switch (relation) { | ||
243 | case CPUFREQ_RELATION_L: | ||
244 | ppcr = sa11x0_freq_to_ppcr(target_freq); | ||
245 | if (sa11x0_ppcr_to_freq(ppcr) > policy->max) | ||
246 | ppcr--; | ||
247 | break; | ||
248 | case CPUFREQ_RELATION_H: | ||
249 | ppcr = sa11x0_freq_to_ppcr(target_freq); | ||
250 | if (ppcr && (sa11x0_ppcr_to_freq(ppcr) > target_freq) && | ||
251 | (sa11x0_ppcr_to_freq(ppcr-1) >= policy->min)) | ||
252 | ppcr--; | ||
253 | break; | ||
254 | default: | ||
255 | return -EINVAL; | ||
256 | } | ||
257 | |||
258 | freqs.old = sa11x0_getspeed(0); | ||
259 | freqs.new = sa11x0_ppcr_to_freq(ppcr); | ||
260 | 238 | ||
261 | sdram_calculate_timing(&sd, freqs.new, sdram); | 239 | sdram_calculate_timing(&sd, sa11x0_freq_table[ppcr].frequency, sdram); |
262 | 240 | ||
263 | #if 0 | 241 | #if 0 |
264 | /* | 242 | /* |
@@ -277,8 +255,6 @@ static int sa1110_target(struct cpufreq_policy *policy, | |||
277 | sd.mdcas[2] = 0xaaaaaaaa; | 255 | sd.mdcas[2] = 0xaaaaaaaa; |
278 | #endif | 256 | #endif |
279 | 257 | ||
280 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
281 | |||
282 | /* | 258 | /* |
283 | * The clock could be going away for some time. Set the SDRAMs | 259 | * The clock could be going away for some time. Set the SDRAMs |
284 | * to refresh rapidly (every 64 memory clock cycles). To get | 260 | * to refresh rapidly (every 64 memory clock cycles). To get |
@@ -323,30 +299,22 @@ static int sa1110_target(struct cpufreq_policy *policy, | |||
323 | /* | 299 | /* |
324 | * Now, return the SDRAM refresh back to normal. | 300 | * Now, return the SDRAM refresh back to normal. |
325 | */ | 301 | */ |
326 | sdram_update_refresh(freqs.new, sdram); | 302 | sdram_update_refresh(sa11x0_freq_table[ppcr].frequency, sdram); |
327 | |||
328 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
329 | 303 | ||
330 | return 0; | 304 | return 0; |
331 | } | 305 | } |
332 | 306 | ||
333 | static int __init sa1110_cpu_init(struct cpufreq_policy *policy) | 307 | static int __init sa1110_cpu_init(struct cpufreq_policy *policy) |
334 | { | 308 | { |
335 | if (policy->cpu != 0) | 309 | return cpufreq_generic_init(policy, sa11x0_freq_table, CPUFREQ_ETERNAL); |
336 | return -EINVAL; | ||
337 | policy->cur = policy->min = policy->max = sa11x0_getspeed(0); | ||
338 | policy->cpuinfo.min_freq = 59000; | ||
339 | policy->cpuinfo.max_freq = 287000; | ||
340 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | ||
341 | return 0; | ||
342 | } | 310 | } |
343 | 311 | ||
344 | /* sa1110_driver needs __refdata because it must remain after init registers | 312 | /* sa1110_driver needs __refdata because it must remain after init registers |
345 | * it with cpufreq_register_driver() */ | 313 | * it with cpufreq_register_driver() */ |
346 | static struct cpufreq_driver sa1110_driver __refdata = { | 314 | static struct cpufreq_driver sa1110_driver __refdata = { |
347 | .flags = CPUFREQ_STICKY, | 315 | .flags = CPUFREQ_STICKY, |
348 | .verify = sa11x0_verify_speed, | 316 | .verify = cpufreq_generic_frequency_table_verify, |
349 | .target = sa1110_target, | 317 | .target_index = sa1110_target, |
350 | .get = sa11x0_getspeed, | 318 | .get = sa11x0_getspeed, |
351 | .init = sa1110_cpu_init, | 319 | .init = sa1110_cpu_init, |
352 | .name = "sa1110", | 320 | .name = "sa1110", |
diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c index d6f6c6f4efa7..6adb354e359c 100644 --- a/drivers/cpufreq/sc520_freq.c +++ b/drivers/cpufreq/sc520_freq.c | |||
@@ -53,21 +53,11 @@ static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu) | |||
53 | } | 53 | } |
54 | } | 54 | } |
55 | 55 | ||
56 | static void sc520_freq_set_cpu_state(struct cpufreq_policy *policy, | 56 | static int sc520_freq_target(struct cpufreq_policy *policy, unsigned int state) |
57 | unsigned int state) | ||
58 | { | 57 | { |
59 | 58 | ||
60 | struct cpufreq_freqs freqs; | ||
61 | u8 clockspeed_reg; | 59 | u8 clockspeed_reg; |
62 | 60 | ||
63 | freqs.old = sc520_freq_get_cpu_frequency(0); | ||
64 | freqs.new = sc520_freq_table[state].frequency; | ||
65 | |||
66 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
67 | |||
68 | pr_debug("attempting to set frequency to %i kHz\n", | ||
69 | sc520_freq_table[state].frequency); | ||
70 | |||
71 | local_irq_disable(); | 61 | local_irq_disable(); |
72 | 62 | ||
73 | clockspeed_reg = *cpuctl & ~0x03; | 63 | clockspeed_reg = *cpuctl & ~0x03; |
@@ -75,30 +65,9 @@ static void sc520_freq_set_cpu_state(struct cpufreq_policy *policy, | |||
75 | 65 | ||
76 | local_irq_enable(); | 66 | local_irq_enable(); |
77 | 67 | ||
78 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
79 | }; | ||
80 | |||
81 | static int sc520_freq_verify(struct cpufreq_policy *policy) | ||
82 | { | ||
83 | return cpufreq_frequency_table_verify(policy, &sc520_freq_table[0]); | ||
84 | } | ||
85 | |||
86 | static int sc520_freq_target(struct cpufreq_policy *policy, | ||
87 | unsigned int target_freq, | ||
88 | unsigned int relation) | ||
89 | { | ||
90 | unsigned int newstate = 0; | ||
91 | |||
92 | if (cpufreq_frequency_table_target(policy, sc520_freq_table, | ||
93 | target_freq, relation, &newstate)) | ||
94 | return -EINVAL; | ||
95 | |||
96 | sc520_freq_set_cpu_state(policy, newstate); | ||
97 | |||
98 | return 0; | 68 | return 0; |
99 | } | 69 | } |
100 | 70 | ||
101 | |||
102 | /* | 71 | /* |
103 | * Module init and exit code | 72 | * Module init and exit code |
104 | */ | 73 | */ |
@@ -106,7 +75,6 @@ static int sc520_freq_target(struct cpufreq_policy *policy, | |||
106 | static int sc520_freq_cpu_init(struct cpufreq_policy *policy) | 75 | static int sc520_freq_cpu_init(struct cpufreq_policy *policy) |
107 | { | 76 | { |
108 | struct cpuinfo_x86 *c = &cpu_data(0); | 77 | struct cpuinfo_x86 *c = &cpu_data(0); |
109 | int result; | ||
110 | 78 | ||
111 | /* capability check */ | 79 | /* capability check */ |
112 | if (c->x86_vendor != X86_VENDOR_AMD || | 80 | if (c->x86_vendor != X86_VENDOR_AMD || |
@@ -115,39 +83,19 @@ static int sc520_freq_cpu_init(struct cpufreq_policy *policy) | |||
115 | 83 | ||
116 | /* cpuinfo and default policy values */ | 84 | /* cpuinfo and default policy values */ |
117 | policy->cpuinfo.transition_latency = 1000000; /* 1ms */ | 85 | policy->cpuinfo.transition_latency = 1000000; /* 1ms */ |
118 | policy->cur = sc520_freq_get_cpu_frequency(0); | ||
119 | |||
120 | result = cpufreq_frequency_table_cpuinfo(policy, sc520_freq_table); | ||
121 | if (result) | ||
122 | return result; | ||
123 | |||
124 | cpufreq_frequency_table_get_attr(sc520_freq_table, policy->cpu); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | 86 | ||
129 | 87 | return cpufreq_table_validate_and_show(policy, sc520_freq_table); | |
130 | static int sc520_freq_cpu_exit(struct cpufreq_policy *policy) | ||
131 | { | ||
132 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
133 | return 0; | ||
134 | } | 88 | } |
135 | 89 | ||
136 | 90 | ||
137 | static struct freq_attr *sc520_freq_attr[] = { | ||
138 | &cpufreq_freq_attr_scaling_available_freqs, | ||
139 | NULL, | ||
140 | }; | ||
141 | |||
142 | |||
143 | static struct cpufreq_driver sc520_freq_driver = { | 91 | static struct cpufreq_driver sc520_freq_driver = { |
144 | .get = sc520_freq_get_cpu_frequency, | 92 | .get = sc520_freq_get_cpu_frequency, |
145 | .verify = sc520_freq_verify, | 93 | .verify = cpufreq_generic_frequency_table_verify, |
146 | .target = sc520_freq_target, | 94 | .target_index = sc520_freq_target, |
147 | .init = sc520_freq_cpu_init, | 95 | .init = sc520_freq_cpu_init, |
148 | .exit = sc520_freq_cpu_exit, | 96 | .exit = cpufreq_generic_exit, |
149 | .name = "sc520_freq", | 97 | .name = "sc520_freq", |
150 | .attr = sc520_freq_attr, | 98 | .attr = cpufreq_generic_attr, |
151 | }; | 99 | }; |
152 | 100 | ||
153 | static const struct x86_cpu_id sc520_ids[] = { | 101 | static const struct x86_cpu_id sc520_ids[] = { |
diff --git a/drivers/cpufreq/sh-cpufreq.c b/drivers/cpufreq/sh-cpufreq.c index ffc6d24b0cfb..387af12503a6 100644 --- a/drivers/cpufreq/sh-cpufreq.c +++ b/drivers/cpufreq/sh-cpufreq.c | |||
@@ -87,15 +87,12 @@ static int sh_cpufreq_verify(struct cpufreq_policy *policy) | |||
87 | if (freq_table) | 87 | if (freq_table) |
88 | return cpufreq_frequency_table_verify(policy, freq_table); | 88 | return cpufreq_frequency_table_verify(policy, freq_table); |
89 | 89 | ||
90 | cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | 90 | cpufreq_verify_within_cpu_limits(policy); |
91 | policy->cpuinfo.max_freq); | ||
92 | 91 | ||
93 | policy->min = (clk_round_rate(cpuclk, 1) + 500) / 1000; | 92 | policy->min = (clk_round_rate(cpuclk, 1) + 500) / 1000; |
94 | policy->max = (clk_round_rate(cpuclk, ~0UL) + 500) / 1000; | 93 | policy->max = (clk_round_rate(cpuclk, ~0UL) + 500) / 1000; |
95 | 94 | ||
96 | cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | 95 | cpufreq_verify_within_cpu_limits(policy); |
97 | policy->cpuinfo.max_freq); | ||
98 | |||
99 | return 0; | 96 | return 0; |
100 | } | 97 | } |
101 | 98 | ||
@@ -114,15 +111,13 @@ static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
114 | return PTR_ERR(cpuclk); | 111 | return PTR_ERR(cpuclk); |
115 | } | 112 | } |
116 | 113 | ||
117 | policy->cur = sh_cpufreq_get(cpu); | ||
118 | |||
119 | freq_table = cpuclk->nr_freqs ? cpuclk->freq_table : NULL; | 114 | freq_table = cpuclk->nr_freqs ? cpuclk->freq_table : NULL; |
120 | if (freq_table) { | 115 | if (freq_table) { |
121 | int result; | 116 | int result; |
122 | 117 | ||
123 | result = cpufreq_frequency_table_cpuinfo(policy, freq_table); | 118 | result = cpufreq_table_validate_and_show(policy, freq_table); |
124 | if (!result) | 119 | if (result) |
125 | cpufreq_frequency_table_get_attr(freq_table, cpu); | 120 | return result; |
126 | } else { | 121 | } else { |
127 | dev_notice(dev, "no frequency table found, falling back " | 122 | dev_notice(dev, "no frequency table found, falling back " |
128 | "to rate rounding.\n"); | 123 | "to rate rounding.\n"); |
@@ -154,11 +149,6 @@ static int sh_cpufreq_cpu_exit(struct cpufreq_policy *policy) | |||
154 | return 0; | 149 | return 0; |
155 | } | 150 | } |
156 | 151 | ||
157 | static struct freq_attr *sh_freq_attr[] = { | ||
158 | &cpufreq_freq_attr_scaling_available_freqs, | ||
159 | NULL, | ||
160 | }; | ||
161 | |||
162 | static struct cpufreq_driver sh_cpufreq_driver = { | 152 | static struct cpufreq_driver sh_cpufreq_driver = { |
163 | .name = "sh", | 153 | .name = "sh", |
164 | .get = sh_cpufreq_get, | 154 | .get = sh_cpufreq_get, |
@@ -166,7 +156,7 @@ static struct cpufreq_driver sh_cpufreq_driver = { | |||
166 | .verify = sh_cpufreq_verify, | 156 | .verify = sh_cpufreq_verify, |
167 | .init = sh_cpufreq_cpu_init, | 157 | .init = sh_cpufreq_cpu_init, |
168 | .exit = sh_cpufreq_cpu_exit, | 158 | .exit = sh_cpufreq_cpu_exit, |
169 | .attr = sh_freq_attr, | 159 | .attr = cpufreq_generic_attr, |
170 | }; | 160 | }; |
171 | 161 | ||
172 | static int __init sh_cpufreq_module_init(void) | 162 | static int __init sh_cpufreq_module_init(void) |
diff --git a/drivers/cpufreq/sparc-us2e-cpufreq.c b/drivers/cpufreq/sparc-us2e-cpufreq.c index cf5bc2ca16fa..62aa23e219d4 100644 --- a/drivers/cpufreq/sparc-us2e-cpufreq.c +++ b/drivers/cpufreq/sparc-us2e-cpufreq.c | |||
@@ -245,14 +245,12 @@ static unsigned int us2e_freq_get(unsigned int cpu) | |||
245 | return clock_tick / estar_to_divisor(estar); | 245 | return clock_tick / estar_to_divisor(estar); |
246 | } | 246 | } |
247 | 247 | ||
248 | static void us2e_set_cpu_divider_index(struct cpufreq_policy *policy, | 248 | static int us2e_freq_target(struct cpufreq_policy *policy, unsigned int index) |
249 | unsigned int index) | ||
250 | { | 249 | { |
251 | unsigned int cpu = policy->cpu; | 250 | unsigned int cpu = policy->cpu; |
252 | unsigned long new_bits, new_freq; | 251 | unsigned long new_bits, new_freq; |
253 | unsigned long clock_tick, divisor, old_divisor, estar; | 252 | unsigned long clock_tick, divisor, old_divisor, estar; |
254 | cpumask_t cpus_allowed; | 253 | cpumask_t cpus_allowed; |
255 | struct cpufreq_freqs freqs; | ||
256 | 254 | ||
257 | cpumask_copy(&cpus_allowed, tsk_cpus_allowed(current)); | 255 | cpumask_copy(&cpus_allowed, tsk_cpus_allowed(current)); |
258 | set_cpus_allowed_ptr(current, cpumask_of(cpu)); | 256 | set_cpus_allowed_ptr(current, cpumask_of(cpu)); |
@@ -266,41 +264,15 @@ static void us2e_set_cpu_divider_index(struct cpufreq_policy *policy, | |||
266 | 264 | ||
267 | old_divisor = estar_to_divisor(estar); | 265 | old_divisor = estar_to_divisor(estar); |
268 | 266 | ||
269 | freqs.old = clock_tick / old_divisor; | ||
270 | freqs.new = new_freq; | ||
271 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
272 | |||
273 | if (old_divisor != divisor) | 267 | if (old_divisor != divisor) |
274 | us2e_transition(estar, new_bits, clock_tick * 1000, | 268 | us2e_transition(estar, new_bits, clock_tick * 1000, |
275 | old_divisor, divisor); | 269 | old_divisor, divisor); |
276 | 270 | ||
277 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
278 | |||
279 | set_cpus_allowed_ptr(current, &cpus_allowed); | 271 | set_cpus_allowed_ptr(current, &cpus_allowed); |
280 | } | ||
281 | |||
282 | static int us2e_freq_target(struct cpufreq_policy *policy, | ||
283 | unsigned int target_freq, | ||
284 | unsigned int relation) | ||
285 | { | ||
286 | unsigned int new_index = 0; | ||
287 | |||
288 | if (cpufreq_frequency_table_target(policy, | ||
289 | &us2e_freq_table[policy->cpu].table[0], | ||
290 | target_freq, relation, &new_index)) | ||
291 | return -EINVAL; | ||
292 | |||
293 | us2e_set_cpu_divider_index(policy, new_index); | ||
294 | 272 | ||
295 | return 0; | 273 | return 0; |
296 | } | 274 | } |
297 | 275 | ||
298 | static int us2e_freq_verify(struct cpufreq_policy *policy) | ||
299 | { | ||
300 | return cpufreq_frequency_table_verify(policy, | ||
301 | &us2e_freq_table[policy->cpu].table[0]); | ||
302 | } | ||
303 | |||
304 | static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy) | 276 | static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy) |
305 | { | 277 | { |
306 | unsigned int cpu = policy->cpu; | 278 | unsigned int cpu = policy->cpu; |
@@ -324,13 +296,15 @@ static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy) | |||
324 | policy->cpuinfo.transition_latency = 0; | 296 | policy->cpuinfo.transition_latency = 0; |
325 | policy->cur = clock_tick; | 297 | policy->cur = clock_tick; |
326 | 298 | ||
327 | return cpufreq_frequency_table_cpuinfo(policy, table); | 299 | return cpufreq_table_validate_and_show(policy, table); |
328 | } | 300 | } |
329 | 301 | ||
330 | static int us2e_freq_cpu_exit(struct cpufreq_policy *policy) | 302 | static int us2e_freq_cpu_exit(struct cpufreq_policy *policy) |
331 | { | 303 | { |
332 | if (cpufreq_us2e_driver) | 304 | if (cpufreq_us2e_driver) { |
333 | us2e_set_cpu_divider_index(policy, 0); | 305 | cpufreq_frequency_table_put_attr(policy->cpu); |
306 | us2e_freq_target(policy, 0); | ||
307 | } | ||
334 | 308 | ||
335 | return 0; | 309 | return 0; |
336 | } | 310 | } |
@@ -361,8 +335,8 @@ static int __init us2e_freq_init(void) | |||
361 | goto err_out; | 335 | goto err_out; |
362 | 336 | ||
363 | driver->init = us2e_freq_cpu_init; | 337 | driver->init = us2e_freq_cpu_init; |
364 | driver->verify = us2e_freq_verify; | 338 | driver->verify = cpufreq_generic_frequency_table_verify; |
365 | driver->target = us2e_freq_target; | 339 | driver->target_index = us2e_freq_target; |
366 | driver->get = us2e_freq_get; | 340 | driver->get = us2e_freq_get; |
367 | driver->exit = us2e_freq_cpu_exit; | 341 | driver->exit = us2e_freq_cpu_exit; |
368 | strcpy(driver->name, "UltraSPARC-IIe"); | 342 | strcpy(driver->name, "UltraSPARC-IIe"); |
diff --git a/drivers/cpufreq/sparc-us3-cpufreq.c b/drivers/cpufreq/sparc-us3-cpufreq.c index ac76b489979d..724ffbd7105d 100644 --- a/drivers/cpufreq/sparc-us3-cpufreq.c +++ b/drivers/cpufreq/sparc-us3-cpufreq.c | |||
@@ -93,13 +93,11 @@ static unsigned int us3_freq_get(unsigned int cpu) | |||
93 | return ret; | 93 | return ret; |
94 | } | 94 | } |
95 | 95 | ||
96 | static void us3_set_cpu_divider_index(struct cpufreq_policy *policy, | 96 | static int us3_freq_target(struct cpufreq_policy *policy, unsigned int index) |
97 | unsigned int index) | ||
98 | { | 97 | { |
99 | unsigned int cpu = policy->cpu; | 98 | unsigned int cpu = policy->cpu; |
100 | unsigned long new_bits, new_freq, reg; | 99 | unsigned long new_bits, new_freq, reg; |
101 | cpumask_t cpus_allowed; | 100 | cpumask_t cpus_allowed; |
102 | struct cpufreq_freqs freqs; | ||
103 | 101 | ||
104 | cpumask_copy(&cpus_allowed, tsk_cpus_allowed(current)); | 102 | cpumask_copy(&cpus_allowed, tsk_cpus_allowed(current)); |
105 | set_cpus_allowed_ptr(current, cpumask_of(cpu)); | 103 | set_cpus_allowed_ptr(current, cpumask_of(cpu)); |
@@ -125,43 +123,15 @@ static void us3_set_cpu_divider_index(struct cpufreq_policy *policy, | |||
125 | 123 | ||
126 | reg = read_safari_cfg(); | 124 | reg = read_safari_cfg(); |
127 | 125 | ||
128 | freqs.old = get_current_freq(cpu, reg); | ||
129 | freqs.new = new_freq; | ||
130 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
131 | |||
132 | reg &= ~SAFARI_CFG_DIV_MASK; | 126 | reg &= ~SAFARI_CFG_DIV_MASK; |
133 | reg |= new_bits; | 127 | reg |= new_bits; |
134 | write_safari_cfg(reg); | 128 | write_safari_cfg(reg); |
135 | 129 | ||
136 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
137 | |||
138 | set_cpus_allowed_ptr(current, &cpus_allowed); | 130 | set_cpus_allowed_ptr(current, &cpus_allowed); |
139 | } | ||
140 | |||
141 | static int us3_freq_target(struct cpufreq_policy *policy, | ||
142 | unsigned int target_freq, | ||
143 | unsigned int relation) | ||
144 | { | ||
145 | unsigned int new_index = 0; | ||
146 | |||
147 | if (cpufreq_frequency_table_target(policy, | ||
148 | &us3_freq_table[policy->cpu].table[0], | ||
149 | target_freq, | ||
150 | relation, | ||
151 | &new_index)) | ||
152 | return -EINVAL; | ||
153 | |||
154 | us3_set_cpu_divider_index(policy, new_index); | ||
155 | 131 | ||
156 | return 0; | 132 | return 0; |
157 | } | 133 | } |
158 | 134 | ||
159 | static int us3_freq_verify(struct cpufreq_policy *policy) | ||
160 | { | ||
161 | return cpufreq_frequency_table_verify(policy, | ||
162 | &us3_freq_table[policy->cpu].table[0]); | ||
163 | } | ||
164 | |||
165 | static int __init us3_freq_cpu_init(struct cpufreq_policy *policy) | 135 | static int __init us3_freq_cpu_init(struct cpufreq_policy *policy) |
166 | { | 136 | { |
167 | unsigned int cpu = policy->cpu; | 137 | unsigned int cpu = policy->cpu; |
@@ -181,13 +151,15 @@ static int __init us3_freq_cpu_init(struct cpufreq_policy *policy) | |||
181 | policy->cpuinfo.transition_latency = 0; | 151 | policy->cpuinfo.transition_latency = 0; |
182 | policy->cur = clock_tick; | 152 | policy->cur = clock_tick; |
183 | 153 | ||
184 | return cpufreq_frequency_table_cpuinfo(policy, table); | 154 | return cpufreq_table_validate_and_show(policy, table); |
185 | } | 155 | } |
186 | 156 | ||
187 | static int us3_freq_cpu_exit(struct cpufreq_policy *policy) | 157 | static int us3_freq_cpu_exit(struct cpufreq_policy *policy) |
188 | { | 158 | { |
189 | if (cpufreq_us3_driver) | 159 | if (cpufreq_us3_driver) { |
190 | us3_set_cpu_divider_index(policy, 0); | 160 | cpufreq_frequency_table_put_attr(policy->cpu); |
161 | us3_freq_target(policy, 0); | ||
162 | } | ||
191 | 163 | ||
192 | return 0; | 164 | return 0; |
193 | } | 165 | } |
@@ -222,8 +194,8 @@ static int __init us3_freq_init(void) | |||
222 | goto err_out; | 194 | goto err_out; |
223 | 195 | ||
224 | driver->init = us3_freq_cpu_init; | 196 | driver->init = us3_freq_cpu_init; |
225 | driver->verify = us3_freq_verify; | 197 | driver->verify = cpufreq_generic_frequency_table_verify; |
226 | driver->target = us3_freq_target; | 198 | driver->target_index = us3_freq_target; |
227 | driver->get = us3_freq_get; | 199 | driver->get = us3_freq_get; |
228 | driver->exit = us3_freq_cpu_exit; | 200 | driver->exit = us3_freq_cpu_exit; |
229 | strcpy(driver->name, "UltraSPARC-III"); | 201 | strcpy(driver->name, "UltraSPARC-III"); |
diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c index 3f418166ce02..d02ccd19c9c4 100644 --- a/drivers/cpufreq/spear-cpufreq.c +++ b/drivers/cpufreq/spear-cpufreq.c | |||
@@ -30,11 +30,6 @@ static struct { | |||
30 | u32 cnt; | 30 | u32 cnt; |
31 | } spear_cpufreq; | 31 | } spear_cpufreq; |
32 | 32 | ||
33 | static int spear_cpufreq_verify(struct cpufreq_policy *policy) | ||
34 | { | ||
35 | return cpufreq_frequency_table_verify(policy, spear_cpufreq.freq_tbl); | ||
36 | } | ||
37 | |||
38 | static unsigned int spear_cpufreq_get(unsigned int cpu) | 33 | static unsigned int spear_cpufreq_get(unsigned int cpu) |
39 | { | 34 | { |
40 | return clk_get_rate(spear_cpufreq.clk) / 1000; | 35 | return clk_get_rate(spear_cpufreq.clk) / 1000; |
@@ -110,20 +105,14 @@ static int spear1340_set_cpu_rate(struct clk *sys_pclk, unsigned long newfreq) | |||
110 | } | 105 | } |
111 | 106 | ||
112 | static int spear_cpufreq_target(struct cpufreq_policy *policy, | 107 | static int spear_cpufreq_target(struct cpufreq_policy *policy, |
113 | unsigned int target_freq, unsigned int relation) | 108 | unsigned int index) |
114 | { | 109 | { |
115 | struct cpufreq_freqs freqs; | ||
116 | long newfreq; | 110 | long newfreq; |
117 | struct clk *srcclk; | 111 | struct clk *srcclk; |
118 | int index, ret, mult = 1; | 112 | int ret, mult = 1; |
119 | |||
120 | if (cpufreq_frequency_table_target(policy, spear_cpufreq.freq_tbl, | ||
121 | target_freq, relation, &index)) | ||
122 | return -EINVAL; | ||
123 | |||
124 | freqs.old = spear_cpufreq_get(0); | ||
125 | 113 | ||
126 | newfreq = spear_cpufreq.freq_tbl[index].frequency * 1000; | 114 | newfreq = spear_cpufreq.freq_tbl[index].frequency * 1000; |
115 | |||
127 | if (of_machine_is_compatible("st,spear1340")) { | 116 | if (of_machine_is_compatible("st,spear1340")) { |
128 | /* | 117 | /* |
129 | * SPEAr1340 is special in the sense that due to the possibility | 118 | * SPEAr1340 is special in the sense that due to the possibility |
@@ -154,65 +143,32 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy, | |||
154 | return newfreq; | 143 | return newfreq; |
155 | } | 144 | } |
156 | 145 | ||
157 | freqs.new = newfreq / 1000; | ||
158 | freqs.new /= mult; | ||
159 | |||
160 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
161 | |||
162 | if (mult == 2) | 146 | if (mult == 2) |
163 | ret = spear1340_set_cpu_rate(srcclk, newfreq); | 147 | ret = spear1340_set_cpu_rate(srcclk, newfreq); |
164 | else | 148 | else |
165 | ret = clk_set_rate(spear_cpufreq.clk, newfreq); | 149 | ret = clk_set_rate(spear_cpufreq.clk, newfreq); |
166 | 150 | ||
167 | /* Get current rate after clk_set_rate, in case of failure */ | 151 | if (ret) |
168 | if (ret) { | ||
169 | pr_err("CPU Freq: cpu clk_set_rate failed: %d\n", ret); | 152 | pr_err("CPU Freq: cpu clk_set_rate failed: %d\n", ret); |
170 | freqs.new = clk_get_rate(spear_cpufreq.clk) / 1000; | ||
171 | } | ||
172 | 153 | ||
173 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
174 | return ret; | 154 | return ret; |
175 | } | 155 | } |
176 | 156 | ||
177 | static int spear_cpufreq_init(struct cpufreq_policy *policy) | 157 | static int spear_cpufreq_init(struct cpufreq_policy *policy) |
178 | { | 158 | { |
179 | int ret; | 159 | return cpufreq_generic_init(policy, spear_cpufreq.freq_tbl, |
180 | 160 | spear_cpufreq.transition_latency); | |
181 | ret = cpufreq_frequency_table_cpuinfo(policy, spear_cpufreq.freq_tbl); | ||
182 | if (ret) { | ||
183 | pr_err("cpufreq_frequency_table_cpuinfo() failed"); | ||
184 | return ret; | ||
185 | } | ||
186 | |||
187 | cpufreq_frequency_table_get_attr(spear_cpufreq.freq_tbl, policy->cpu); | ||
188 | policy->cpuinfo.transition_latency = spear_cpufreq.transition_latency; | ||
189 | policy->cur = spear_cpufreq_get(0); | ||
190 | |||
191 | cpumask_setall(policy->cpus); | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static int spear_cpufreq_exit(struct cpufreq_policy *policy) | ||
197 | { | ||
198 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
199 | return 0; | ||
200 | } | 161 | } |
201 | 162 | ||
202 | static struct freq_attr *spear_cpufreq_attr[] = { | ||
203 | &cpufreq_freq_attr_scaling_available_freqs, | ||
204 | NULL, | ||
205 | }; | ||
206 | |||
207 | static struct cpufreq_driver spear_cpufreq_driver = { | 163 | static struct cpufreq_driver spear_cpufreq_driver = { |
208 | .name = "cpufreq-spear", | 164 | .name = "cpufreq-spear", |
209 | .flags = CPUFREQ_STICKY, | 165 | .flags = CPUFREQ_STICKY, |
210 | .verify = spear_cpufreq_verify, | 166 | .verify = cpufreq_generic_frequency_table_verify, |
211 | .target = spear_cpufreq_target, | 167 | .target_index = spear_cpufreq_target, |
212 | .get = spear_cpufreq_get, | 168 | .get = spear_cpufreq_get, |
213 | .init = spear_cpufreq_init, | 169 | .init = spear_cpufreq_init, |
214 | .exit = spear_cpufreq_exit, | 170 | .exit = cpufreq_generic_exit, |
215 | .attr = spear_cpufreq_attr, | 171 | .attr = cpufreq_generic_attr, |
216 | }; | 172 | }; |
217 | 173 | ||
218 | static int spear_cpufreq_driver_init(void) | 174 | static int spear_cpufreq_driver_init(void) |
diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c index f897d5105842..4e1daca5ce3b 100644 --- a/drivers/cpufreq/speedstep-centrino.c +++ b/drivers/cpufreq/speedstep-centrino.c | |||
@@ -343,9 +343,7 @@ static unsigned int get_cur_freq(unsigned int cpu) | |||
343 | static int centrino_cpu_init(struct cpufreq_policy *policy) | 343 | static int centrino_cpu_init(struct cpufreq_policy *policy) |
344 | { | 344 | { |
345 | struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu); | 345 | struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu); |
346 | unsigned freq; | ||
347 | unsigned l, h; | 346 | unsigned l, h; |
348 | int ret; | ||
349 | int i; | 347 | int i; |
350 | 348 | ||
351 | /* Only Intel makes Enhanced Speedstep-capable CPUs */ | 349 | /* Only Intel makes Enhanced Speedstep-capable CPUs */ |
@@ -373,9 +371,8 @@ static int centrino_cpu_init(struct cpufreq_policy *policy) | |||
373 | return -ENODEV; | 371 | return -ENODEV; |
374 | } | 372 | } |
375 | 373 | ||
376 | if (centrino_cpu_init_table(policy)) { | 374 | if (centrino_cpu_init_table(policy)) |
377 | return -ENODEV; | 375 | return -ENODEV; |
378 | } | ||
379 | 376 | ||
380 | /* Check to see if Enhanced SpeedStep is enabled, and try to | 377 | /* Check to see if Enhanced SpeedStep is enabled, and try to |
381 | enable it if not. */ | 378 | enable it if not. */ |
@@ -395,22 +392,11 @@ static int centrino_cpu_init(struct cpufreq_policy *policy) | |||
395 | } | 392 | } |
396 | } | 393 | } |
397 | 394 | ||
398 | freq = get_cur_freq(policy->cpu); | ||
399 | policy->cpuinfo.transition_latency = 10000; | 395 | policy->cpuinfo.transition_latency = 10000; |
400 | /* 10uS transition latency */ | 396 | /* 10uS transition latency */ |
401 | policy->cur = freq; | ||
402 | |||
403 | pr_debug("centrino_cpu_init: cur=%dkHz\n", policy->cur); | ||
404 | 397 | ||
405 | ret = cpufreq_frequency_table_cpuinfo(policy, | 398 | return cpufreq_table_validate_and_show(policy, |
406 | per_cpu(centrino_model, policy->cpu)->op_points); | 399 | per_cpu(centrino_model, policy->cpu)->op_points); |
407 | if (ret) | ||
408 | return (ret); | ||
409 | |||
410 | cpufreq_frequency_table_get_attr( | ||
411 | per_cpu(centrino_model, policy->cpu)->op_points, policy->cpu); | ||
412 | |||
413 | return 0; | ||
414 | } | 400 | } |
415 | 401 | ||
416 | static int centrino_cpu_exit(struct cpufreq_policy *policy) | 402 | static int centrino_cpu_exit(struct cpufreq_policy *policy) |
@@ -428,36 +414,18 @@ static int centrino_cpu_exit(struct cpufreq_policy *policy) | |||
428 | } | 414 | } |
429 | 415 | ||
430 | /** | 416 | /** |
431 | * centrino_verify - verifies a new CPUFreq policy | ||
432 | * @policy: new policy | ||
433 | * | ||
434 | * Limit must be within this model's frequency range at least one | ||
435 | * border included. | ||
436 | */ | ||
437 | static int centrino_verify (struct cpufreq_policy *policy) | ||
438 | { | ||
439 | return cpufreq_frequency_table_verify(policy, | ||
440 | per_cpu(centrino_model, policy->cpu)->op_points); | ||
441 | } | ||
442 | |||
443 | /** | ||
444 | * centrino_setpolicy - set a new CPUFreq policy | 417 | * centrino_setpolicy - set a new CPUFreq policy |
445 | * @policy: new policy | 418 | * @policy: new policy |
446 | * @target_freq: the target frequency | 419 | * @index: index of target frequency |
447 | * @relation: how that frequency relates to achieved frequency | ||
448 | * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) | ||
449 | * | 420 | * |
450 | * Sets a new CPUFreq policy. | 421 | * Sets a new CPUFreq policy. |
451 | */ | 422 | */ |
452 | static int centrino_target (struct cpufreq_policy *policy, | 423 | static int centrino_target(struct cpufreq_policy *policy, unsigned int index) |
453 | unsigned int target_freq, | ||
454 | unsigned int relation) | ||
455 | { | 424 | { |
456 | unsigned int newstate = 0; | ||
457 | unsigned int msr, oldmsr = 0, h = 0, cpu = policy->cpu; | 425 | unsigned int msr, oldmsr = 0, h = 0, cpu = policy->cpu; |
458 | struct cpufreq_freqs freqs; | ||
459 | int retval = 0; | 426 | int retval = 0; |
460 | unsigned int j, first_cpu, tmp; | 427 | unsigned int j, first_cpu; |
428 | struct cpufreq_frequency_table *op_points; | ||
461 | cpumask_var_t covered_cpus; | 429 | cpumask_var_t covered_cpus; |
462 | 430 | ||
463 | if (unlikely(!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL))) | 431 | if (unlikely(!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL))) |
@@ -468,16 +436,8 @@ static int centrino_target (struct cpufreq_policy *policy, | |||
468 | goto out; | 436 | goto out; |
469 | } | 437 | } |
470 | 438 | ||
471 | if (unlikely(cpufreq_frequency_table_target(policy, | ||
472 | per_cpu(centrino_model, cpu)->op_points, | ||
473 | target_freq, | ||
474 | relation, | ||
475 | &newstate))) { | ||
476 | retval = -EINVAL; | ||
477 | goto out; | ||
478 | } | ||
479 | |||
480 | first_cpu = 1; | 439 | first_cpu = 1; |
440 | op_points = &per_cpu(centrino_model, cpu)->op_points[index]; | ||
481 | for_each_cpu(j, policy->cpus) { | 441 | for_each_cpu(j, policy->cpus) { |
482 | int good_cpu; | 442 | int good_cpu; |
483 | 443 | ||
@@ -501,7 +461,7 @@ static int centrino_target (struct cpufreq_policy *policy, | |||
501 | break; | 461 | break; |
502 | } | 462 | } |
503 | 463 | ||
504 | msr = per_cpu(centrino_model, cpu)->op_points[newstate].driver_data; | 464 | msr = op_points->driver_data; |
505 | 465 | ||
506 | if (first_cpu) { | 466 | if (first_cpu) { |
507 | rdmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, &oldmsr, &h); | 467 | rdmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, &oldmsr, &h); |
@@ -512,15 +472,6 @@ static int centrino_target (struct cpufreq_policy *policy, | |||
512 | goto out; | 472 | goto out; |
513 | } | 473 | } |
514 | 474 | ||
515 | freqs.old = extract_clock(oldmsr, cpu, 0); | ||
516 | freqs.new = extract_clock(msr, cpu, 0); | ||
517 | |||
518 | pr_debug("target=%dkHz old=%d new=%d msr=%04x\n", | ||
519 | target_freq, freqs.old, freqs.new, msr); | ||
520 | |||
521 | cpufreq_notify_transition(policy, &freqs, | ||
522 | CPUFREQ_PRECHANGE); | ||
523 | |||
524 | first_cpu = 0; | 475 | first_cpu = 0; |
525 | /* all but 16 LSB are reserved, treat them with care */ | 476 | /* all but 16 LSB are reserved, treat them with care */ |
526 | oldmsr &= ~0xffff; | 477 | oldmsr &= ~0xffff; |
@@ -535,8 +486,6 @@ static int centrino_target (struct cpufreq_policy *policy, | |||
535 | cpumask_set_cpu(j, covered_cpus); | 486 | cpumask_set_cpu(j, covered_cpus); |
536 | } | 487 | } |
537 | 488 | ||
538 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
539 | |||
540 | if (unlikely(retval)) { | 489 | if (unlikely(retval)) { |
541 | /* | 490 | /* |
542 | * We have failed halfway through the frequency change. | 491 | * We have failed halfway through the frequency change. |
@@ -547,12 +496,6 @@ static int centrino_target (struct cpufreq_policy *policy, | |||
547 | 496 | ||
548 | for_each_cpu(j, covered_cpus) | 497 | for_each_cpu(j, covered_cpus) |
549 | wrmsr_on_cpu(j, MSR_IA32_PERF_CTL, oldmsr, h); | 498 | wrmsr_on_cpu(j, MSR_IA32_PERF_CTL, oldmsr, h); |
550 | |||
551 | tmp = freqs.new; | ||
552 | freqs.new = freqs.old; | ||
553 | freqs.old = tmp; | ||
554 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
555 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
556 | } | 499 | } |
557 | retval = 0; | 500 | retval = 0; |
558 | 501 | ||
@@ -561,20 +504,15 @@ out: | |||
561 | return retval; | 504 | return retval; |
562 | } | 505 | } |
563 | 506 | ||
564 | static struct freq_attr* centrino_attr[] = { | ||
565 | &cpufreq_freq_attr_scaling_available_freqs, | ||
566 | NULL, | ||
567 | }; | ||
568 | |||
569 | static struct cpufreq_driver centrino_driver = { | 507 | static struct cpufreq_driver centrino_driver = { |
570 | .name = "centrino", /* should be speedstep-centrino, | 508 | .name = "centrino", /* should be speedstep-centrino, |
571 | but there's a 16 char limit */ | 509 | but there's a 16 char limit */ |
572 | .init = centrino_cpu_init, | 510 | .init = centrino_cpu_init, |
573 | .exit = centrino_cpu_exit, | 511 | .exit = centrino_cpu_exit, |
574 | .verify = centrino_verify, | 512 | .verify = cpufreq_generic_frequency_table_verify, |
575 | .target = centrino_target, | 513 | .target_index = centrino_target, |
576 | .get = get_cur_freq, | 514 | .get = get_cur_freq, |
577 | .attr = centrino_attr, | 515 | .attr = cpufreq_generic_attr, |
578 | }; | 516 | }; |
579 | 517 | ||
580 | /* | 518 | /* |
diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c index 5355abb69afc..7639b2be2a90 100644 --- a/drivers/cpufreq/speedstep-ich.c +++ b/drivers/cpufreq/speedstep-ich.c | |||
@@ -251,56 +251,23 @@ static unsigned int speedstep_get(unsigned int cpu) | |||
251 | /** | 251 | /** |
252 | * speedstep_target - set a new CPUFreq policy | 252 | * speedstep_target - set a new CPUFreq policy |
253 | * @policy: new policy | 253 | * @policy: new policy |
254 | * @target_freq: the target frequency | 254 | * @index: index of target frequency |
255 | * @relation: how that frequency relates to achieved frequency | ||
256 | * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H) | ||
257 | * | 255 | * |
258 | * Sets a new CPUFreq policy. | 256 | * Sets a new CPUFreq policy. |
259 | */ | 257 | */ |
260 | static int speedstep_target(struct cpufreq_policy *policy, | 258 | static int speedstep_target(struct cpufreq_policy *policy, unsigned int index) |
261 | unsigned int target_freq, | ||
262 | unsigned int relation) | ||
263 | { | 259 | { |
264 | unsigned int newstate = 0, policy_cpu; | 260 | unsigned int policy_cpu; |
265 | struct cpufreq_freqs freqs; | ||
266 | |||
267 | if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], | ||
268 | target_freq, relation, &newstate)) | ||
269 | return -EINVAL; | ||
270 | 261 | ||
271 | policy_cpu = cpumask_any_and(policy->cpus, cpu_online_mask); | 262 | policy_cpu = cpumask_any_and(policy->cpus, cpu_online_mask); |
272 | freqs.old = speedstep_get(policy_cpu); | ||
273 | freqs.new = speedstep_freqs[newstate].frequency; | ||
274 | |||
275 | pr_debug("transiting from %u to %u kHz\n", freqs.old, freqs.new); | ||
276 | |||
277 | /* no transition necessary */ | ||
278 | if (freqs.old == freqs.new) | ||
279 | return 0; | ||
280 | 263 | ||
281 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 264 | smp_call_function_single(policy_cpu, _speedstep_set_state, &index, |
282 | |||
283 | smp_call_function_single(policy_cpu, _speedstep_set_state, &newstate, | ||
284 | true); | 265 | true); |
285 | 266 | ||
286 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
287 | |||
288 | return 0; | 267 | return 0; |
289 | } | 268 | } |
290 | 269 | ||
291 | 270 | ||
292 | /** | ||
293 | * speedstep_verify - verifies a new CPUFreq policy | ||
294 | * @policy: new policy | ||
295 | * | ||
296 | * Limit must be within speedstep_low_freq and speedstep_high_freq, with | ||
297 | * at least one border included. | ||
298 | */ | ||
299 | static int speedstep_verify(struct cpufreq_policy *policy) | ||
300 | { | ||
301 | return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]); | ||
302 | } | ||
303 | |||
304 | struct get_freqs { | 271 | struct get_freqs { |
305 | struct cpufreq_policy *policy; | 272 | struct cpufreq_policy *policy; |
306 | int ret; | 273 | int ret; |
@@ -320,8 +287,7 @@ static void get_freqs_on_cpu(void *_get_freqs) | |||
320 | 287 | ||
321 | static int speedstep_cpu_init(struct cpufreq_policy *policy) | 288 | static int speedstep_cpu_init(struct cpufreq_policy *policy) |
322 | { | 289 | { |
323 | int result; | 290 | unsigned int policy_cpu; |
324 | unsigned int policy_cpu, speed; | ||
325 | struct get_freqs gf; | 291 | struct get_freqs gf; |
326 | 292 | ||
327 | /* only run on CPU to be set, or on its sibling */ | 293 | /* only run on CPU to be set, or on its sibling */ |
@@ -336,49 +302,18 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) | |||
336 | if (gf.ret) | 302 | if (gf.ret) |
337 | return gf.ret; | 303 | return gf.ret; |
338 | 304 | ||
339 | /* get current speed setting */ | 305 | return cpufreq_table_validate_and_show(policy, speedstep_freqs); |
340 | speed = speedstep_get(policy_cpu); | ||
341 | if (!speed) | ||
342 | return -EIO; | ||
343 | |||
344 | pr_debug("currently at %s speed setting - %i MHz\n", | ||
345 | (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) | ||
346 | ? "low" : "high", | ||
347 | (speed / 1000)); | ||
348 | |||
349 | /* cpuinfo and default policy values */ | ||
350 | policy->cur = speed; | ||
351 | |||
352 | result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); | ||
353 | if (result) | ||
354 | return result; | ||
355 | |||
356 | cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu); | ||
357 | |||
358 | return 0; | ||
359 | } | 306 | } |
360 | 307 | ||
361 | 308 | ||
362 | static int speedstep_cpu_exit(struct cpufreq_policy *policy) | ||
363 | { | ||
364 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static struct freq_attr *speedstep_attr[] = { | ||
369 | &cpufreq_freq_attr_scaling_available_freqs, | ||
370 | NULL, | ||
371 | }; | ||
372 | |||
373 | |||
374 | static struct cpufreq_driver speedstep_driver = { | 309 | static struct cpufreq_driver speedstep_driver = { |
375 | .name = "speedstep-ich", | 310 | .name = "speedstep-ich", |
376 | .verify = speedstep_verify, | 311 | .verify = cpufreq_generic_frequency_table_verify, |
377 | .target = speedstep_target, | 312 | .target_index = speedstep_target, |
378 | .init = speedstep_cpu_init, | 313 | .init = speedstep_cpu_init, |
379 | .exit = speedstep_cpu_exit, | 314 | .exit = cpufreq_generic_exit, |
380 | .get = speedstep_get, | 315 | .get = speedstep_get, |
381 | .attr = speedstep_attr, | 316 | .attr = cpufreq_generic_attr, |
382 | }; | 317 | }; |
383 | 318 | ||
384 | static const struct x86_cpu_id ss_smi_ids[] = { | 319 | static const struct x86_cpu_id ss_smi_ids[] = { |
diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c index abfba4f731eb..0f5326d6f79f 100644 --- a/drivers/cpufreq/speedstep-smi.c +++ b/drivers/cpufreq/speedstep-smi.c | |||
@@ -235,52 +235,21 @@ static void speedstep_set_state(unsigned int state) | |||
235 | /** | 235 | /** |
236 | * speedstep_target - set a new CPUFreq policy | 236 | * speedstep_target - set a new CPUFreq policy |
237 | * @policy: new policy | 237 | * @policy: new policy |
238 | * @target_freq: new freq | 238 | * @index: index of new freq |
239 | * @relation: | ||
240 | * | 239 | * |
241 | * Sets a new CPUFreq policy/freq. | 240 | * Sets a new CPUFreq policy/freq. |
242 | */ | 241 | */ |
243 | static int speedstep_target(struct cpufreq_policy *policy, | 242 | static int speedstep_target(struct cpufreq_policy *policy, unsigned int index) |
244 | unsigned int target_freq, unsigned int relation) | ||
245 | { | 243 | { |
246 | unsigned int newstate = 0; | 244 | speedstep_set_state(index); |
247 | struct cpufreq_freqs freqs; | ||
248 | |||
249 | if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], | ||
250 | target_freq, relation, &newstate)) | ||
251 | return -EINVAL; | ||
252 | |||
253 | freqs.old = speedstep_freqs[speedstep_get_state()].frequency; | ||
254 | freqs.new = speedstep_freqs[newstate].frequency; | ||
255 | |||
256 | if (freqs.old == freqs.new) | ||
257 | return 0; | ||
258 | |||
259 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
260 | speedstep_set_state(newstate); | ||
261 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
262 | 245 | ||
263 | return 0; | 246 | return 0; |
264 | } | 247 | } |
265 | 248 | ||
266 | 249 | ||
267 | /** | ||
268 | * speedstep_verify - verifies a new CPUFreq policy | ||
269 | * @policy: new policy | ||
270 | * | ||
271 | * Limit must be within speedstep_low_freq and speedstep_high_freq, with | ||
272 | * at least one border included. | ||
273 | */ | ||
274 | static int speedstep_verify(struct cpufreq_policy *policy) | ||
275 | { | ||
276 | return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]); | ||
277 | } | ||
278 | |||
279 | |||
280 | static int speedstep_cpu_init(struct cpufreq_policy *policy) | 250 | static int speedstep_cpu_init(struct cpufreq_policy *policy) |
281 | { | 251 | { |
282 | int result; | 252 | int result; |
283 | unsigned int speed, state; | ||
284 | unsigned int *low, *high; | 253 | unsigned int *low, *high; |
285 | 254 | ||
286 | /* capability check */ | 255 | /* capability check */ |
@@ -316,32 +285,8 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) | |||
316 | pr_debug("workaround worked.\n"); | 285 | pr_debug("workaround worked.\n"); |
317 | } | 286 | } |
318 | 287 | ||
319 | /* get current speed setting */ | ||
320 | state = speedstep_get_state(); | ||
321 | speed = speedstep_freqs[state].frequency; | ||
322 | |||
323 | pr_debug("currently at %s speed setting - %i MHz\n", | ||
324 | (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) | ||
325 | ? "low" : "high", | ||
326 | (speed / 1000)); | ||
327 | |||
328 | /* cpuinfo and default policy values */ | ||
329 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 288 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; |
330 | policy->cur = speed; | 289 | return cpufreq_table_validate_and_show(policy, speedstep_freqs); |
331 | |||
332 | result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); | ||
333 | if (result) | ||
334 | return result; | ||
335 | |||
336 | cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu); | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static int speedstep_cpu_exit(struct cpufreq_policy *policy) | ||
342 | { | ||
343 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
344 | return 0; | ||
345 | } | 290 | } |
346 | 291 | ||
347 | static unsigned int speedstep_get(unsigned int cpu) | 292 | static unsigned int speedstep_get(unsigned int cpu) |
@@ -362,20 +307,15 @@ static int speedstep_resume(struct cpufreq_policy *policy) | |||
362 | return result; | 307 | return result; |
363 | } | 308 | } |
364 | 309 | ||
365 | static struct freq_attr *speedstep_attr[] = { | ||
366 | &cpufreq_freq_attr_scaling_available_freqs, | ||
367 | NULL, | ||
368 | }; | ||
369 | |||
370 | static struct cpufreq_driver speedstep_driver = { | 310 | static struct cpufreq_driver speedstep_driver = { |
371 | .name = "speedstep-smi", | 311 | .name = "speedstep-smi", |
372 | .verify = speedstep_verify, | 312 | .verify = cpufreq_generic_frequency_table_verify, |
373 | .target = speedstep_target, | 313 | .target_index = speedstep_target, |
374 | .init = speedstep_cpu_init, | 314 | .init = speedstep_cpu_init, |
375 | .exit = speedstep_cpu_exit, | 315 | .exit = cpufreq_generic_exit, |
376 | .get = speedstep_get, | 316 | .get = speedstep_get, |
377 | .resume = speedstep_resume, | 317 | .resume = speedstep_resume, |
378 | .attr = speedstep_attr, | 318 | .attr = cpufreq_generic_attr, |
379 | }; | 319 | }; |
380 | 320 | ||
381 | static const struct x86_cpu_id ss_smi_ids[] = { | 321 | static const struct x86_cpu_id ss_smi_ids[] = { |
diff --git a/drivers/cpufreq/tegra-cpufreq.c b/drivers/cpufreq/tegra-cpufreq.c index a7b876fdc1d8..f42df7ec03c5 100644 --- a/drivers/cpufreq/tegra-cpufreq.c +++ b/drivers/cpufreq/tegra-cpufreq.c | |||
@@ -51,11 +51,6 @@ static unsigned long target_cpu_speed[NUM_CPUS]; | |||
51 | static DEFINE_MUTEX(tegra_cpu_lock); | 51 | static DEFINE_MUTEX(tegra_cpu_lock); |
52 | static bool is_suspended; | 52 | static bool is_suspended; |
53 | 53 | ||
54 | static int tegra_verify_speed(struct cpufreq_policy *policy) | ||
55 | { | ||
56 | return cpufreq_frequency_table_verify(policy, freq_table); | ||
57 | } | ||
58 | |||
59 | static unsigned int tegra_getspeed(unsigned int cpu) | 54 | static unsigned int tegra_getspeed(unsigned int cpu) |
60 | { | 55 | { |
61 | unsigned long rate; | 56 | unsigned long rate; |
@@ -107,12 +102,8 @@ static int tegra_update_cpu_speed(struct cpufreq_policy *policy, | |||
107 | unsigned long rate) | 102 | unsigned long rate) |
108 | { | 103 | { |
109 | int ret = 0; | 104 | int ret = 0; |
110 | struct cpufreq_freqs freqs; | ||
111 | 105 | ||
112 | freqs.old = tegra_getspeed(0); | 106 | if (tegra_getspeed(0) == rate) |
113 | freqs.new = rate; | ||
114 | |||
115 | if (freqs.old == freqs.new) | ||
116 | return ret; | 107 | return ret; |
117 | 108 | ||
118 | /* | 109 | /* |
@@ -126,21 +117,10 @@ static int tegra_update_cpu_speed(struct cpufreq_policy *policy, | |||
126 | else | 117 | else |
127 | clk_set_rate(emc_clk, 100000000); /* emc 50Mhz */ | 118 | clk_set_rate(emc_clk, 100000000); /* emc 50Mhz */ |
128 | 119 | ||
129 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 120 | ret = tegra_cpu_clk_set_rate(rate * 1000); |
130 | 121 | if (ret) | |
131 | #ifdef CONFIG_CPU_FREQ_DEBUG | 122 | pr_err("cpu-tegra: Failed to set cpu frequency to %lu kHz\n", |
132 | printk(KERN_DEBUG "cpufreq-tegra: transition: %u --> %u\n", | 123 | rate); |
133 | freqs.old, freqs.new); | ||
134 | #endif | ||
135 | |||
136 | ret = tegra_cpu_clk_set_rate(freqs.new * 1000); | ||
137 | if (ret) { | ||
138 | pr_err("cpu-tegra: Failed to set cpu frequency to %d kHz\n", | ||
139 | freqs.new); | ||
140 | freqs.new = freqs.old; | ||
141 | } | ||
142 | |||
143 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
144 | 124 | ||
145 | return ret; | 125 | return ret; |
146 | } | 126 | } |
@@ -155,11 +135,8 @@ static unsigned long tegra_cpu_highest_speed(void) | |||
155 | return rate; | 135 | return rate; |
156 | } | 136 | } |
157 | 137 | ||
158 | static int tegra_target(struct cpufreq_policy *policy, | 138 | static int tegra_target(struct cpufreq_policy *policy, unsigned int index) |
159 | unsigned int target_freq, | ||
160 | unsigned int relation) | ||
161 | { | 139 | { |
162 | unsigned int idx; | ||
163 | unsigned int freq; | 140 | unsigned int freq; |
164 | int ret = 0; | 141 | int ret = 0; |
165 | 142 | ||
@@ -170,10 +147,7 @@ static int tegra_target(struct cpufreq_policy *policy, | |||
170 | goto out; | 147 | goto out; |
171 | } | 148 | } |
172 | 149 | ||
173 | cpufreq_frequency_table_target(policy, freq_table, target_freq, | 150 | freq = freq_table[index].frequency; |
174 | relation, &idx); | ||
175 | |||
176 | freq = freq_table[idx].frequency; | ||
177 | 151 | ||
178 | target_cpu_speed[policy->cpu] = freq; | 152 | target_cpu_speed[policy->cpu] = freq; |
179 | 153 | ||
@@ -209,21 +183,23 @@ static struct notifier_block tegra_cpu_pm_notifier = { | |||
209 | 183 | ||
210 | static int tegra_cpu_init(struct cpufreq_policy *policy) | 184 | static int tegra_cpu_init(struct cpufreq_policy *policy) |
211 | { | 185 | { |
186 | int ret; | ||
187 | |||
212 | if (policy->cpu >= NUM_CPUS) | 188 | if (policy->cpu >= NUM_CPUS) |
213 | return -EINVAL; | 189 | return -EINVAL; |
214 | 190 | ||
215 | clk_prepare_enable(emc_clk); | 191 | clk_prepare_enable(emc_clk); |
216 | clk_prepare_enable(cpu_clk); | 192 | clk_prepare_enable(cpu_clk); |
217 | 193 | ||
218 | cpufreq_frequency_table_cpuinfo(policy, freq_table); | 194 | target_cpu_speed[policy->cpu] = tegra_getspeed(policy->cpu); |
219 | cpufreq_frequency_table_get_attr(freq_table, policy->cpu); | ||
220 | policy->cur = tegra_getspeed(policy->cpu); | ||
221 | target_cpu_speed[policy->cpu] = policy->cur; | ||
222 | 195 | ||
223 | /* FIXME: what's the actual transition time? */ | 196 | /* FIXME: what's the actual transition time? */ |
224 | policy->cpuinfo.transition_latency = 300 * 1000; | 197 | ret = cpufreq_generic_init(policy, freq_table, 300 * 1000); |
225 | 198 | if (ret) { | |
226 | cpumask_copy(policy->cpus, cpu_possible_mask); | 199 | clk_disable_unprepare(cpu_clk); |
200 | clk_disable_unprepare(emc_clk); | ||
201 | return ret; | ||
202 | } | ||
227 | 203 | ||
228 | if (policy->cpu == 0) | 204 | if (policy->cpu == 0) |
229 | register_pm_notifier(&tegra_cpu_pm_notifier); | 205 | register_pm_notifier(&tegra_cpu_pm_notifier); |
@@ -233,24 +209,20 @@ static int tegra_cpu_init(struct cpufreq_policy *policy) | |||
233 | 209 | ||
234 | static int tegra_cpu_exit(struct cpufreq_policy *policy) | 210 | static int tegra_cpu_exit(struct cpufreq_policy *policy) |
235 | { | 211 | { |
236 | cpufreq_frequency_table_cpuinfo(policy, freq_table); | 212 | cpufreq_frequency_table_put_attr(policy->cpu); |
213 | clk_disable_unprepare(cpu_clk); | ||
237 | clk_disable_unprepare(emc_clk); | 214 | clk_disable_unprepare(emc_clk); |
238 | return 0; | 215 | return 0; |
239 | } | 216 | } |
240 | 217 | ||
241 | static struct freq_attr *tegra_cpufreq_attr[] = { | ||
242 | &cpufreq_freq_attr_scaling_available_freqs, | ||
243 | NULL, | ||
244 | }; | ||
245 | |||
246 | static struct cpufreq_driver tegra_cpufreq_driver = { | 218 | static struct cpufreq_driver tegra_cpufreq_driver = { |
247 | .verify = tegra_verify_speed, | 219 | .verify = cpufreq_generic_frequency_table_verify, |
248 | .target = tegra_target, | 220 | .target_index = tegra_target, |
249 | .get = tegra_getspeed, | 221 | .get = tegra_getspeed, |
250 | .init = tegra_cpu_init, | 222 | .init = tegra_cpu_init, |
251 | .exit = tegra_cpu_exit, | 223 | .exit = tegra_cpu_exit, |
252 | .name = "tegra", | 224 | .name = "tegra", |
253 | .attr = tegra_cpufreq_attr, | 225 | .attr = cpufreq_generic_attr, |
254 | }; | 226 | }; |
255 | 227 | ||
256 | static int __init tegra_cpufreq_init(void) | 228 | static int __init tegra_cpufreq_init(void) |
diff --git a/drivers/cpufreq/unicore2-cpufreq.c b/drivers/cpufreq/unicore2-cpufreq.c index b225f04d8ae5..653ae2955b55 100644 --- a/drivers/cpufreq/unicore2-cpufreq.c +++ b/drivers/cpufreq/unicore2-cpufreq.c | |||
@@ -29,9 +29,7 @@ static int ucv2_verify_speed(struct cpufreq_policy *policy) | |||
29 | if (policy->cpu) | 29 | if (policy->cpu) |
30 | return -EINVAL; | 30 | return -EINVAL; |
31 | 31 | ||
32 | cpufreq_verify_within_limits(policy, | 32 | cpufreq_verify_within_cpu_limits(policy); |
33 | policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); | ||
34 | |||
35 | return 0; | 33 | return 0; |
36 | } | 34 | } |
37 | 35 | ||
@@ -68,7 +66,6 @@ static int __init ucv2_cpu_init(struct cpufreq_policy *policy) | |||
68 | { | 66 | { |
69 | if (policy->cpu != 0) | 67 | if (policy->cpu != 0) |
70 | return -EINVAL; | 68 | return -EINVAL; |
71 | policy->cur = ucv2_getspeed(0); | ||
72 | policy->min = policy->cpuinfo.min_freq = 250000; | 69 | policy->min = policy->cpuinfo.min_freq = 250000; |
73 | policy->max = policy->cpuinfo.max_freq = 1000000; | 70 | policy->max = policy->cpuinfo.max_freq = 1000000; |
74 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 71 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; |
diff --git a/drivers/cpufreq/vexpress-spc-cpufreq.c b/drivers/cpufreq/vexpress-spc-cpufreq.c new file mode 100644 index 000000000000..7f7c9c01b44e --- /dev/null +++ b/drivers/cpufreq/vexpress-spc-cpufreq.c | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * Versatile Express SPC CPUFreq Interface driver | ||
3 | * | ||
4 | * It provides necessary ops to arm_big_little cpufreq driver. | ||
5 | * | ||
6 | * Copyright (C) 2013 ARM Ltd. | ||
7 | * Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
14 | * kind, whether express or implied; without even the implied warranty | ||
15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | */ | ||
18 | |||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
20 | |||
21 | #include <linux/cpufreq.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/pm_opp.h> | ||
25 | #include <linux/types.h> | ||
26 | |||
27 | #include "arm_big_little.h" | ||
28 | |||
29 | static int ve_spc_init_opp_table(struct device *cpu_dev) | ||
30 | { | ||
31 | /* | ||
32 | * platform specific SPC code must initialise the opp table | ||
33 | * so just check if the OPP count is non-zero | ||
34 | */ | ||
35 | return dev_pm_opp_get_opp_count(cpu_dev) <= 0; | ||
36 | } | ||
37 | |||
38 | static int ve_spc_get_transition_latency(struct device *cpu_dev) | ||
39 | { | ||
40 | return 1000000; /* 1 ms */ | ||
41 | } | ||
42 | |||
43 | static struct cpufreq_arm_bL_ops ve_spc_cpufreq_ops = { | ||
44 | .name = "vexpress-spc", | ||
45 | .get_transition_latency = ve_spc_get_transition_latency, | ||
46 | .init_opp_table = ve_spc_init_opp_table, | ||
47 | }; | ||
48 | |||
49 | static int ve_spc_cpufreq_probe(struct platform_device *pdev) | ||
50 | { | ||
51 | return bL_cpufreq_register(&ve_spc_cpufreq_ops); | ||
52 | } | ||
53 | |||
54 | static int ve_spc_cpufreq_remove(struct platform_device *pdev) | ||
55 | { | ||
56 | bL_cpufreq_unregister(&ve_spc_cpufreq_ops); | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static struct platform_driver ve_spc_cpufreq_platdrv = { | ||
61 | .driver = { | ||
62 | .name = "vexpress-spc-cpufreq", | ||
63 | .owner = THIS_MODULE, | ||
64 | }, | ||
65 | .probe = ve_spc_cpufreq_probe, | ||
66 | .remove = ve_spc_cpufreq_remove, | ||
67 | }; | ||
68 | module_platform_driver(ve_spc_cpufreq_platdrv); | ||
69 | |||
70 | MODULE_LICENSE("GPL"); | ||