X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fi386%2Fkernel%2Fcpu%2Fcpufreq%2Fp4-clockmod.c;h=aa622d52c6e538bf616c8d4eeaee8bbe4efce96a;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=ef139496401f82b79a440ffc39e8b2c0cb8a81c6;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c index ef1394964..aa622d52c 100644 --- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c @@ -36,6 +36,7 @@ #include "speedstep-lib.h" #define PFX "p4-clockmod: " +#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "p4-clockmod", msg) /* * Duty Cycle (3bits), note DC_DISABLE is not specified in @@ -62,20 +63,20 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) return -EINVAL; rdmsr(MSR_IA32_THERM_STATUS, l, h); -#if 0 + if (l & 0x01) - printk(KERN_DEBUG PFX "CPU#%d currently thermal throttled\n", cpu); -#endif + dprintk("CPU#%d currently thermal throttled\n", cpu); + if (has_N44_O17_errata[cpu] && (newstate == DC_25PT || newstate == DC_DFLT)) newstate = DC_38PT; rdmsr(MSR_IA32_THERM_CONTROL, l, h); if (newstate == DC_DISABLE) { - /* printk(KERN_INFO PFX "CPU#%d disabling modulation\n", cpu); */ + dprintk("CPU#%d disabling modulation\n", cpu); wrmsr(MSR_IA32_THERM_CONTROL, l & ~(1<<4), h); } else { - /* printk(KERN_INFO PFX "CPU#%d setting duty cycle to %d%%\n", - cpu, ((125 * newstate) / 10)); */ + dprintk("CPU#%d setting duty cycle to %d%%\n", + cpu, ((125 * newstate) / 10)); /* bits 63 - 5 : reserved * bit 4 : enable/disable * bits 3-1 : duty cycle @@ -110,7 +111,7 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy, { unsigned int newstate = DC_RESV; struct cpufreq_freqs freqs; - cpumask_t cpus_allowed, affected_cpu_map; + cpumask_t cpus_allowed; int i; if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0], target_freq, relation, &newstate)) @@ -122,18 +123,8 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy, if (freqs.new == freqs.old) return 0; - /* switch to physical CPU where state is to be changed*/ - cpus_allowed = current->cpus_allowed; - - /* only run on CPU to be set, or on its sibling */ -#ifdef CONFIG_SMP - affected_cpu_map = cpu_sibling_map[policy->cpu]; -#else - affected_cpu_map = cpumask_of_cpu(policy->cpu); -#endif - /* notifiers */ - for_each_cpu_mask(i, affected_cpu_map) { + for_each_cpu_mask(i, policy->cpus) { freqs.cpu = i; cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); } @@ -141,7 +132,9 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy, /* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software * Developer's Manual, Volume 3 */ - for_each_cpu_mask(i, affected_cpu_map) { + cpus_allowed = current->cpus_allowed; + + for_each_cpu_mask(i, policy->cpus) { cpumask_t this_cpu = cpumask_of_cpu(i); set_cpus_allowed(current, this_cpu); @@ -152,7 +145,7 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy, set_cpus_allowed(current, cpus_allowed); /* notifiers */ - for_each_cpu_mask(i, affected_cpu_map) { + for_each_cpu_mask(i, policy->cpus) { freqs.cpu = i; cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); } @@ -178,7 +171,7 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c) return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PM); } - if ((c->x86 == 0x06) && (c->x86_model == 0x13)) { + if ((c->x86 == 0x06) && (c->x86_model == 0x0D)) { /* Pentium M (Dothan) */ printk(KERN_WARNING PFX "Warning: Pentium M detected. " "The speedstep_centrino module offers voltage scaling" @@ -219,6 +212,10 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) int cpuid = 0; unsigned int i; +#ifdef CONFIG_SMP + policy->cpus = cpu_sibling_map[policy->cpu]; +#endif + /* Errata workaround */ cpuid = (c->x86 << 8) | (c->x86_model << 4) | c->x86_mask; switch (cpuid) { @@ -227,6 +224,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) case 0x0f11: case 0x0f12: has_N44_O17_errata[policy->cpu] = 1; + dprintk("has errata -- disabling low frequencies\n"); } /* get max frequency */ @@ -260,14 +258,13 @@ static int cpufreq_p4_cpu_exit(struct cpufreq_policy *policy) static unsigned int cpufreq_p4_get(unsigned int cpu) { - cpumask_t cpus_allowed, affected_cpu_map; + cpumask_t cpus_allowed; u32 l, h; cpus_allowed = current->cpus_allowed; - affected_cpu_map = cpumask_of_cpu(cpu); - set_cpus_allowed(current, affected_cpu_map); - BUG_ON(!cpu_isset(smp_processor_id(), affected_cpu_map)); + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + BUG_ON(smp_processor_id() != cpu); rdmsr(MSR_IA32_THERM_CONTROL, l, h); @@ -305,6 +302,7 @@ static struct cpufreq_driver p4clockmod_driver = { static int __init cpufreq_p4_init(void) { struct cpuinfo_x86 *c = cpu_data; + int ret; /* * THERM_CONTROL is architectural for IA32 now, so @@ -317,9 +315,11 @@ static int __init cpufreq_p4_init(void) !test_bit(X86_FEATURE_ACC, c->x86_capability)) return -ENODEV; - printk(KERN_INFO PFX "P4/Xeon(TM) CPU On-Demand Clock Modulation available\n"); + ret = cpufreq_register_driver(&p4clockmod_driver); + if (!ret) + printk(KERN_INFO PFX "P4/Xeon(TM) CPU On-Demand Clock Modulation available\n"); - return cpufreq_register_driver(&p4clockmod_driver); + return (ret); } @@ -335,4 +335,3 @@ MODULE_LICENSE ("GPL"); late_initcall(cpufreq_p4_init); module_exit(cpufreq_p4_exit); -