diff options
| -rw-r--r-- | Documentation/ABI/testing/sysfs-devices-system-cpu | 18 | ||||
| -rw-r--r-- | Documentation/cpu-freq/cpu-drivers.txt | 6 | ||||
| -rw-r--r-- | Documentation/cpu-freq/user-guide.txt | 11 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 17 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k6.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k7.c | 19 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 32 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/speedstep-ich.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/speedstep-lib.c | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/speedstep-lib.h | 24 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/speedstep-smi.c | 2 | ||||
| -rw-r--r-- | drivers/acpi/processor_perflib.c | 13 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 34 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_conservative.c | 129 | ||||
| -rw-r--r-- | include/acpi/processor.h | 6 | ||||
| -rw-r--r-- | include/linux/cpufreq.h | 1 |
16 files changed, 248 insertions, 74 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index a703b9e9aeb9..974e29f5da86 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu | |||
| @@ -136,6 +136,24 @@ Description: Discover cpuidle policy and mechanism | |||
| 136 | See files in Documentation/cpuidle/ for more information. | 136 | See files in Documentation/cpuidle/ for more information. |
| 137 | 137 | ||
| 138 | 138 | ||
| 139 | What: /sys/devices/system/cpu/cpu#/cpufreq/* | ||
| 140 | Date: pre-git history | ||
| 141 | Contact: cpufreq@vger.kernel.org | ||
| 142 | Description: Discover and change clock speed of CPUs | ||
| 143 | |||
| 144 | Clock scaling allows you to change the clock speed of the | ||
| 145 | CPUs on the fly. This is a nice method to save battery | ||
| 146 | power, because the lower the clock speed, the less power | ||
| 147 | the CPU consumes. | ||
| 148 | |||
| 149 | There are many knobs to tweak in this directory. | ||
| 150 | |||
| 151 | See files in Documentation/cpu-freq/ for more information. | ||
| 152 | |||
| 153 | In particular, read Documentation/cpu-freq/user-guide.txt | ||
| 154 | to learn how to control the knobs. | ||
| 155 | |||
| 156 | |||
| 139 | What: /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X | 157 | What: /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X |
| 140 | Date: August 2008 | 158 | Date: August 2008 |
| 141 | KernelVersion: 2.6.27 | 159 | KernelVersion: 2.6.27 |
diff --git a/Documentation/cpu-freq/cpu-drivers.txt b/Documentation/cpu-freq/cpu-drivers.txt index 75a58d14d3cf..6c30e930c122 100644 --- a/Documentation/cpu-freq/cpu-drivers.txt +++ b/Documentation/cpu-freq/cpu-drivers.txt | |||
| @@ -92,9 +92,9 @@ policy->cpuinfo.max_freq - the minimum and maximum frequency | |||
| 92 | (in kHz) which is supported by | 92 | (in kHz) which is supported by |
| 93 | this CPU | 93 | this CPU |
| 94 | policy->cpuinfo.transition_latency the time it takes on this CPU to | 94 | policy->cpuinfo.transition_latency the time it takes on this CPU to |
| 95 | switch between two frequencies (if | 95 | switch between two frequencies in |
| 96 | appropriate, else specify | 96 | nanoseconds (if appropriate, else |
| 97 | CPUFREQ_ETERNAL) | 97 | specify CPUFREQ_ETERNAL) |
| 98 | 98 | ||
| 99 | policy->cur The current operating frequency of | 99 | policy->cur The current operating frequency of |
| 100 | this CPU (if appropriate) | 100 | this CPU (if appropriate) |
diff --git a/Documentation/cpu-freq/user-guide.txt b/Documentation/cpu-freq/user-guide.txt index 2a5b850847c0..04f6b32993e6 100644 --- a/Documentation/cpu-freq/user-guide.txt +++ b/Documentation/cpu-freq/user-guide.txt | |||
| @@ -203,6 +203,17 @@ scaling_cur_freq : Current frequency of the CPU as determined by | |||
| 203 | the frequency the kernel thinks the CPU runs | 203 | the frequency the kernel thinks the CPU runs |
| 204 | at. | 204 | at. |
| 205 | 205 | ||
| 206 | bios_limit : If the BIOS tells the OS to limit a CPU to | ||
| 207 | lower frequencies, the user can read out the | ||
| 208 | maximum available frequency from this file. | ||
| 209 | This typically can happen through (often not | ||
| 210 | intended) BIOS settings, restrictions | ||
| 211 | triggered through a service processor or other | ||
| 212 | BIOS/HW based implementations. | ||
| 213 | This does not cover thermal ACPI limitations | ||
| 214 | which can be detected through the generic | ||
| 215 | thermal driver. | ||
| 216 | |||
| 206 | If you have selected the "userspace" governor which allows you to | 217 | If you have selected the "userspace" governor which allows you to |
| 207 | set the CPU operating frequency to a specific value, you can read out | 218 | set the CPU operating frequency to a specific value, you can read out |
| 208 | the current frequency in | 219 | the current frequency in |
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 8b581d3905cb..d2e7c77c1ea4 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
| @@ -764,14 +764,15 @@ static struct freq_attr *acpi_cpufreq_attr[] = { | |||
| 764 | }; | 764 | }; |
| 765 | 765 | ||
| 766 | static struct cpufreq_driver acpi_cpufreq_driver = { | 766 | static struct cpufreq_driver acpi_cpufreq_driver = { |
| 767 | .verify = acpi_cpufreq_verify, | 767 | .verify = acpi_cpufreq_verify, |
| 768 | .target = acpi_cpufreq_target, | 768 | .target = acpi_cpufreq_target, |
| 769 | .init = acpi_cpufreq_cpu_init, | 769 | .bios_limit = acpi_processor_get_bios_limit, |
| 770 | .exit = acpi_cpufreq_cpu_exit, | 770 | .init = acpi_cpufreq_cpu_init, |
| 771 | .resume = acpi_cpufreq_resume, | 771 | .exit = acpi_cpufreq_cpu_exit, |
| 772 | .name = "acpi-cpufreq", | 772 | .resume = acpi_cpufreq_resume, |
| 773 | .owner = THIS_MODULE, | 773 | .name = "acpi-cpufreq", |
| 774 | .attr = acpi_cpufreq_attr, | 774 | .owner = THIS_MODULE, |
| 775 | .attr = acpi_cpufreq_attr, | ||
| 775 | }; | 776 | }; |
| 776 | 777 | ||
| 777 | static int __init acpi_cpufreq_init(void) | 778 | static int __init acpi_cpufreq_init(void) |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c index f10dea409f40..cb01dac267d3 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c | |||
| @@ -164,7 +164,7 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) | |||
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | /* cpuinfo and default policy values */ | 166 | /* cpuinfo and default policy values */ |
| 167 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 167 | policy->cpuinfo.transition_latency = 200000; |
| 168 | policy->cur = busfreq * max_multiplier; | 168 | policy->cur = busfreq * max_multiplier; |
| 169 | 169 | ||
| 170 | result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio); | 170 | result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio); |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c index d47c775eb0ab..9a97116f89e5 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c | |||
| @@ -714,14 +714,17 @@ static struct freq_attr *powernow_table_attr[] = { | |||
| 714 | }; | 714 | }; |
| 715 | 715 | ||
| 716 | static struct cpufreq_driver powernow_driver = { | 716 | static struct cpufreq_driver powernow_driver = { |
| 717 | .verify = powernow_verify, | 717 | .verify = powernow_verify, |
| 718 | .target = powernow_target, | 718 | .target = powernow_target, |
| 719 | .get = powernow_get, | 719 | .get = powernow_get, |
| 720 | .init = powernow_cpu_init, | 720 | #ifdef CONFIG_X86_POWERNOW_K7_ACPI |
| 721 | .exit = powernow_cpu_exit, | 721 | .bios_limit = acpi_processor_get_bios_limit, |
| 722 | .name = "powernow-k7", | 722 | #endif |
| 723 | .owner = THIS_MODULE, | 723 | .init = powernow_cpu_init, |
| 724 | .attr = powernow_table_attr, | 724 | .exit = powernow_cpu_exit, |
| 725 | .name = "powernow-k7", | ||
| 726 | .owner = THIS_MODULE, | ||
| 727 | .attr = powernow_table_attr, | ||
| 725 | }; | 728 | }; |
| 726 | 729 | ||
| 727 | static int __init powernow_init(void) | 730 | static int __init powernow_init(void) |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 3f12dabeab52..a9df9441a9a2 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
| @@ -1118,7 +1118,7 @@ static int transition_frequency_pstate(struct powernow_k8_data *data, | |||
| 1118 | static int powernowk8_target(struct cpufreq_policy *pol, | 1118 | static int powernowk8_target(struct cpufreq_policy *pol, |
| 1119 | unsigned targfreq, unsigned relation) | 1119 | unsigned targfreq, unsigned relation) |
| 1120 | { | 1120 | { |
| 1121 | cpumask_t oldmask; | 1121 | cpumask_var_t oldmask; |
| 1122 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); | 1122 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); |
| 1123 | u32 checkfid; | 1123 | u32 checkfid; |
| 1124 | u32 checkvid; | 1124 | u32 checkvid; |
| @@ -1131,9 +1131,13 @@ static int powernowk8_target(struct cpufreq_policy *pol, | |||
| 1131 | checkfid = data->currfid; | 1131 | checkfid = data->currfid; |
| 1132 | checkvid = data->currvid; | 1132 | checkvid = data->currvid; |
| 1133 | 1133 | ||
| 1134 | /* only run on specific CPU from here on */ | 1134 | /* only run on specific CPU from here on. */ |
| 1135 | oldmask = current->cpus_allowed; | 1135 | /* This is poor form: use a workqueue or smp_call_function_single */ |
| 1136 | set_cpus_allowed_ptr(current, &cpumask_of_cpu(pol->cpu)); | 1136 | if (!alloc_cpumask_var(&oldmask, GFP_KERNEL)) |
| 1137 | return -ENOMEM; | ||
| 1138 | |||
| 1139 | cpumask_copy(oldmask, tsk_cpumask(current)); | ||
| 1140 | set_cpus_allowed_ptr(current, cpumask_of(pol->cpu)); | ||
| 1137 | 1141 | ||
| 1138 | if (smp_processor_id() != pol->cpu) { | 1142 | if (smp_processor_id() != pol->cpu) { |
| 1139 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); | 1143 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); |
| @@ -1193,7 +1197,8 @@ static int powernowk8_target(struct cpufreq_policy *pol, | |||
| 1193 | ret = 0; | 1197 | ret = 0; |
| 1194 | 1198 | ||
| 1195 | err_out: | 1199 | err_out: |
| 1196 | set_cpus_allowed_ptr(current, &oldmask); | 1200 | set_cpus_allowed_ptr(current, oldmask); |
| 1201 | free_cpumask_var(oldmask); | ||
| 1197 | return ret; | 1202 | return ret; |
| 1198 | } | 1203 | } |
| 1199 | 1204 | ||
| @@ -1393,14 +1398,15 @@ static struct freq_attr *powernow_k8_attr[] = { | |||
| 1393 | }; | 1398 | }; |
| 1394 | 1399 | ||
| 1395 | static struct cpufreq_driver cpufreq_amd64_driver = { | 1400 | static struct cpufreq_driver cpufreq_amd64_driver = { |
| 1396 | .verify = powernowk8_verify, | 1401 | .verify = powernowk8_verify, |
| 1397 | .target = powernowk8_target, | 1402 | .target = powernowk8_target, |
| 1398 | .init = powernowk8_cpu_init, | 1403 | .bios_limit = acpi_processor_get_bios_limit, |
| 1399 | .exit = __devexit_p(powernowk8_cpu_exit), | 1404 | .init = powernowk8_cpu_init, |
| 1400 | .get = powernowk8_get, | 1405 | .exit = __devexit_p(powernowk8_cpu_exit), |
| 1401 | .name = "powernow-k8", | 1406 | .get = powernowk8_get, |
| 1402 | .owner = THIS_MODULE, | 1407 | .name = "powernow-k8", |
| 1403 | .attr = powernow_k8_attr, | 1408 | .owner = THIS_MODULE, |
| 1409 | .attr = powernow_k8_attr, | ||
| 1404 | }; | 1410 | }; |
| 1405 | 1411 | ||
| 1406 | /* driver entry point for init */ | 1412 | /* driver entry point for init */ |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c index 3ae5a7a3a500..2ce8e0b5cc54 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c | |||
| @@ -39,7 +39,7 @@ static struct pci_dev *speedstep_chipset_dev; | |||
| 39 | 39 | ||
| 40 | /* speedstep_processor | 40 | /* speedstep_processor |
| 41 | */ | 41 | */ |
| 42 | static unsigned int speedstep_processor; | 42 | static enum speedstep_processor speedstep_processor; |
| 43 | 43 | ||
| 44 | static u32 pmbase; | 44 | static u32 pmbase; |
| 45 | 45 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c index f4c290b8482f..ad0083abfa23 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c | |||
| @@ -34,7 +34,7 @@ static int relaxed_check; | |||
| 34 | * GET PROCESSOR CORE SPEED IN KHZ * | 34 | * GET PROCESSOR CORE SPEED IN KHZ * |
| 35 | *********************************************************************/ | 35 | *********************************************************************/ |
| 36 | 36 | ||
| 37 | static unsigned int pentium3_get_frequency(unsigned int processor) | 37 | static unsigned int pentium3_get_frequency(enum speedstep_processor processor) |
| 38 | { | 38 | { |
| 39 | /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */ | 39 | /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */ |
| 40 | struct { | 40 | struct { |
| @@ -227,7 +227,7 @@ static unsigned int pentium4_get_frequency(void) | |||
| 227 | 227 | ||
| 228 | 228 | ||
| 229 | /* Warning: may get called from smp_call_function_single. */ | 229 | /* Warning: may get called from smp_call_function_single. */ |
| 230 | unsigned int speedstep_get_frequency(unsigned int processor) | 230 | unsigned int speedstep_get_frequency(enum speedstep_processor processor) |
| 231 | { | 231 | { |
| 232 | switch (processor) { | 232 | switch (processor) { |
| 233 | case SPEEDSTEP_CPU_PCORE: | 233 | case SPEEDSTEP_CPU_PCORE: |
| @@ -380,7 +380,7 @@ EXPORT_SYMBOL_GPL(speedstep_detect_processor); | |||
| 380 | * DETECT SPEEDSTEP SPEEDS * | 380 | * DETECT SPEEDSTEP SPEEDS * |
| 381 | *********************************************************************/ | 381 | *********************************************************************/ |
| 382 | 382 | ||
| 383 | unsigned int speedstep_get_freqs(unsigned int processor, | 383 | unsigned int speedstep_get_freqs(enum speedstep_processor processor, |
| 384 | unsigned int *low_speed, | 384 | unsigned int *low_speed, |
| 385 | unsigned int *high_speed, | 385 | unsigned int *high_speed, |
| 386 | unsigned int *transition_latency, | 386 | unsigned int *transition_latency, |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h index 2b6c04e5a304..70d9cea1219d 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h | |||
| @@ -11,18 +11,18 @@ | |||
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | /* processors */ | 13 | /* processors */ |
| 14 | 14 | enum speedstep_processor { | |
| 15 | #define SPEEDSTEP_CPU_PIII_C_EARLY 0x00000001 /* Coppermine core */ | 15 | SPEEDSTEP_CPU_PIII_C_EARLY = 0x00000001, /* Coppermine core */ |
| 16 | #define SPEEDSTEP_CPU_PIII_C 0x00000002 /* Coppermine core */ | 16 | SPEEDSTEP_CPU_PIII_C = 0x00000002, /* Coppermine core */ |
| 17 | #define SPEEDSTEP_CPU_PIII_T 0x00000003 /* Tualatin core */ | 17 | SPEEDSTEP_CPU_PIII_T = 0x00000003, /* Tualatin core */ |
| 18 | #define SPEEDSTEP_CPU_P4M 0x00000004 /* P4-M */ | 18 | SPEEDSTEP_CPU_P4M = 0x00000004, /* P4-M */ |
| 19 | |||
| 20 | /* the following processors are not speedstep-capable and are not auto-detected | 19 | /* the following processors are not speedstep-capable and are not auto-detected |
| 21 | * in speedstep_detect_processor(). However, their speed can be detected using | 20 | * in speedstep_detect_processor(). However, their speed can be detected using |
| 22 | * the speedstep_get_frequency() call. */ | 21 | * the speedstep_get_frequency() call. */ |
| 23 | #define SPEEDSTEP_CPU_PM 0xFFFFFF03 /* Pentium M */ | 22 | SPEEDSTEP_CPU_PM = 0xFFFFFF03, /* Pentium M */ |
| 24 | #define SPEEDSTEP_CPU_P4D 0xFFFFFF04 /* desktop P4 */ | 23 | SPEEDSTEP_CPU_P4D = 0xFFFFFF04, /* desktop P4 */ |
| 25 | #define SPEEDSTEP_CPU_PCORE 0xFFFFFF05 /* Core */ | 24 | SPEEDSTEP_CPU_PCORE = 0xFFFFFF05, /* Core */ |
| 25 | }; | ||
| 26 | 26 | ||
| 27 | /* speedstep states -- only two of them */ | 27 | /* speedstep states -- only two of them */ |
| 28 | 28 | ||
| @@ -31,10 +31,10 @@ | |||
| 31 | 31 | ||
| 32 | 32 | ||
| 33 | /* detect a speedstep-capable processor */ | 33 | /* detect a speedstep-capable processor */ |
| 34 | extern unsigned int speedstep_detect_processor (void); | 34 | extern enum speedstep_processor speedstep_detect_processor(void); |
| 35 | 35 | ||
| 36 | /* detect the current speed (in khz) of the processor */ | 36 | /* detect the current speed (in khz) of the processor */ |
| 37 | extern unsigned int speedstep_get_frequency(unsigned int processor); | 37 | extern unsigned int speedstep_get_frequency(enum speedstep_processor processor); |
| 38 | 38 | ||
| 39 | 39 | ||
| 40 | /* detect the low and high speeds of the processor. The callback | 40 | /* detect the low and high speeds of the processor. The callback |
| @@ -42,7 +42,7 @@ extern unsigned int speedstep_get_frequency(unsigned int processor); | |||
| 42 | * SPEEDSTEP_LOW; the second argument is zero so that no | 42 | * SPEEDSTEP_LOW; the second argument is zero so that no |
| 43 | * cpufreq_notify_transition calls are initiated. | 43 | * cpufreq_notify_transition calls are initiated. |
| 44 | */ | 44 | */ |
| 45 | extern unsigned int speedstep_get_freqs(unsigned int processor, | 45 | extern unsigned int speedstep_get_freqs(enum speedstep_processor processor, |
| 46 | unsigned int *low_speed, | 46 | unsigned int *low_speed, |
| 47 | unsigned int *high_speed, | 47 | unsigned int *high_speed, |
| 48 | unsigned int *transition_latency, | 48 | unsigned int *transition_latency, |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c index befea088e4f5..04d73c114e49 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c | |||
| @@ -35,7 +35,7 @@ static int smi_cmd; | |||
| 35 | static unsigned int smi_sig; | 35 | static unsigned int smi_sig; |
| 36 | 36 | ||
| 37 | /* info about the processor */ | 37 | /* info about the processor */ |
| 38 | static unsigned int speedstep_processor; | 38 | static enum speedstep_processor speedstep_processor; |
| 39 | 39 | ||
| 40 | /* | 40 | /* |
| 41 | * There are only two frequency states for each processor. Values | 41 | * There are only two frequency states for each processor. Values |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 8ba0ed0b9ddb..01e366d2b6fb 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
| @@ -167,6 +167,19 @@ int acpi_processor_ppc_has_changed(struct acpi_processor *pr) | |||
| 167 | return cpufreq_update_policy(pr->id); | 167 | return cpufreq_update_policy(pr->id); |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) | ||
| 171 | { | ||
| 172 | struct acpi_processor *pr; | ||
| 173 | |||
| 174 | pr = per_cpu(processors, cpu); | ||
| 175 | if (!pr || !pr->performance || !pr->performance->state_count) | ||
| 176 | return -ENODEV; | ||
| 177 | *limit = pr->performance->states[pr->performance_platform_limit]. | ||
| 178 | core_frequency * 1000; | ||
| 179 | return 0; | ||
| 180 | } | ||
| 181 | EXPORT_SYMBOL(acpi_processor_get_bios_limit); | ||
| 182 | |||
| 170 | void acpi_processor_ppc_init(void) | 183 | void acpi_processor_ppc_init(void) |
| 171 | { | 184 | { |
| 172 | if (!cpufreq_register_notifier | 185 | if (!cpufreq_register_notifier |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index ff57c40e9b8b..f20668c09ce0 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -647,6 +647,21 @@ static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf) | |||
| 647 | return policy->governor->show_setspeed(policy, buf); | 647 | return policy->governor->show_setspeed(policy, buf); |
| 648 | } | 648 | } |
| 649 | 649 | ||
| 650 | /** | ||
| 651 | * show_scaling_driver - show the current cpufreq HW/BIOS limitation | ||
| 652 | */ | ||
| 653 | static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf) | ||
| 654 | { | ||
| 655 | unsigned int limit; | ||
| 656 | int ret; | ||
| 657 | if (cpufreq_driver->bios_limit) { | ||
| 658 | ret = cpufreq_driver->bios_limit(policy->cpu, &limit); | ||
| 659 | if (!ret) | ||
| 660 | return sprintf(buf, "%u\n", limit); | ||
| 661 | } | ||
| 662 | return sprintf(buf, "%u\n", policy->cpuinfo.max_freq); | ||
| 663 | } | ||
| 664 | |||
| 650 | #define define_one_ro(_name) \ | 665 | #define define_one_ro(_name) \ |
| 651 | static struct freq_attr _name = \ | 666 | static struct freq_attr _name = \ |
| 652 | __ATTR(_name, 0444, show_##_name, NULL) | 667 | __ATTR(_name, 0444, show_##_name, NULL) |
| @@ -666,6 +681,7 @@ define_one_ro(cpuinfo_transition_latency); | |||
| 666 | define_one_ro(scaling_available_governors); | 681 | define_one_ro(scaling_available_governors); |
| 667 | define_one_ro(scaling_driver); | 682 | define_one_ro(scaling_driver); |
| 668 | define_one_ro(scaling_cur_freq); | 683 | define_one_ro(scaling_cur_freq); |
| 684 | define_one_ro(bios_limit); | ||
| 669 | define_one_ro(related_cpus); | 685 | define_one_ro(related_cpus); |
| 670 | define_one_ro(affected_cpus); | 686 | define_one_ro(affected_cpus); |
| 671 | define_one_rw(scaling_min_freq); | 687 | define_one_rw(scaling_min_freq); |
| @@ -767,8 +783,9 @@ static struct kobj_type ktype_cpufreq = { | |||
| 767 | * 0: Success | 783 | * 0: Success |
| 768 | * Positive: When we have a managed CPU and the sysfs got symlinked | 784 | * Positive: When we have a managed CPU and the sysfs got symlinked |
| 769 | */ | 785 | */ |
| 770 | int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy, | 786 | static int cpufreq_add_dev_policy(unsigned int cpu, |
| 771 | struct sys_device *sys_dev) | 787 | struct cpufreq_policy *policy, |
| 788 | struct sys_device *sys_dev) | ||
| 772 | { | 789 | { |
| 773 | int ret = 0; | 790 | int ret = 0; |
| 774 | #ifdef CONFIG_SMP | 791 | #ifdef CONFIG_SMP |
| @@ -842,7 +859,8 @@ int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy, | |||
| 842 | 859 | ||
| 843 | 860 | ||
| 844 | /* symlink affected CPUs */ | 861 | /* symlink affected CPUs */ |
| 845 | int cpufreq_add_dev_symlink(unsigned int cpu, struct cpufreq_policy *policy) | 862 | static int cpufreq_add_dev_symlink(unsigned int cpu, |
| 863 | struct cpufreq_policy *policy) | ||
| 846 | { | 864 | { |
| 847 | unsigned int j; | 865 | unsigned int j; |
| 848 | int ret = 0; | 866 | int ret = 0; |
| @@ -869,8 +887,9 @@ int cpufreq_add_dev_symlink(unsigned int cpu, struct cpufreq_policy *policy) | |||
| 869 | return ret; | 887 | return ret; |
| 870 | } | 888 | } |
| 871 | 889 | ||
| 872 | int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy, | 890 | static int cpufreq_add_dev_interface(unsigned int cpu, |
| 873 | struct sys_device *sys_dev) | 891 | struct cpufreq_policy *policy, |
| 892 | struct sys_device *sys_dev) | ||
| 874 | { | 893 | { |
| 875 | struct cpufreq_policy new_policy; | 894 | struct cpufreq_policy new_policy; |
| 876 | struct freq_attr **drv_attr; | 895 | struct freq_attr **drv_attr; |
| @@ -902,6 +921,11 @@ int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy, | |||
| 902 | if (ret) | 921 | if (ret) |
| 903 | goto err_out_kobj_put; | 922 | goto err_out_kobj_put; |
| 904 | } | 923 | } |
| 924 | if (cpufreq_driver->bios_limit) { | ||
| 925 | ret = sysfs_create_file(&policy->kobj, &bios_limit.attr); | ||
| 926 | if (ret) | ||
| 927 | goto err_out_kobj_put; | ||
| 928 | } | ||
| 905 | 929 | ||
| 906 | spin_lock_irqsave(&cpufreq_driver_lock, flags); | 930 | spin_lock_irqsave(&cpufreq_driver_lock, flags); |
| 907 | for_each_cpu(j, policy->cpus) { | 931 | for_each_cpu(j, policy->cpus) { |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index c7b081b839ff..599a40b25cb0 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
| @@ -164,20 +164,22 @@ static struct notifier_block dbs_cpufreq_notifier_block = { | |||
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | /************************** sysfs interface ************************/ | 166 | /************************** sysfs interface ************************/ |
| 167 | static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) | 167 | static ssize_t show_sampling_rate_max(struct kobject *kobj, |
| 168 | struct attribute *attr, char *buf) | ||
| 168 | { | 169 | { |
| 169 | printk_once(KERN_INFO "CPUFREQ: conservative sampling_rate_max " | 170 | printk_once(KERN_INFO "CPUFREQ: conservative sampling_rate_max " |
| 170 | "sysfs file is deprecated - used by: %s\n", current->comm); | 171 | "sysfs file is deprecated - used by: %s\n", current->comm); |
| 171 | return sprintf(buf, "%u\n", -1U); | 172 | return sprintf(buf, "%u\n", -1U); |
| 172 | } | 173 | } |
| 173 | 174 | ||
| 174 | static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf) | 175 | static ssize_t show_sampling_rate_min(struct kobject *kobj, |
| 176 | struct attribute *attr, char *buf) | ||
| 175 | { | 177 | { |
| 176 | return sprintf(buf, "%u\n", min_sampling_rate); | 178 | return sprintf(buf, "%u\n", min_sampling_rate); |
| 177 | } | 179 | } |
| 178 | 180 | ||
| 179 | #define define_one_ro(_name) \ | 181 | #define define_one_ro(_name) \ |
| 180 | static struct freq_attr _name = \ | 182 | static struct global_attr _name = \ |
| 181 | __ATTR(_name, 0444, show_##_name, NULL) | 183 | __ATTR(_name, 0444, show_##_name, NULL) |
| 182 | 184 | ||
| 183 | define_one_ro(sampling_rate_max); | 185 | define_one_ro(sampling_rate_max); |
| @@ -186,7 +188,7 @@ define_one_ro(sampling_rate_min); | |||
| 186 | /* cpufreq_conservative Governor Tunables */ | 188 | /* cpufreq_conservative Governor Tunables */ |
| 187 | #define show_one(file_name, object) \ | 189 | #define show_one(file_name, object) \ |
| 188 | static ssize_t show_##file_name \ | 190 | static ssize_t show_##file_name \ |
| 189 | (struct cpufreq_policy *unused, char *buf) \ | 191 | (struct kobject *kobj, struct attribute *attr, char *buf) \ |
| 190 | { \ | 192 | { \ |
| 191 | return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ | 193 | return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ |
| 192 | } | 194 | } |
| @@ -197,8 +199,40 @@ show_one(down_threshold, down_threshold); | |||
| 197 | show_one(ignore_nice_load, ignore_nice); | 199 | show_one(ignore_nice_load, ignore_nice); |
| 198 | show_one(freq_step, freq_step); | 200 | show_one(freq_step, freq_step); |
| 199 | 201 | ||
| 200 | static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, | 202 | /*** delete after deprecation time ***/ |
| 201 | const char *buf, size_t count) | 203 | #define DEPRECATION_MSG(file_name) \ |
| 204 | printk_once(KERN_INFO "CPUFREQ: Per core conservative sysfs " \ | ||
| 205 | "interface is deprecated - " #file_name "\n"); | ||
| 206 | |||
| 207 | #define show_one_old(file_name) \ | ||
| 208 | static ssize_t show_##file_name##_old \ | ||
| 209 | (struct cpufreq_policy *unused, char *buf) \ | ||
| 210 | { \ | ||
| 211 | printk_once(KERN_INFO "CPUFREQ: Per core conservative sysfs " \ | ||
| 212 | "interface is deprecated - " #file_name "\n"); \ | ||
| 213 | return show_##file_name(NULL, NULL, buf); \ | ||
| 214 | } | ||
| 215 | show_one_old(sampling_rate); | ||
| 216 | show_one_old(sampling_down_factor); | ||
| 217 | show_one_old(up_threshold); | ||
| 218 | show_one_old(down_threshold); | ||
| 219 | show_one_old(ignore_nice_load); | ||
| 220 | show_one_old(freq_step); | ||
| 221 | show_one_old(sampling_rate_min); | ||
| 222 | show_one_old(sampling_rate_max); | ||
| 223 | |||
| 224 | #define define_one_ro_old(object, _name) \ | ||
| 225 | static struct freq_attr object = \ | ||
| 226 | __ATTR(_name, 0444, show_##_name##_old, NULL) | ||
| 227 | |||
| 228 | define_one_ro_old(sampling_rate_min_old, sampling_rate_min); | ||
| 229 | define_one_ro_old(sampling_rate_max_old, sampling_rate_max); | ||
| 230 | |||
| 231 | /*** delete after deprecation time ***/ | ||
| 232 | |||
| 233 | static ssize_t store_sampling_down_factor(struct kobject *a, | ||
| 234 | struct attribute *b, | ||
| 235 | const char *buf, size_t count) | ||
| 202 | { | 236 | { |
| 203 | unsigned int input; | 237 | unsigned int input; |
| 204 | int ret; | 238 | int ret; |
| @@ -214,8 +248,8 @@ static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, | |||
| 214 | return count; | 248 | return count; |
| 215 | } | 249 | } |
| 216 | 250 | ||
| 217 | static ssize_t store_sampling_rate(struct cpufreq_policy *unused, | 251 | static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b, |
| 218 | const char *buf, size_t count) | 252 | const char *buf, size_t count) |
| 219 | { | 253 | { |
| 220 | unsigned int input; | 254 | unsigned int input; |
| 221 | int ret; | 255 | int ret; |
| @@ -231,8 +265,8 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused, | |||
| 231 | return count; | 265 | return count; |
| 232 | } | 266 | } |
| 233 | 267 | ||
| 234 | static ssize_t store_up_threshold(struct cpufreq_policy *unused, | 268 | static ssize_t store_up_threshold(struct kobject *a, struct attribute *b, |
| 235 | const char *buf, size_t count) | 269 | const char *buf, size_t count) |
| 236 | { | 270 | { |
| 237 | unsigned int input; | 271 | unsigned int input; |
| 238 | int ret; | 272 | int ret; |
| @@ -251,8 +285,8 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, | |||
| 251 | return count; | 285 | return count; |
| 252 | } | 286 | } |
| 253 | 287 | ||
| 254 | static ssize_t store_down_threshold(struct cpufreq_policy *unused, | 288 | static ssize_t store_down_threshold(struct kobject *a, struct attribute *b, |
| 255 | const char *buf, size_t count) | 289 | const char *buf, size_t count) |
| 256 | { | 290 | { |
| 257 | unsigned int input; | 291 | unsigned int input; |
| 258 | int ret; | 292 | int ret; |
| @@ -272,8 +306,8 @@ static ssize_t store_down_threshold(struct cpufreq_policy *unused, | |||
| 272 | return count; | 306 | return count; |
| 273 | } | 307 | } |
| 274 | 308 | ||
| 275 | static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, | 309 | static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b, |
| 276 | const char *buf, size_t count) | 310 | const char *buf, size_t count) |
| 277 | { | 311 | { |
| 278 | unsigned int input; | 312 | unsigned int input; |
| 279 | int ret; | 313 | int ret; |
| @@ -308,8 +342,8 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy, | |||
| 308 | return count; | 342 | return count; |
| 309 | } | 343 | } |
| 310 | 344 | ||
| 311 | static ssize_t store_freq_step(struct cpufreq_policy *policy, | 345 | static ssize_t store_freq_step(struct kobject *a, struct attribute *b, |
| 312 | const char *buf, size_t count) | 346 | const char *buf, size_t count) |
| 313 | { | 347 | { |
| 314 | unsigned int input; | 348 | unsigned int input; |
| 315 | int ret; | 349 | int ret; |
| @@ -331,7 +365,7 @@ static ssize_t store_freq_step(struct cpufreq_policy *policy, | |||
| 331 | } | 365 | } |
| 332 | 366 | ||
| 333 | #define define_one_rw(_name) \ | 367 | #define define_one_rw(_name) \ |
| 334 | static struct freq_attr _name = \ | 368 | static struct global_attr _name = \ |
| 335 | __ATTR(_name, 0644, show_##_name, store_##_name) | 369 | __ATTR(_name, 0644, show_##_name, store_##_name) |
| 336 | 370 | ||
| 337 | define_one_rw(sampling_rate); | 371 | define_one_rw(sampling_rate); |
| @@ -358,6 +392,53 @@ static struct attribute_group dbs_attr_group = { | |||
| 358 | .name = "conservative", | 392 | .name = "conservative", |
| 359 | }; | 393 | }; |
| 360 | 394 | ||
| 395 | /*** delete after deprecation time ***/ | ||
| 396 | |||
| 397 | #define write_one_old(file_name) \ | ||
| 398 | static ssize_t store_##file_name##_old \ | ||
| 399 | (struct cpufreq_policy *unused, const char *buf, size_t count) \ | ||
| 400 | { \ | ||
| 401 | printk_once(KERN_INFO "CPUFREQ: Per core conservative sysfs " \ | ||
| 402 | "interface is deprecated - " #file_name "\n"); \ | ||
| 403 | return store_##file_name(NULL, NULL, buf, count); \ | ||
| 404 | } | ||
| 405 | write_one_old(sampling_rate); | ||
| 406 | write_one_old(sampling_down_factor); | ||
| 407 | write_one_old(up_threshold); | ||
| 408 | write_one_old(down_threshold); | ||
| 409 | write_one_old(ignore_nice_load); | ||
| 410 | write_one_old(freq_step); | ||
| 411 | |||
| 412 | #define define_one_rw_old(object, _name) \ | ||
| 413 | static struct freq_attr object = \ | ||
| 414 | __ATTR(_name, 0644, show_##_name##_old, store_##_name##_old) | ||
| 415 | |||
| 416 | define_one_rw_old(sampling_rate_old, sampling_rate); | ||
| 417 | define_one_rw_old(sampling_down_factor_old, sampling_down_factor); | ||
| 418 | define_one_rw_old(up_threshold_old, up_threshold); | ||
| 419 | define_one_rw_old(down_threshold_old, down_threshold); | ||
| 420 | define_one_rw_old(ignore_nice_load_old, ignore_nice_load); | ||
| 421 | define_one_rw_old(freq_step_old, freq_step); | ||
| 422 | |||
| 423 | static struct attribute *dbs_attributes_old[] = { | ||
| 424 | &sampling_rate_max_old.attr, | ||
| 425 | &sampling_rate_min_old.attr, | ||
| 426 | &sampling_rate_old.attr, | ||
| 427 | &sampling_down_factor_old.attr, | ||
| 428 | &up_threshold_old.attr, | ||
| 429 | &down_threshold_old.attr, | ||
| 430 | &ignore_nice_load_old.attr, | ||
| 431 | &freq_step_old.attr, | ||
| 432 | NULL | ||
| 433 | }; | ||
| 434 | |||
| 435 | static struct attribute_group dbs_attr_group_old = { | ||
| 436 | .attrs = dbs_attributes_old, | ||
| 437 | .name = "conservative", | ||
| 438 | }; | ||
| 439 | |||
| 440 | /*** delete after deprecation time ***/ | ||
| 441 | |||
| 361 | /************************** sysfs end ************************/ | 442 | /************************** sysfs end ************************/ |
| 362 | 443 | ||
| 363 | static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | 444 | static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) |
| @@ -530,7 +611,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 530 | 611 | ||
| 531 | mutex_lock(&dbs_mutex); | 612 | mutex_lock(&dbs_mutex); |
| 532 | 613 | ||
| 533 | rc = sysfs_create_group(&policy->kobj, &dbs_attr_group); | 614 | rc = sysfs_create_group(&policy->kobj, &dbs_attr_group_old); |
| 534 | if (rc) { | 615 | if (rc) { |
| 535 | mutex_unlock(&dbs_mutex); | 616 | mutex_unlock(&dbs_mutex); |
| 536 | return rc; | 617 | return rc; |
| @@ -564,6 +645,13 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 564 | if (latency == 0) | 645 | if (latency == 0) |
| 565 | latency = 1; | 646 | latency = 1; |
| 566 | 647 | ||
| 648 | rc = sysfs_create_group(cpufreq_global_kobject, | ||
| 649 | &dbs_attr_group); | ||
| 650 | if (rc) { | ||
| 651 | mutex_unlock(&dbs_mutex); | ||
| 652 | return rc; | ||
| 653 | } | ||
| 654 | |||
| 567 | /* | 655 | /* |
| 568 | * conservative does not implement micro like ondemand | 656 | * conservative does not implement micro like ondemand |
| 569 | * governor, thus we are bound to jiffes/HZ | 657 | * governor, thus we are bound to jiffes/HZ |
| @@ -591,7 +679,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 591 | dbs_timer_exit(this_dbs_info); | 679 | dbs_timer_exit(this_dbs_info); |
| 592 | 680 | ||
| 593 | mutex_lock(&dbs_mutex); | 681 | mutex_lock(&dbs_mutex); |
| 594 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); | 682 | sysfs_remove_group(&policy->kobj, &dbs_attr_group_old); |
| 595 | dbs_enable--; | 683 | dbs_enable--; |
| 596 | mutex_destroy(&this_dbs_info->timer_mutex); | 684 | mutex_destroy(&this_dbs_info->timer_mutex); |
| 597 | 685 | ||
| @@ -605,6 +693,9 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 605 | CPUFREQ_TRANSITION_NOTIFIER); | 693 | CPUFREQ_TRANSITION_NOTIFIER); |
| 606 | 694 | ||
| 607 | mutex_unlock(&dbs_mutex); | 695 | mutex_unlock(&dbs_mutex); |
| 696 | if (!dbs_enable) | ||
| 697 | sysfs_remove_group(cpufreq_global_kobject, | ||
| 698 | &dbs_attr_group); | ||
| 608 | 699 | ||
| 609 | break; | 700 | break; |
| 610 | 701 | ||
diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 740ac3ad8fd0..8b668ead6d6e 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h | |||
| @@ -295,6 +295,7 @@ static inline void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx | |||
| 295 | void acpi_processor_ppc_init(void); | 295 | void acpi_processor_ppc_init(void); |
| 296 | void acpi_processor_ppc_exit(void); | 296 | void acpi_processor_ppc_exit(void); |
| 297 | int acpi_processor_ppc_has_changed(struct acpi_processor *pr); | 297 | int acpi_processor_ppc_has_changed(struct acpi_processor *pr); |
| 298 | extern int acpi_processor_get_bios_limit(int cpu, unsigned int *limit); | ||
| 298 | #else | 299 | #else |
| 299 | static inline void acpi_processor_ppc_init(void) | 300 | static inline void acpi_processor_ppc_init(void) |
| 300 | { | 301 | { |
| @@ -316,6 +317,11 @@ static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr) | |||
| 316 | } | 317 | } |
| 317 | return 0; | 318 | return 0; |
| 318 | } | 319 | } |
| 320 | static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit) | ||
| 321 | { | ||
| 322 | return -ENODEV; | ||
| 323 | } | ||
| 324 | |||
| 319 | #endif /* CONFIG_CPU_FREQ */ | 325 | #endif /* CONFIG_CPU_FREQ */ |
| 320 | 326 | ||
| 321 | /* in processor_throttling.c */ | 327 | /* in processor_throttling.c */ |
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 79a2340d83cd..4de02b10007f 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
| @@ -232,6 +232,7 @@ struct cpufreq_driver { | |||
| 232 | /* optional */ | 232 | /* optional */ |
| 233 | unsigned int (*getavg) (struct cpufreq_policy *policy, | 233 | unsigned int (*getavg) (struct cpufreq_policy *policy, |
| 234 | unsigned int cpu); | 234 | unsigned int cpu); |
| 235 | int (*bios_limit) (int cpu, unsigned int *limit); | ||
| 235 | 236 | ||
| 236 | int (*exit) (struct cpufreq_policy *policy); | 237 | int (*exit) (struct cpufreq_policy *policy); |
| 237 | int (*suspend) (struct cpufreq_policy *policy, pm_message_t pmsg); | 238 | int (*suspend) (struct cpufreq_policy *policy, pm_message_t pmsg); |
