
From: Valdis.Kletnieks@vt.edu

I was having problems with i810_audio clocking as well.  It turned out to be
the Intel Speedstep support, of all things.  *IF* your kernel includes:

CONFIG_X86_SPEEDSTEP_ICH=y

it was possible to end up with a broken value for loops_per_jiffie.  I've
attached a patch that fixes the bug and does a few cleanups...



 arch/i386/kernel/cpu/cpufreq/speedstep-ich.c |   15 ++++++++++-----
 1 files changed, 10 insertions(+), 5 deletions(-)

diff -puN arch/i386/kernel/cpu/cpufreq/speedstep-ich.c~speedstep-ich-timing-fix arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
--- 25/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c~speedstep-ich-timing-fix	2003-07-18 22:57:31.000000000 -0700
+++ 25-akpm/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c	2003-07-18 22:57:31.000000000 -0700
@@ -77,15 +77,17 @@ static void speedstep_set_state (unsigne
 	u8			value;
 	unsigned long		flags;
 	struct cpufreq_freqs	freqs;
+	int			newfreq;
 
 	if (!speedstep_chipset_dev || (state > 0x1))
 		return;
 
 	freqs.old = speedstep_get_processor_frequency(speedstep_processor);
-	freqs.new = speedstep_freqs[SPEEDSTEP_LOW].frequency;
+	freqs.new = speedstep_freqs[state].frequency;
 	freqs.cpu = 0; /* speedstep.c is UP only driver */
 	
-	if (notify)
+	/* make sure we've initialized before calling notify */
+	if (notify && (freqs.new != 0))
 		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 
 	/* get PMBASE */
@@ -136,13 +138,16 @@ static void speedstep_set_state (unsigne
 
 	dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
 
+	/* freqs.new may not be set yet - need local copy */
+	newfreq = speedstep_get_processor_frequency(speedstep_processor);
 	if (state == (value & 0x1)) {
-		dprintk (KERN_INFO "cpufreq: change to %u MHz succeeded\n", (freqs.new / 1000));
+		dprintk (KERN_INFO "cpufreq: change to %u MHz succeeded\n", (newfreq / 1000));
 	} else {
 		printk (KERN_ERR "cpufreq: change failed - I/O error\n");
 	}
 
-	if (notify)
+	/* Make sure we're initialized before calling notify */
+	if (notify && (freqs.new != 0))
 		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
 	return;
@@ -295,7 +300,7 @@ static int speedstep_cpu_init(struct cpu
 		return -EIO;
 
 	dprintk(KERN_INFO "cpufreq: currently at %s speed setting - %i MHz\n", 
-		(speed == speedstep_low_freq) ? "low" : "high",
+		(speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high",
 		(speed / 1000));
 
 	/* cpuinfo and default policy values */

_
