Commit 20ab1b04 authored by Dominik Brodowski's avatar Dominik Brodowski Committed by Linus Torvalds

[PATCH] cpufreq bugfixes

- incorrect pointer calculation spotted by Gerald Britton
- speedstep.c cleanup (Gerald Britton)
parent 05178dd5
...@@ -290,7 +290,7 @@ static int __init elanfreq_init(void) ...@@ -290,7 +290,7 @@ static int __init elanfreq_init(void)
if (!driver) if (!driver)
return -ENOMEM; return -ENOMEM;
driver->policy = (struct cpufreq_policy *) (driver + sizeof(struct cpufreq_driver)); driver->policy = (struct cpufreq_policy *) (driver + 1);
if (!max_freq) if (!max_freq)
max_freq = elanfreq_get_cpu_frequency(); max_freq = elanfreq_get_cpu_frequency();
......
/* /*
* $Id: longhaul.c,v 1.70 2002/09/12 10:22:17 db Exp $ * $Id: longhaul.c,v 1.72 2002/09/29 23:43:10 db Exp $
* *
* (C) 2001 Dave Jones. <davej@suse.de> * (C) 2001 Dave Jones. <davej@suse.de>
* (C) 2002 Padraig Brady. <padraig@antefacto.com> * (C) 2002 Padraig Brady. <padraig@antefacto.com>
...@@ -771,7 +771,7 @@ static int __init longhaul_init (void) ...@@ -771,7 +771,7 @@ static int __init longhaul_init (void)
if (!driver) if (!driver)
return -ENOMEM; return -ENOMEM;
driver->policy = (struct cpufreq_policy *) (driver + sizeof(struct cpufreq_driver)); driver->policy = (struct cpufreq_policy *) (driver + 1);
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = (unsigned int) lowest_speed; driver->cpu_min_freq = (unsigned int) lowest_speed;
......
/* /*
* $Id: longrun.c,v 1.10 2002/09/22 09:01:41 db Exp $ * $Id: longrun.c,v 1.12 2002/09/29 23:43:10 db Exp $
* *
* (C) 2002 Dominik Brodowski <linux@brodo.de> * (C) 2002 Dominik Brodowski <linux@brodo.de>
* *
...@@ -241,7 +241,7 @@ static int __init longrun_init(void) ...@@ -241,7 +241,7 @@ static int __init longrun_init(void)
if (!driver) if (!driver)
return -ENOMEM; return -ENOMEM;
driver->policy = (struct cpufreq_policy *) (driver + sizeof(struct cpufreq_driver)); driver->policy = (struct cpufreq_policy *) (driver + 1);
if (longrun_determine_freqs(&longrun_low_freq, &longrun_high_freq)) { if (longrun_determine_freqs(&longrun_low_freq, &longrun_high_freq)) {
kfree(driver); kfree(driver);
......
...@@ -225,7 +225,7 @@ int __init cpufreq_p4_init(void) ...@@ -225,7 +225,7 @@ int __init cpufreq_p4_init(void)
if (!driver) if (!driver)
return -ENOMEM; return -ENOMEM;
driver->policy = (struct cpufreq_policy *) (driver + sizeof(struct cpufreq_driver)); driver->policy = (struct cpufreq_policy *) (driver + 1);
if (!stock_freq) if (!stock_freq)
stock_freq = cpu_khz; stock_freq = cpu_khz;
......
/* /*
* $Id: powernow-k6.c,v 1.31 2002/09/21 09:05:29 db Exp $ * $Id: powernow-k6.c,v 1.33 2002/09/29 23:43:11 db Exp $
* This file was part of Powertweak Linux (http://powertweak.sf.net) * This file was part of Powertweak Linux (http://powertweak.sf.net)
* and is shared with the Linux Kernel module. * and is shared with the Linux Kernel module.
* *
...@@ -239,7 +239,7 @@ static int __init powernow_k6_init(void) ...@@ -239,7 +239,7 @@ static int __init powernow_k6_init(void)
release_region (POWERNOW_IOPORT, 16); release_region (POWERNOW_IOPORT, 16);
return -ENOMEM; return -ENOMEM;
} }
driver->policy = (struct cpufreq_policy *) (driver + sizeof(struct cpufreq_driver)); driver->policy = (struct cpufreq_policy *) (driver + 1);
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = busfreq * 20; driver->cpu_min_freq = busfreq * 20;
......
/* /*
* $Id: speedstep.c,v 1.50 2002/09/22 08:16:25 db Exp $ * $Id: speedstep.c,v 1.53 2002/09/29 23:43:11 db Exp $
* *
* (C) 2001 Dave Jones, Arjan van de ven. * (C) 2001 Dave Jones, Arjan van de ven.
* (C) 2002 Dominik Brodowski <linux@brodo.de> * (C) 2002 Dominik Brodowski <linux@brodo.de>
...@@ -91,6 +91,7 @@ static unsigned int speedstep_high_freq; ...@@ -91,6 +91,7 @@ static unsigned int speedstep_high_freq;
*/ */
static int speedstep_get_state (unsigned int *state) static int speedstep_get_state (unsigned int *state)
{ {
unsigned long flags;
u32 pmbase; u32 pmbase;
u8 value; u8 value;
...@@ -110,9 +111,9 @@ static int speedstep_get_state (unsigned int *state) ...@@ -110,9 +111,9 @@ static int speedstep_get_state (unsigned int *state)
return -EIO; return -EIO;
/* read state */ /* read state */
local_irq_disable(); local_irq_save(flags);
value = inb(pmbase + 0x50); value = inb(pmbase + 0x50);
local_irq_enable(); local_irq_restore(flags);
dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
...@@ -132,7 +133,7 @@ static int speedstep_get_state (unsigned int *state) ...@@ -132,7 +133,7 @@ static int speedstep_get_state (unsigned int *state)
* *
* Tries to change the SpeedStep state. * Tries to change the SpeedStep state.
*/ */
static void speedstep_set_state (unsigned int state) static void speedstep_set_state (unsigned int state, int notify)
{ {
u32 pmbase; u32 pmbase;
u8 pm2_blk; u8 pm2_blk;
...@@ -154,7 +155,8 @@ static void speedstep_set_state (unsigned int state) ...@@ -154,7 +155,8 @@ static void speedstep_set_state (unsigned int state)
freqs.new = (state == SPEEDSTEP_HIGH) ? speedstep_high_freq : speedstep_low_freq; freqs.new = (state == SPEEDSTEP_HIGH) ? speedstep_high_freq : speedstep_low_freq;
freqs.cpu = CPUFREQ_ALL_CPUS; /* speedstep.c is UP only driver */ freqs.cpu = CPUFREQ_ALL_CPUS; /* speedstep.c is UP only driver */
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); if (notify)
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
switch (speedstep_chipset) { switch (speedstep_chipset) {
case SPEEDSTEP_CHIPSET_ICH2M: case SPEEDSTEP_CHIPSET_ICH2M:
...@@ -173,10 +175,11 @@ static void speedstep_set_state (unsigned int state) ...@@ -173,10 +175,11 @@ static void speedstep_set_state (unsigned int state)
return; return;
} }
/* Disable IRQs */
local_irq_save(flags);
/* read state */ /* read state */
local_irq_disable();
value = inb(pmbase + 0x50); value = inb(pmbase + 0x50);
local_irq_enable();
dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
...@@ -186,10 +189,6 @@ static void speedstep_set_state (unsigned int state) ...@@ -186,10 +189,6 @@ static void speedstep_set_state (unsigned int state)
dprintk(KERN_DEBUG "cpufreq: writing 0x%x to pmbase 0x%x + 0x50\n", value, pmbase); dprintk(KERN_DEBUG "cpufreq: writing 0x%x to pmbase 0x%x + 0x50\n", value, pmbase);
/* Disable IRQs */
local_irq_save(flags);
local_irq_disable();
/* Disable bus master arbitration */ /* Disable bus master arbitration */
pm2_blk = inb(pmbase + 0x20); pm2_blk = inb(pmbase + 0x20);
pm2_blk |= 0x01; pm2_blk |= 0x01;
...@@ -202,14 +201,11 @@ static void speedstep_set_state (unsigned int state) ...@@ -202,14 +201,11 @@ static void speedstep_set_state (unsigned int state)
pm2_blk &= 0xfe; pm2_blk &= 0xfe;
outb(pm2_blk, (pmbase + 0x20)); outb(pm2_blk, (pmbase + 0x20));
/* Enable IRQs */
local_irq_enable();
local_irq_restore(flags);
/* check if transition was sucessful */ /* check if transition was sucessful */
local_irq_disable();
value = inb(pmbase + 0x50); value = inb(pmbase + 0x50);
local_irq_enable();
/* Enable IRQs */
local_irq_restore(flags);
dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
...@@ -223,7 +219,8 @@ static void speedstep_set_state (unsigned int state) ...@@ -223,7 +219,8 @@ static void speedstep_set_state (unsigned int state)
printk (KERN_ERR "cpufreq: setting CPU frequency on this chipset unsupported.\n"); printk (KERN_ERR "cpufreq: setting CPU frequency on this chipset unsupported.\n");
} }
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); if (notify)
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return; return;
} }
...@@ -526,10 +523,13 @@ static unsigned int speedstep_detect_processor (void) ...@@ -526,10 +523,13 @@ static unsigned int speedstep_detect_processor (void)
*/ */
static int speedstep_detect_speeds (void) static int speedstep_detect_speeds (void)
{ {
unsigned long flags;
unsigned int state; unsigned int state;
unsigned int low = 0, high = 0;
int i, result; int i, result;
/* Disable irqs for entire detection process */
local_irq_save(flags);
for (i=0; i<2; i++) { for (i=0; i<2; i++) {
/* read the current state */ /* read the current state */
result = speedstep_get_state(&state); result = speedstep_get_state(&state);
...@@ -541,31 +541,30 @@ static int speedstep_detect_speeds (void) ...@@ -541,31 +541,30 @@ static int speedstep_detect_speeds (void)
switch (speedstep_processor) { switch (speedstep_processor) {
case SPEEDSTEP_PROCESSOR_PIII_C: case SPEEDSTEP_PROCESSOR_PIII_C:
case SPEEDSTEP_PROCESSOR_PIII_T: case SPEEDSTEP_PROCESSOR_PIII_T:
low = pentium3_get_frequency(); speedstep_low_freq = pentium3_get_frequency();
break; break;
case SPEEDSTEP_PROCESSOR_P4M: case SPEEDSTEP_PROCESSOR_P4M:
low = pentium4_get_frequency(); speedstep_low_freq = pentium4_get_frequency();
} }
speedstep_set_state(SPEEDSTEP_HIGH); speedstep_set_state(SPEEDSTEP_HIGH, 0);
} else { } else {
switch (speedstep_processor) { switch (speedstep_processor) {
case SPEEDSTEP_PROCESSOR_PIII_C: case SPEEDSTEP_PROCESSOR_PIII_C:
case SPEEDSTEP_PROCESSOR_PIII_T: case SPEEDSTEP_PROCESSOR_PIII_T:
high = pentium3_get_frequency(); speedstep_high_freq = pentium3_get_frequency();
break; break;
case SPEEDSTEP_PROCESSOR_P4M: case SPEEDSTEP_PROCESSOR_P4M:
high = pentium4_get_frequency(); speedstep_high_freq = pentium4_get_frequency();
} }
speedstep_set_state(SPEEDSTEP_LOW); speedstep_set_state(SPEEDSTEP_LOW, 0);
} }
if (!low || !high ||
(speedstep_low_freq == speedstep_high_freq))
return -EIO;
} }
speedstep_low_freq = low; local_irq_restore(flags);
speedstep_high_freq = high;
if (!speedstep_low_freq || !speedstep_high_freq ||
(speedstep_low_freq == speedstep_high_freq))
return -EIO;
return 0; return 0;
} }
...@@ -583,16 +582,16 @@ static void speedstep_setpolicy (struct cpufreq_policy *policy) ...@@ -583,16 +582,16 @@ static void speedstep_setpolicy (struct cpufreq_policy *policy)
return; return;
if (policy->min > speedstep_low_freq) if (policy->min > speedstep_low_freq)
speedstep_set_state(SPEEDSTEP_HIGH); speedstep_set_state(SPEEDSTEP_HIGH, 1);
else { else {
if (policy->max < speedstep_high_freq) if (policy->max < speedstep_high_freq)
speedstep_set_state(SPEEDSTEP_LOW); speedstep_set_state(SPEEDSTEP_LOW, 1);
else { else {
/* both frequency states are allowed */ /* both frequency states are allowed */
if (policy->policy == CPUFREQ_POLICY_POWERSAVE) if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
speedstep_set_state(SPEEDSTEP_LOW); speedstep_set_state(SPEEDSTEP_LOW, 1);
else else
speedstep_set_state(SPEEDSTEP_HIGH); speedstep_set_state(SPEEDSTEP_HIGH, 1);
} }
} }
} }
...@@ -649,7 +648,7 @@ static int __init speedstep_init(void) ...@@ -649,7 +648,7 @@ static int __init speedstep_init(void)
return -ENODEV; return -ENODEV;
} }
dprintk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.50 $\n"); dprintk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.53 $\n");
dprintk(KERN_DEBUG "cpufreq: chipset 0x%x - processor 0x%x\n", dprintk(KERN_DEBUG "cpufreq: chipset 0x%x - processor 0x%x\n",
speedstep_chipset, speedstep_processor); speedstep_chipset, speedstep_processor);
...@@ -659,8 +658,6 @@ static int __init speedstep_init(void) ...@@ -659,8 +658,6 @@ static int __init speedstep_init(void)
return result; return result;
/* detect low and high frequency */ /* detect low and high frequency */
speedstep_low_freq = 100000;
speedstep_high_freq = 200000;
result = speedstep_detect_speeds(); result = speedstep_detect_speeds();
if (result) if (result)
return result; return result;
...@@ -682,8 +679,8 @@ static int __init speedstep_init(void) ...@@ -682,8 +679,8 @@ static int __init speedstep_init(void)
if (!driver) if (!driver)
return -ENOMEM; return -ENOMEM;
driver->policy = (struct cpufreq_policy *) (driver + sizeof(struct cpufreq_driver)); driver->policy = (struct cpufreq_policy *) (driver + 1);
#ifdef CONFIG_CPU_FREQ_24_API #ifdef CONFIG_CPU_FREQ_24_API
driver->cpu_min_freq = speedstep_low_freq; driver->cpu_min_freq = speedstep_low_freq;
driver->cpu_cur_freq[0] = speed; driver->cpu_cur_freq[0] = speed;
......
...@@ -626,7 +626,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, ...@@ -626,7 +626,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
} }
for (i=0; i<NR_CPUS; i++) for (i=0; i<NR_CPUS; i++)
if ((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == i)) if ((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == i))
cpu_data[i].loops_per_jiffy = cpufreq_scale(loops_per_jiffy, freq->old, freq->new); cpu_data[i].loops_per_jiffy = cpufreq_scale(cpu_data[i].loops_per_jiffy, freq->old, freq->new);
break; break;
case CPUFREQ_POSTCHANGE: case CPUFREQ_POSTCHANGE:
...@@ -637,7 +637,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, ...@@ -637,7 +637,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
} }
for (i=0; i<NR_CPUS; i++) for (i=0; i<NR_CPUS; i++)
if ((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == i)) if ((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == i))
cpu_data[i].loops_per_jiffy = cpufreq_scale(loops_per_jiffy, freq->old, freq->new); cpu_data[i].loops_per_jiffy = cpufreq_scale(cpu_data[i].loops_per_jiffy, freq->old, freq->new);
break; break;
} }
......
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