Commit 3ee1e204 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linux-dj.bkbits.net/cpufreq

into home.osdl.org:/home/torvalds/v2.5/linux
parents 6fd6bef3 b9ecdfd3
......@@ -1522,17 +1522,12 @@ S: USA
N: Dave Jones
E: davej@codemonkey.org.uk
E: davej@suse.de
W: http://www.codemonkey.org.uk
D: x86 errata/setup maintenance.
D: AGPGART driver.
D: CPUFREQ maintenance.
D: Backport/Forwardport merge monkey.
D: Various Janitor work.
S: c/o SuSE Linux UK Ltd
S: Appleton House
S: 139 King Street
S: Hammersmith
S: W6 9JG
S: United Kingdom
N: Ani Joshi
......
......@@ -73,9 +73,9 @@ The phase is specified in the second argument to the notifier.
The third argument, a void *pointer, points to a struct cpufreq_policy
consisting of five values: cpu, min, max, policy and max_cpu_freq. min
and max are the lower and upper frequencies (in kHz) of the new
policy, policy the new policy, cpu the number of the affected CPU or
CPUFREQ_ALL_CPUS for all CPUs; and max_cpu_freq the maximum supported
CPU frequency. This value is given for informational purposes only.
policy, policy the new policy, cpu the number of the affected CPU; and
max_cpu_freq the maximum supported CPU frequency. This value is given
for informational purposes only.
2.2 CPUFreq transition notifiers
......@@ -89,6 +89,6 @@ CPUFREQ_POSTCHANGE.
The third argument is a struct cpufreq_freqs with the following
values:
cpu - number of the affected CPU or CPUFREQ_ALL_CPUS
cpu - number of the affected CPU
old - old frequency
new - new frequency
......@@ -41,16 +41,17 @@ on what is necessary:
1.1 Initialization
------------------
First of all, in an __initcall level 7 or later (preferrably
module_init() so that your driver is modularized) function check
whether this kernel runs on the right CPU and the right chipset. If
so, register a struct cpufreq_driver with the CPUfreq core using
cpufreq_register_driver()
First of all, in an __initcall level 7 (module_init()) or later
function check whether this kernel runs on the right CPU and the right
chipset. If so, register a struct cpufreq_driver with the CPUfreq core
using cpufreq_register_driver()
What shall this struct cpufreq_driver contain?
cpufreq_driver.name - The name of this driver.
cpufreq_driver.owner - THIS_MODULE;
cpufreq_driver.init - A pointer to the per-CPU initialization
function.
......@@ -76,8 +77,7 @@ cpufreq driver registers itself, the per-CPU initialization function
cpufreq_driver.init is called. It takes a struct cpufreq_policy
*policy as argument. What to do now?
If necessary, activate the CPUfreq support on your CPU (unlock that
register etc.).
If necessary, activate the CPUfreq support on your CPU.
Then, the driver must fill in the following values:
......
......@@ -135,21 +135,21 @@ CPUfreq core to ensure proper locking.
The CPUfreq governor may call the CPU processor driver using one of
these two functions:
inline int cpufreq_driver_target(struct cpufreq_policy *policy,
int cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation);
inline int cpufreq_driver_target_l(struct cpufreq_policy *policy,
int __cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation);
target_freq must be within policy->min and policy->max, of course.
What's the difference between these two functions? When your governor
still is in a direct code path of a call to governor->governor, the
cpufreq_driver_sem lock is still held in the cpufreq core, and there's
per-CPU cpufreq lock is still held in the cpufreq core, and there's
no need to lock it again (in fact, this would cause a deadlock). So
use cpufreq_driver_target only in these cases. In all other cases (for
example, when there's a "daemonized" function that wakes up every
second), use cpufreq_driver_target_l to lock the cpufreq_driver_sem
before the command is passed to the cpufreq processor driver.
use __cpufreq_driver_target only in these cases. In all other cases
(for example, when there's a "daemonized" function that wakes up
every second), use cpufreq_driver_target to lock the cpufreq per-CPU
lock before the command is passed to the cpufreq processor driver.
......@@ -132,7 +132,7 @@ the processor shall run at.
The preferred interface is located in the sysfs filesystem. If you
mounted it at /sys, the cpufreq interface is located in a subdirectory
"cpufreq" within the cpu-device directory
(e.g. /sys/class/cpu/cpu0/cpufreq/ for the first CPU).
(e.g. /sys/devices/system/cpu/cpu0/cpufreq/ for the first CPU).
cpuinfo_min_freq : this file shows the minimum operating
frequency the processor can run at(in kHz)
......
......@@ -431,9 +431,11 @@ W: http://www.fi.muni.cz/~kas/cosa/
S: Maintained
CPU FREQUENCY DRIVERS
L: cpufreq@www.linux.org.uk
W: http://www.brodo.de/cpufreq/
S: Maintained
P: Dave Jones
M: davej@codemonkey.org.uk
L: cpufreq@www.linux.org.uk
W: http://www.codemonkey.org.uk/cpufreq/
S: Maintained
CPUID/MSR DRIVER
P: H. Peter Anvin
......@@ -840,7 +842,7 @@ S: Maintained
i386 SETUP CODE / CPU ERRATA WORKAROUNDS
P: Dave Jones
M: davej@suse.de
M: davej@codemonkey.org.uk
P: H. Peter Anvin
M: hpa@zytor.com
S: Maintained
......
......@@ -288,10 +288,23 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
c->x86 = 3;
}
if (this_cpu->c_identify)
generic_identify(c);
printk(KERN_DEBUG "CPU: After generic identify, caps: %08lx %08lx %08lx %08lx\n",
c->x86_capability[0],
c->x86_capability[1],
c->x86_capability[2],
c->x86_capability[3]);
if (this_cpu->c_identify) {
this_cpu->c_identify(c);
else
generic_identify(c);
printk(KERN_DEBUG "CPU: After vendor identify, caps: %08lx %08lx %08lx %08lx\n",
c->x86_capability[0],
c->x86_capability[1],
c->x86_capability[2],
c->x86_capability[3]);
}
/*
* Vendor-specific initialization. In this section we
......@@ -341,7 +354,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
/* Now the feature flags better reflect actual CPU features! */
printk(KERN_DEBUG "CPU: After generic, caps: %08lx %08lx %08lx %08lx\n",
printk(KERN_DEBUG "CPU: After all inits, caps: %08lx %08lx %08lx %08lx\n",
c->x86_capability[0],
c->x86_capability[1],
c->x86_capability[2],
......
......@@ -380,7 +380,7 @@ static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file)
static int
acpi_processor_write_performance (
struct file *file,
const char *buffer,
const char __user *buffer,
size_t count,
loff_t *data)
{
......
This diff is collapsed.
/*
* longhaul.h
* (C) 2003 Dave Jones.
*
* Licensed under the terms of the GNU GPL License version 2.
*
* VIA-specific information
*/
union msr_bcr2 {
struct {
unsigned Reseved:19, // 18:0
ESOFTBF:1, // 19
Reserved2:3, // 22:20
CLOCKMUL:4, // 26:23
Reserved3:5; // 31:27
} bits;
unsigned long val;
};
union msr_longhaul {
struct {
unsigned RevisionID:4, // 3:0
RevisionKey:4, // 7:4
EnableSoftBusRatio:1, // 8
EnableSoftVID:1, // 9
EnableSoftBSEL:1, // 10
Reserved:3, // 11:13
SoftBusRatio4:1, // 14
VRMRev:1, // 15
SoftBusRatio:4, // 19:16
SoftVID:5, // 24:20
Reserved2:3, // 27:25
SoftBSEL:2, // 29:28
Reserved3:2, // 31:30
MaxMHzBR:4, // 35:32
MaximumVID:5, // 40:36
MaxMHzFSB:2, // 42:41
MaxMHzBR4:1, // 43
Reserved4:4, // 47:44
MinMHzBR:4, // 51:48
MinimumVID:5, // 56:52
MinMHzFSB:2, // 58:57
MinMHzBR4:1, // 59
Reserved5:4; // 63:60
} bits;
unsigned long long val;
};
/*
* $Id: longrun.c,v 1.25 2003/02/28 16:03:50 db Exp $
*
* (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
*
* Licensed under the terms of the GNU GPL License version 2.
......@@ -123,7 +121,7 @@ static int longrun_verify_policy(struct cpufreq_policy *policy)
policy->cpuinfo.max_freq);
if (policy->policy == CPUFREQ_POLICY_GOVERNOR)
policy->policy = longrun_driver.policy[0].policy;
return -EINVAL;
return 0;
}
......
/*
* $Id: powernow-k6.c,v 1.48 2003/02/22 10:23:46 db Exp $
* This file was part of Powertweak Linux (http://powertweak.sf.net)
* and is shared with the Linux Kernel module.
*
* This file was based upon code in Powertweak Linux (http://powertweak.sf.net)
* (C) 2000-2003 Dave Jones, Arjan van de Ven, Janne Pnkl, Dominik Brodowski.
*
* Licensed under the terms of the GNU GPL License version 2.
......@@ -230,7 +227,7 @@ static void __exit powernow_k6_exit(void)
}
MODULE_AUTHOR ("Arjan van de Ven <arjanv@redhat.com>, Dave Jones <davej@suse.de>, Dominik Brodowski <linux@brodo.de>");
MODULE_AUTHOR ("Arjan van de Ven <arjanv@redhat.com>, Dave Jones <davej@codemonkey.org.uk>, Dominik Brodowski <linux@brodo.de>");
MODULE_DESCRIPTION ("PowerNow! driver for AMD K6-2+ / K6-3+ processors.");
MODULE_LICENSE ("GPL");
......
/*
* $Id: powernow-k7.c,v 1.34 2003/02/22 10:23:46 db Exp $
*
* (C) 2003 Dave Jones <davej@suse.de>
* AMD K7 Powernow driver.
* (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs.
*
* Licensed under the terms of the GNU GPL License version 2.
* Based upon datasheets & sample CPUs kindly provided by AMD.
......@@ -85,27 +84,6 @@ static unsigned int latency;
static char have_a0;
#ifndef rdmsrl
#define rdmsrl(msr,val) do {unsigned long l__,h__; \
rdmsr (msr, l__, h__); \
val = l__; \
val |= ((u64)h__<<32); \
} while(0)
#endif
#ifndef wrmsrl
static void wrmsrl (u32 msr, u64 val)
{
u32 lo, hi;
lo = (u32) val;
hi = val >> 32;
wrmsr (msr, lo, hi);
}
#endif
static int check_powernow(void)
{
struct cpuinfo_x86 *c = cpu_data;
......@@ -240,6 +218,7 @@ static void change_speed (unsigned int index)
u8 fid, vid;
struct cpufreq_freqs freqs;
union msr_fidvidstatus fidvidstatus;
int cfid;
/* fid are the lower 8 bits of the index we stored into
* the cpufreq frequency table in powernow_decode_bios,
......@@ -251,8 +230,9 @@ static void change_speed (unsigned int index)
freqs.cpu = 0;
cfid = fidvidstatus.bits.CFID;
rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
freqs.old = fsb * fid_codes[fidvidstatus.bits.CFID] * 100;
freqs.old = fsb * fid_codes[cfid] * 100;
freqs.new = powernow_table[index].frequency;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
......@@ -426,7 +406,7 @@ static void __exit powernow_exit (void)
kfree(powernow_table);
}
MODULE_AUTHOR ("Dave Jones <davej@suse.de>");
MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
MODULE_LICENSE ("GPL");
......
......@@ -8,14 +8,6 @@
*
*/
#ifndef MSR_K7_FID_VID_CTL
#define MSR_K7_FID_VID_CTL 0xc0010041
#endif
#ifndef MSR_K7_FID_VID_STATUS
#define MSR_K7_FID_VID_STATUS 0xc0010042
#endif
union msr_fidvidctl {
struct {
unsigned FID:5, // 4:0
......
......@@ -82,7 +82,7 @@ static void speedstep_set_state (unsigned int state, unsigned int notify)
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)
......@@ -137,7 +137,7 @@ static void speedstep_set_state (unsigned int state, unsigned int notify)
dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
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", (speedstep_get_processor_frequency(speedstep_processor) / 1000));
} else {
printk (KERN_ERR "cpufreq: change failed - I/O error\n");
}
......@@ -295,7 +295,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
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 */
......@@ -356,7 +356,7 @@ static void __exit speedstep_exit(void)
}
MODULE_AUTHOR ("Dave Jones <davej@suse.de>, Dominik Brodowski <linux@brodo.de>");
MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>, Dominik Brodowski <linux@brodo.de>");
MODULE_DESCRIPTION ("Speedstep driver for Intel mobile processors on chipsets with ICH-M southbridges.");
MODULE_LICENSE ("GPL");
......
......@@ -158,7 +158,7 @@ EXPORT_SYMBOL(cpufreq_get);
/*********************** cpufreq_sysctl interface ********************/
static int
cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
void *buffer, size_t *lenp)
void __user *buffer, size_t *lenp)
{
char buf[16], *p;
int cpu = (int) ctl->extra1;
......@@ -195,9 +195,9 @@ cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
}
static int
cpufreq_sysctl(ctl_table *table, int *name, int nlen,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen, void **context)
cpufreq_sysctl(ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen, void **context)
{
int cpu = (int) table->extra1;
......@@ -524,10 +524,10 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
cpu_min_freq[cpu] = policy->min;
cpu_max_freq[cpu] = policy->max;
if (policy->max < cpu_cur_freq[cpu])
cpufreq_driver_target(&current_policy[cpu], policy->max,
__cpufreq_driver_target(&current_policy[cpu], policy->max,
CPUFREQ_RELATION_H);
else if (policy->min > cpu_cur_freq[cpu])
cpufreq_driver_target(&current_policy[cpu], policy->min,
__cpufreq_driver_target(&current_policy[cpu], policy->min,
CPUFREQ_RELATION_L);
memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
up(&userspace_sem);
......
......@@ -8,15 +8,30 @@
*/
#define rdmsr(msr,val1,val2) \
__asm__ __volatile__("rdmsr" \
__asm__ __volatile__("rdmsr" \
: "=a" (val1), "=d" (val2) \
: "c" (msr))
#define wrmsr(msr,val1,val2) \
__asm__ __volatile__("wrmsr" \
__asm__ __volatile__("wrmsr" \
: /* no outputs */ \
: "c" (msr), "a" (val1), "d" (val2))
#define rdmsrl(msr,val) do { \
unsigned long l__,h__; \
rdmsr (msr, l__, h__); \
val = l__; \
val |= ((u64)h__<<32); \
} while(0)
static inline void wrmsrl (unsigned long msr, unsigned long long val)
{
unsigned long lo, hi;
lo = (unsigned long) val;
hi = val >> 32;
wrmsr (msr, lo, hi);
}
#define rdtsc(low,high) \
__asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
......@@ -200,7 +215,7 @@
#define MSR_K7_HWCR 0xC0010015
#define MSR_K7_CLK_CTL 0xC001001b
#define MSR_K7_FID_VID_CTL 0xC0010041
#define MSR_K7_VID_STATUS 0xC0010042
#define MSR_K7_FID_VID_STATUS 0xC0010042
/* Centaur-Hauls/IDT defined MSRs. */
#define MSR_IDT_FCR1 0x107
......
......@@ -137,9 +137,13 @@ struct cpufreq_governor {
/* pass a target to the cpufreq driver
*/
inline int cpufreq_driver_target(struct cpufreq_policy *policy,
extern int cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation);
extern int __cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation);
/* pass an event to the cpufreq governor */
int cpufreq_governor(unsigned int cpu, unsigned int event);
......@@ -160,8 +164,6 @@ struct cpufreq_driver {
struct module *owner;
char name[CPUFREQ_NAME_LEN];
struct cpufreq_policy *policy;
/* needed by all drivers */
int (*init) (struct cpufreq_policy *policy);
int (*verify) (struct cpufreq_policy *policy);
......
This diff is collapsed.
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