X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fi386%2Fkernel%2Fcpu%2Fcpufreq%2Fspeedstep-smi.c;h=79440b3f087ec9beeca123de97b9da6b572bd171;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=5d176b19acfb7890581f80a7b8227ebd9bcfcf30;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c index 5d176b19a..79440b3f0 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c @@ -24,8 +24,6 @@ #include "speedstep-lib.h" -#define PFX "speedstep-smi: " - /* speedstep system management interface port/command. * * These parameters are got from IST-SMI BIOS call. @@ -58,16 +56,7 @@ static struct cpufreq_frequency_table speedstep_freqs[] = { * of DMA activity going on? */ #define SMI_TRIES 5 -/* DEBUG - * Define it if you want verbose debug output, e.g. for bug reporting - */ -//#define SPEEDSTEP_DEBUG - -#ifdef SPEEDSTEP_DEBUG -#define dprintk(msg...) printk(msg) -#else -#define dprintk(msg...) do { } while(0) -#endif +#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-smi", msg) /** * speedstep_smi_ownership @@ -81,12 +70,16 @@ static int speedstep_smi_ownership (void) command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); magic = virt_to_phys(magic_data); + dprintk("trying to obtain ownership with command %x at port %x\n", command, smi_port); + __asm__ __volatile__( "out %%al, (%%dx)\n" : "=D" (result) : "a" (command), "b" (function), "c" (0), "d" (smi_port), "D" (0), "S" (magic) ); + dprintk("result is %x\n", result); + return result; } @@ -101,21 +94,27 @@ static int speedstep_smi_ownership (void) */ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high) { - u32 command, result, edi, high_mhz, low_mhz; + u32 command, result = 0, edi, high_mhz, low_mhz; u32 state=0; u32 function = GET_SPEEDSTEP_FREQS; - if (!(ist_info.event & 0xFFFF)) + if (!(ist_info.event & 0xFFFF)) { + dprintk("bug #1422 -- can't read freqs from BIOS\n", result); return -ENODEV; + } command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); + dprintk("trying to determine frequencies with command %x at port %x\n", command, smi_port); + __asm__ __volatile__("movl $0, %%edi\n" "out %%al, (%%dx)\n" : "=a" (result), "=b" (high_mhz), "=c" (low_mhz), "=d" (state), "=D" (edi) : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0) ); + dprintk("result %x, low_freq %u, high_freq %u\n", result, low_mhz, high_mhz); + /* abort if results are obviously incorrect... */ if ((high_mhz + low_mhz) < 600) return -EINVAL; @@ -138,15 +137,20 @@ static int speedstep_get_state (void) command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); + dprintk("trying to determine current setting with command %x at port %x\n", command, smi_port); + __asm__ __volatile__("movl $0, %%edi\n" "out %%al, (%%dx)\n" : "=a" (result), "=b" (state), "=D" (edi) : "a" (command), "b" (function), "c" (0), "d" (smi_port), "S" (0) ); + dprintk("state is %x, result is %x\n", state, result); + return (state & 1); } + /** * speedstep_set_state - set the SpeedStep state * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) @@ -167,9 +171,11 @@ static void speedstep_set_state (unsigned int state) command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); + dprintk("trying to set frequency to state %u with command %x at port %x\n", state, command, smi_port); + do { if (retry) { - dprintk(KERN_INFO "cpufreq: retry %u, previous result %u\n", retry, result); + dprintk("retry %u, previous result %u, waiting...\n", retry, result); mdelay(retry * 50); } retry++; @@ -185,7 +191,7 @@ static void speedstep_set_state (unsigned int state) local_irq_restore(flags); if (new_state == state) { - dprintk(KERN_INFO "cpufreq: change to %u MHz succeeded after %u tries with result %u\n", (speedstep_freqs[new_state].frequency / 1000), retry, result); + dprintk("change to %u MHz succeeded after %u tries with result %u\n", (speedstep_freqs[new_state].frequency / 1000), retry, result); } else { printk(KERN_ERR "cpufreq: change failed with new_state %u and result %u\n", new_state, result); } @@ -250,7 +256,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) result = speedstep_smi_ownership(); if (result) { - dprintk(KERN_INFO "cpufreq: fails an aquiring ownership of a SMI interface.\n"); + dprintk("fails in aquiring ownership of a SMI interface.\n"); return -EINVAL; } @@ -259,30 +265,24 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) &speedstep_freqs[SPEEDSTEP_HIGH].frequency); if (result) { /* fall back to speedstep_lib.c dection mechanism: try both states out */ - dprintk(KERN_INFO PFX "could not detect low and high frequencies by SMI call.\n"); - if (!speedstep_processor) - speedstep_processor = speedstep_detect_processor(); - - if (!speedstep_processor) - return -ENODEV; - + dprintk("could not detect low and high frequencies by SMI call.\n"); result = speedstep_get_freqs(speedstep_processor, &speedstep_freqs[SPEEDSTEP_LOW].frequency, &speedstep_freqs[SPEEDSTEP_HIGH].frequency, &speedstep_set_state); if (result) { - dprintk(KERN_INFO PFX "could not detect two different speeds -- aborting.\n"); + dprintk("could not detect two different speeds -- aborting.\n"); return result; } else - dprintk(KERN_INFO PFX "workaround worked.\n"); + dprintk("workaround worked.\n"); } /* get current speed setting */ state = speedstep_get_state(); speed = speedstep_freqs[state].frequency; - dprintk(KERN_INFO "cpufreq: currently at %s speed setting - %i MHz\n", + dprintk("currently at %s speed setting - %i MHz\n", (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high", (speed / 1000)); @@ -310,10 +310,6 @@ static unsigned int speedstep_get(unsigned int cpu) { if (cpu) return -ENODEV; - if (!speedstep_processor) - speedstep_processor = speedstep_detect_processor(); - if (!speedstep_processor) - return 0; return speedstep_get_processor_frequency(speedstep_processor); } @@ -323,7 +319,7 @@ static int speedstep_resume(struct cpufreq_policy *policy) int result = speedstep_smi_ownership(); if (result) - dprintk(KERN_INFO "cpufreq: fails an aquiring ownership of a SMI interface.\n"); + dprintk("fails in re-aquiring ownership of a SMI interface.\n"); return result; } @@ -354,14 +350,23 @@ static struct cpufreq_driver speedstep_driver = { */ static int __init speedstep_init(void) { - struct cpuinfo_x86 *c = cpu_data; + speedstep_processor = speedstep_detect_processor(); + + switch (speedstep_processor) { + case SPEEDSTEP_PROCESSOR_PIII_T: + case SPEEDSTEP_PROCESSOR_PIII_C: + case SPEEDSTEP_PROCESSOR_PIII_C_EARLY: + break; + default: + speedstep_processor = 0; + } - if (c->x86_vendor != X86_VENDOR_INTEL) { - printk (KERN_INFO PFX "No Intel CPU detected.\n"); + if (!speedstep_processor) { + dprintk ("No supported Intel CPU detected.\n"); return -ENODEV; } - dprintk(KERN_DEBUG PFX "signature:0x%.8lx, command:0x%.8lx, event:0x%.8lx, perf_level:0x%.8lx.\n", + dprintk("signature:0x%.8lx, command:0x%.8lx, event:0x%.8lx, perf_level:0x%.8lx.\n", ist_info.signature, ist_info.command, ist_info.event, ist_info.perf_level);