aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/e_powersaver.c
diff options
context:
space:
mode:
authorRafał Bilski <rafalbilski@interia.pl>2011-07-20 16:20:56 -0400
committerDave Jones <davej@redhat.com>2011-10-26 17:19:46 -0400
commited361bf08033f165e0a004f254919e13f07df0ae (patch)
tree6241c9d1f047aeeb460e80f22d2f6d1b1c49e54a /drivers/cpufreq/e_powersaver.c
parent5beae3b9b6f5479998310a849f73aa32a637dd3b (diff)
[CPUFREQ] e_powersaver: Additional checks
Some systems are using 1,2Ghz@844mV processors running at 600MHz@796mV. Try to detect such systems and don't touch anything on it. If CPU doesn't have P-States in BIOS it should run at maximum frequency. Allow user to bypass checks by means of two new options. Don't set frequency to maximum on module unloading to avoid bada boom. It is also possible that some processors may have incorrect values in min/max registers caused by error in manufacturing process. Probably it would be BIOS job to set them to right frequency and P-States tables would have correct values inside. Two additional sanity checks for voltage. Signed-off-by: Rafał Bilski <rafalbilski@interia.pl> Signed-off-by: Dave Jones <davej@redhat.com>
Diffstat (limited to 'drivers/cpufreq/e_powersaver.c')
-rw-r--r--drivers/cpufreq/e_powersaver.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c
index 35a257dd4bb7..84661c54a74c 100644
--- a/drivers/cpufreq/e_powersaver.c
+++ b/drivers/cpufreq/e_powersaver.c
@@ -32,6 +32,10 @@ struct eps_cpu_data {
32 32
33static struct eps_cpu_data *eps_cpu[NR_CPUS]; 33static struct eps_cpu_data *eps_cpu[NR_CPUS];
34 34
35/* Module parameters */
36static int freq_failsafe_off;
37static int voltage_failsafe_off;
38
35 39
36static unsigned int eps_get(unsigned int cpu) 40static unsigned int eps_get(unsigned int cpu)
37{ 41{
@@ -244,9 +248,27 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
244 return -EINVAL; 248 return -EINVAL;
245 if (current_voltage > 0x1f || max_voltage > 0x1f) 249 if (current_voltage > 0x1f || max_voltage > 0x1f)
246 return -EINVAL; 250 return -EINVAL;
247 if (max_voltage < min_voltage) 251 if (max_voltage < min_voltage
252 || current_voltage < min_voltage
253 || current_voltage > max_voltage)
248 return -EINVAL; 254 return -EINVAL;
249 255
256 /* Check for systems using underclocked CPU */
257 if (!freq_failsafe_off && max_multiplier != current_multiplier) {
258 printk(KERN_INFO "eps: Your processor is running at different "
259 "frequency then its maximum. Aborting.\n");
260 printk(KERN_INFO "eps: You can use freq_failsafe_off option "
261 "to disable this check.\n");
262 return -EINVAL;
263 }
264 if (!voltage_failsafe_off && max_voltage != current_voltage) {
265 printk(KERN_INFO "eps: Your processor is running at different "
266 "voltage then its maximum. Aborting.\n");
267 printk(KERN_INFO "eps: You can use voltage_failsafe_off "
268 "option to disable this check.\n");
269 return -EINVAL;
270 }
271
250 /* Calc FSB speed */ 272 /* Calc FSB speed */
251 fsb = cpu_khz / current_multiplier; 273 fsb = cpu_khz / current_multiplier;
252 /* Calc number of p-states supported */ 274 /* Calc number of p-states supported */
@@ -303,17 +325,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
303static int eps_cpu_exit(struct cpufreq_policy *policy) 325static int eps_cpu_exit(struct cpufreq_policy *policy)
304{ 326{
305 unsigned int cpu = policy->cpu; 327 unsigned int cpu = policy->cpu;
306 struct eps_cpu_data *centaur;
307 u32 lo, hi;
308
309 if (eps_cpu[cpu] == NULL)
310 return -ENODEV;
311 centaur = eps_cpu[cpu];
312 328
313 /* Get max frequency */
314 rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
315 /* Set max frequency */
316 eps_set_state(centaur, cpu, hi & 0xffff);
317 /* Bye */ 329 /* Bye */
318 cpufreq_frequency_table_put_attr(policy->cpu); 330 cpufreq_frequency_table_put_attr(policy->cpu);
319 kfree(eps_cpu[cpu]); 331 kfree(eps_cpu[cpu]);
@@ -359,6 +371,13 @@ static void __exit eps_exit(void)
359 cpufreq_unregister_driver(&eps_driver); 371 cpufreq_unregister_driver(&eps_driver);
360} 372}
361 373
374/* Allow user to overclock his machine or to change frequency to higher after
375 * unloading module */
376module_param(freq_failsafe_off, int, 0644);
377MODULE_PARM_DESC(freq_failsafe_off, "Disable current vs max frequency check");
378module_param(voltage_failsafe_off, int, 0644);
379MODULE_PARM_DESC(voltage_failsafe_off, "Disable current vs max voltage check");
380
362MODULE_AUTHOR("Rafal Bilski <rafalbilski@interia.pl>"); 381MODULE_AUTHOR("Rafal Bilski <rafalbilski@interia.pl>");
363MODULE_DESCRIPTION("Enhanced PowerSaver driver for VIA C7 CPU's."); 382MODULE_DESCRIPTION("Enhanced PowerSaver driver for VIA C7 CPU's.");
364MODULE_LICENSE("GPL"); 383MODULE_LICENSE("GPL");