diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-11-30 20:46:24 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-11-30 20:46:24 -0500 |
commit | 8a497cfdc03412c36ba1689f0e68529d179f4e03 (patch) | |
tree | 5d4ea8f243de593d03ba95b1c44228c2b0e03c25 | |
parent | 009d0431c3914de64666bec0d350e54fdd59df6a (diff) | |
parent | 9a004428d77f1571c883b993d77ec64767b1959a (diff) |
Merge back earlier cpufreq material for 3.19-rc1.
-rw-r--r-- | Documentation/cpu-freq/intel-pstate.txt | 37 | ||||
-rw-r--r-- | Documentation/kernel-parameters.txt | 3 | ||||
-rw-r--r-- | arch/x86/include/asm/cpufeature.h | 5 | ||||
-rw-r--r-- | arch/x86/include/uapi/asm/msr-index.h | 41 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/scattered.c | 5 | ||||
-rw-r--r-- | drivers/cpufreq/Kconfig | 57 | ||||
-rw-r--r-- | drivers/cpufreq/Kconfig.arm | 8 | ||||
-rw-r--r-- | drivers/cpufreq/Makefile | 4 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq-dt.c | 60 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 53 | ||||
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 101 | ||||
-rw-r--r-- | drivers/cpufreq/ls1x-cpufreq.c | 223 | ||||
-rw-r--r-- | drivers/cpufreq/pcc-cpufreq.c | 7 | ||||
-rw-r--r-- | include/linux/cpufreq.h | 54 |
14 files changed, 543 insertions, 115 deletions
diff --git a/Documentation/cpu-freq/intel-pstate.txt b/Documentation/cpu-freq/intel-pstate.txt index a69ffe1d54d5..765d7fc0e692 100644 --- a/Documentation/cpu-freq/intel-pstate.txt +++ b/Documentation/cpu-freq/intel-pstate.txt | |||
@@ -1,17 +1,28 @@ | |||
1 | Intel P-state driver | 1 | Intel P-state driver |
2 | -------------------- | 2 | -------------------- |
3 | 3 | ||
4 | This driver implements a scaling driver with an internal governor for | 4 | This driver provides an interface to control the P state selection for |
5 | Intel Core processors. The driver follows the same model as the | 5 | SandyBridge+ Intel processors. The driver can operate two different |
6 | Transmeta scaling driver (longrun.c) and implements the setpolicy() | 6 | modes based on the processor model legacy and Hardware P state (HWP) |
7 | instead of target(). Scaling drivers that implement setpolicy() are | 7 | mode. |
8 | assumed to implement internal governors by the cpufreq core. All the | 8 | |
9 | logic for selecting the current P state is contained within the | 9 | In legacy mode the driver implements a scaling driver with an internal |
10 | driver; no external governor is used by the cpufreq core. | 10 | governor for Intel Core processors. The driver follows the same model |
11 | 11 | as the Transmeta scaling driver (longrun.c) and implements the | |
12 | Intel SandyBridge+ processors are supported. | 12 | setpolicy() instead of target(). Scaling drivers that implement |
13 | 13 | setpolicy() are assumed to implement internal governors by the cpufreq | |
14 | New sysfs files for controlling P state selection have been added to | 14 | core. All the logic for selecting the current P state is contained |
15 | within the driver; no external governor is used by the cpufreq core. | ||
16 | |||
17 | In HWP mode P state selection is implemented in the processor | ||
18 | itself. The driver provides the interfaces between the cpufreq core and | ||
19 | the processor to control P state selection based on user preferences | ||
20 | and reporting frequency to the cpufreq core. In this mode the | ||
21 | internal governor code is disabled. | ||
22 | |||
23 | In addtion to the interfaces provided by the cpufreq core for | ||
24 | controlling frequency the driver provides sysfs files for | ||
25 | controlling P state selection. These files have been added to | ||
15 | /sys/devices/system/cpu/intel_pstate/ | 26 | /sys/devices/system/cpu/intel_pstate/ |
16 | 27 | ||
17 | max_perf_pct: limits the maximum P state that will be requested by | 28 | max_perf_pct: limits the maximum P state that will be requested by |
@@ -33,7 +44,9 @@ frequency is fiction for Intel Core processors. Even if the scaling | |||
33 | driver selects a single P state the actual frequency the processor | 44 | driver selects a single P state the actual frequency the processor |
34 | will run at is selected by the processor itself. | 45 | will run at is selected by the processor itself. |
35 | 46 | ||
36 | New debugfs files have also been added to /sys/kernel/debug/pstate_snb/ | 47 | For legacy mode debugfs files have also been added to allow tuning of |
48 | the internal governor algorythm. These files are located at | ||
49 | /sys/kernel/debug/pstate_snb/ These files are NOT present in HWP mode. | ||
37 | 50 | ||
38 | deadband | 51 | deadband |
39 | d_gain_pct | 52 | d_gain_pct |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 479f33204a37..5fdf714f40a0 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1446,6 +1446,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1446 | disable | 1446 | disable |
1447 | Do not enable intel_pstate as the default | 1447 | Do not enable intel_pstate as the default |
1448 | scaling driver for the supported processors | 1448 | scaling driver for the supported processors |
1449 | no_hwp | ||
1450 | Do not enable hardware P state control (HWP) | ||
1451 | if available. | ||
1449 | 1452 | ||
1450 | intremap= [X86-64, Intel-IOMMU] | 1453 | intremap= [X86-64, Intel-IOMMU] |
1451 | on enable Interrupt Remapping (default) | 1454 | on enable Interrupt Remapping (default) |
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 0bb1335313b2..aede2c347bde 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
@@ -189,6 +189,11 @@ | |||
189 | #define X86_FEATURE_DTHERM ( 7*32+ 7) /* Digital Thermal Sensor */ | 189 | #define X86_FEATURE_DTHERM ( 7*32+ 7) /* Digital Thermal Sensor */ |
190 | #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ | 190 | #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ |
191 | #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ | 191 | #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ |
192 | #define X86_FEATURE_HWP ( 7*32+ 10) /* "hwp" Intel HWP */ | ||
193 | #define X86_FEATURE_HWP_NOITFY ( 7*32+ 11) /* Intel HWP_NOTIFY */ | ||
194 | #define X86_FEATURE_HWP_ACT_WINDOW ( 7*32+ 12) /* Intel HWP_ACT_WINDOW */ | ||
195 | #define X86_FEATURE_HWP_EPP ( 7*32+13) /* Intel HWP_EPP */ | ||
196 | #define X86_FEATURE_HWP_PKG_REQ ( 7*32+14) /* Intel HWP_PKG_REQ */ | ||
192 | 197 | ||
193 | /* Virtualization flags: Linux defined, word 8 */ | 198 | /* Virtualization flags: Linux defined, word 8 */ |
194 | #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ | 199 | #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ |
diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index e21331ce368f..62838e54947d 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h | |||
@@ -152,6 +152,45 @@ | |||
152 | #define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668 | 152 | #define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668 |
153 | #define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669 | 153 | #define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669 |
154 | 154 | ||
155 | /* Hardware P state interface */ | ||
156 | #define MSR_PPERF 0x0000064e | ||
157 | #define MSR_PERF_LIMIT_REASONS 0x0000064f | ||
158 | #define MSR_PM_ENABLE 0x00000770 | ||
159 | #define MSR_HWP_CAPABILITIES 0x00000771 | ||
160 | #define MSR_HWP_REQUEST_PKG 0x00000772 | ||
161 | #define MSR_HWP_INTERRUPT 0x00000773 | ||
162 | #define MSR_HWP_REQUEST 0x00000774 | ||
163 | #define MSR_HWP_STATUS 0x00000777 | ||
164 | |||
165 | /* CPUID.6.EAX */ | ||
166 | #define HWP_BASE_BIT (1<<7) | ||
167 | #define HWP_NOTIFICATIONS_BIT (1<<8) | ||
168 | #define HWP_ACTIVITY_WINDOW_BIT (1<<9) | ||
169 | #define HWP_ENERGY_PERF_PREFERENCE_BIT (1<<10) | ||
170 | #define HWP_PACKAGE_LEVEL_REQUEST_BIT (1<<11) | ||
171 | |||
172 | /* IA32_HWP_CAPABILITIES */ | ||
173 | #define HWP_HIGHEST_PERF(x) (x & 0xff) | ||
174 | #define HWP_GUARANTEED_PERF(x) ((x & (0xff << 8)) >>8) | ||
175 | #define HWP_MOSTEFFICIENT_PERF(x) ((x & (0xff << 16)) >>16) | ||
176 | #define HWP_LOWEST_PERF(x) ((x & (0xff << 24)) >>24) | ||
177 | |||
178 | /* IA32_HWP_REQUEST */ | ||
179 | #define HWP_MIN_PERF(x) (x & 0xff) | ||
180 | #define HWP_MAX_PERF(x) ((x & 0xff) << 8) | ||
181 | #define HWP_DESIRED_PERF(x) ((x & 0xff) << 16) | ||
182 | #define HWP_ENERGY_PERF_PREFERENCE(x) ((x & 0xff) << 24) | ||
183 | #define HWP_ACTIVITY_WINDOW(x) ((x & 0xff3) << 32) | ||
184 | #define HWP_PACKAGE_CONTROL(x) ((x & 0x1) << 42) | ||
185 | |||
186 | /* IA32_HWP_STATUS */ | ||
187 | #define HWP_GUARANTEED_CHANGE(x) (x & 0x1) | ||
188 | #define HWP_EXCURSION_TO_MINIMUM(x) (x & 0x4) | ||
189 | |||
190 | /* IA32_HWP_INTERRUPT */ | ||
191 | #define HWP_CHANGE_TO_GUARANTEED_INT(x) (x & 0x1) | ||
192 | #define HWP_EXCURSION_TO_MINIMUM_INT(x) (x & 0x2) | ||
193 | |||
155 | #define MSR_AMD64_MC0_MASK 0xc0010044 | 194 | #define MSR_AMD64_MC0_MASK 0xc0010044 |
156 | 195 | ||
157 | #define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x)) | 196 | #define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x)) |
@@ -345,6 +384,8 @@ | |||
345 | 384 | ||
346 | #define MSR_IA32_TEMPERATURE_TARGET 0x000001a2 | 385 | #define MSR_IA32_TEMPERATURE_TARGET 0x000001a2 |
347 | 386 | ||
387 | #define MSR_MISC_PWR_MGMT 0x000001aa | ||
388 | |||
348 | #define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0 | 389 | #define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0 |
349 | #define ENERGY_PERF_BIAS_PERFORMANCE 0 | 390 | #define ENERGY_PERF_BIAS_PERFORMANCE 0 |
350 | #define ENERGY_PERF_BIAS_NORMAL 6 | 391 | #define ENERGY_PERF_BIAS_NORMAL 6 |
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index 4a8013d55947..60639093d536 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c | |||
@@ -36,6 +36,11 @@ void init_scattered_cpuid_features(struct cpuinfo_x86 *c) | |||
36 | { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, | 36 | { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, |
37 | { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, | 37 | { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, |
38 | { X86_FEATURE_PTS, CR_EAX, 6, 0x00000006, 0 }, | 38 | { X86_FEATURE_PTS, CR_EAX, 6, 0x00000006, 0 }, |
39 | { X86_FEATURE_HWP, CR_EAX, 7, 0x00000006, 0 }, | ||
40 | { X86_FEATURE_HWP_NOITFY, CR_EAX, 8, 0x00000006, 0 }, | ||
41 | { X86_FEATURE_HWP_ACT_WINDOW, CR_EAX, 9, 0x00000006, 0 }, | ||
42 | { X86_FEATURE_HWP_EPP, CR_EAX,10, 0x00000006, 0 }, | ||
43 | { X86_FEATURE_HWP_PKG_REQ, CR_EAX,11, 0x00000006, 0 }, | ||
39 | { X86_FEATURE_APERFMPERF, CR_ECX, 0, 0x00000006, 0 }, | 44 | { X86_FEATURE_APERFMPERF, CR_ECX, 0, 0x00000006, 0 }, |
40 | { X86_FEATURE_EPB, CR_ECX, 3, 0x00000006, 0 }, | 45 | { X86_FEATURE_EPB, CR_ECX, 3, 0x00000006, 0 }, |
41 | { X86_FEATURE_HW_PSTATE, CR_EDX, 7, 0x80000007, 0 }, | 46 | { X86_FEATURE_HW_PSTATE, CR_EDX, 7, 0x80000007, 0 }, |
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 3489f8f5fada..29b2ef5a68b9 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig | |||
@@ -63,7 +63,6 @@ config CPU_FREQ_DEFAULT_GOV_PERFORMANCE | |||
63 | 63 | ||
64 | config CPU_FREQ_DEFAULT_GOV_POWERSAVE | 64 | config CPU_FREQ_DEFAULT_GOV_POWERSAVE |
65 | bool "powersave" | 65 | bool "powersave" |
66 | depends on EXPERT | ||
67 | select CPU_FREQ_GOV_POWERSAVE | 66 | select CPU_FREQ_GOV_POWERSAVE |
68 | help | 67 | help |
69 | Use the CPUFreq governor 'powersave' as default. This sets | 68 | Use the CPUFreq governor 'powersave' as default. This sets |
@@ -183,6 +182,8 @@ config CPU_FREQ_GOV_CONSERVATIVE | |||
183 | 182 | ||
184 | If in doubt, say N. | 183 | If in doubt, say N. |
185 | 184 | ||
185 | comment "CPU frequency scaling drivers" | ||
186 | |||
186 | config CPUFREQ_DT | 187 | config CPUFREQ_DT |
187 | tristate "Generic DT based cpufreq driver" | 188 | tristate "Generic DT based cpufreq driver" |
188 | depends on HAVE_CLK && OF | 189 | depends on HAVE_CLK && OF |
@@ -196,19 +197,19 @@ config CPUFREQ_DT | |||
196 | 197 | ||
197 | If in doubt, say N. | 198 | If in doubt, say N. |
198 | 199 | ||
199 | menu "x86 CPU frequency scaling drivers" | 200 | if X86 |
200 | depends on X86 | ||
201 | source "drivers/cpufreq/Kconfig.x86" | 201 | source "drivers/cpufreq/Kconfig.x86" |
202 | endmenu | 202 | endif |
203 | 203 | ||
204 | menu "ARM CPU frequency scaling drivers" | 204 | if ARM || ARM64 |
205 | depends on ARM || ARM64 | ||
206 | source "drivers/cpufreq/Kconfig.arm" | 205 | source "drivers/cpufreq/Kconfig.arm" |
207 | endmenu | 206 | endif |
208 | 207 | ||
209 | menu "AVR32 CPU frequency scaling drivers" | 208 | if PPC32 || PPC64 |
210 | depends on AVR32 | 209 | source "drivers/cpufreq/Kconfig.powerpc" |
210 | endif | ||
211 | 211 | ||
212 | if AVR32 | ||
212 | config AVR32_AT32AP_CPUFREQ | 213 | config AVR32_AT32AP_CPUFREQ |
213 | bool "CPU frequency driver for AT32AP" | 214 | bool "CPU frequency driver for AT32AP" |
214 | depends on PLATFORM_AT32AP | 215 | depends on PLATFORM_AT32AP |
@@ -216,12 +217,9 @@ config AVR32_AT32AP_CPUFREQ | |||
216 | help | 217 | help |
217 | This enables the CPU frequency driver for AT32AP processors. | 218 | This enables the CPU frequency driver for AT32AP processors. |
218 | If in doubt, say N. | 219 | If in doubt, say N. |
220 | endif | ||
219 | 221 | ||
220 | endmenu | 222 | if IA64 |
221 | |||
222 | menu "CPUFreq processor drivers" | ||
223 | depends on IA64 | ||
224 | |||
225 | config IA64_ACPI_CPUFREQ | 223 | config IA64_ACPI_CPUFREQ |
226 | tristate "ACPI Processor P-States driver" | 224 | tristate "ACPI Processor P-States driver" |
227 | depends on ACPI_PROCESSOR | 225 | depends on ACPI_PROCESSOR |
@@ -232,12 +230,9 @@ config IA64_ACPI_CPUFREQ | |||
232 | For details, take a look at <file:Documentation/cpu-freq/>. | 230 | For details, take a look at <file:Documentation/cpu-freq/>. |
233 | 231 | ||
234 | If in doubt, say N. | 232 | If in doubt, say N. |
233 | endif | ||
235 | 234 | ||
236 | endmenu | 235 | if MIPS |
237 | |||
238 | menu "MIPS CPUFreq processor drivers" | ||
239 | depends on MIPS | ||
240 | |||
241 | config LOONGSON2_CPUFREQ | 236 | config LOONGSON2_CPUFREQ |
242 | tristate "Loongson2 CPUFreq Driver" | 237 | tristate "Loongson2 CPUFreq Driver" |
243 | help | 238 | help |
@@ -250,15 +245,18 @@ config LOONGSON2_CPUFREQ | |||
250 | 245 | ||
251 | If in doubt, say N. | 246 | If in doubt, say N. |
252 | 247 | ||
253 | endmenu | 248 | config LOONGSON1_CPUFREQ |
249 | tristate "Loongson1 CPUFreq Driver" | ||
250 | help | ||
251 | This option adds a CPUFreq driver for loongson1 processors which | ||
252 | support software configurable cpu frequency. | ||
254 | 253 | ||
255 | menu "PowerPC CPU frequency scaling drivers" | 254 | For details, take a look at <file:Documentation/cpu-freq/>. |
256 | depends on PPC32 || PPC64 | ||
257 | source "drivers/cpufreq/Kconfig.powerpc" | ||
258 | endmenu | ||
259 | 255 | ||
260 | menu "SPARC CPU frequency scaling drivers" | 256 | If in doubt, say N. |
261 | depends on SPARC64 | 257 | endif |
258 | |||
259 | if SPARC64 | ||
262 | config SPARC_US3_CPUFREQ | 260 | config SPARC_US3_CPUFREQ |
263 | tristate "UltraSPARC-III CPU Frequency driver" | 261 | tristate "UltraSPARC-III CPU Frequency driver" |
264 | help | 262 | help |
@@ -276,10 +274,9 @@ config SPARC_US2E_CPUFREQ | |||
276 | For details, take a look at <file:Documentation/cpu-freq>. | 274 | For details, take a look at <file:Documentation/cpu-freq>. |
277 | 275 | ||
278 | If in doubt, say N. | 276 | If in doubt, say N. |
279 | endmenu | 277 | endif |
280 | 278 | ||
281 | menu "SH CPU Frequency scaling" | 279 | if SUPERH |
282 | depends on SUPERH | ||
283 | config SH_CPU_FREQ | 280 | config SH_CPU_FREQ |
284 | tristate "SuperH CPU Frequency driver" | 281 | tristate "SuperH CPU Frequency driver" |
285 | help | 282 | help |
@@ -293,7 +290,7 @@ config SH_CPU_FREQ | |||
293 | For details, take a look at <file:Documentation/cpu-freq>. | 290 | For details, take a look at <file:Documentation/cpu-freq>. |
294 | 291 | ||
295 | If unsure, say N. | 292 | If unsure, say N. |
296 | endmenu | 293 | endif |
297 | 294 | ||
298 | endif | 295 | endif |
299 | endmenu | 296 | endmenu |
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index 83a75dc84761..0f9a2c3c0e0d 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm | |||
@@ -247,3 +247,11 @@ config ARM_TEGRA_CPUFREQ | |||
247 | default y | 247 | default y |
248 | help | 248 | help |
249 | This adds the CPUFreq driver support for TEGRA SOCs. | 249 | This adds the CPUFreq driver support for TEGRA SOCs. |
250 | |||
251 | config ARM_PXA2xx_CPUFREQ | ||
252 | tristate "Intel PXA2xx CPUfreq driver" | ||
253 | depends on PXA27x || PXA25x | ||
254 | help | ||
255 | This add the CPUFreq driver support for Intel PXA2xx SOCs. | ||
256 | |||
257 | If in doubt, say N. | ||
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 40c53dc1937e..b3ca7b0b2c33 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile | |||
@@ -61,8 +61,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o | |||
61 | obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o | 61 | obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o |
62 | obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o | 62 | obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o |
63 | obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o | 63 | obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o |
64 | obj-$(CONFIG_PXA25x) += pxa2xx-cpufreq.o | 64 | obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o |
65 | obj-$(CONFIG_PXA27x) += pxa2xx-cpufreq.o | ||
66 | obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o | 65 | obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o |
67 | obj-$(CONFIG_ARM_S3C24XX_CPUFREQ) += s3c24xx-cpufreq.o | 66 | obj-$(CONFIG_ARM_S3C24XX_CPUFREQ) += s3c24xx-cpufreq.o |
68 | obj-$(CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS) += s3c24xx-cpufreq-debugfs.o | 67 | obj-$(CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS) += s3c24xx-cpufreq-debugfs.o |
@@ -98,6 +97,7 @@ obj-$(CONFIG_CRIS_MACH_ARTPEC3) += cris-artpec3-cpufreq.o | |||
98 | obj-$(CONFIG_ETRAXFS) += cris-etraxfs-cpufreq.o | 97 | obj-$(CONFIG_ETRAXFS) += cris-etraxfs-cpufreq.o |
99 | obj-$(CONFIG_IA64_ACPI_CPUFREQ) += ia64-acpi-cpufreq.o | 98 | obj-$(CONFIG_IA64_ACPI_CPUFREQ) += ia64-acpi-cpufreq.o |
100 | obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o | 99 | obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o |
100 | obj-$(CONFIG_LOONGSON1_CPUFREQ) += ls1x-cpufreq.o | ||
101 | obj-$(CONFIG_SH_CPU_FREQ) += sh-cpufreq.o | 101 | obj-$(CONFIG_SH_CPU_FREQ) += sh-cpufreq.o |
102 | obj-$(CONFIG_SPARC_US2E_CPUFREQ) += sparc-us2e-cpufreq.o | 102 | obj-$(CONFIG_SPARC_US2E_CPUFREQ) += sparc-us2e-cpufreq.o |
103 | obj-$(CONFIG_SPARC_US3_CPUFREQ) += sparc-us3-cpufreq.o | 103 | obj-$(CONFIG_SPARC_US3_CPUFREQ) += sparc-us3-cpufreq.o |
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index f657c571b18e..e720954244b1 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c | |||
@@ -58,6 +58,8 @@ static int set_target(struct cpufreq_policy *policy, unsigned int index) | |||
58 | old_freq = clk_get_rate(cpu_clk) / 1000; | 58 | old_freq = clk_get_rate(cpu_clk) / 1000; |
59 | 59 | ||
60 | if (!IS_ERR(cpu_reg)) { | 60 | if (!IS_ERR(cpu_reg)) { |
61 | unsigned long opp_freq; | ||
62 | |||
61 | rcu_read_lock(); | 63 | rcu_read_lock(); |
62 | opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_Hz); | 64 | opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_Hz); |
63 | if (IS_ERR(opp)) { | 65 | if (IS_ERR(opp)) { |
@@ -67,13 +69,16 @@ static int set_target(struct cpufreq_policy *policy, unsigned int index) | |||
67 | return PTR_ERR(opp); | 69 | return PTR_ERR(opp); |
68 | } | 70 | } |
69 | volt = dev_pm_opp_get_voltage(opp); | 71 | volt = dev_pm_opp_get_voltage(opp); |
72 | opp_freq = dev_pm_opp_get_freq(opp); | ||
70 | rcu_read_unlock(); | 73 | rcu_read_unlock(); |
71 | tol = volt * priv->voltage_tolerance / 100; | 74 | tol = volt * priv->voltage_tolerance / 100; |
72 | volt_old = regulator_get_voltage(cpu_reg); | 75 | volt_old = regulator_get_voltage(cpu_reg); |
76 | dev_dbg(cpu_dev, "Found OPP: %ld kHz, %ld uV\n", | ||
77 | opp_freq / 1000, volt); | ||
73 | } | 78 | } |
74 | 79 | ||
75 | dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n", | 80 | dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n", |
76 | old_freq / 1000, volt_old ? volt_old / 1000 : -1, | 81 | old_freq / 1000, (volt_old > 0) ? volt_old / 1000 : -1, |
77 | new_freq / 1000, volt ? volt / 1000 : -1); | 82 | new_freq / 1000, volt ? volt / 1000 : -1); |
78 | 83 | ||
79 | /* scaling up? scale voltage before frequency */ | 84 | /* scaling up? scale voltage before frequency */ |
@@ -89,7 +94,7 @@ static int set_target(struct cpufreq_policy *policy, unsigned int index) | |||
89 | ret = clk_set_rate(cpu_clk, freq_exact); | 94 | ret = clk_set_rate(cpu_clk, freq_exact); |
90 | if (ret) { | 95 | if (ret) { |
91 | dev_err(cpu_dev, "failed to set clock rate: %d\n", ret); | 96 | dev_err(cpu_dev, "failed to set clock rate: %d\n", ret); |
92 | if (!IS_ERR(cpu_reg)) | 97 | if (!IS_ERR(cpu_reg) && volt_old > 0) |
93 | regulator_set_voltage_tol(cpu_reg, volt_old, tol); | 98 | regulator_set_voltage_tol(cpu_reg, volt_old, tol); |
94 | return ret; | 99 | return ret; |
95 | } | 100 | } |
@@ -181,7 +186,6 @@ static int cpufreq_init(struct cpufreq_policy *policy) | |||
181 | { | 186 | { |
182 | struct cpufreq_dt_platform_data *pd; | 187 | struct cpufreq_dt_platform_data *pd; |
183 | struct cpufreq_frequency_table *freq_table; | 188 | struct cpufreq_frequency_table *freq_table; |
184 | struct thermal_cooling_device *cdev; | ||
185 | struct device_node *np; | 189 | struct device_node *np; |
186 | struct private_data *priv; | 190 | struct private_data *priv; |
187 | struct device *cpu_dev; | 191 | struct device *cpu_dev; |
@@ -264,20 +268,6 @@ static int cpufreq_init(struct cpufreq_policy *policy) | |||
264 | goto out_free_priv; | 268 | goto out_free_priv; |
265 | } | 269 | } |
266 | 270 | ||
267 | /* | ||
268 | * For now, just loading the cooling device; | ||
269 | * thermal DT code takes care of matching them. | ||
270 | */ | ||
271 | if (of_find_property(np, "#cooling-cells", NULL)) { | ||
272 | cdev = of_cpufreq_cooling_register(np, cpu_present_mask); | ||
273 | if (IS_ERR(cdev)) | ||
274 | dev_err(cpu_dev, | ||
275 | "running cpufreq without cooling device: %ld\n", | ||
276 | PTR_ERR(cdev)); | ||
277 | else | ||
278 | priv->cdev = cdev; | ||
279 | } | ||
280 | |||
281 | priv->cpu_dev = cpu_dev; | 271 | priv->cpu_dev = cpu_dev; |
282 | priv->cpu_reg = cpu_reg; | 272 | priv->cpu_reg = cpu_reg; |
283 | policy->driver_data = priv; | 273 | policy->driver_data = priv; |
@@ -287,7 +277,7 @@ static int cpufreq_init(struct cpufreq_policy *policy) | |||
287 | if (ret) { | 277 | if (ret) { |
288 | dev_err(cpu_dev, "%s: invalid frequency table: %d\n", __func__, | 278 | dev_err(cpu_dev, "%s: invalid frequency table: %d\n", __func__, |
289 | ret); | 279 | ret); |
290 | goto out_cooling_unregister; | 280 | goto out_free_cpufreq_table; |
291 | } | 281 | } |
292 | 282 | ||
293 | policy->cpuinfo.transition_latency = transition_latency; | 283 | policy->cpuinfo.transition_latency = transition_latency; |
@@ -300,8 +290,7 @@ static int cpufreq_init(struct cpufreq_policy *policy) | |||
300 | 290 | ||
301 | return 0; | 291 | return 0; |
302 | 292 | ||
303 | out_cooling_unregister: | 293 | out_free_cpufreq_table: |
304 | cpufreq_cooling_unregister(priv->cdev); | ||
305 | dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); | 294 | dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); |
306 | out_free_priv: | 295 | out_free_priv: |
307 | kfree(priv); | 296 | kfree(priv); |
@@ -319,7 +308,8 @@ static int cpufreq_exit(struct cpufreq_policy *policy) | |||
319 | { | 308 | { |
320 | struct private_data *priv = policy->driver_data; | 309 | struct private_data *priv = policy->driver_data; |
321 | 310 | ||
322 | cpufreq_cooling_unregister(priv->cdev); | 311 | if (priv->cdev) |
312 | cpufreq_cooling_unregister(priv->cdev); | ||
323 | dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); | 313 | dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); |
324 | clk_put(policy->clk); | 314 | clk_put(policy->clk); |
325 | if (!IS_ERR(priv->cpu_reg)) | 315 | if (!IS_ERR(priv->cpu_reg)) |
@@ -329,6 +319,33 @@ static int cpufreq_exit(struct cpufreq_policy *policy) | |||
329 | return 0; | 319 | return 0; |
330 | } | 320 | } |
331 | 321 | ||
322 | static void cpufreq_ready(struct cpufreq_policy *policy) | ||
323 | { | ||
324 | struct private_data *priv = policy->driver_data; | ||
325 | struct device_node *np = of_node_get(priv->cpu_dev->of_node); | ||
326 | |||
327 | if (WARN_ON(!np)) | ||
328 | return; | ||
329 | |||
330 | /* | ||
331 | * For now, just loading the cooling device; | ||
332 | * thermal DT code takes care of matching them. | ||
333 | */ | ||
334 | if (of_find_property(np, "#cooling-cells", NULL)) { | ||
335 | priv->cdev = of_cpufreq_cooling_register(np, | ||
336 | policy->related_cpus); | ||
337 | if (IS_ERR(priv->cdev)) { | ||
338 | dev_err(priv->cpu_dev, | ||
339 | "running cpufreq without cooling device: %ld\n", | ||
340 | PTR_ERR(priv->cdev)); | ||
341 | |||
342 | priv->cdev = NULL; | ||
343 | } | ||
344 | } | ||
345 | |||
346 | of_node_put(np); | ||
347 | } | ||
348 | |||
332 | static struct cpufreq_driver dt_cpufreq_driver = { | 349 | static struct cpufreq_driver dt_cpufreq_driver = { |
333 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | 350 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
334 | .verify = cpufreq_generic_frequency_table_verify, | 351 | .verify = cpufreq_generic_frequency_table_verify, |
@@ -336,6 +353,7 @@ static struct cpufreq_driver dt_cpufreq_driver = { | |||
336 | .get = cpufreq_generic_get, | 353 | .get = cpufreq_generic_get, |
337 | .init = cpufreq_init, | 354 | .init = cpufreq_init, |
338 | .exit = cpufreq_exit, | 355 | .exit = cpufreq_exit, |
356 | .ready = cpufreq_ready, | ||
339 | .name = "cpufreq-dt", | 357 | .name = "cpufreq-dt", |
340 | .attr = cpufreq_generic_attr, | 358 | .attr = cpufreq_generic_attr, |
341 | }; | 359 | }; |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 4473eba1d6b0..a09a29c312a9 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -535,7 +535,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, | |||
535 | static ssize_t store_##file_name \ | 535 | static ssize_t store_##file_name \ |
536 | (struct cpufreq_policy *policy, const char *buf, size_t count) \ | 536 | (struct cpufreq_policy *policy, const char *buf, size_t count) \ |
537 | { \ | 537 | { \ |
538 | int ret; \ | 538 | int ret, temp; \ |
539 | struct cpufreq_policy new_policy; \ | 539 | struct cpufreq_policy new_policy; \ |
540 | \ | 540 | \ |
541 | ret = cpufreq_get_policy(&new_policy, policy->cpu); \ | 541 | ret = cpufreq_get_policy(&new_policy, policy->cpu); \ |
@@ -546,8 +546,10 @@ static ssize_t store_##file_name \ | |||
546 | if (ret != 1) \ | 546 | if (ret != 1) \ |
547 | return -EINVAL; \ | 547 | return -EINVAL; \ |
548 | \ | 548 | \ |
549 | temp = new_policy.object; \ | ||
549 | ret = cpufreq_set_policy(policy, &new_policy); \ | 550 | ret = cpufreq_set_policy(policy, &new_policy); \ |
550 | policy->user_policy.object = policy->object; \ | 551 | if (!ret) \ |
552 | policy->user_policy.object = temp; \ | ||
551 | \ | 553 | \ |
552 | return ret ? ret : count; \ | 554 | return ret ? ret : count; \ |
553 | } | 555 | } |
@@ -898,46 +900,31 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy, | |||
898 | struct freq_attr **drv_attr; | 900 | struct freq_attr **drv_attr; |
899 | int ret = 0; | 901 | int ret = 0; |
900 | 902 | ||
901 | /* prepare interface data */ | ||
902 | ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, | ||
903 | &dev->kobj, "cpufreq"); | ||
904 | if (ret) | ||
905 | return ret; | ||
906 | |||
907 | /* set up files for this cpu device */ | 903 | /* set up files for this cpu device */ |
908 | drv_attr = cpufreq_driver->attr; | 904 | drv_attr = cpufreq_driver->attr; |
909 | while ((drv_attr) && (*drv_attr)) { | 905 | while ((drv_attr) && (*drv_attr)) { |
910 | ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); | 906 | ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); |
911 | if (ret) | 907 | if (ret) |
912 | goto err_out_kobj_put; | 908 | return ret; |
913 | drv_attr++; | 909 | drv_attr++; |
914 | } | 910 | } |
915 | if (cpufreq_driver->get) { | 911 | if (cpufreq_driver->get) { |
916 | ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); | 912 | ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); |
917 | if (ret) | 913 | if (ret) |
918 | goto err_out_kobj_put; | 914 | return ret; |
919 | } | 915 | } |
920 | 916 | ||
921 | ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); | 917 | ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); |
922 | if (ret) | 918 | if (ret) |
923 | goto err_out_kobj_put; | 919 | return ret; |
924 | 920 | ||
925 | if (cpufreq_driver->bios_limit) { | 921 | if (cpufreq_driver->bios_limit) { |
926 | ret = sysfs_create_file(&policy->kobj, &bios_limit.attr); | 922 | ret = sysfs_create_file(&policy->kobj, &bios_limit.attr); |
927 | if (ret) | 923 | if (ret) |
928 | goto err_out_kobj_put; | 924 | return ret; |
929 | } | 925 | } |
930 | 926 | ||
931 | ret = cpufreq_add_dev_symlink(policy); | 927 | return cpufreq_add_dev_symlink(policy); |
932 | if (ret) | ||
933 | goto err_out_kobj_put; | ||
934 | |||
935 | return ret; | ||
936 | |||
937 | err_out_kobj_put: | ||
938 | kobject_put(&policy->kobj); | ||
939 | wait_for_completion(&policy->kobj_unregister); | ||
940 | return ret; | ||
941 | } | 928 | } |
942 | 929 | ||
943 | static void cpufreq_init_policy(struct cpufreq_policy *policy) | 930 | static void cpufreq_init_policy(struct cpufreq_policy *policy) |
@@ -1196,6 +1183,8 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
1196 | goto err_set_policy_cpu; | 1183 | goto err_set_policy_cpu; |
1197 | } | 1184 | } |
1198 | 1185 | ||
1186 | down_write(&policy->rwsem); | ||
1187 | |||
1199 | /* related cpus should atleast have policy->cpus */ | 1188 | /* related cpus should atleast have policy->cpus */ |
1200 | cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); | 1189 | cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); |
1201 | 1190 | ||
@@ -1208,9 +1197,17 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
1208 | if (!recover_policy) { | 1197 | if (!recover_policy) { |
1209 | policy->user_policy.min = policy->min; | 1198 | policy->user_policy.min = policy->min; |
1210 | policy->user_policy.max = policy->max; | 1199 | policy->user_policy.max = policy->max; |
1200 | |||
1201 | /* prepare interface data */ | ||
1202 | ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, | ||
1203 | &dev->kobj, "cpufreq"); | ||
1204 | if (ret) { | ||
1205 | pr_err("%s: failed to init policy->kobj: %d\n", | ||
1206 | __func__, ret); | ||
1207 | goto err_init_policy_kobj; | ||
1208 | } | ||
1211 | } | 1209 | } |
1212 | 1210 | ||
1213 | down_write(&policy->rwsem); | ||
1214 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 1211 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
1215 | for_each_cpu(j, policy->cpus) | 1212 | for_each_cpu(j, policy->cpus) |
1216 | per_cpu(cpufreq_cpu_data, j) = policy; | 1213 | per_cpu(cpufreq_cpu_data, j) = policy; |
@@ -1288,8 +1285,13 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) | |||
1288 | up_write(&policy->rwsem); | 1285 | up_write(&policy->rwsem); |
1289 | 1286 | ||
1290 | kobject_uevent(&policy->kobj, KOBJ_ADD); | 1287 | kobject_uevent(&policy->kobj, KOBJ_ADD); |
1288 | |||
1291 | up_read(&cpufreq_rwsem); | 1289 | up_read(&cpufreq_rwsem); |
1292 | 1290 | ||
1291 | /* Callback for handling stuff after policy is ready */ | ||
1292 | if (cpufreq_driver->ready) | ||
1293 | cpufreq_driver->ready(policy); | ||
1294 | |||
1293 | pr_debug("initialization complete\n"); | 1295 | pr_debug("initialization complete\n"); |
1294 | 1296 | ||
1295 | return 0; | 1297 | return 0; |
@@ -1301,6 +1303,11 @@ err_get_freq: | |||
1301 | per_cpu(cpufreq_cpu_data, j) = NULL; | 1303 | per_cpu(cpufreq_cpu_data, j) = NULL; |
1302 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1304 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1303 | 1305 | ||
1306 | if (!recover_policy) { | ||
1307 | kobject_put(&policy->kobj); | ||
1308 | wait_for_completion(&policy->kobj_unregister); | ||
1309 | } | ||
1310 | err_init_policy_kobj: | ||
1304 | up_write(&policy->rwsem); | 1311 | up_write(&policy->rwsem); |
1305 | 1312 | ||
1306 | if (cpufreq_driver->exit) | 1313 | if (cpufreq_driver->exit) |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 27bb6d3877ed..ab2e100a1807 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -137,6 +137,7 @@ struct cpu_defaults { | |||
137 | 137 | ||
138 | static struct pstate_adjust_policy pid_params; | 138 | static struct pstate_adjust_policy pid_params; |
139 | static struct pstate_funcs pstate_funcs; | 139 | static struct pstate_funcs pstate_funcs; |
140 | static int hwp_active; | ||
140 | 141 | ||
141 | struct perf_limits { | 142 | struct perf_limits { |
142 | int no_turbo; | 143 | int no_turbo; |
@@ -244,6 +245,34 @@ static inline void update_turbo_state(void) | |||
244 | cpu->pstate.max_pstate == cpu->pstate.turbo_pstate); | 245 | cpu->pstate.max_pstate == cpu->pstate.turbo_pstate); |
245 | } | 246 | } |
246 | 247 | ||
248 | #define PCT_TO_HWP(x) (x * 255 / 100) | ||
249 | static void intel_pstate_hwp_set(void) | ||
250 | { | ||
251 | int min, max, cpu; | ||
252 | u64 value, freq; | ||
253 | |||
254 | get_online_cpus(); | ||
255 | |||
256 | for_each_online_cpu(cpu) { | ||
257 | rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value); | ||
258 | min = PCT_TO_HWP(limits.min_perf_pct); | ||
259 | value &= ~HWP_MIN_PERF(~0L); | ||
260 | value |= HWP_MIN_PERF(min); | ||
261 | |||
262 | max = PCT_TO_HWP(limits.max_perf_pct); | ||
263 | if (limits.no_turbo) { | ||
264 | rdmsrl( MSR_HWP_CAPABILITIES, freq); | ||
265 | max = HWP_GUARANTEED_PERF(freq); | ||
266 | } | ||
267 | |||
268 | value &= ~HWP_MAX_PERF(~0L); | ||
269 | value |= HWP_MAX_PERF(max); | ||
270 | wrmsrl_on_cpu(cpu, MSR_HWP_REQUEST, value); | ||
271 | } | ||
272 | |||
273 | put_online_cpus(); | ||
274 | } | ||
275 | |||
247 | /************************** debugfs begin ************************/ | 276 | /************************** debugfs begin ************************/ |
248 | static int pid_param_set(void *data, u64 val) | 277 | static int pid_param_set(void *data, u64 val) |
249 | { | 278 | { |
@@ -279,6 +308,8 @@ static void __init intel_pstate_debug_expose_params(void) | |||
279 | struct dentry *debugfs_parent; | 308 | struct dentry *debugfs_parent; |
280 | int i = 0; | 309 | int i = 0; |
281 | 310 | ||
311 | if (hwp_active) | ||
312 | return; | ||
282 | debugfs_parent = debugfs_create_dir("pstate_snb", NULL); | 313 | debugfs_parent = debugfs_create_dir("pstate_snb", NULL); |
283 | if (IS_ERR_OR_NULL(debugfs_parent)) | 314 | if (IS_ERR_OR_NULL(debugfs_parent)) |
284 | return; | 315 | return; |
@@ -329,8 +360,12 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b, | |||
329 | pr_warn("Turbo disabled by BIOS or unavailable on processor\n"); | 360 | pr_warn("Turbo disabled by BIOS or unavailable on processor\n"); |
330 | return -EPERM; | 361 | return -EPERM; |
331 | } | 362 | } |
363 | |||
332 | limits.no_turbo = clamp_t(int, input, 0, 1); | 364 | limits.no_turbo = clamp_t(int, input, 0, 1); |
333 | 365 | ||
366 | if (hwp_active) | ||
367 | intel_pstate_hwp_set(); | ||
368 | |||
334 | return count; | 369 | return count; |
335 | } | 370 | } |
336 | 371 | ||
@@ -348,6 +383,8 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b, | |||
348 | limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct); | 383 | limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct); |
349 | limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100)); | 384 | limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100)); |
350 | 385 | ||
386 | if (hwp_active) | ||
387 | intel_pstate_hwp_set(); | ||
351 | return count; | 388 | return count; |
352 | } | 389 | } |
353 | 390 | ||
@@ -363,6 +400,8 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b, | |||
363 | limits.min_perf_pct = clamp_t(int, input, 0 , 100); | 400 | limits.min_perf_pct = clamp_t(int, input, 0 , 100); |
364 | limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); | 401 | limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); |
365 | 402 | ||
403 | if (hwp_active) | ||
404 | intel_pstate_hwp_set(); | ||
366 | return count; | 405 | return count; |
367 | } | 406 | } |
368 | 407 | ||
@@ -395,8 +434,16 @@ static void __init intel_pstate_sysfs_expose_params(void) | |||
395 | rc = sysfs_create_group(intel_pstate_kobject, &intel_pstate_attr_group); | 434 | rc = sysfs_create_group(intel_pstate_kobject, &intel_pstate_attr_group); |
396 | BUG_ON(rc); | 435 | BUG_ON(rc); |
397 | } | 436 | } |
398 | |||
399 | /************************** sysfs end ************************/ | 437 | /************************** sysfs end ************************/ |
438 | |||
439 | static void intel_pstate_hwp_enable(void) | ||
440 | { | ||
441 | hwp_active++; | ||
442 | pr_info("intel_pstate HWP enabled\n"); | ||
443 | |||
444 | wrmsrl( MSR_PM_ENABLE, 0x1); | ||
445 | } | ||
446 | |||
400 | static int byt_get_min_pstate(void) | 447 | static int byt_get_min_pstate(void) |
401 | { | 448 | { |
402 | u64 value; | 449 | u64 value; |
@@ -648,6 +695,14 @@ static inline void intel_pstate_sample(struct cpudata *cpu) | |||
648 | cpu->prev_mperf = mperf; | 695 | cpu->prev_mperf = mperf; |
649 | } | 696 | } |
650 | 697 | ||
698 | static inline void intel_hwp_set_sample_time(struct cpudata *cpu) | ||
699 | { | ||
700 | int delay; | ||
701 | |||
702 | delay = msecs_to_jiffies(50); | ||
703 | mod_timer_pinned(&cpu->timer, jiffies + delay); | ||
704 | } | ||
705 | |||
651 | static inline void intel_pstate_set_sample_time(struct cpudata *cpu) | 706 | static inline void intel_pstate_set_sample_time(struct cpudata *cpu) |
652 | { | 707 | { |
653 | int delay; | 708 | int delay; |
@@ -694,6 +749,14 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) | |||
694 | intel_pstate_set_pstate(cpu, cpu->pstate.current_pstate - ctl); | 749 | intel_pstate_set_pstate(cpu, cpu->pstate.current_pstate - ctl); |
695 | } | 750 | } |
696 | 751 | ||
752 | static void intel_hwp_timer_func(unsigned long __data) | ||
753 | { | ||
754 | struct cpudata *cpu = (struct cpudata *) __data; | ||
755 | |||
756 | intel_pstate_sample(cpu); | ||
757 | intel_hwp_set_sample_time(cpu); | ||
758 | } | ||
759 | |||
697 | static void intel_pstate_timer_func(unsigned long __data) | 760 | static void intel_pstate_timer_func(unsigned long __data) |
698 | { | 761 | { |
699 | struct cpudata *cpu = (struct cpudata *) __data; | 762 | struct cpudata *cpu = (struct cpudata *) __data; |
@@ -730,6 +793,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { | |||
730 | ICPU(0x3f, core_params), | 793 | ICPU(0x3f, core_params), |
731 | ICPU(0x45, core_params), | 794 | ICPU(0x45, core_params), |
732 | ICPU(0x46, core_params), | 795 | ICPU(0x46, core_params), |
796 | ICPU(0x47, core_params), | ||
733 | ICPU(0x4c, byt_params), | 797 | ICPU(0x4c, byt_params), |
734 | ICPU(0x4f, core_params), | 798 | ICPU(0x4f, core_params), |
735 | ICPU(0x56, core_params), | 799 | ICPU(0x56, core_params), |
@@ -737,6 +801,11 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = { | |||
737 | }; | 801 | }; |
738 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); | 802 | MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids); |
739 | 803 | ||
804 | static const struct x86_cpu_id intel_pstate_cpu_oob_ids[] = { | ||
805 | ICPU(0x56, core_params), | ||
806 | {} | ||
807 | }; | ||
808 | |||
740 | static int intel_pstate_init_cpu(unsigned int cpunum) | 809 | static int intel_pstate_init_cpu(unsigned int cpunum) |
741 | { | 810 | { |
742 | struct cpudata *cpu; | 811 | struct cpudata *cpu; |
@@ -753,9 +822,14 @@ static int intel_pstate_init_cpu(unsigned int cpunum) | |||
753 | intel_pstate_get_cpu_pstates(cpu); | 822 | intel_pstate_get_cpu_pstates(cpu); |
754 | 823 | ||
755 | init_timer_deferrable(&cpu->timer); | 824 | init_timer_deferrable(&cpu->timer); |
756 | cpu->timer.function = intel_pstate_timer_func; | ||
757 | cpu->timer.data = (unsigned long)cpu; | 825 | cpu->timer.data = (unsigned long)cpu; |
758 | cpu->timer.expires = jiffies + HZ/100; | 826 | cpu->timer.expires = jiffies + HZ/100; |
827 | |||
828 | if (!hwp_active) | ||
829 | cpu->timer.function = intel_pstate_timer_func; | ||
830 | else | ||
831 | cpu->timer.function = intel_hwp_timer_func; | ||
832 | |||
759 | intel_pstate_busy_pid_reset(cpu); | 833 | intel_pstate_busy_pid_reset(cpu); |
760 | intel_pstate_sample(cpu); | 834 | intel_pstate_sample(cpu); |
761 | 835 | ||
@@ -792,6 +866,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) | |||
792 | limits.no_turbo = 0; | 866 | limits.no_turbo = 0; |
793 | return 0; | 867 | return 0; |
794 | } | 868 | } |
869 | |||
795 | limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq; | 870 | limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq; |
796 | limits.min_perf_pct = clamp_t(int, limits.min_perf_pct, 0 , 100); | 871 | limits.min_perf_pct = clamp_t(int, limits.min_perf_pct, 0 , 100); |
797 | limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); | 872 | limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); |
@@ -801,6 +876,9 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) | |||
801 | limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct); | 876 | limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct); |
802 | limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100)); | 877 | limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100)); |
803 | 878 | ||
879 | if (hwp_active) | ||
880 | intel_pstate_hwp_set(); | ||
881 | |||
804 | return 0; | 882 | return 0; |
805 | } | 883 | } |
806 | 884 | ||
@@ -823,6 +901,9 @@ static void intel_pstate_stop_cpu(struct cpufreq_policy *policy) | |||
823 | pr_info("intel_pstate CPU %d exiting\n", cpu_num); | 901 | pr_info("intel_pstate CPU %d exiting\n", cpu_num); |
824 | 902 | ||
825 | del_timer_sync(&all_cpu_data[cpu_num]->timer); | 903 | del_timer_sync(&all_cpu_data[cpu_num]->timer); |
904 | if (hwp_active) | ||
905 | return; | ||
906 | |||
826 | intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate); | 907 | intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate); |
827 | } | 908 | } |
828 | 909 | ||
@@ -866,6 +947,7 @@ static struct cpufreq_driver intel_pstate_driver = { | |||
866 | }; | 947 | }; |
867 | 948 | ||
868 | static int __initdata no_load; | 949 | static int __initdata no_load; |
950 | static int __initdata no_hwp; | ||
869 | 951 | ||
870 | static int intel_pstate_msrs_not_valid(void) | 952 | static int intel_pstate_msrs_not_valid(void) |
871 | { | 953 | { |
@@ -959,6 +1041,15 @@ static bool intel_pstate_platform_pwr_mgmt_exists(void) | |||
959 | { | 1041 | { |
960 | struct acpi_table_header hdr; | 1042 | struct acpi_table_header hdr; |
961 | struct hw_vendor_info *v_info; | 1043 | struct hw_vendor_info *v_info; |
1044 | const struct x86_cpu_id *id; | ||
1045 | u64 misc_pwr; | ||
1046 | |||
1047 | id = x86_match_cpu(intel_pstate_cpu_oob_ids); | ||
1048 | if (id) { | ||
1049 | rdmsrl(MSR_MISC_PWR_MGMT, misc_pwr); | ||
1050 | if ( misc_pwr & (1 << 8)) | ||
1051 | return true; | ||
1052 | } | ||
962 | 1053 | ||
963 | if (acpi_disabled || | 1054 | if (acpi_disabled || |
964 | ACPI_FAILURE(acpi_get_table_header(ACPI_SIG_FADT, 0, &hdr))) | 1055 | ACPI_FAILURE(acpi_get_table_header(ACPI_SIG_FADT, 0, &hdr))) |
@@ -982,6 +1073,7 @@ static int __init intel_pstate_init(void) | |||
982 | int cpu, rc = 0; | 1073 | int cpu, rc = 0; |
983 | const struct x86_cpu_id *id; | 1074 | const struct x86_cpu_id *id; |
984 | struct cpu_defaults *cpu_info; | 1075 | struct cpu_defaults *cpu_info; |
1076 | struct cpuinfo_x86 *c = &boot_cpu_data; | ||
985 | 1077 | ||
986 | if (no_load) | 1078 | if (no_load) |
987 | return -ENODEV; | 1079 | return -ENODEV; |
@@ -1011,6 +1103,9 @@ static int __init intel_pstate_init(void) | |||
1011 | if (!all_cpu_data) | 1103 | if (!all_cpu_data) |
1012 | return -ENOMEM; | 1104 | return -ENOMEM; |
1013 | 1105 | ||
1106 | if (cpu_has(c,X86_FEATURE_HWP) && !no_hwp) | ||
1107 | intel_pstate_hwp_enable(); | ||
1108 | |||
1014 | rc = cpufreq_register_driver(&intel_pstate_driver); | 1109 | rc = cpufreq_register_driver(&intel_pstate_driver); |
1015 | if (rc) | 1110 | if (rc) |
1016 | goto out; | 1111 | goto out; |
@@ -1041,6 +1136,8 @@ static int __init intel_pstate_setup(char *str) | |||
1041 | 1136 | ||
1042 | if (!strcmp(str, "disable")) | 1137 | if (!strcmp(str, "disable")) |
1043 | no_load = 1; | 1138 | no_load = 1; |
1139 | if (!strcmp(str, "no_hwp")) | ||
1140 | no_hwp = 1; | ||
1044 | return 0; | 1141 | return 0; |
1045 | } | 1142 | } |
1046 | early_param("intel_pstate", intel_pstate_setup); | 1143 | early_param("intel_pstate", intel_pstate_setup); |
diff --git a/drivers/cpufreq/ls1x-cpufreq.c b/drivers/cpufreq/ls1x-cpufreq.c new file mode 100644 index 000000000000..25fbd6a1374f --- /dev/null +++ b/drivers/cpufreq/ls1x-cpufreq.c | |||
@@ -0,0 +1,223 @@ | |||
1 | /* | ||
2 | * CPU Frequency Scaling for Loongson 1 SoC | ||
3 | * | ||
4 | * Copyright (C) 2014 Zhang, Keguang <keguang.zhang@gmail.com> | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk.h> | ||
12 | #include <linux/clk-provider.h> | ||
13 | #include <linux/cpu.h> | ||
14 | #include <linux/cpufreq.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/slab.h> | ||
19 | |||
20 | #include <asm/mach-loongson1/cpufreq.h> | ||
21 | #include <asm/mach-loongson1/loongson1.h> | ||
22 | |||
23 | static struct { | ||
24 | struct device *dev; | ||
25 | struct clk *clk; /* CPU clk */ | ||
26 | struct clk *mux_clk; /* MUX of CPU clk */ | ||
27 | struct clk *pll_clk; /* PLL clk */ | ||
28 | struct clk *osc_clk; /* OSC clk */ | ||
29 | unsigned int max_freq; | ||
30 | unsigned int min_freq; | ||
31 | } ls1x_cpufreq; | ||
32 | |||
33 | static int ls1x_cpufreq_notifier(struct notifier_block *nb, | ||
34 | unsigned long val, void *data) | ||
35 | { | ||
36 | if (val == CPUFREQ_POSTCHANGE) | ||
37 | current_cpu_data.udelay_val = loops_per_jiffy; | ||
38 | |||
39 | return NOTIFY_OK; | ||
40 | } | ||
41 | |||
42 | static struct notifier_block ls1x_cpufreq_notifier_block = { | ||
43 | .notifier_call = ls1x_cpufreq_notifier | ||
44 | }; | ||
45 | |||
46 | static int ls1x_cpufreq_target(struct cpufreq_policy *policy, | ||
47 | unsigned int index) | ||
48 | { | ||
49 | unsigned int old_freq, new_freq; | ||
50 | |||
51 | old_freq = policy->cur; | ||
52 | new_freq = policy->freq_table[index].frequency; | ||
53 | |||
54 | /* | ||
55 | * The procedure of reconfiguring CPU clk is as below. | ||
56 | * | ||
57 | * - Reparent CPU clk to OSC clk | ||
58 | * - Reset CPU clock (very important) | ||
59 | * - Reconfigure CPU DIV | ||
60 | * - Reparent CPU clk back to CPU DIV clk | ||
61 | */ | ||
62 | |||
63 | dev_dbg(ls1x_cpufreq.dev, "%u KHz --> %u KHz\n", old_freq, new_freq); | ||
64 | clk_set_parent(policy->clk, ls1x_cpufreq.osc_clk); | ||
65 | __raw_writel(__raw_readl(LS1X_CLK_PLL_DIV) | RST_CPU_EN | RST_CPU, | ||
66 | LS1X_CLK_PLL_DIV); | ||
67 | __raw_writel(__raw_readl(LS1X_CLK_PLL_DIV) & ~(RST_CPU_EN | RST_CPU), | ||
68 | LS1X_CLK_PLL_DIV); | ||
69 | clk_set_rate(ls1x_cpufreq.mux_clk, new_freq * 1000); | ||
70 | clk_set_parent(policy->clk, ls1x_cpufreq.mux_clk); | ||
71 | |||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static int ls1x_cpufreq_init(struct cpufreq_policy *policy) | ||
76 | { | ||
77 | struct cpufreq_frequency_table *freq_tbl; | ||
78 | unsigned int pll_freq, freq; | ||
79 | int steps, i, ret; | ||
80 | |||
81 | pll_freq = clk_get_rate(ls1x_cpufreq.pll_clk) / 1000; | ||
82 | |||
83 | steps = 1 << DIV_CPU_WIDTH; | ||
84 | freq_tbl = kzalloc(sizeof(*freq_tbl) * steps, GFP_KERNEL); | ||
85 | if (!freq_tbl) { | ||
86 | dev_err(ls1x_cpufreq.dev, | ||
87 | "failed to alloc cpufreq_frequency_table\n"); | ||
88 | ret = -ENOMEM; | ||
89 | goto out; | ||
90 | } | ||
91 | |||
92 | for (i = 0; i < (steps - 1); i++) { | ||
93 | freq = pll_freq / (i + 1); | ||
94 | if ((freq < ls1x_cpufreq.min_freq) || | ||
95 | (freq > ls1x_cpufreq.max_freq)) | ||
96 | freq_tbl[i].frequency = CPUFREQ_ENTRY_INVALID; | ||
97 | else | ||
98 | freq_tbl[i].frequency = freq; | ||
99 | dev_dbg(ls1x_cpufreq.dev, | ||
100 | "cpufreq table: index %d: frequency %d\n", i, | ||
101 | freq_tbl[i].frequency); | ||
102 | } | ||
103 | freq_tbl[i].frequency = CPUFREQ_TABLE_END; | ||
104 | |||
105 | policy->clk = ls1x_cpufreq.clk; | ||
106 | ret = cpufreq_generic_init(policy, freq_tbl, 0); | ||
107 | if (ret) | ||
108 | kfree(freq_tbl); | ||
109 | out: | ||
110 | return ret; | ||
111 | } | ||
112 | |||
113 | static int ls1x_cpufreq_exit(struct cpufreq_policy *policy) | ||
114 | { | ||
115 | kfree(policy->freq_table); | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static struct cpufreq_driver ls1x_cpufreq_driver = { | ||
120 | .name = "cpufreq-ls1x", | ||
121 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | ||
122 | .verify = cpufreq_generic_frequency_table_verify, | ||
123 | .target_index = ls1x_cpufreq_target, | ||
124 | .get = cpufreq_generic_get, | ||
125 | .init = ls1x_cpufreq_init, | ||
126 | .exit = ls1x_cpufreq_exit, | ||
127 | .attr = cpufreq_generic_attr, | ||
128 | }; | ||
129 | |||
130 | static int ls1x_cpufreq_remove(struct platform_device *pdev) | ||
131 | { | ||
132 | cpufreq_unregister_notifier(&ls1x_cpufreq_notifier_block, | ||
133 | CPUFREQ_TRANSITION_NOTIFIER); | ||
134 | cpufreq_unregister_driver(&ls1x_cpufreq_driver); | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static int ls1x_cpufreq_probe(struct platform_device *pdev) | ||
140 | { | ||
141 | struct plat_ls1x_cpufreq *pdata = pdev->dev.platform_data; | ||
142 | struct clk *clk; | ||
143 | int ret; | ||
144 | |||
145 | if (!pdata || !pdata->clk_name || !pdata->osc_clk_name) | ||
146 | return -EINVAL; | ||
147 | |||
148 | ls1x_cpufreq.dev = &pdev->dev; | ||
149 | |||
150 | clk = devm_clk_get(&pdev->dev, pdata->clk_name); | ||
151 | if (IS_ERR(clk)) { | ||
152 | dev_err(ls1x_cpufreq.dev, "unable to get %s clock\n", | ||
153 | pdata->clk_name); | ||
154 | ret = PTR_ERR(clk); | ||
155 | goto out; | ||
156 | } | ||
157 | ls1x_cpufreq.clk = clk; | ||
158 | |||
159 | clk = clk_get_parent(clk); | ||
160 | if (IS_ERR(clk)) { | ||
161 | dev_err(ls1x_cpufreq.dev, "unable to get parent of %s clock\n", | ||
162 | __clk_get_name(ls1x_cpufreq.clk)); | ||
163 | ret = PTR_ERR(clk); | ||
164 | goto out; | ||
165 | } | ||
166 | ls1x_cpufreq.mux_clk = clk; | ||
167 | |||
168 | clk = clk_get_parent(clk); | ||
169 | if (IS_ERR(clk)) { | ||
170 | dev_err(ls1x_cpufreq.dev, "unable to get parent of %s clock\n", | ||
171 | __clk_get_name(ls1x_cpufreq.mux_clk)); | ||
172 | ret = PTR_ERR(clk); | ||
173 | goto out; | ||
174 | } | ||
175 | ls1x_cpufreq.pll_clk = clk; | ||
176 | |||
177 | clk = devm_clk_get(&pdev->dev, pdata->osc_clk_name); | ||
178 | if (IS_ERR(clk)) { | ||
179 | dev_err(ls1x_cpufreq.dev, "unable to get %s clock\n", | ||
180 | pdata->osc_clk_name); | ||
181 | ret = PTR_ERR(clk); | ||
182 | goto out; | ||
183 | } | ||
184 | ls1x_cpufreq.osc_clk = clk; | ||
185 | |||
186 | ls1x_cpufreq.max_freq = pdata->max_freq; | ||
187 | ls1x_cpufreq.min_freq = pdata->min_freq; | ||
188 | |||
189 | ret = cpufreq_register_driver(&ls1x_cpufreq_driver); | ||
190 | if (ret) { | ||
191 | dev_err(ls1x_cpufreq.dev, | ||
192 | "failed to register cpufreq driver: %d\n", ret); | ||
193 | goto out; | ||
194 | } | ||
195 | |||
196 | ret = cpufreq_register_notifier(&ls1x_cpufreq_notifier_block, | ||
197 | CPUFREQ_TRANSITION_NOTIFIER); | ||
198 | |||
199 | if (!ret) | ||
200 | goto out; | ||
201 | |||
202 | dev_err(ls1x_cpufreq.dev, "failed to register cpufreq notifier: %d\n", | ||
203 | ret); | ||
204 | |||
205 | cpufreq_unregister_driver(&ls1x_cpufreq_driver); | ||
206 | out: | ||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | static struct platform_driver ls1x_cpufreq_platdrv = { | ||
211 | .driver = { | ||
212 | .name = "ls1x-cpufreq", | ||
213 | .owner = THIS_MODULE, | ||
214 | }, | ||
215 | .probe = ls1x_cpufreq_probe, | ||
216 | .remove = ls1x_cpufreq_remove, | ||
217 | }; | ||
218 | |||
219 | module_platform_driver(ls1x_cpufreq_platdrv); | ||
220 | |||
221 | MODULE_AUTHOR("Kelvin Cheung <keguang.zhang@gmail.com>"); | ||
222 | MODULE_DESCRIPTION("Loongson 1 CPUFreq driver"); | ||
223 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c index 4d2c8e861089..2a0d58959acf 100644 --- a/drivers/cpufreq/pcc-cpufreq.c +++ b/drivers/cpufreq/pcc-cpufreq.c | |||
@@ -603,6 +603,13 @@ static void __exit pcc_cpufreq_exit(void) | |||
603 | free_percpu(pcc_cpu_info); | 603 | free_percpu(pcc_cpu_info); |
604 | } | 604 | } |
605 | 605 | ||
606 | static const struct acpi_device_id processor_device_ids[] = { | ||
607 | {ACPI_PROCESSOR_OBJECT_HID, }, | ||
608 | {ACPI_PROCESSOR_DEVICE_HID, }, | ||
609 | {}, | ||
610 | }; | ||
611 | MODULE_DEVICE_TABLE(acpi, processor_device_ids); | ||
612 | |||
606 | MODULE_AUTHOR("Matthew Garrett, Naga Chumbalkar"); | 613 | MODULE_AUTHOR("Matthew Garrett, Naga Chumbalkar"); |
607 | MODULE_VERSION(PCC_VERSION); | 614 | MODULE_VERSION(PCC_VERSION); |
608 | MODULE_DESCRIPTION("Processor Clocking Control interface driver"); | 615 | MODULE_DESCRIPTION("Processor Clocking Control interface driver"); |
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 503b085b7832..4d078cebafd2 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
@@ -217,26 +217,26 @@ __ATTR(_name, 0644, show_##_name, store_##_name) | |||
217 | 217 | ||
218 | 218 | ||
219 | struct cpufreq_driver { | 219 | struct cpufreq_driver { |
220 | char name[CPUFREQ_NAME_LEN]; | 220 | char name[CPUFREQ_NAME_LEN]; |
221 | u8 flags; | 221 | u8 flags; |
222 | void *driver_data; | 222 | void *driver_data; |
223 | 223 | ||
224 | /* needed by all drivers */ | 224 | /* needed by all drivers */ |
225 | int (*init) (struct cpufreq_policy *policy); | 225 | int (*init)(struct cpufreq_policy *policy); |
226 | int (*verify) (struct cpufreq_policy *policy); | 226 | int (*verify)(struct cpufreq_policy *policy); |
227 | 227 | ||
228 | /* define one out of two */ | 228 | /* define one out of two */ |
229 | int (*setpolicy) (struct cpufreq_policy *policy); | 229 | int (*setpolicy)(struct cpufreq_policy *policy); |
230 | 230 | ||
231 | /* | 231 | /* |
232 | * On failure, should always restore frequency to policy->restore_freq | 232 | * On failure, should always restore frequency to policy->restore_freq |
233 | * (i.e. old freq). | 233 | * (i.e. old freq). |
234 | */ | 234 | */ |
235 | int (*target) (struct cpufreq_policy *policy, /* Deprecated */ | 235 | int (*target)(struct cpufreq_policy *policy, |
236 | unsigned int target_freq, | 236 | unsigned int target_freq, |
237 | unsigned int relation); | 237 | unsigned int relation); /* Deprecated */ |
238 | int (*target_index) (struct cpufreq_policy *policy, | 238 | int (*target_index)(struct cpufreq_policy *policy, |
239 | unsigned int index); | 239 | unsigned int index); |
240 | /* | 240 | /* |
241 | * Only for drivers with target_index() and CPUFREQ_ASYNC_NOTIFICATION | 241 | * Only for drivers with target_index() and CPUFREQ_ASYNC_NOTIFICATION |
242 | * unset. | 242 | * unset. |
@@ -252,27 +252,31 @@ struct cpufreq_driver { | |||
252 | * wish to switch to intermediate frequency for some target frequency. | 252 | * wish to switch to intermediate frequency for some target frequency. |
253 | * In that case core will directly call ->target_index(). | 253 | * In that case core will directly call ->target_index(). |
254 | */ | 254 | */ |
255 | unsigned int (*get_intermediate)(struct cpufreq_policy *policy, | 255 | unsigned int (*get_intermediate)(struct cpufreq_policy *policy, |
256 | unsigned int index); | 256 | unsigned int index); |
257 | int (*target_intermediate)(struct cpufreq_policy *policy, | 257 | int (*target_intermediate)(struct cpufreq_policy *policy, |
258 | unsigned int index); | 258 | unsigned int index); |
259 | 259 | ||
260 | /* should be defined, if possible */ | 260 | /* should be defined, if possible */ |
261 | unsigned int (*get) (unsigned int cpu); | 261 | unsigned int (*get)(unsigned int cpu); |
262 | 262 | ||
263 | /* optional */ | 263 | /* optional */ |
264 | int (*bios_limit) (int cpu, unsigned int *limit); | 264 | int (*bios_limit)(int cpu, unsigned int *limit); |
265 | |||
266 | int (*exit)(struct cpufreq_policy *policy); | ||
267 | void (*stop_cpu)(struct cpufreq_policy *policy); | ||
268 | int (*suspend)(struct cpufreq_policy *policy); | ||
269 | int (*resume)(struct cpufreq_policy *policy); | ||
270 | |||
271 | /* Will be called after the driver is fully initialized */ | ||
272 | void (*ready)(struct cpufreq_policy *policy); | ||
265 | 273 | ||
266 | int (*exit) (struct cpufreq_policy *policy); | 274 | struct freq_attr **attr; |
267 | void (*stop_cpu) (struct cpufreq_policy *policy); | ||
268 | int (*suspend) (struct cpufreq_policy *policy); | ||
269 | int (*resume) (struct cpufreq_policy *policy); | ||
270 | struct freq_attr **attr; | ||
271 | 275 | ||
272 | /* platform specific boost support code */ | 276 | /* platform specific boost support code */ |
273 | bool boost_supported; | 277 | bool boost_supported; |
274 | bool boost_enabled; | 278 | bool boost_enabled; |
275 | int (*set_boost) (int state); | 279 | int (*set_boost)(int state); |
276 | }; | 280 | }; |
277 | 281 | ||
278 | /* flags */ | 282 | /* flags */ |