Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.osdl.org>2004-01-04 19:03:45 -0800
committerLinus Torvalds <torvalds@home.osdl.org>2004-01-04 19:03:45 -0800
commit259cf59f8d249c126d42e55cc12c51eaf0cdf07e (patch)
treeb4f2f02ba8b1226187a06da6ee804f52f4d90379
parent48818fe15745470d76a3768eef93569ded9c9fa5 (diff)
parentb8645a8e13908d9260b52825d259a5828794e0de (diff)
Merge centrino speedstep duplicate patches
-rw-r--r--arch/arm/mach-integrator/cpu.c2
-rw-r--r--arch/i386/kernel/cpu/cpufreq/acpi.c4
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c11
-rw-r--r--arch/i386/kernel/cpu/cpufreq/p4-clockmod.c68
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k7.c9
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k8.c16
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c16
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-lib.c37
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-lib.h2
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-smi.c46
-rw-r--r--arch/i386/kernel/timers/timer_tsc.c35
-rw-r--r--drivers/cpufreq/Kconfig2
-rw-r--r--include/linux/cpufreq.h12
13 files changed, 191 insertions, 69 deletions
diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c
index 69456d0f095d..a33722ede48a 100644
--- a/arch/arm/mach-integrator/cpu.c
+++ b/arch/arm/mach-integrator/cpu.c
@@ -172,7 +172,7 @@ static int integrator_cpufreq_init(struct cpufreq_policy *policy)
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.max_freq = 160000;
policy->cpuinfo.min_freq = 12000;
- policy->cpuinfo.transition_latency = 1000; /* 1 ms, assumed */
+ policy->cpuinfo.transition_latency = 1000000; /* 1 ms, assumed */
policy->cur = policy->min = policy->max =
icst525_khz(&cclk_params, vco); /* current freq */
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi.c b/arch/i386/kernel/cpu/cpufreq/acpi.c
index 1da77a79043e..776ac256fb6e 100644
--- a/arch/i386/kernel/cpu/cpufreq/acpi.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi.c
@@ -578,8 +578,8 @@ acpi_cpufreq_cpu_init (
/* detect transition latency */
policy->cpuinfo.transition_latency = 0;
for (i=0;i<perf->state_count;i++) {
- if (perf->states[i].transition_latency > policy->cpuinfo.transition_latency)
- policy->cpuinfo.transition_latency = perf->states[i].transition_latency;
+ if ((perf->states[i].transition_latency * 1000) > policy->cpuinfo.transition_latency)
+ policy->cpuinfo.transition_latency = perf->states[i].transition_latency * 1000;
}
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cur = perf->states[pr->limit.state.px].core_frequency * 1000;
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index c0dd4b2622ab..24d06b63a72c 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -170,6 +170,9 @@ static void longhaul_setstate (unsigned int clock_ratio_index)
* between that value multiplied by possible FSBs and cpu_mhz which
* was calculated at boot time. Really ugly, but no other way to do this.
*/
+
+#define ROUNDING 0xf
+
static int _guess (int guess, int maxmult)
{
int target;
@@ -177,16 +180,20 @@ static int _guess (int guess, int maxmult)
target = ((maxmult/10)*guess);
if (maxmult%10 != 0)
target += (guess/2);
- target &= ~0xf;
+ target += ROUNDING/2;
+ target &= ~ROUNDING;
return target;
}
static int guess_fsb(int maxmult)
{
- int speed = (cpu_khz/1000) & ~0xf;
+ int speed = (cpu_khz/1000);
int i;
int speeds[3] = { 66, 100, 133 };
+ speed += ROUNDING/2;
+ speed &= ~ROUNDING;
+
for (i=0; i<3; i++) {
if (_guess(speeds[i],maxmult) == speed)
return speeds[i];
diff --git a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
index da3e11035e3a..d8837afdf69d 100644
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
@@ -48,8 +48,7 @@ enum {
static int has_N44_O17_errata[NR_CPUS];
-static int stock_freq;
-
+static unsigned int stock_freq;
static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
{
@@ -175,6 +174,54 @@ static int cpufreq_p4_verify(struct cpufreq_policy *policy)
return cpufreq_frequency_table_verify(policy, &p4clockmod_table[0]);
}
+/* copied from speedstep_lib, made SMP-compatible */
+static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
+{
+ u32 msr_lo, msr_hi, mult;
+ unsigned int fsb = 0;
+
+ if (c->x86 != 0xF) {
+ printk(KERN_DEBUG PFX "Unknown P4. Please send an e-mail to <linux@brodo.de>\n");
+ return 0;
+ }
+
+ rdmsr(0x2c, msr_lo, msr_hi);
+
+ /* printk(KERN_DEBUG PFX "P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); */
+ /* decode the FSB: see IA-32 Intel (C) Architecture Software
+ * Developer's Manual, Volume 3: System Prgramming Guide,
+ * revision #12 in Table B-1: MSRs in the Pentium 4 and
+ * Intel Xeon Processors, on page B-4 and B-5.
+ */
+ if (c->x86_model < 2)
+ fsb = 100 * 1000;
+ else {
+ u8 fsb_code = (msr_lo >> 16) & 0x7;
+ switch (fsb_code) {
+ case 0:
+ fsb = 100 * 1000;
+ break;
+ case 1:
+ fsb = 13333 * 10;
+ break;
+ case 2:
+ fsb = 200 * 1000;
+ break;
+ }
+ }
+
+ if (!fsb) {
+ printk(KERN_DEBUG PFX "couldn't detect FSB speed. Please send an e-mail to <linux@brodo.de>\n");
+ printk(KERN_DEBUG PFX "P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi);
+ }
+
+ /* Multiplier. */
+ mult = msr_lo >> 24;
+
+ return (fsb * mult);
+}
+
+
static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
{
@@ -192,15 +239,10 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
has_N44_O17_errata[policy->cpu] = 1;
}
- /* get frequency */
- if (!stock_freq) {
- if (cpu_khz)
- stock_freq = cpu_khz;
- else {
- printk(KERN_INFO PFX "unknown core frequency - please use module parameter 'stock_freq'\n");
- return -EINVAL;
- }
- }
+ /* get max frequency */
+ stock_freq = cpufreq_p4_get_frequency(c);
+ if (!stock_freq)
+ return -EINVAL;
/* table init */
for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) {
@@ -213,7 +255,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
/* cpuinfo and default policy values */
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
- policy->cpuinfo.transition_latency = 1000;
+ policy->cpuinfo.transition_latency = 1000000; /* assumed */
policy->cur = stock_freq;
return cpufreq_frequency_table_cpuinfo(policy, &p4clockmod_table[0]);
@@ -269,8 +311,6 @@ static void __exit cpufreq_p4_exit(void)
}
-MODULE_PARM(stock_freq, "i");
-
MODULE_AUTHOR ("Zwane Mwaikambo <zwane@commfireservices.com>");
MODULE_DESCRIPTION ("cpufreq driver for Pentium(TM) 4/Xeon(TM)");
MODULE_LICENSE ("GPL");
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
index e3632cbf0da8..ee99237eb2e3 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
@@ -337,7 +337,8 @@ static int powernow_decode_bios (int maxfid, int startvid)
}
}
printk (KERN_INFO PFX "No PST tables match this cpuid (0x%x)\n", etuple);
- printk ("This is indicative of a broken BIOS. Email davej@redhat.com\n");
+ printk (KERN_INFO PFX "This is indicative of a broken BIOS.\n");
+ printk (KERN_INFO PFX "See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.shtml\n");
return -EINVAL;
}
p++;
@@ -386,7 +387,11 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
minimum_speed, maximum_speed);
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
- policy->cpuinfo.transition_latency = latency;
+
+ /* latency is in 10 ns (look for SGTC above) for each VID
+ * and FID transition, so multiply that value with 20 */
+ policy->cpuinfo.transition_latency = latency * 20;
+
policy->cur = maximum_speed;
return cpufreq_frequency_table_cpuinfo(policy, powernow_table);
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
index ef8393cfa54e..f38f4a5be3e8 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -687,11 +687,13 @@ find_psb_table(void)
if (ppst[j].vid < rvo) { /* vid+rvo >= 0 */
printk(KERN_ERR BFX
"0 vid exceeded with pstate %d\n", j);
+ kfree(ppst);
return -ENODEV;
}
if (ppst[j].vid < maxvid+rvo) { /* vid+rvo >= maxvid */
printk(KERN_ERR BFX
"maxvid exceeded with pstate %d\n", j);
+ kfree(ppst);
return -ENODEV;
}
}
@@ -706,7 +708,7 @@ find_psb_table(void)
for (j = 0; j < numps; j++)
if ((ppst[j].fid==currfid) && (ppst[j].vid==currvid))
- return (0);
+ return 0;
printk(KERN_ERR BFX "currfid/vid do not match PST, ignoring\n");
return 0;
@@ -935,10 +937,7 @@ powernowk8_verify(struct cpufreq_policy *pol)
return -ENODEV;
}
-#warning pol->policy is in undefined state here
- res = find_match(&targ, &min, &max,
- pol->policy == CPUFREQ_POLICY_POWERSAVE ?
- SEARCH_DOWN : SEARCH_UP, 0, 0);
+ res = find_match(&targ, &min, &max, SEARCH_DOWN, 0, 0);
if (!res) {
pol->min = min * 1000;
pol->max = max * 1000;
@@ -957,9 +956,10 @@ powernowk8_cpu_init(struct cpufreq_policy *pol)
pol->governor = CPUFREQ_DEFAULT_GOVERNOR;
- /* Take a crude guess here. */
- pol->cpuinfo.transition_latency = ((rvo + 8) * vstable * VST_UNITS_20US)
- + (3 * (1 << irt) * 10);
+ /* Take a crude guess here.
+ * That guess was in microseconds, so multply with 1000 */
+ pol->cpuinfo.transition_latency = (((rvo + 8) * vstable * VST_UNITS_20US)
+ + (3 * (1 << irt) * 10)) * 1000;
if (query_current_values_with_pending_wait())
return -EIO;
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index 55f881115747..7f8844cffcf9 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -75,13 +75,13 @@ static struct cpufreq_frequency_table op_900[] =
/* Ultra Low Voltage Intel Pentium M processor 1000MHz */
static struct cpufreq_frequency_table op_1000[] =
- {
- OP(600, 844),
- OP(800, 972),
- OP(900, 988),
- OP(1000, 1004),
- { .frequency = CPUFREQ_TABLE_END }
- };
+{
+ OP(600, 844),
+ OP(800, 972),
+ OP(900, 988),
+ OP(1000, 1004),
+ { .frequency = CPUFREQ_TABLE_END }
+};
/* Low Voltage Intel Pentium M processor 1.10GHz */
static struct cpufreq_frequency_table op_1100[] =
@@ -175,7 +175,7 @@ static struct cpufreq_frequency_table op_1700[] =
static const struct cpu_model models[] =
{
_CPU( 900, " 900"),
- CPU(1000),
+ CPU(1000),
CPU(1100),
CPU(1200),
CPU(1300),
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
index e3a75684f1d1..927d3bebd6ff 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
@@ -106,14 +106,45 @@ static unsigned int pentium3_get_frequency (unsigned int processor)
static unsigned int pentium4_get_frequency(void)
{
- u32 msr_lo, msr_hi;
+ struct cpuinfo_x86 *c = &boot_cpu_data;
+ u32 msr_lo, msr_hi, mult;
+ unsigned int fsb = 0;
rdmsr(0x2c, msr_lo, msr_hi);
dprintk(KERN_DEBUG "speedstep-lib: P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi);
- msr_lo >>= 24;
- return (msr_lo * 100000);
+ /* decode the FSB: see IA-32 Intel (C) Architecture Software
+ * Developer's Manual, Volume 3: System Prgramming Guide,
+ * revision #12 in Table B-1: MSRs in the Pentium 4 and
+ * Intel Xeon Processors, on page B-4 and B-5.
+ */
+ if (c->x86_model < 2)
+ fsb = 100 * 1000;
+ else {
+ u8 fsb_code = (msr_lo >> 16) & 0x7;
+ switch (fsb_code) {
+ case 0:
+ fsb = 100 * 1000;
+ break;
+ case 1:
+ fsb = 13333 * 10;
+ break;
+ case 2:
+ fsb = 200 * 1000;
+ break;
+ }
+ }
+
+ if (!fsb)
+ printk(KERN_DEBUG "speedstep-lib: couldn't detect FSB speed. Please send an e-mail to <linux@brodo.de>\n");
+
+ /* Multiplier. */
+ mult = msr_lo >> 24;
+
+ dprintk(KERN_DEBUG "speedstep-lib: P4 - FSB %u kHz; Multiplier %u\n", fsb, mult);
+
+ return (fsb * mult);
}
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
index 04951e0e65d1..ff7521d0195d 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
@@ -15,7 +15,7 @@
#define SPEEDSTEP_PROCESSOR_PIII_C_EARLY 0x00000001 /* Coppermine core */
#define SPEEDSTEP_PROCESSOR_PIII_C 0x00000002 /* Coppermine core */
#define SPEEDSTEP_PROCESSOR_PIII_T 0x00000003 /* Tualatin core */
-#define SPEEDSTEP_PROCESSOR_P4M 0x00000004 /* P4-M with 100 MHz FSB */
+#define SPEEDSTEP_PROCESSOR_P4M 0x00000004 /* P4-M */
/* speedstep states -- only two of them */
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
index bab8d19dd3e1..157899d60d7a 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
@@ -19,6 +19,7 @@
#include <linux/cpufreq.h>
#include <linux/pci.h>
#include <linux/slab.h>
+#include <linux/delay.h>
#include <asm/ist.h>
#include "speedstep-lib.h"
@@ -51,10 +52,14 @@ static struct cpufreq_frequency_table speedstep_freqs[] = {
#define SET_SPEEDSTEP_STATE 2
#define GET_SPEEDSTEP_FREQS 4
+/* how often shall the SMI call be tried if it failed, e.g. because
+ * 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
+//#define SPEEDSTEP_DEBUG
#ifdef SPEEDSTEP_DEBUG
#define dprintk(msg...) printk(msg)
@@ -85,6 +90,9 @@ static int speedstep_smi_ownership (void)
/**
* speedstep_smi_get_freqs - get SpeedStep preferred & current freq.
+ * Only available on later SpeedStep-enabled systems, returns false results or
+ * even hangs [cf. bugme.osdl.org # 1422] on earlier systems. Empirical testing
+ * shows that the latter occurs if !(ist_info.event & 0xFFFF).
*
*/
static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
@@ -93,6 +101,9 @@ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
u32 state=0;
u32 function = GET_SPEEDSTEP_FREQS;
+ if (!(ist_info.event & 0xFFFF))
+ return -ENODEV;
+
command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
__asm__ __volatile__("movl $0, %%edi\n"
@@ -134,10 +145,11 @@ static int speedstep_get_state (void)
*/
static void speedstep_set_state (unsigned int state, unsigned int notify)
{
- unsigned int old_state, result, command, new_state;
+ unsigned int old_state, result = 0, command, new_state;
unsigned long flags;
struct cpufreq_freqs freqs;
unsigned int function=SET_SPEEDSTEP_STATE;
+ unsigned int retry = 0;
if (state > 0x1)
return;
@@ -157,20 +169,28 @@ static void speedstep_set_state (unsigned int state, unsigned int notify)
local_irq_save(flags);
command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
- __asm__ __volatile__(
- "movl $0, %%edi\n"
- "out %%al, (%%dx)\n"
- : "=b" (new_state), "=D" (result)
- : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0)
- );
+
+ do {
+ if (retry) {
+ dprintk(KERN_INFO "cpufreq: retry %u, previous result %u\n", retry, result);
+ mdelay(retry * 50);
+ }
+ retry++;
+ __asm__ __volatile__(
+ "movl $0, %%edi\n"
+ "out %%al, (%%dx)\n"
+ : "=b" (new_state), "=D" (result)
+ : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0)
+ );
+ } while ((new_state != state) && (retry <= SMI_TRIES));
/* enable IRQs */
local_irq_restore(flags);
if (new_state == state) {
- dprintk(KERN_INFO "cpufreq: change to %u MHz succeded\n", (freqs.new / 1000));
+ dprintk(KERN_INFO "cpufreq: change to %u MHz succeeded after %u tries with result %u\n", (freqs.new / 1000), retry, result);
} else {
- printk(KERN_ERR "cpufreq: change failed\n");
+ printk(KERN_ERR "cpufreq: change failed with new_state %u and result %u\n", new_state, result);
}
if (notify)
@@ -225,9 +245,10 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
return -ENODEV;
result = speedstep_smi_ownership();
-
- if (result)
+ if (result) {
dprintk(KERN_INFO "cpufreq: fails an aquiring ownership of a SMI interface.\n");
+ return -EINVAL;
+ }
/* detect low and high frequency */
result = speedstep_smi_get_freqs(&speedstep_freqs[SPEEDSTEP_LOW].frequency,
@@ -286,6 +307,7 @@ static struct cpufreq_driver speedstep_driver = {
.target = speedstep_target,
.init = speedstep_cpu_init,
.resume = speedstep_resume,
+ .owner = THIS_MODULE,
};
/**
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
index 67db5f6ebe2f..0030d7989fea 100644
--- a/arch/i386/kernel/timers/timer_tsc.c
+++ b/arch/i386/kernel/timers/timer_tsc.c
@@ -317,9 +317,17 @@ static void mark_offset_tsc_hpet(void)
}
#endif
+
#ifdef CONFIG_CPU_FREQ
+/* If the CPU frequency is scaled, TSC-based delays will need a different
+ * loops_per_jiffy value to function properly. An exception to this
+ * are modern Intel Pentium 4 processors, where the TSC runs at a constant
+ * speed independent of frequency scaling.
+ */
+
static unsigned int ref_freq = 0;
static unsigned long loops_per_jiffy_ref = 0;
+static unsigned int variable_tsc = 1;
#ifndef CONFIG_SMP
static unsigned long fast_gettimeoffset_ref = 0;
@@ -344,12 +352,15 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) ||
(val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
- cpu_data[freq->cpu].loops_per_jiffy = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new);
+ if (variable_tsc)
+ cpu_data[freq->cpu].loops_per_jiffy = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new);
#ifndef CONFIG_SMP
if (use_tsc) {
- fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq);
cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new);
- set_cyc2ns_scale(cpu_khz/1000);
+ if (variable_tsc) {
+ fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_ref, freq->new, ref_freq);
+ set_cyc2ns_scale(cpu_khz/1000);
+ }
}
#endif
}
@@ -361,7 +372,19 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
static struct notifier_block time_cpufreq_notifier_block = {
.notifier_call = time_cpufreq_notifier
};
-#endif
+
+
+static int __init cpufreq_tsc(void)
+{
+ /* P4 and above CPU TSC freq doesn't change when CPU frequency changes*/
+ if ((boot_cpu_data.x86 >= 15) && (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL))
+ variable_tsc = 0;
+
+ return cpufreq_register_notifier(&time_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
+}
+core_initcall(cpufreq_tsc);
+
+#endif
static int __init init_tsc(char* override)
@@ -403,10 +426,6 @@ static int __init init_tsc(char* override)
* some CPU's have a TSC. Thats never worked and nobody has
* moaned if you have the only one in the world - you fix it!
*/
-
-#ifdef CONFIG_CPU_FREQ
- cpufreq_register_notifier(&time_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
-#endif
count2 = LATCH; /* initialize counter for mark_offset_tsc() */
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index 3c496cfef0e1..8fde104e4f08 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -74,7 +74,7 @@ config CPU_FREQ_24_API
help
This enables the /proc/sys/cpu/ sysctl interface for controlling
the CPUFreq,"userspace" governor. This is the same interface
- as known from the.4.-kernel patches for CPUFreq, and offers
+ as known from the 2.4.-kernel patches for CPUFreq, and offers
the same functionality as long as "userspace" is the
selected governor for the specified CPU.
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 51790ee0ed6c..bbc983dc8913 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -57,7 +57,7 @@ struct cpufreq_governor;
struct cpufreq_cpuinfo {
unsigned int max_freq;
unsigned int min_freq;
- unsigned int transition_latency; /* in 10^(-9) s */
+ unsigned int transition_latency; /* in 10^(-9) s = nanoseconds */
};
struct cpufreq_real_policy {
@@ -231,17 +231,18 @@ int cpufreq_update_policy(unsigned int cpu);
/* the proc_intf.c needs this */
int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor);
-#if defined(CONFIG_CPU_FREQ_GOV_USERSPACE) || defined(CONFIG_CPU_FREQ_GOV_USERSPACE_MODULE)
+
/*********************************************************************
* CPUFREQ USERSPACE GOVERNOR *
*********************************************************************/
int cpufreq_gov_userspace_init(void);
+#ifdef CONFIG_CPU_FREQ_24_API
+
int cpufreq_setmax(unsigned int cpu);
int cpufreq_set(unsigned int kHz, unsigned int cpu);
unsigned int cpufreq_get(unsigned int cpu);
-#ifdef CONFIG_CPU_FREQ_24_API
/* /proc/sys/cpu */
enum {
@@ -289,8 +290,6 @@ enum {
#endif /* CONFIG_CPU_FREQ_24_API */
-#endif /* CONFIG_CPU_FREQ_GOV_USERSPACE */
-
/*********************************************************************
* CPUFREQ DEFAULT GOVERNOR *
@@ -305,6 +304,7 @@ extern struct cpufreq_governor cpufreq_gov_userspace;
#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_userspace
#endif
+
/*********************************************************************
* FREQUENCY TABLE HELPERS *
*********************************************************************/
@@ -318,7 +318,6 @@ struct cpufreq_frequency_table {
* order */
};
-#if defined(CONFIG_CPU_FREQ_TABLE) || defined(CONFIG_CPU_FREQ_TABLE_MODULE)
int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table);
@@ -340,5 +339,4 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
void cpufreq_frequency_table_put_attr(unsigned int cpu);
-#endif /* CONFIG_CPU_FREQ_TABLE */
#endif /* _LINUX_CPUFREQ_H */