diff options
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/Kconfig | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/e_powersaver.c | 61 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/gx-suspmod.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k7.c | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 9 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k8.h | 2 | ||||
| -rw-r--r-- | drivers/cpufreq/Kconfig | 3 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 33 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_userspace.c | 40 | ||||
| -rw-r--r-- | drivers/cpufreq/freq_table.c | 2 | ||||
| -rw-r--r-- | include/linux/cpufreq.h | 4 |
11 files changed, 97 insertions, 67 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/Kconfig b/arch/x86/kernel/cpu/cpufreq/Kconfig index 151eda0a23fc..cb7a5715596d 100644 --- a/arch/x86/kernel/cpu/cpufreq/Kconfig +++ b/arch/x86/kernel/cpu/cpufreq/Kconfig | |||
| @@ -29,7 +29,7 @@ config X86_ACPI_CPUFREQ | |||
| 29 | config ELAN_CPUFREQ | 29 | config ELAN_CPUFREQ |
| 30 | tristate "AMD Elan SC400 and SC410" | 30 | tristate "AMD Elan SC400 and SC410" |
| 31 | select CPU_FREQ_TABLE | 31 | select CPU_FREQ_TABLE |
| 32 | depends on X86_32 && X86_ELAN | 32 | depends on X86_ELAN |
| 33 | ---help--- | 33 | ---help--- |
| 34 | This adds the CPUFreq driver for AMD Elan SC400 and SC410 | 34 | This adds the CPUFreq driver for AMD Elan SC400 and SC410 |
| 35 | processors. | 35 | processors. |
| @@ -45,7 +45,7 @@ config ELAN_CPUFREQ | |||
| 45 | config SC520_CPUFREQ | 45 | config SC520_CPUFREQ |
| 46 | tristate "AMD Elan SC520" | 46 | tristate "AMD Elan SC520" |
| 47 | select CPU_FREQ_TABLE | 47 | select CPU_FREQ_TABLE |
| 48 | depends on X86_32 && X86_ELAN | 48 | depends on X86_ELAN |
| 49 | ---help--- | 49 | ---help--- |
| 50 | This adds the CPUFreq driver for AMD Elan SC520 processor. | 50 | This adds the CPUFreq driver for AMD Elan SC520 processor. |
| 51 | 51 | ||
diff --git a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c index 326a4c81f684..39f8cb18296c 100644 --- a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c +++ b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #define EPS_BRAND_C7 1 | 23 | #define EPS_BRAND_C7 1 |
| 24 | #define EPS_BRAND_EDEN 2 | 24 | #define EPS_BRAND_EDEN 2 |
| 25 | #define EPS_BRAND_C3 3 | 25 | #define EPS_BRAND_C3 3 |
| 26 | #define EPS_BRAND_C7D 4 | ||
| 26 | 27 | ||
| 27 | struct eps_cpu_data { | 28 | struct eps_cpu_data { |
| 28 | u32 fsb; | 29 | u32 fsb; |
| @@ -54,6 +55,7 @@ static int eps_set_state(struct eps_cpu_data *centaur, | |||
| 54 | { | 55 | { |
| 55 | struct cpufreq_freqs freqs; | 56 | struct cpufreq_freqs freqs; |
| 56 | u32 lo, hi; | 57 | u32 lo, hi; |
| 58 | u8 current_multiplier, current_voltage; | ||
| 57 | int err = 0; | 59 | int err = 0; |
| 58 | int i; | 60 | int i; |
| 59 | 61 | ||
| @@ -93,6 +95,15 @@ postchange: | |||
| 93 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); | 95 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); |
| 94 | freqs.new = centaur->fsb * ((lo >> 8) & 0xff); | 96 | freqs.new = centaur->fsb * ((lo >> 8) & 0xff); |
| 95 | 97 | ||
| 98 | /* Print voltage and multiplier */ | ||
| 99 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); | ||
| 100 | current_voltage = lo & 0xff; | ||
| 101 | printk(KERN_INFO "eps: Current voltage = %dmV\n", | ||
| 102 | current_voltage * 16 + 700); | ||
| 103 | current_multiplier = (lo >> 8) & 0xff; | ||
| 104 | printk(KERN_INFO "eps: Current multiplier = %d\n", | ||
| 105 | current_multiplier); | ||
| 106 | |||
| 96 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 107 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); |
| 97 | return err; | 108 | return err; |
| 98 | } | 109 | } |
| @@ -141,9 +152,10 @@ static int eps_cpu_init(struct cpufreq_policy *policy) | |||
| 141 | u8 current_multiplier, current_voltage; | 152 | u8 current_multiplier, current_voltage; |
| 142 | u8 max_multiplier, max_voltage; | 153 | u8 max_multiplier, max_voltage; |
| 143 | u8 min_multiplier, min_voltage; | 154 | u8 min_multiplier, min_voltage; |
| 144 | u8 brand; | 155 | u8 brand = 0; |
| 145 | u32 fsb; | 156 | u32 fsb; |
| 146 | struct eps_cpu_data *centaur; | 157 | struct eps_cpu_data *centaur; |
| 158 | struct cpuinfo_x86 *c = &cpu_data(0); | ||
| 147 | struct cpufreq_frequency_table *f_table; | 159 | struct cpufreq_frequency_table *f_table; |
| 148 | int k, step, voltage; | 160 | int k, step, voltage; |
| 149 | int ret; | 161 | int ret; |
| @@ -153,21 +165,36 @@ static int eps_cpu_init(struct cpufreq_policy *policy) | |||
| 153 | return -ENODEV; | 165 | return -ENODEV; |
| 154 | 166 | ||
| 155 | /* Check brand */ | 167 | /* Check brand */ |
| 156 | printk("eps: Detected VIA "); | 168 | printk(KERN_INFO "eps: Detected VIA "); |
| 157 | rdmsr(0x1153, lo, hi); | 169 | |
| 158 | brand = (((lo >> 2) ^ lo) >> 18) & 3; | 170 | switch (c->x86_model) { |
| 171 | case 10: | ||
| 172 | rdmsr(0x1153, lo, hi); | ||
| 173 | brand = (((lo >> 2) ^ lo) >> 18) & 3; | ||
| 174 | printk(KERN_CONT "Model A "); | ||
| 175 | break; | ||
| 176 | case 13: | ||
| 177 | rdmsr(0x1154, lo, hi); | ||
| 178 | brand = (((lo >> 4) ^ (lo >> 2))) & 0x000000ff; | ||
| 179 | printk(KERN_CONT "Model D "); | ||
| 180 | break; | ||
| 181 | } | ||
| 182 | |||
| 159 | switch(brand) { | 183 | switch(brand) { |
| 160 | case EPS_BRAND_C7M: | 184 | case EPS_BRAND_C7M: |
| 161 | printk("C7-M\n"); | 185 | printk(KERN_CONT "C7-M\n"); |
| 162 | break; | 186 | break; |
| 163 | case EPS_BRAND_C7: | 187 | case EPS_BRAND_C7: |
| 164 | printk("C7\n"); | 188 | printk(KERN_CONT "C7\n"); |
| 165 | break; | 189 | break; |
| 166 | case EPS_BRAND_EDEN: | 190 | case EPS_BRAND_EDEN: |
| 167 | printk("Eden\n"); | 191 | printk(KERN_CONT "Eden\n"); |
| 192 | break; | ||
| 193 | case EPS_BRAND_C7D: | ||
| 194 | printk(KERN_CONT "C7-D\n"); | ||
| 168 | break; | 195 | break; |
| 169 | case EPS_BRAND_C3: | 196 | case EPS_BRAND_C3: |
| 170 | printk("C3\n"); | 197 | printk(KERN_CONT "C3\n"); |
| 171 | return -ENODEV; | 198 | return -ENODEV; |
| 172 | break; | 199 | break; |
| 173 | } | 200 | } |
| @@ -179,7 +206,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy) | |||
| 179 | /* Can be locked at 0 */ | 206 | /* Can be locked at 0 */ |
| 180 | rdmsrl(MSR_IA32_MISC_ENABLE, val); | 207 | rdmsrl(MSR_IA32_MISC_ENABLE, val); |
| 181 | if (!(val & 1 << 16)) { | 208 | if (!(val & 1 << 16)) { |
| 182 | printk("eps: Can't enable Enhanced PowerSaver\n"); | 209 | printk(KERN_INFO "eps: Can't enable Enhanced PowerSaver\n"); |
| 183 | return -ENODEV; | 210 | return -ENODEV; |
| 184 | } | 211 | } |
| 185 | } | 212 | } |
| @@ -187,19 +214,19 @@ static int eps_cpu_init(struct cpufreq_policy *policy) | |||
| 187 | /* Print voltage and multiplier */ | 214 | /* Print voltage and multiplier */ |
| 188 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); | 215 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); |
| 189 | current_voltage = lo & 0xff; | 216 | current_voltage = lo & 0xff; |
| 190 | printk("eps: Current voltage = %dmV\n", current_voltage * 16 + 700); | 217 | printk(KERN_INFO "eps: Current voltage = %dmV\n", current_voltage * 16 + 700); |
| 191 | current_multiplier = (lo >> 8) & 0xff; | 218 | current_multiplier = (lo >> 8) & 0xff; |
| 192 | printk("eps: Current multiplier = %d\n", current_multiplier); | 219 | printk(KERN_INFO "eps: Current multiplier = %d\n", current_multiplier); |
| 193 | 220 | ||
| 194 | /* Print limits */ | 221 | /* Print limits */ |
| 195 | max_voltage = hi & 0xff; | 222 | max_voltage = hi & 0xff; |
| 196 | printk("eps: Highest voltage = %dmV\n", max_voltage * 16 + 700); | 223 | printk(KERN_INFO "eps: Highest voltage = %dmV\n", max_voltage * 16 + 700); |
| 197 | max_multiplier = (hi >> 8) & 0xff; | 224 | max_multiplier = (hi >> 8) & 0xff; |
| 198 | printk("eps: Highest multiplier = %d\n", max_multiplier); | 225 | printk(KERN_INFO "eps: Highest multiplier = %d\n", max_multiplier); |
| 199 | min_voltage = (hi >> 16) & 0xff; | 226 | min_voltage = (hi >> 16) & 0xff; |
| 200 | printk("eps: Lowest voltage = %dmV\n", min_voltage * 16 + 700); | 227 | printk(KERN_INFO "eps: Lowest voltage = %dmV\n", min_voltage * 16 + 700); |
| 201 | min_multiplier = (hi >> 24) & 0xff; | 228 | min_multiplier = (hi >> 24) & 0xff; |
| 202 | printk("eps: Lowest multiplier = %d\n", min_multiplier); | 229 | printk(KERN_INFO "eps: Lowest multiplier = %d\n", min_multiplier); |
| 203 | 230 | ||
| 204 | /* Sanity checks */ | 231 | /* Sanity checks */ |
| 205 | if (current_multiplier == 0 || max_multiplier == 0 | 232 | if (current_multiplier == 0 || max_multiplier == 0 |
| @@ -208,7 +235,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy) | |||
| 208 | if (current_multiplier > max_multiplier | 235 | if (current_multiplier > max_multiplier |
| 209 | || max_multiplier <= min_multiplier) | 236 | || max_multiplier <= min_multiplier) |
| 210 | return -EINVAL; | 237 | return -EINVAL; |
| 211 | if (current_voltage > 0x1c || max_voltage > 0x1c) | 238 | if (current_voltage > 0x1f || max_voltage > 0x1f) |
| 212 | return -EINVAL; | 239 | return -EINVAL; |
| 213 | if (max_voltage < min_voltage) | 240 | if (max_voltage < min_voltage) |
| 214 | return -EINVAL; | 241 | return -EINVAL; |
| @@ -310,7 +337,7 @@ static int __init eps_init(void) | |||
| 310 | /* This driver will work only on Centaur C7 processors with | 337 | /* This driver will work only on Centaur C7 processors with |
| 311 | * Enhanced SpeedStep/PowerSaver registers */ | 338 | * Enhanced SpeedStep/PowerSaver registers */ |
| 312 | if (c->x86_vendor != X86_VENDOR_CENTAUR | 339 | if (c->x86_vendor != X86_VENDOR_CENTAUR |
| 313 | || c->x86 != 6 || c->x86_model != 10) | 340 | || c->x86 != 6 || c->x86_model < 10) |
| 314 | return -ENODEV; | 341 | return -ENODEV; |
| 315 | if (!cpu_has(c, X86_FEATURE_EST)) | 342 | if (!cpu_has(c, X86_FEATURE_EST)) |
| 316 | return -ENODEV; | 343 | return -ENODEV; |
diff --git a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c index 2ed7db2fd257..9d9eae82e60f 100644 --- a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c | |||
| @@ -181,8 +181,8 @@ static __init struct pci_dev *gx_detect_chipset(void) | |||
| 181 | struct pci_dev *gx_pci = NULL; | 181 | struct pci_dev *gx_pci = NULL; |
| 182 | 182 | ||
| 183 | /* check if CPU is a MediaGX or a Geode. */ | 183 | /* check if CPU is a MediaGX or a Geode. */ |
| 184 | if ((current_cpu_data.x86_vendor != X86_VENDOR_NSC) && | 184 | if ((boot_cpu_data.x86_vendor != X86_VENDOR_NSC) && |
| 185 | (current_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) { | 185 | (boot_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) { |
| 186 | dprintk("error: no MediaGX/Geode processor found!\n"); | 186 | dprintk("error: no MediaGX/Geode processor found!\n"); |
| 187 | return NULL; | 187 | return NULL; |
| 188 | } | 188 | } |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c index b5a9863d6cdc..0a61159d7b71 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c | |||
| @@ -460,7 +460,7 @@ static int powernow_decode_bios (int maxfid, int startvid) | |||
| 460 | 460 | ||
| 461 | latency = psb->settlingtime; | 461 | latency = psb->settlingtime; |
| 462 | if (latency < 100) { | 462 | if (latency < 100) { |
| 463 | printk (KERN_INFO PFX "BIOS set settling time to %d microseconds." | 463 | printk(KERN_INFO PFX "BIOS set settling time to %d microseconds. " |
| 464 | "Should be at least 100. Correcting.\n", latency); | 464 | "Should be at least 100. Correcting.\n", latency); |
| 465 | latency = 100; | 465 | latency = 100; |
| 466 | } | 466 | } |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 5affe91ca1e5..c99d59d8ef2e 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
| @@ -578,10 +578,9 @@ static void print_basics(struct powernow_k8_data *data) | |||
| 578 | for (j = 0; j < data->numps; j++) { | 578 | for (j = 0; j < data->numps; j++) { |
| 579 | if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) { | 579 | if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) { |
| 580 | if (cpu_family == CPU_HW_PSTATE) { | 580 | if (cpu_family == CPU_HW_PSTATE) { |
| 581 | printk(KERN_INFO PFX " %d : fid 0x%x did 0x%x (%d MHz)\n", | 581 | printk(KERN_INFO PFX " %d : pstate %d (%d MHz)\n", |
| 582 | j, | 582 | j, |
| 583 | (data->powernow_table[j].index & 0xff00) >> 8, | 583 | data->powernow_table[j].index, |
| 584 | (data->powernow_table[j].index & 0xff0000) >> 16, | ||
| 585 | data->powernow_table[j].frequency/1000); | 584 | data->powernow_table[j].frequency/1000); |
| 586 | } else { | 585 | } else { |
| 587 | printk(KERN_INFO PFX " %d : fid 0x%x (%d MHz), vid 0x%x\n", | 586 | printk(KERN_INFO PFX " %d : fid 0x%x (%d MHz), vid 0x%x\n", |
| @@ -1235,8 +1234,10 @@ static unsigned int powernowk8_get (unsigned int cpu) | |||
| 1235 | struct powernow_k8_data *data; | 1234 | struct powernow_k8_data *data; |
| 1236 | cpumask_t oldmask = current->cpus_allowed; | 1235 | cpumask_t oldmask = current->cpus_allowed; |
| 1237 | unsigned int khz = 0; | 1236 | unsigned int khz = 0; |
| 1237 | unsigned int first; | ||
| 1238 | 1238 | ||
| 1239 | data = per_cpu(powernow_data, first_cpu(per_cpu(cpu_core_map, cpu))); | 1239 | first = first_cpu(per_cpu(cpu_core_map, cpu)); |
| 1240 | data = per_cpu(powernow_data, first); | ||
| 1240 | 1241 | ||
| 1241 | if (!data) | 1242 | if (!data) |
| 1242 | return -EINVAL; | 1243 | return -EINVAL; |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h index afd2b520d35c..ab48cfed4d96 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h | |||
| @@ -47,7 +47,7 @@ struct powernow_k8_data { | |||
| 47 | #define CPUID_XFAM 0x0ff00000 /* extended family */ | 47 | #define CPUID_XFAM 0x0ff00000 /* extended family */ |
| 48 | #define CPUID_XFAM_K8 0 | 48 | #define CPUID_XFAM_K8 0 |
| 49 | #define CPUID_XMOD 0x000f0000 /* extended model */ | 49 | #define CPUID_XMOD 0x000f0000 /* extended model */ |
| 50 | #define CPUID_XMOD_REV_MASK 0x00080000 | 50 | #define CPUID_XMOD_REV_MASK 0x000c0000 |
| 51 | #define CPUID_XFAM_10H 0x00100000 /* family 0x10 */ | 51 | #define CPUID_XFAM_10H 0x00100000 /* family 0x10 */ |
| 52 | #define CPUID_USE_XFAM_XMOD 0x00000f00 | 52 | #define CPUID_USE_XFAM_XMOD 0x00000f00 |
| 53 | #define CPUID_GET_MAX_CAPABILITIES 0x80000000 | 53 | #define CPUID_GET_MAX_CAPABILITIES 0x80000000 |
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 721f86f4f008..c159ae64eeb2 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig | |||
| @@ -9,9 +9,6 @@ config CPU_FREQ | |||
| 9 | clock speed, you need to either enable a dynamic cpufreq governor | 9 | clock speed, you need to either enable a dynamic cpufreq governor |
| 10 | (see below) after boot, or use a userspace tool. | 10 | (see below) after boot, or use a userspace tool. |
| 11 | 11 | ||
| 12 | To compile this driver as a module, choose M here: the | ||
| 13 | module will be called cpufreq. | ||
| 14 | |||
| 15 | For details, take a look at <file:Documentation/cpu-freq>. | 12 | For details, take a look at <file:Documentation/cpu-freq>. |
| 16 | 13 | ||
| 17 | If in doubt, say N. | 14 | If in doubt, say N. |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index b730d6709529..64926aa990db 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -287,7 +287,7 @@ static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) | |||
| 287 | if (!l_p_j_ref_freq) { | 287 | if (!l_p_j_ref_freq) { |
| 288 | l_p_j_ref = loops_per_jiffy; | 288 | l_p_j_ref = loops_per_jiffy; |
| 289 | l_p_j_ref_freq = ci->old; | 289 | l_p_j_ref_freq = ci->old; |
| 290 | dprintk("saving %lu as reference value for loops_per_jiffy;" | 290 | dprintk("saving %lu as reference value for loops_per_jiffy; " |
| 291 | "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq); | 291 | "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq); |
| 292 | } | 292 | } |
| 293 | if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) || | 293 | if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) || |
| @@ -295,7 +295,7 @@ static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) | |||
| 295 | (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) { | 295 | (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) { |
| 296 | loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, | 296 | loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, |
| 297 | ci->new); | 297 | ci->new); |
| 298 | dprintk("scaling loops_per_jiffy to %lu" | 298 | dprintk("scaling loops_per_jiffy to %lu " |
| 299 | "for frequency %u kHz\n", loops_per_jiffy, ci->new); | 299 | "for frequency %u kHz\n", loops_per_jiffy, ci->new); |
| 300 | } | 300 | } |
| 301 | } | 301 | } |
| @@ -601,6 +601,31 @@ static ssize_t show_affected_cpus (struct cpufreq_policy * policy, char *buf) | |||
| 601 | return i; | 601 | return i; |
| 602 | } | 602 | } |
| 603 | 603 | ||
| 604 | static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, | ||
| 605 | const char *buf, size_t count) | ||
| 606 | { | ||
| 607 | unsigned int freq = 0; | ||
| 608 | unsigned int ret; | ||
| 609 | |||
| 610 | if (!policy->governor->store_setspeed) | ||
| 611 | return -EINVAL; | ||
| 612 | |||
| 613 | ret = sscanf(buf, "%u", &freq); | ||
| 614 | if (ret != 1) | ||
| 615 | return -EINVAL; | ||
| 616 | |||
| 617 | policy->governor->store_setspeed(policy, freq); | ||
| 618 | |||
| 619 | return count; | ||
| 620 | } | ||
| 621 | |||
| 622 | static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf) | ||
| 623 | { | ||
| 624 | if (!policy->governor->show_setspeed) | ||
| 625 | return sprintf(buf, "<unsupported>\n"); | ||
| 626 | |||
| 627 | return policy->governor->show_setspeed(policy, buf); | ||
| 628 | } | ||
| 604 | 629 | ||
| 605 | #define define_one_ro(_name) \ | 630 | #define define_one_ro(_name) \ |
| 606 | static struct freq_attr _name = \ | 631 | static struct freq_attr _name = \ |
| @@ -624,6 +649,7 @@ define_one_ro(affected_cpus); | |||
| 624 | define_one_rw(scaling_min_freq); | 649 | define_one_rw(scaling_min_freq); |
| 625 | define_one_rw(scaling_max_freq); | 650 | define_one_rw(scaling_max_freq); |
| 626 | define_one_rw(scaling_governor); | 651 | define_one_rw(scaling_governor); |
| 652 | define_one_rw(scaling_setspeed); | ||
| 627 | 653 | ||
| 628 | static struct attribute * default_attrs[] = { | 654 | static struct attribute * default_attrs[] = { |
| 629 | &cpuinfo_min_freq.attr, | 655 | &cpuinfo_min_freq.attr, |
| @@ -634,6 +660,7 @@ static struct attribute * default_attrs[] = { | |||
| 634 | &scaling_governor.attr, | 660 | &scaling_governor.attr, |
| 635 | &scaling_driver.attr, | 661 | &scaling_driver.attr, |
| 636 | &scaling_available_governors.attr, | 662 | &scaling_available_governors.attr, |
| 663 | &scaling_setspeed.attr, | ||
| 637 | NULL | 664 | NULL |
| 638 | }; | 665 | }; |
| 639 | 666 | ||
| @@ -1313,7 +1340,7 @@ static int cpufreq_resume(struct sys_device * sysdev) | |||
| 1313 | struct cpufreq_freqs freqs; | 1340 | struct cpufreq_freqs freqs; |
| 1314 | 1341 | ||
| 1315 | if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) | 1342 | if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) |
| 1316 | dprintk("Warning: CPU frequency" | 1343 | dprintk("Warning: CPU frequency " |
| 1317 | "is %u, cpufreq assumed %u kHz.\n", | 1344 | "is %u, cpufreq assumed %u kHz.\n", |
| 1318 | cur_freq, cpu_policy->cur); | 1345 | cur_freq, cpu_policy->cur); |
| 1319 | 1346 | ||
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index f8cdde4bf6cd..cb2ac01a41a1 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c | |||
| @@ -65,12 +65,12 @@ static struct notifier_block userspace_cpufreq_notifier_block = { | |||
| 65 | 65 | ||
| 66 | /** | 66 | /** |
| 67 | * cpufreq_set - set the CPU frequency | 67 | * cpufreq_set - set the CPU frequency |
| 68 | * @policy: pointer to policy struct where freq is being set | ||
| 68 | * @freq: target frequency in kHz | 69 | * @freq: target frequency in kHz |
| 69 | * @cpu: CPU for which the frequency is to be set | ||
| 70 | * | 70 | * |
| 71 | * Sets the CPU frequency to freq. | 71 | * Sets the CPU frequency to freq. |
| 72 | */ | 72 | */ |
| 73 | static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy) | 73 | static int cpufreq_set(struct cpufreq_policy *policy, unsigned int freq) |
| 74 | { | 74 | { |
| 75 | int ret = -EINVAL; | 75 | int ret = -EINVAL; |
| 76 | 76 | ||
| @@ -102,34 +102,11 @@ static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy) | |||
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | 104 | ||
| 105 | /************************** sysfs interface ************************/ | 105 | static ssize_t show_speed(struct cpufreq_policy *policy, char *buf) |
| 106 | static ssize_t show_speed (struct cpufreq_policy *policy, char *buf) | ||
| 107 | { | 106 | { |
| 108 | return sprintf (buf, "%u\n", cpu_cur_freq[policy->cpu]); | 107 | return sprintf(buf, "%u\n", cpu_cur_freq[policy->cpu]); |
| 109 | } | 108 | } |
| 110 | 109 | ||
| 111 | static ssize_t | ||
| 112 | store_speed (struct cpufreq_policy *policy, const char *buf, size_t count) | ||
| 113 | { | ||
| 114 | unsigned int freq = 0; | ||
| 115 | unsigned int ret; | ||
| 116 | |||
| 117 | ret = sscanf (buf, "%u", &freq); | ||
| 118 | if (ret != 1) | ||
| 119 | return -EINVAL; | ||
| 120 | |||
| 121 | cpufreq_set(freq, policy); | ||
| 122 | |||
| 123 | return count; | ||
| 124 | } | ||
| 125 | |||
| 126 | static struct freq_attr freq_attr_scaling_setspeed = | ||
| 127 | { | ||
| 128 | .attr = { .name = "scaling_setspeed", .mode = 0644 }, | ||
| 129 | .show = show_speed, | ||
| 130 | .store = store_speed, | ||
| 131 | }; | ||
| 132 | |||
| 133 | static int cpufreq_governor_userspace(struct cpufreq_policy *policy, | 110 | static int cpufreq_governor_userspace(struct cpufreq_policy *policy, |
| 134 | unsigned int event) | 111 | unsigned int event) |
| 135 | { | 112 | { |
| @@ -142,10 +119,6 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, | |||
| 142 | return -EINVAL; | 119 | return -EINVAL; |
| 143 | BUG_ON(!policy->cur); | 120 | BUG_ON(!policy->cur); |
| 144 | mutex_lock(&userspace_mutex); | 121 | mutex_lock(&userspace_mutex); |
| 145 | rc = sysfs_create_file (&policy->kobj, | ||
| 146 | &freq_attr_scaling_setspeed.attr); | ||
| 147 | if (rc) | ||
| 148 | goto start_out; | ||
| 149 | 122 | ||
| 150 | if (cpus_using_userspace_governor == 0) { | 123 | if (cpus_using_userspace_governor == 0) { |
| 151 | cpufreq_register_notifier( | 124 | cpufreq_register_notifier( |
| @@ -160,7 +133,7 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy, | |||
| 160 | cpu_cur_freq[cpu] = policy->cur; | 133 | cpu_cur_freq[cpu] = policy->cur; |
| 161 | cpu_set_freq[cpu] = policy->cur; | 134 | cpu_set_freq[cpu] = policy->cur; |
| 162 | dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]); | 135 | dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]); |
| 163 | start_out: | 136 | |
| 164 | mutex_unlock(&userspace_mutex); | 137 | mutex_unlock(&userspace_mutex); |
| 165 | break; | 138 | break; |
| 166 | case CPUFREQ_GOV_STOP: | 139 | case CPUFREQ_GOV_STOP: |
| @@ -176,7 +149,6 @@ start_out: | |||
| 176 | cpu_min_freq[cpu] = 0; | 149 | cpu_min_freq[cpu] = 0; |
| 177 | cpu_max_freq[cpu] = 0; | 150 | cpu_max_freq[cpu] = 0; |
| 178 | cpu_set_freq[cpu] = 0; | 151 | cpu_set_freq[cpu] = 0; |
| 179 | sysfs_remove_file (&policy->kobj, &freq_attr_scaling_setspeed.attr); | ||
| 180 | dprintk("managing cpu %u stopped\n", cpu); | 152 | dprintk("managing cpu %u stopped\n", cpu); |
| 181 | mutex_unlock(&userspace_mutex); | 153 | mutex_unlock(&userspace_mutex); |
| 182 | break; | 154 | break; |
| @@ -211,6 +183,8 @@ start_out: | |||
| 211 | struct cpufreq_governor cpufreq_gov_userspace = { | 183 | struct cpufreq_governor cpufreq_gov_userspace = { |
| 212 | .name = "userspace", | 184 | .name = "userspace", |
| 213 | .governor = cpufreq_governor_userspace, | 185 | .governor = cpufreq_governor_userspace, |
| 186 | .store_setspeed = cpufreq_set, | ||
| 187 | .show_setspeed = show_speed, | ||
| 214 | .owner = THIS_MODULE, | 188 | .owner = THIS_MODULE, |
| 215 | }; | 189 | }; |
| 216 | EXPORT_SYMBOL(cpufreq_gov_userspace); | 190 | EXPORT_SYMBOL(cpufreq_gov_userspace); |
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 5409f3afb3f8..ae6cd60d5c14 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c | |||
| @@ -171,7 +171,7 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target); | |||
| 171 | 171 | ||
| 172 | static struct cpufreq_frequency_table *show_table[NR_CPUS]; | 172 | static struct cpufreq_frequency_table *show_table[NR_CPUS]; |
| 173 | /** | 173 | /** |
| 174 | * show_scaling_governor - show the current policy for the specified CPU | 174 | * show_available_freqs - show available frequencies for the specified CPU |
| 175 | */ | 175 | */ |
| 176 | static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf) | 176 | static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf) |
| 177 | { | 177 | { |
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 23932d7741a9..ddd8652fc3f3 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
| @@ -167,6 +167,10 @@ struct cpufreq_governor { | |||
| 167 | char name[CPUFREQ_NAME_LEN]; | 167 | char name[CPUFREQ_NAME_LEN]; |
| 168 | int (*governor) (struct cpufreq_policy *policy, | 168 | int (*governor) (struct cpufreq_policy *policy, |
| 169 | unsigned int event); | 169 | unsigned int event); |
| 170 | ssize_t (*show_setspeed) (struct cpufreq_policy *policy, | ||
| 171 | char *buf); | ||
| 172 | int (*store_setspeed) (struct cpufreq_policy *policy, | ||
| 173 | unsigned int freq); | ||
| 170 | unsigned int max_transition_latency; /* HW must be able to switch to | 174 | unsigned int max_transition_latency; /* HW must be able to switch to |
| 171 | next freq faster than this value in nano secs or we | 175 | next freq faster than this value in nano secs or we |
| 172 | will fallback to performance governor */ | 176 | will fallback to performance governor */ |
