Commit ed361bf0 authored by Rafał Bilski's avatar Rafał Bilski Committed by Dave Jones

[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: default avatarRafał Bilski <rafalbilski@interia.pl>
Signed-off-by: default avatarDave Jones <davej@redhat.com>
parent 5beae3b9
...@@ -32,6 +32,10 @@ struct eps_cpu_data { ...@@ -32,6 +32,10 @@ struct eps_cpu_data {
static struct eps_cpu_data *eps_cpu[NR_CPUS]; static struct eps_cpu_data *eps_cpu[NR_CPUS];
/* Module parameters */
static int freq_failsafe_off;
static int voltage_failsafe_off;
static unsigned int eps_get(unsigned int cpu) static unsigned int eps_get(unsigned int cpu)
{ {
...@@ -244,9 +248,27 @@ static int eps_cpu_init(struct cpufreq_policy *policy) ...@@ -244,9 +248,27 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
return -EINVAL; return -EINVAL;
if (current_voltage > 0x1f || max_voltage > 0x1f) if (current_voltage > 0x1f || max_voltage > 0x1f)
return -EINVAL; return -EINVAL;
if (max_voltage < min_voltage) if (max_voltage < min_voltage
|| current_voltage < min_voltage
|| current_voltage > max_voltage)
return -EINVAL; return -EINVAL;
/* Check for systems using underclocked CPU */
if (!freq_failsafe_off && max_multiplier != current_multiplier) {
printk(KERN_INFO "eps: Your processor is running at different "
"frequency then its maximum. Aborting.\n");
printk(KERN_INFO "eps: You can use freq_failsafe_off option "
"to disable this check.\n");
return -EINVAL;
}
if (!voltage_failsafe_off && max_voltage != current_voltage) {
printk(KERN_INFO "eps: Your processor is running at different "
"voltage then its maximum. Aborting.\n");
printk(KERN_INFO "eps: You can use voltage_failsafe_off "
"option to disable this check.\n");
return -EINVAL;
}
/* Calc FSB speed */ /* Calc FSB speed */
fsb = cpu_khz / current_multiplier; fsb = cpu_khz / current_multiplier;
/* Calc number of p-states supported */ /* Calc number of p-states supported */
...@@ -303,17 +325,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy) ...@@ -303,17 +325,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
static int eps_cpu_exit(struct cpufreq_policy *policy) static int eps_cpu_exit(struct cpufreq_policy *policy)
{ {
unsigned int cpu = policy->cpu; unsigned int cpu = policy->cpu;
struct eps_cpu_data *centaur;
u32 lo, hi;
if (eps_cpu[cpu] == NULL)
return -ENODEV;
centaur = eps_cpu[cpu];
/* Get max frequency */
rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
/* Set max frequency */
eps_set_state(centaur, cpu, hi & 0xffff);
/* Bye */ /* Bye */
cpufreq_frequency_table_put_attr(policy->cpu); cpufreq_frequency_table_put_attr(policy->cpu);
kfree(eps_cpu[cpu]); kfree(eps_cpu[cpu]);
...@@ -359,6 +371,13 @@ static void __exit eps_exit(void) ...@@ -359,6 +371,13 @@ static void __exit eps_exit(void)
cpufreq_unregister_driver(&eps_driver); cpufreq_unregister_driver(&eps_driver);
} }
/* Allow user to overclock his machine or to change frequency to higher after
* unloading module */
module_param(freq_failsafe_off, int, 0644);
MODULE_PARM_DESC(freq_failsafe_off, "Disable current vs max frequency check");
module_param(voltage_failsafe_off, int, 0644);
MODULE_PARM_DESC(voltage_failsafe_off, "Disable current vs max voltage check");
MODULE_AUTHOR("Rafal Bilski <rafalbilski@interia.pl>"); MODULE_AUTHOR("Rafal Bilski <rafalbilski@interia.pl>");
MODULE_DESCRIPTION("Enhanced PowerSaver driver for VIA C7 CPU's."); MODULE_DESCRIPTION("Enhanced PowerSaver driver for VIA C7 CPU's.");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment