Commit f3af7498 authored by Linus Torvalds's avatar Linus Torvalds

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

into ppc970.osdl.org:/home/torvalds/v2.6/linux

Fix up cpufreq Makefile merge manually
parents 2d202ddc a1d487d4
The cpufreq-nforce2 driver changes the FSB on nVidia nForce2 plattforms.
This works better than on other plattforms, because the FSB of the CPU
can be controlled independently from the PCI/AGP clock.
The module has two options:
fid: multiplier * 10 (for example 8.5 = 85)
min_fsb: minimum FSB
If not set, fid is calculated from the current CPU speed and the FSB.
min_fsb defaults to FSB at boot time - 50 MHz.
IMPORTANT: The available range is limited downwards!
Also the minimum available FSB can differ, for systems
booting with 200 MHz, 150 should always work.
......@@ -389,17 +389,6 @@ config XIP_PHYS_ADDR
if (ARCH_SA1100 || ARCH_INTEGRATOR)
config CPU_FREQ
bool "Support CPU clock change"
help
CPU clock scaling allows you to change the clock speed of the
running CPU on the fly. This is a nice method to save battery power,
because the lower the clock speed, the less power the CPU
consumes. Note that this driver doesn't automatically change the CPU
clock speed, you need some userland tools (which still have to be
written) to implement the policy. If you don't understand what this
is all about, it's safe to say 'N'.
source "drivers/cpufreq/Kconfig"
config CPU_FREQ_SA1100
......
......@@ -4,18 +4,6 @@
menu "CPU Frequency scaling"
config CPU_FREQ
bool "CPU Frequency scaling"
help
Clock scaling allows you to change the clock speed of CPUs on the
fly. This is a nice method to save battery power on notebooks,
because the lower the clock speed, the less power the CPU consumes.
For more information, take a look at <file:Documentation/cpu-freq/>
or at <http://www.codemonkey.org.uk/projects/cpufreq/>
If in doubt, say N.
source "drivers/cpufreq/Kconfig"
config CPU_FREQ_TABLE
......@@ -182,6 +170,17 @@ config X86_P4_CLOCKMOD
If in doubt, say N.
config X86_CPUFREQ_NFORCE2
tristate "nVidia nForce2 FSB changing"
depends on CPU_FREQ && EXPERIMENTAL
help
This adds the CPUFreq driver for FSB changing on nVidia nForce2
plattforms.
For details, take a look at <file:Documentation/cpu-freq/>.
If in doubt, say N.
config X86_LONGRUN
tristate "Transmeta LongRun"
depends on CPU_FREQ
......
......@@ -9,11 +9,6 @@ obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o
obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o
obj-$(CONFIG_X86_SPEEDSTEP_SMI) += speedstep-smi.o
obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi.o
obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o
ifdef CONFIG_X86_ACPI_CPUFREQ
ifdef CONFIG_ACPI_DEBUG
EXTRA_CFLAGS += -DACPI_DEBUG_OUTPUT
endif
endif
obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o
/*
* acpi-cpufreq-io.c - ACPI Processor P-States Driver ($Revision: 1.3 $)
* acpi-cpufreq.c - ACPI Processor P-States Driver ($Revision: 1.3 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
......@@ -38,16 +38,10 @@
#include <linux/acpi.h>
#include <acpi/processor.h>
#define ACPI_PROCESSOR_COMPONENT 0x01000000
#define ACPI_PROCESSOR_CLASS "processor"
#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor P-States Driver"
#define ACPI_PROCESSOR_DEVICE_NAME "Processor"
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME ("acpi_processor_perf")
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg)
MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME);
MODULE_DESCRIPTION("ACPI Processor P-States Driver");
MODULE_LICENSE("GPL");
......@@ -111,7 +105,7 @@ acpi_processor_set_performance (
cpumask_t saved_mask;
int retval;
ACPI_FUNCTION_TRACE("acpi_processor_set_performance");
dprintk("acpi_processor_set_performance\n");
/*
* TBD: Use something other than set_cpus_allowed.
......@@ -121,18 +115,17 @@ acpi_processor_set_performance (
saved_mask = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(cpu));
if (smp_processor_id() != cpu) {
return_VALUE(-EAGAIN);
return (-EAGAIN);
}
if (state == data->acpi_data.state) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Already at target state (P%d)\n", state));
dprintk("Already at target state (P%d)\n", state);
retval = 0;
goto migrate_end;
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Transitioning from P%d to P%d\n",
data->acpi_data.state, state));
dprintk("Transitioning from P%d to P%d\n",
data->acpi_data.state, state);
/* cpufreq frequency struct */
cpufreq_freqs.cpu = cpu;
......@@ -151,13 +144,11 @@ acpi_processor_set_performance (
bit_width = data->acpi_data.control_register.bit_width;
value = (u32) data->acpi_data.states[state].control;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Writing 0x%08x to port 0x%04x\n", value, port));
dprintk("Writing 0x%08x to port 0x%04x\n", value, port);
ret = acpi_processor_write_port(port, bit_width, value);
if (ret) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN,
"Invalid port width 0x%04x\n", bit_width));
dprintk("Invalid port width 0x%04x\n", bit_width);
retval = ret;
goto migrate_end;
}
......@@ -172,15 +163,13 @@ acpi_processor_set_performance (
port = data->acpi_data.status_register.address;
bit_width = data->acpi_data.status_register.bit_width;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Looking for 0x%08x from port 0x%04x\n",
(u32) data->acpi_data.states[state].status, port));
dprintk("Looking for 0x%08x from port 0x%04x\n",
(u32) data->acpi_data.states[state].status, port);
for (i=0; i<100; i++) {
ret = acpi_processor_read_port(port, bit_width, &value);
if (ret) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN,
"Invalid port width 0x%04x\n", bit_width));
dprintk("Invalid port width 0x%04x\n", bit_width);
retval = ret;
goto migrate_end;
}
......@@ -198,21 +187,19 @@ acpi_processor_set_performance (
cpufreq_freqs.old = tmp;
cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE);
cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Transition failed\n"));
printk(KERN_WARNING "acpi-cpufreq: Transition failed\n");
retval = -ENODEV;
goto migrate_end;
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Transition successful after %d microseconds\n",
i * 10));
dprintk("Transition successful after %d microseconds\n", i * 10);
data->acpi_data.state = state;
retval = 0;
migrate_end:
set_cpus_allowed(current, saved_mask);
return_VALUE(retval);
return (retval);
}
......@@ -226,7 +213,7 @@ acpi_cpufreq_target (
unsigned int next_state = 0;
unsigned int result = 0;
ACPI_FUNCTION_TRACE("acpi_cpufreq_setpolicy");
dprintk("acpi_cpufreq_setpolicy\n");
result = cpufreq_frequency_table_target(policy,
data->freq_table,
......@@ -234,11 +221,11 @@ acpi_cpufreq_target (
relation,
&next_state);
if (result)
return_VALUE(result);
return (result);
result = acpi_processor_set_performance (data, policy->cpu, next_state);
return_VALUE(result);
return (result);
}
......@@ -249,12 +236,12 @@ acpi_cpufreq_verify (
unsigned int result = 0;
struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
ACPI_FUNCTION_TRACE("acpi_cpufreq_verify");
dprintk("acpi_cpufreq_verify\n");
result = cpufreq_frequency_table_verify(policy,
data->freq_table);
return_VALUE(result);
return (result);
}
......@@ -308,17 +295,17 @@ acpi_processor_cpu_init_pdc_est(
union acpi_object *obj;
u32 *buf;
struct cpuinfo_x86 *c = cpu_data + cpu;
ACPI_FUNCTION_TRACE("acpi_processor_cpu_init_pdc_est");
dprintk("acpi_processor_cpu_init_pdc_est\n");
if (!cpu_has(c, X86_FEATURE_EST))
return_VOID;
return;
/* Initialize pdc. It will be used later. */
if (!obj_list)
return_VOID;
return;
if (!(obj_list->count && obj_list->pointer))
return_VOID;
return;
obj = obj_list->pointer;
if ((obj->buffer.length == 12) && obj->buffer.pointer) {
......@@ -328,7 +315,7 @@ acpi_processor_cpu_init_pdc_est(
buf[2] = ACPI_PDC_EST_CAPABILITY_SMP;
perf->pdc = obj_list;
}
return_VOID;
return;
}
......@@ -341,11 +328,11 @@ acpi_processor_cpu_init_pdc(
)
{
struct cpuinfo_x86 *c = cpu_data + cpu;
ACPI_FUNCTION_TRACE("acpi_processor_cpu_init_pdc");
dprintk("acpi_processor_cpu_init_pdc\n");
perf->pdc = NULL;
if (cpu_has(c, X86_FEATURE_EST))
acpi_processor_cpu_init_pdc_est(perf, cpu, obj_list);
return_VOID;
return;
}
......@@ -362,14 +349,14 @@ acpi_cpufreq_cpu_init (
u32 arg0_buf[3];
struct acpi_object_list arg_list = {1, &arg0};
ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_init");
dprintk("acpi_cpufreq_cpu_init\n");
/* setup arg_list for _PDC settings */
arg0.buffer.length = 12;
arg0.buffer.pointer = (u8 *) arg0_buf;
data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
if (!data)
return_VALUE(-ENOMEM);
return (-ENOMEM);
memset(data, 0, sizeof(struct cpufreq_acpi_io));
acpi_io_data[cpu] = data;
......@@ -383,15 +370,15 @@ acpi_cpufreq_cpu_init (
/* capability check */
if (data->acpi_data.state_count <= 1) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No P-States\n"));
dprintk("No P-States\n");
result = -ENODEV;
goto err_unreg;
}
if ((data->acpi_data.control_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO) ||
(data->acpi_data.status_register.space_id != ACPI_ADR_SPACE_SYSTEM_IO)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unsupported address space [%d, %d]\n",
dprintk("Unsupported address space [%d, %d]\n",
(u32) (data->acpi_data.control_register.space_id),
(u32) (data->acpi_data.status_register.space_id)));
(u32) (data->acpi_data.status_register.space_id));
result = -ENODEV;
goto err_unreg;
}
......@@ -432,17 +419,17 @@ acpi_cpufreq_cpu_init (
/* notify BIOS that we exist */
acpi_processor_notify_smm(THIS_MODULE);
printk(KERN_INFO "cpufreq: CPU%u - ACPI performance management activated.\n",
printk(KERN_INFO "acpi-cpufreq: CPU%u - ACPI performance management activated.\n",
cpu);
for (i = 0; i < data->acpi_data.state_count; i++)
printk(KERN_INFO "cpufreq: %cP%d: %d MHz, %d mW, %d uS\n",
dprintk(" %cP%d: %d MHz, %d mW, %d uS\n",
(i == data->acpi_data.state?'*':' '), i,
(u32) data->acpi_data.states[i].core_frequency,
(u32) data->acpi_data.states[i].power,
(u32) data->acpi_data.states[i].transition_latency);
cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu);
return_VALUE(result);
return (result);
err_freqfree:
kfree(data->freq_table);
......@@ -452,7 +439,7 @@ acpi_cpufreq_cpu_init (
kfree(data);
acpi_io_data[cpu] = NULL;
return_VALUE(result);
return (result);
}
......@@ -463,7 +450,7 @@ acpi_cpufreq_cpu_exit (
struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_exit");
dprintk("acpi_cpufreq_cpu_exit\n");
if (data) {
cpufreq_frequency_table_put_attr(policy->cpu);
......@@ -472,7 +459,7 @@ acpi_cpufreq_cpu_exit (
kfree(data);
}
return_VALUE(0);
return (0);
}
......@@ -497,24 +484,26 @@ acpi_cpufreq_init (void)
{
int result = 0;
ACPI_FUNCTION_TRACE("acpi_cpufreq_init");
dprintk("acpi_cpufreq_init\n");
result = cpufreq_register_driver(&acpi_cpufreq_driver);
return_VALUE(result);
return (result);
}
static void __exit
acpi_cpufreq_exit (void)
{
ACPI_FUNCTION_TRACE("acpi_cpufreq_exit");
dprintk("acpi_cpufreq_exit\n");
cpufreq_unregister_driver(&acpi_cpufreq_driver);
return_VOID;
return;
}
late_initcall(acpi_cpufreq_init);
module_exit(acpi_cpufreq_exit);
MODULE_ALIAS("acpi");
/*
* (C) 2004 Sebastian Witt <se.witt@gmx.net>
*
* Licensed under the terms of the GNU GPL License version 2.
* Based upon reverse engineered information
*
* BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/pci.h>
#include <linux/delay.h>
#define NFORCE2_XTAL 25
#define NFORCE2_BOOTFSB 0x48
#define NFORCE2_PLLENABLE 0xa8
#define NFORCE2_PLLREG 0xa4
#define NFORCE2_PLLADR 0xa0
#define NFORCE2_PLL(mul, div) (0x100000 | (mul << 8) | div)
#define NFORCE2_MIN_FSB 50
#define NFORCE2_SAFE_DISTANCE 50
/* Delay in ms between FSB changes */
//#define NFORCE2_DELAY 10
/* nforce2_chipset:
* FSB is changed using the chipset
*/
static struct pci_dev *nforce2_chipset_dev;
/* fid:
* multiplier * 10
*/
static int fid = 0;
/* min_fsb, max_fsb:
* minimum and maximum FSB (= FSB at boot time)
*/
static int min_fsb = 0;
static int max_fsb = 0;
MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>");
MODULE_DESCRIPTION("nForce2 FSB changing cpufreq driver");
MODULE_LICENSE("GPL");
module_param(fid, int, 0444);
module_param(min_fsb, int, 0444);
MODULE_PARM_DESC(fid, "CPU multiplier to use (11.5 = 115)");
MODULE_PARM_DESC(min_fsb,
"Minimum FSB to use, if not defined: current FSB - 50");
/* DEBUG
* Define it if you want verbose debug output, e.g. for bug reporting
*/
//#define NFORCE2_DEBUG
#ifdef NFORCE2_DEBUG
#define dprintk(msg...) printk(msg)
#else
#define dprintk(msg...) do { } while(0)
#endif
/*
* nforce2_calc_fsb - calculate FSB
* @pll: PLL value
*
* Calculates FSB from PLL value
*/
static int nforce2_calc_fsb(int pll)
{
unsigned char mul, div;
mul = (pll >> 8) & 0xff;
div = pll & 0xff;
if (div > 0)
return NFORCE2_XTAL * mul / div;
return 0;
}
/*
* nforce2_calc_pll - calculate PLL value
* @fsb: FSB
*
* Calculate PLL value for given FSB
*/
static int nforce2_calc_pll(unsigned int fsb)
{
unsigned char xmul, xdiv;
unsigned char mul = 0, div = 0;
int tried = 0;
/* Try to calculate multiplier and divider up to 4 times */
while (((mul == 0) || (div == 0)) && (tried <= 3)) {
for (xdiv = 1; xdiv <= 0x80; xdiv++)
for (xmul = 1; xmul <= 0xfe; xmul++)
if (nforce2_calc_fsb(NFORCE2_PLL(xmul, xdiv)) ==
fsb + tried) {
mul = xmul;
div = xdiv;
}
tried++;
}
if ((mul == 0) || (div == 0))
return -1;
return NFORCE2_PLL(mul, div);
}
/*
* nforce2_write_pll - write PLL value to chipset
* @pll: PLL value
*
* Writes new FSB PLL value to chipset
*/
static void nforce2_write_pll(int pll)
{
int temp;
/* Set the pll addr. to 0x00 */
temp = 0x00;
pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLADR, temp);
/* Now write the value in all 64 registers */
for (temp = 0; temp <= 0x3f; temp++) {
pci_write_config_dword(nforce2_chipset_dev,
NFORCE2_PLLREG, pll);
}
return;
}
/*
* nforce2_fsb_read - Read FSB
*
* Read FSB from chipset
* If bootfsb != 0, return FSB at boot-time
*/
static unsigned int nforce2_fsb_read(int bootfsb)
{
struct pci_dev *nforce2_sub5;
u32 fsb, temp = 0;
/* Get chipset boot FSB from subdevice 5 (FSB at boot-time) */
nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
0x01EF,
PCI_ANY_ID,
PCI_ANY_ID,
NULL);
if (!nforce2_sub5)
return 0;
pci_read_config_dword(nforce2_sub5, NFORCE2_BOOTFSB, &fsb);
fsb /= 1000000;
/* Check if PLL register is already set */
pci_read_config_byte(nforce2_chipset_dev,
NFORCE2_PLLENABLE, (u8 *)&temp);
if(bootfsb || !temp)
return fsb;
/* Use PLL register FSB value */
pci_read_config_dword(nforce2_chipset_dev,
NFORCE2_PLLREG, &temp);
fsb = nforce2_calc_fsb(temp);
return fsb;
}
/*
* nforce2_set_fsb - set new FSB
* @fsb: New FSB
*
* Sets new FSB
*/
static int nforce2_set_fsb(unsigned int fsb)
{
u32 pll, temp = 0;
unsigned int tfsb;
int diff;
if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb);
return -EINVAL;
}
tfsb = nforce2_fsb_read(0);
if (!tfsb) {
printk(KERN_ERR "cpufreq: Error while reading the FSB\n");
return -EINVAL;
}
/* First write? Then set actual value */
pci_read_config_byte(nforce2_chipset_dev,
NFORCE2_PLLENABLE, (u8 *)&temp);
if (!temp) {
pll = nforce2_calc_pll(tfsb);
if (pll < 0)
return -EINVAL;
nforce2_write_pll(pll);
}
/* Enable write access */
temp = 0x01;
pci_write_config_byte(nforce2_chipset_dev, NFORCE2_PLLENABLE, (u8)temp);
diff = tfsb - fsb;
if (!diff)
return 0;
while ((tfsb != fsb) && (tfsb <= max_fsb) && (tfsb >= min_fsb)) {
if (diff < 0)
tfsb++;
else
tfsb--;
/* Calculate the PLL reg. value */
if ((pll = nforce2_calc_pll(tfsb)) == -1)
return -EINVAL;
nforce2_write_pll(pll);
#ifdef NFORCE2_DELAY
mdelay(NFORCE2_DELAY);
#endif
}
temp = 0x40;
pci_write_config_byte(nforce2_chipset_dev, NFORCE2_PLLADR, (u8)temp);
return 0;
}
/**
* nforce2_get - get the CPU frequency
* @cpu: CPU number
*
* Returns the CPU frequency
*/
static unsigned int nforce2_get(unsigned int cpu)
{
if (cpu)
return 0;
return nforce2_fsb_read(0) * fid * 100;
}
/**
* nforce2_target - set a new CPUFreq policy
* @policy: new policy
* @target_freq: the target frequency
* @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
*
* Sets a new CPUFreq policy.
*/
static int nforce2_target(struct cpufreq_policy *policy,
unsigned int target_freq, unsigned int relation)
{
// unsigned long flags;
struct cpufreq_freqs freqs;
unsigned int target_fsb;
if ((target_freq > policy->max) || (target_freq < policy->min))
return -EINVAL;
target_fsb = target_freq / (fid * 100);
freqs.old = nforce2_get(policy->cpu);
freqs.new = target_fsb * fid * 100;
freqs.cpu = 0; /* Only one CPU on nForce2 plattforms */
if (freqs.old == freqs.new)
return 0;
dprintk(KERN_INFO "cpufreq: Old CPU frequency %d kHz, new %d kHz\n",
freqs.old, freqs.new);
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
/* Disable IRQs */
//local_irq_save(flags);
if (nforce2_set_fsb(target_fsb) < 0)
printk(KERN_ERR "cpufreq: Changing FSB to %d failed\n",
target_fsb);
else
dprintk(KERN_INFO "cpufreq: Changed FSB successfully to %d\n",
target_fsb);
/* Enable IRQs */
//local_irq_restore(flags);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return 0;
}
/**
* nforce2_verify - verifies a new CPUFreq policy
* @policy: new policy
*/
static int nforce2_verify(struct cpufreq_policy *policy)
{
unsigned int fsb_pol_max;
fsb_pol_max = policy->max / (fid * 100);
if (policy->min < (fsb_pol_max * fid * 100))
policy->max = (fsb_pol_max + 1) * fid * 100;
cpufreq_verify_within_limits(policy,
policy->cpuinfo.min_freq,
policy->cpuinfo.max_freq);
return 0;
}
static int nforce2_cpu_init(struct cpufreq_policy *policy)
{
unsigned int fsb;
unsigned int rfid;
/* capability check */
if (policy->cpu != 0)
return -ENODEV;
/* Get current FSB */
fsb = nforce2_fsb_read(0);
if (!fsb)
return -EIO;
/* FIX: Get FID from CPU */
if (!fid) {
if (!cpu_khz) {
printk(KERN_WARNING
"cpufreq: cpu_khz not set, can't calculate multiplier!\n");
return -ENODEV;
}
fid = cpu_khz / (fsb * 100);
rfid = fid % 5;
if (rfid) {
if (rfid > 2)
fid += 5 - rfid;
else
fid -= rfid;
}
}
printk(KERN_INFO "cpufreq: FSB currently at %i MHz, FID %d.%d\n", fsb,
fid / 10, fid % 10);
/* Set maximum FSB to FSB at boot time */
max_fsb = nforce2_fsb_read(1);
if(!max_fsb)
return -EIO;
if (!min_fsb)
min_fsb = max_fsb - NFORCE2_SAFE_DISTANCE;
if (min_fsb < NFORCE2_MIN_FSB)
min_fsb = NFORCE2_MIN_FSB;
/* cpuinfo and default policy values */
policy->cpuinfo.min_freq = min_fsb * fid * 100;
policy->cpuinfo.max_freq = max_fsb * fid * 100;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->cur = nforce2_get(policy->cpu);
policy->min = policy->cpuinfo.min_freq;
policy->max = policy->cpuinfo.max_freq;
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
return 0;
}
static int nforce2_cpu_exit(struct cpufreq_policy *policy)
{
return 0;
}
static struct cpufreq_driver nforce2_driver = {
.name = "nforce2",
.verify = nforce2_verify,
.target = nforce2_target,
.get = nforce2_get,
.init = nforce2_cpu_init,
.exit = nforce2_cpu_exit,
.owner = THIS_MODULE,
};
/**
* nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic
*
* Detects nForce2 A2 and C1 stepping
*
*/
static unsigned int nforce2_detect_chipset(void)
{
u8 revision;
nforce2_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
PCI_DEVICE_ID_NVIDIA_NFORCE2,
PCI_ANY_ID,
PCI_ANY_ID,
NULL);
if (nforce2_chipset_dev == NULL)
return -ENODEV;
pci_read_config_byte(nforce2_chipset_dev, PCI_REVISION_ID, &revision);
printk(KERN_INFO "cpufreq: Detected nForce2 chipset revision %X\n",
revision);
printk(KERN_INFO
"cpufreq: FSB changing is maybe unstable and can lead to crashes and data loss.\n");
return 0;
}
/**
* nforce2_init - initializes the nForce2 CPUFreq driver
*
* Initializes the nForce2 FSB support. Returns -ENODEV on unsupported
* devices, -EINVAL on problems during initiatization, and zero on
* success.
*/
static int __init nforce2_init(void)
{
/* TODO: do we need to detect the processor? */
/* detect chipset */
if (nforce2_detect_chipset()) {
printk(KERN_ERR "cpufreq: No nForce2 chipset.\n");
return -ENODEV;
}
return cpufreq_register_driver(&nforce2_driver);
}
/**
* nforce2_exit - unregisters cpufreq module
*
* Unregisters nForce2 FSB change support.
*/
static void __exit nforce2_exit(void)
{
cpufreq_unregister_driver(&nforce2_driver);
}
module_init(nforce2_init);
module_exit(nforce2_exit);
......@@ -141,17 +141,7 @@ module_param (max_duration, int, 0444);
#define POLICY_MIN_DIV 20
/* DEBUG
* Define it if you want verbose debug output
*/
#define SUSPMOD_DEBUG 1
#ifdef SUSPMOD_DEBUG
#define dprintk(msg...) printk(KERN_DEBUG "cpufreq:" msg)
#else
#define dprintk(msg...) do { } while(0)
#endif
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "gx-suspmod", msg)
/**
* we can detect a core multipiler from dir0_lsb
......@@ -194,7 +184,7 @@ static __init struct pci_dev *gx_detect_chipset(void)
/* check if CPU is a MediaGX or a Geode. */
if ((current_cpu_data.x86_vendor != X86_VENDOR_NSC) &&
(current_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) {
printk(KERN_INFO "gx-suspmod: error: no MediaGX/Geode processor found!\n");
dprintk("error: no MediaGX/Geode processor found!\n");
return NULL;
}
......@@ -205,7 +195,7 @@ static __init struct pci_dev *gx_detect_chipset(void)
}
}
dprintk(KERN_INFO "gx-suspmod: error: no supported chipset found!\n");
dprintk("error: no supported chipset found!\n");
return NULL;
}
......
......@@ -58,21 +58,9 @@ static int vrmrev;
/* Module parameters */
static int dont_scale_voltage;
static int debug;
static void dprintk(const char *fmt, ...)
{
char s[256];
va_list args;
if (debug == 0)
return;
va_start(args, fmt);
vsprintf(s, fmt, args);
printk(s);
va_end(args);
}
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg)
#define __hlt() __asm__ __volatile__("hlt": : :"memory")
......@@ -84,6 +72,8 @@ static int voltage_table[32];
static unsigned int highest_speed, lowest_speed; /* kHz */
static int longhaul_version;
static struct cpufreq_frequency_table *longhaul_table;
#ifdef CONFIG_CPU_FREQ_DEBUG
static char speedbuffer[8];
static char *print_speed(int speed)
......@@ -98,6 +88,7 @@ static char *print_speed(int speed)
return speedbuffer;
}
#endif
static unsigned int calc_speed(int mult)
......@@ -192,7 +183,7 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
dprintk (KERN_INFO PFX "Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
dprintk ("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
fsb, mult/10, mult%10, print_speed(speed/1000));
switch (longhaul_version) {
......@@ -356,7 +347,7 @@ static int __init longhaul_get_ranges(void)
}
}
dprintk (KERN_INFO PFX "MinMult:%d.%dx MaxMult:%d.%dx\n",
dprintk ("MinMult:%d.%dx MaxMult:%d.%dx\n",
minmult/10, minmult%10, maxmult/10, maxmult%10);
if (fsb == -1) {
......@@ -366,9 +357,9 @@ static int __init longhaul_get_ranges(void)
highest_speed = calc_speed(maxmult);
lowest_speed = calc_speed(minmult);
dprintk (KERN_INFO PFX "FSB:%dMHz ", fsb);
dprintk ("Lowest speed:%s ", print_speed(lowest_speed/1000));
dprintk ("Highest speed:%s\n", print_speed(highest_speed/1000));
dprintk ("FSB:%dMHz Lowest speed: %s Highest speed:%s\n", fsb,
print_speed(lowest_speed/1000),
print_speed(highest_speed/1000));
if (lowest_speed == highest_speed) {
printk (KERN_INFO PFX "highestspeed == lowest, aborting.\n");
......@@ -434,11 +425,11 @@ static void __init longhaul_setup_voltagescaling(void)
}
if (vrmrev==0) {
dprintk (KERN_INFO PFX "VRM 8.5 : ");
dprintk ("VRM 8.5 \n");
memcpy (voltage_table, vrm85scales, sizeof(voltage_table));
numvscales = (voltage_table[maxvid]-voltage_table[minvid])/25;
} else {
dprintk (KERN_INFO PFX "Mobile VRM : ");
dprintk ("Mobile VRM \n");
memcpy (voltage_table, mobilevrmscales, sizeof(voltage_table));
numvscales = (voltage_table[maxvid]-voltage_table[minvid])/5;
}
......@@ -658,9 +649,6 @@ static void __exit longhaul_exit(void)
module_param (dont_scale_voltage, int, 0644);
MODULE_PARM_DESC(dont_scale_voltage, "Don't scale voltage of processor");
module_param (debug, int, 0644);
MODULE_PARM_DESC(debug, "Dump debugging information.");
MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
MODULE_LICENSE ("GPL");
......
......@@ -16,6 +16,8 @@
#include <asm/processor.h>
#include <asm/timex.h>
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longrun", msg)
static struct cpufreq_driver longrun_driver;
/**
......@@ -38,12 +40,14 @@ static void __init longrun_get_policy(struct cpufreq_policy *policy)
u32 msr_lo, msr_hi;
rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
dprintk("longrun flags are %x - %x\n", msr_lo, msr_hi);
if (msr_lo & 0x01)
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
else
policy->policy = CPUFREQ_POLICY_POWERSAVE;
rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
dprintk("longrun ctrl is %x - %x\n", msr_lo, msr_hi);
msr_lo &= 0x0000007F;
msr_hi &= 0x0000007F;
......@@ -146,6 +150,7 @@ static unsigned int longrun_get(unsigned int cpu)
return 0;
cpuid(0x80860007, &eax, &ebx, &ecx, &edx);
dprintk("cpuid eax is %u\n", eax);
return (eax * 1000);
}
......@@ -191,6 +196,8 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq,
rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi);
*high_freq = msr_lo * 1000; /* to kHz */
dprintk("longrun table interface told %u - %u kHz\n", *low_freq, *high_freq);
if (*low_freq > *high_freq)
*low_freq = *high_freq;
return 0;
......@@ -199,6 +206,7 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq,
/* set the upper border to the value determined during TSC init */
*high_freq = (cpu_khz / 1000);
*high_freq = *high_freq * 1000;
dprintk("high frequency is %u kHz\n", *high_freq);
/* get current borders */
rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
......@@ -225,6 +233,7 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq,
/* restore values */
wrmsr(MSR_TMTA_LONGRUN_CTRL, save_lo, save_hi);
}
dprintk("percentage is %u %%, freq is %u MHz\n", ecx, eax);
/* performance_pctg = (current_freq - low_freq)/(high_freq - low_freq)
* eqals
......@@ -240,6 +249,8 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq,
edx = (eax - ebx) / (100 - ecx);
*low_freq = edx * 1000; /* back to kHz */
dprintk("low frequency is %u kHz\n", *low_freq);
if (*low_freq > *high_freq)
*low_freq = *high_freq;
......
......@@ -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
......@@ -223,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 */
......@@ -300,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
......@@ -312,9 +315,11 @@ static int __init cpufreq_p4_init(void)
!test_bit(X86_FEATURE_ACC, c->x86_capability))
return -ENODEV;
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);
}
......
......@@ -66,6 +66,7 @@ union powernow_acpi_control_t {
};
#endif
#ifdef CONFIG_CPU_FREQ_DEBUG
/* divide by 1000 to get VID. */
static int mobile_vid_table[32] = {
2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
......@@ -73,6 +74,7 @@ static int mobile_vid_table[32] = {
1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
1075, 1050, 1024, 1000, 975, 950, 925, 0,
};
#endif
/* divide by 10 to get FID. */
static int fid_codes[32] = {
......@@ -87,7 +89,6 @@ static int fid_codes[32] = {
*/
static int acpi_force;
static int debug;
static struct cpufreq_frequency_table *powernow_table;
......@@ -100,20 +101,7 @@ static unsigned int fsb;
static unsigned int latency;
static char have_a0;
static void dprintk(const char *fmt, ...)
{
char s[256];
va_list args;
if (debug==0)
return;
va_start(args,fmt);
vsprintf(s, fmt, args);
printk(s);
va_end(args);
}
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "powernow-k7", msg)
static int check_fsb(unsigned int fsbspeed)
{
......@@ -202,9 +190,6 @@ static int get_ranges (unsigned char *pst)
#endif
}
dprintk (KERN_INFO PFX " FID: 0x%x (%d.%dx [%dMHz]) ", fid,
fid_codes[fid] / 10, fid_codes[fid] % 10, speed/1000);
if (speed < minimum_speed)
minimum_speed = speed;
if (speed > maximum_speed)
......@@ -212,7 +197,11 @@ static int get_ranges (unsigned char *pst)
vid = *pst++;
powernow_table[j].index |= (vid << 8); /* upper 8 bits */
dprintk ("VID: 0x%x (%d.%03dV)\n", vid, mobile_vid_table[vid]/1000,
dprintk (" FID: 0x%x (%d.%dx [%dMHz]) "
"VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
fid_codes[fid] % 10, speed/1000, vid,
mobile_vid_table[vid]/1000,
mobile_vid_table[vid]%1000);
}
powernow_table[number_scales].frequency = CPUFREQ_TABLE_END;
......@@ -302,7 +291,7 @@ static void change_speed (unsigned int index)
#ifdef CONFIG_X86_POWERNOW_K7_ACPI
struct acpi_processor_performance *acpi_processor_perf;
static struct acpi_processor_performance *acpi_processor_perf;
static int powernow_acpi_init(void)
{
......@@ -361,7 +350,7 @@ static int powernow_acpi_init(void)
unsigned int speed;
pc.val = (unsigned long) acpi_processor_perf->states[i].control;
dprintk (KERN_INFO PFX "acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d\n",
dprintk ("acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d\n",
i,
(u32) acpi_processor_perf->states[i].core_frequency,
(u32) acpi_processor_perf->states[i].power,
......@@ -383,9 +372,10 @@ static int powernow_acpi_init(void)
powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
}
dprintk (KERN_INFO PFX " FID: 0x%x (%d.%dx [%dMHz]) ", fid,
fid_codes[fid] / 10, fid_codes[fid] % 10, speed/1000);
dprintk ("VID: 0x%x (%d.%03dV)\n", vid, mobile_vid_table[vid]/1000,
dprintk (" FID: 0x%x (%d.%dx [%dMHz]) "
"VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
fid_codes[fid] % 10, speed/1000, vid,
mobile_vid_table[vid]/1000,
mobile_vid_table[vid]%1000);
if (latency < pc.bits.sgtc)
......@@ -439,21 +429,20 @@ static int powernow_decode_bios (int maxfid, int startvid)
p = phys_to_virt(i);
if (memcmp(p, "AMDK7PNOW!", 10) == 0){
dprintk (KERN_INFO PFX "Found PSB header at %p\n", p);
dprintk ("Found PSB header at %p\n", p);
psb = (struct psb_s *) p;
dprintk (KERN_INFO PFX "Table version: 0x%x\n", psb->tableversion);
dprintk ("Table version: 0x%x\n", psb->tableversion);
if (psb->tableversion != 0x12) {
printk (KERN_INFO PFX "Sorry, only v1.2 tables supported right now\n");
return -ENODEV;
}
dprintk (KERN_INFO PFX "Flags: 0x%x (", psb->flags);
dprintk ("Flags: 0x%x\n", psb->flags);
if ((psb->flags & 1)==0) {
dprintk ("Mobile");
dprintk ("Mobile voltage regulator\n");
} else {
dprintk ("Desktop");
dprintk ("Desktop voltage regulator\n");
}
dprintk (" voltage regulator)\n");
latency = psb->settlingtime;
if (latency < 100) {
......@@ -461,8 +450,8 @@ static int powernow_decode_bios (int maxfid, int startvid)
"Should be at least 100. Correcting.\n", latency);
latency = 100;
}
dprintk (KERN_INFO PFX "Settling Time: %d microseconds.\n", psb->settlingtime);
dprintk (KERN_INFO PFX "Has %d PST tables. (Only dumping ones relevant to this CPU).\n", psb->numpst);
dprintk ("Settling Time: %d microseconds.\n", psb->settlingtime);
dprintk ("Has %d PST tables. (Only dumping ones relevant to this CPU).\n", psb->numpst);
p += sizeof (struct psb_s);
......@@ -475,11 +464,9 @@ static int powernow_decode_bios (int maxfid, int startvid)
if ((etuple == pst->cpuid) && check_fsb(pst->fsbspeed) &&
(maxfid==pst->maxfid) && (startvid==pst->startvid))
{
dprintk (KERN_INFO PFX "PST:%d (@%p)\n", i, pst);
dprintk (KERN_INFO PFX " cpuid: 0x%x ", pst->cpuid);
dprintk ("fsb: %d ", pst->fsbspeed);
dprintk ("maxFID: 0x%x ", pst->maxfid);
dprintk ("startvid: 0x%x\n", pst->startvid);
dprintk ("PST:%d (@%p)\n", i, pst);
dprintk (" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n",
pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid);
ret = get_ranges ((char *) pst + sizeof (struct pst_s));
return ret;
......@@ -605,7 +592,7 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
printk(KERN_WARNING PFX "can not determine bus frequency\n");
return -EINVAL;
}
dprintk(KERN_INFO PFX "FSB: %3d.%03d MHz\n", fsb/1000, fsb%1000);
dprintk("FSB: %3d.%03d MHz\n", fsb/1000, fsb%1000);
if (dmi_check_system(powernow_dmi_table) || acpi_force) {
printk (KERN_INFO PFX "PSB/PST known to be broken. Trying ACPI instead\n");
......@@ -688,8 +675,6 @@ static void __exit powernow_exit (void)
kfree(powernow_table);
}
module_param(debug, int, 0444);
MODULE_PARM_DESC(debug, "enable debug output.");
module_param(acpi_force, int, 0444);
MODULE_PARM_DESC(acpi_force, "Force ACPI to be used.");
......
......@@ -136,7 +136,7 @@ static void fidvid_msr_init(void)
fid = lo & MSR_S_LO_CURRENT_FID;
lo = fid | (vid << MSR_C_LO_VID_SHIFT);
hi = MSR_C_HI_STP_GNT_BENIGN;
dprintk(PFX "cpu%d, init lo 0x%x, hi 0x%x\n", smp_processor_id(), lo, hi);
dprintk("cpu%d, init lo 0x%x, hi 0x%x\n", smp_processor_id(), lo, hi);
wrmsr(MSR_FIDVID_CTL, lo, hi);
}
......@@ -154,7 +154,7 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid)
lo = fid | (data->currvid << MSR_C_LO_VID_SHIFT) | MSR_C_LO_INIT_FID_VID;
dprintk(KERN_DEBUG PFX "writing fid 0x%x, lo 0x%x, hi 0x%x\n",
dprintk("writing fid 0x%x, lo 0x%x, hi 0x%x\n",
fid, lo, data->plllock * PLL_LOCK_CONVERSION);
wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION);
......@@ -192,7 +192,7 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid)
lo = data->currfid | (vid << MSR_C_LO_VID_SHIFT) | MSR_C_LO_INIT_FID_VID;
dprintk(KERN_DEBUG PFX "writing vid 0x%x, lo 0x%x, hi 0x%x\n",
dprintk("writing vid 0x%x, lo 0x%x, hi 0x%x\n",
vid, lo, STOP_GRANT_5NS);
wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
......@@ -255,7 +255,7 @@ static int transition_fid_vid(struct powernow_k8_data *data, u32 reqfid, u32 req
return 1;
}
dprintk(KERN_INFO PFX "transitioned (cpu%d): new fid 0x%x, vid 0x%x\n",
dprintk("transitioned (cpu%d): new fid 0x%x, vid 0x%x\n",
smp_processor_id(), data->currfid, data->currvid);
return 0;
......@@ -267,13 +267,12 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
u32 rvosteps = data->rvo;
u32 savefid = data->currfid;
dprintk(KERN_DEBUG PFX
"ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n",
dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n",
smp_processor_id(),
data->currfid, data->currvid, reqvid, data->rvo);
while (data->currvid > reqvid) {
dprintk(KERN_DEBUG PFX "ph1: curr 0x%x, req vid 0x%x\n",
dprintk("ph1: curr 0x%x, req vid 0x%x\n",
data->currvid, reqvid);
if (decrease_vid_code_by_step(data, reqvid, data->vidmvs))
return 1;
......@@ -283,8 +282,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
if (data->currvid == 0) {
rvosteps = 0;
} else {
dprintk(KERN_DEBUG PFX
"ph1: changing vid for rvo, req 0x%x\n",
dprintk("ph1: changing vid for rvo, req 0x%x\n",
data->currvid - 1);
if (decrease_vid_code_by_step(data, data->currvid - 1, 1))
return 1;
......@@ -300,7 +298,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
return 1;
}
dprintk(KERN_DEBUG PFX "ph1 complete, currfid 0x%x, currvid 0x%x\n",
dprintk("ph1 complete, currfid 0x%x, currvid 0x%x\n",
data->currfid, data->currvid);
return 0;
......@@ -325,8 +323,7 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
return 0;
}
dprintk(KERN_DEBUG PFX
"ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, reqfid 0x%x\n",
dprintk("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, reqfid 0x%x\n",
smp_processor_id(),
data->currfid, data->currvid, reqfid);
......@@ -376,7 +373,7 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
return 1;
}
dprintk(KERN_DEBUG PFX "ph2 complete, currfid 0x%x, currvid 0x%x\n",
dprintk("ph2 complete, currfid 0x%x, currvid 0x%x\n",
data->currfid, data->currvid);
return 0;
......@@ -388,7 +385,7 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvi
u32 savefid = data->currfid;
u32 savereqvid = reqvid;
dprintk(KERN_DEBUG PFX "ph3 (cpu%d): starting, currfid 0x%x, currvid 0x%x\n",
dprintk("ph3 (cpu%d): starting, currfid 0x%x, currvid 0x%x\n",
smp_processor_id(),
data->currfid, data->currvid);
......@@ -415,17 +412,17 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvi
return 1;
if (savereqvid != data->currvid) {
dprintk(KERN_ERR PFX "ph3 failed, currvid 0x%x\n", data->currvid);
dprintk("ph3 failed, currvid 0x%x\n", data->currvid);
return 1;
}
if (savefid != data->currfid) {
dprintk(KERN_ERR PFX "ph3 failed, currfid changed 0x%x\n",
dprintk("ph3 failed, currfid changed 0x%x\n",
data->currfid);
return 1;
}
dprintk(KERN_DEBUG PFX "ph3 complete, currfid 0x%x, currvid 0x%x\n",
dprintk("ph3 complete, currfid 0x%x, currvid 0x%x\n",
data->currfid, data->currvid);
return 0;
......@@ -577,7 +574,7 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst,
return -EIO;
}
dprintk(KERN_INFO PFX "cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
data->powernow_table = powernow_table;
print_basics(data);
......@@ -585,7 +582,7 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst,
if ((pst[j].fid==data->currfid) && (pst[j].vid==data->currvid))
return 0;
dprintk(KERN_ERR PFX "currfid/vid do not match PST, ignoring\n");
dprintk("currfid/vid do not match PST, ignoring\n");
return 0;
}
......@@ -607,35 +604,35 @@ static int find_psb_table(struct powernow_k8_data *data)
if (memcmp(psb, PSB_ID_STRING, PSB_ID_STRING_LEN) != 0)
continue;
dprintk(KERN_DEBUG PFX "found PSB header at 0x%p\n", psb);
dprintk("found PSB header at 0x%p\n", psb);
dprintk(KERN_DEBUG PFX "table vers: 0x%x\n", psb->tableversion);
dprintk("table vers: 0x%x\n", psb->tableversion);
if (psb->tableversion != PSB_VERSION_1_4) {
printk(KERN_INFO BFX "PSB table is not v1.4\n");
return -ENODEV;
}
dprintk(KERN_DEBUG PFX "flags: 0x%x\n", psb->flags1);
dprintk("flags: 0x%x\n", psb->flags1);
if (psb->flags1) {
printk(KERN_ERR BFX "unknown flags\n");
return -ENODEV;
}
data->vstable = psb->voltagestabilizationtime;
dprintk(KERN_INFO PFX "voltage stabilization time: %d(*20us)\n", data->vstable);
dprintk("voltage stabilization time: %d(*20us)\n", data->vstable);
dprintk(KERN_DEBUG PFX "flags2: 0x%x\n", psb->flags2);
dprintk("flags2: 0x%x\n", psb->flags2);
data->rvo = psb->flags2 & 3;
data->irt = ((psb->flags2) >> 2) & 3;
mvs = ((psb->flags2) >> 4) & 3;
data->vidmvs = 1 << mvs;
data->batps = ((psb->flags2) >> 6) & 3;
dprintk(KERN_INFO PFX "ramp voltage offset: %d\n", data->rvo);
dprintk(KERN_INFO PFX "isochronous relief time: %d\n", data->irt);
dprintk(KERN_INFO PFX "maximum voltage step: %d - 0x%x\n", mvs, data->vidmvs);
dprintk("ramp voltage offset: %d\n", data->rvo);
dprintk("isochronous relief time: %d\n", data->irt);
dprintk("maximum voltage step: %d - 0x%x\n", mvs, data->vidmvs);
dprintk(KERN_DEBUG PFX "numpst: 0x%x\n", psb->numpst);
dprintk("numpst: 0x%x\n", psb->numpst);
cpst = psb->numpst;
if ((psb->cpuid == 0x00000fc0) || (psb->cpuid == 0x00000fe0) ){
thiscpuid = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
......@@ -649,13 +646,13 @@ static int find_psb_table(struct powernow_k8_data *data)
}
data->plllock = psb->plllocktime;
dprintk(KERN_INFO PFX "plllocktime: 0x%x (units 1us)\n", psb->plllocktime);
dprintk(KERN_INFO PFX "maxfid: 0x%x\n", psb->maxfid);
dprintk(KERN_INFO PFX "maxvid: 0x%x\n", psb->maxvid);
dprintk("plllocktime: 0x%x (units 1us)\n", psb->plllocktime);
dprintk("maxfid: 0x%x\n", psb->maxfid);
dprintk("maxvid: 0x%x\n", psb->maxvid);
maxvid = psb->maxvid;
data->numps = psb->numpstates;
dprintk(KERN_INFO PFX "numpstates: 0x%x\n", data->numps);
dprintk("numpstates: 0x%x\n", data->numps);
return fill_powernow_table(data, (struct pst_s *)(psb+1), maxvid);
}
/*
......@@ -693,19 +690,21 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
struct cpufreq_frequency_table *powernow_table;
if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) {
dprintk(KERN_DEBUG PFX "register performance failed\n");
dprintk("register performance failed\n");
return -EIO;
}
/* verify the data contained in the ACPI structures */
if (data->acpi_data.state_count <= 1) {
dprintk(KERN_DEBUG PFX "No ACPI P-States\n");
dprintk("No ACPI P-States\n");
goto err_out;
}
if ((data->acpi_data.control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
(data->acpi_data.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
dprintk(KERN_DEBUG PFX "Invalid control/status registers\n");
dprintk("Invalid control/status registers (%x - %x)\n",
data->acpi_data.control_register.space_id,
data->acpi_data.status_register.space_id);
goto err_out;
}
......@@ -713,7 +712,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table)
* (data->acpi_data.state_count + 1)), GFP_KERNEL);
if (!powernow_table) {
dprintk(KERN_ERR PFX "powernow_table memory alloc failure\n");
dprintk("powernow_table memory alloc failure\n");
goto err_out;
}
......@@ -721,7 +720,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
u32 fid = data->acpi_data.states[i].control & FID_MASK;
u32 vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK;
dprintk(KERN_INFO PFX " %d : fid 0x%x, vid 0x%x\n", i, fid, vid);
dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid);
powernow_table[i].index = fid; /* lower 8 bits */
powernow_table[i].index |= (vid << 8); /* upper 8 bits */
......@@ -730,14 +729,14 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
/* verify frequency is OK */
if ((powernow_table[i].frequency > (MAX_FREQ * 1000)) ||
(powernow_table[i].frequency < (MIN_FREQ * 1000))) {
dprintk(KERN_INFO PFX "invalid freq %u kHz, ignoring\n", powernow_table[i].frequency);
dprintk("invalid freq %u kHz, ignoring\n", powernow_table[i].frequency);
powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
continue;
}
/* verify voltage is OK - BIOSs are using "off" to indicate invalid */
if (vid == 0x1f) {
dprintk(KERN_INFO PFX "invalid vid %u, ignoring\n", vid);
dprintk("invalid vid %u, ignoring\n", vid);
powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
continue;
}
......@@ -753,7 +752,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
goto err_out_mem;
}
dprintk(KERN_INFO PFX "double low frequency table entry, ignoring it.\n");
dprintk("double low frequency table entry, ignoring it.\n");
powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
continue;
} else
......@@ -815,8 +814,7 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde
int res;
struct cpufreq_freqs freqs;
dprintk(KERN_DEBUG PFX "cpu %d transition to index %u\n",
smp_processor_id(), index );
dprintk("cpu %d transition to index %u\n", smp_processor_id(), index);
/* fid are the lower 8 bits of the index we stored into
* the cpufreq frequency table in find_psb_table, vid are
......@@ -826,27 +824,24 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde
fid = data->powernow_table[index].index & 0xFF;
vid = (data->powernow_table[index].index & 0xFF00) >> 8;
dprintk(KERN_DEBUG PFX "table matched fid 0x%x, giving vid 0x%x\n",
fid, vid);
dprintk("table matched fid 0x%x, giving vid 0x%x\n", fid, vid);
if (query_current_values_with_pending_wait(data))
return 1;
if ((data->currvid == vid) && (data->currfid == fid)) {
dprintk(KERN_DEBUG PFX
"target matches current values (fid 0x%x, vid 0x%x)\n",
dprintk("target matches current values (fid 0x%x, vid 0x%x)\n",
fid, vid);
return 0;
}
if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
printk(KERN_ERR PFX
"ignoring illegal change in lo freq table-%x to 0x%x\n",
printk("ignoring illegal change in lo freq table-%x to 0x%x\n",
data->currfid, fid);
return 1;
}
dprintk(KERN_DEBUG PFX "cpu %d, changing to fid 0x%x, vid 0x%x\n",
dprintk("cpu %d, changing to fid 0x%x, vid 0x%x\n",
smp_processor_id(), fid, vid);
freqs.cpu = data->cpu;
......@@ -890,7 +885,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
goto err_out;
}
dprintk(KERN_DEBUG PFX "targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
dprintk("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
pol->cpu, targfreq, pol->min, pol->max, relation);
if (query_current_values_with_pending_wait(data)) {
......@@ -898,7 +893,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
goto err_out;
}
dprintk(KERN_DEBUG PFX "targ: curr fid 0x%x, vid 0x%x\n",
dprintk("targ: curr fid 0x%x, vid 0x%x\n",
data->currfid, data->currvid);
if ((checkvid != data->currvid) || (checkfid != data->currfid)) {
......@@ -1010,7 +1005,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
+ (3 * (1 << data->irt) * 10)) * 1000;
pol->cur = find_khz_freq_from_fid(data->currfid);
dprintk(KERN_DEBUG PFX "policy current frequency %d kHz\n", pol->cur);
dprintk("policy current frequency %d kHz\n", pol->cur);
/* min/max the cpu is capable of */
if (cpufreq_frequency_table_cpuinfo(pol, data->powernow_table)) {
......@@ -1022,7 +1017,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu);
printk(KERN_INFO PFX "cpu_init done, current fid 0x%x, vid 0x%x\n",
printk("cpu_init done, current fid 0x%x, vid 0x%x\n",
data->currfid, data->currvid);
powernow_data[pol->cpu] = data;
......@@ -1120,7 +1115,7 @@ static int __init powernowk8_init(void)
/* driver entry point for term */
static void __exit powernowk8_exit(void)
{
dprintk(KERN_INFO PFX "exit\n");
dprintk("exit\n");
cpufreq_unregister_driver(&cpufreq_amd64_driver);
}
......
......@@ -168,11 +168,7 @@ struct pst_s {
u8 vid;
};
#ifdef DEBUG
#define dprintk(msg...) printk(msg)
#else
#define dprintk(msg...) do { } while(0)
#endif
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "powernow-k8", msg)
static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid);
static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvid);
......
......@@ -35,13 +35,8 @@
#define PFX "speedstep-centrino: "
#define MAINTAINER "Jeremy Fitzhardinge <jeremy@goop.org>"
/*#define CENTRINO_DEBUG*/
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg)
#ifdef CENTRINO_DEBUG
#define dprintk(msg...) printk(msg)
#else
#define dprintk(msg...) do { } while(0)
#endif
struct cpu_id
{
......@@ -254,13 +249,15 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy)
/* Matched a non-match */
printk(KERN_INFO PFX "no table support for CPU model \"%s\": \n",
cpu->x86_model_id);
#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
printk(KERN_INFO PFX "try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n");
#endif
return -ENOENT;
}
centrino_model = model;
printk(KERN_INFO PFX "found \"%s\": max frequency: %dkHz\n",
dprintk("found \"%s\": max frequency: %dkHz\n",
model->model_name, model->max_freq);
return 0;
......@@ -353,38 +350,43 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
p.pdc = &arg_list;
/* register with ACPI core */
if (acpi_processor_register_performance(&p, policy->cpu))
if (acpi_processor_register_performance(&p, policy->cpu)) {
printk(KERN_INFO PFX "obtaining ACPI data failed\n");
return -EIO;
}
/* verify the acpi_data */
if (p.state_count <= 1) {
printk(KERN_DEBUG "No P-States\n");
dprintk("No P-States\n");
result = -ENODEV;
goto err_unreg;
}
if ((p.control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
(p.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
printk(KERN_DEBUG "Invalid control/status registers\n");
dprintk("Invalid control/status registers (%x - %x)\n",
p.control_register.space_id, p.status_register.space_id);
result = -EIO;
goto err_unreg;
}
for (i=0; i<p.state_count; i++) {
if (p.states[i].control != p.states[i].status) {
printk(KERN_DEBUG "Different control and status values\n");
dprintk("Different control (%x) and status values (%x)\n",
p.states[i].control, p.states[i].status);
result = -EINVAL;
goto err_unreg;
}
if (!p.states[i].core_frequency) {
printk(KERN_DEBUG "Zero core frequency\n");
dprintk("Zero core frequency for state %u\n", i);
result = -EINVAL;
goto err_unreg;
}
if (p.states[i].core_frequency > p.states[0].core_frequency) {
printk(KERN_DEBUG "P%u has larger frequency than P0, skipping\n", i);
dprintk("P%u has larger frequency (%u) than P0 (%u), skipping\n", i,
p.states[i].core_frequency, p.states[0].core_frequency);
p.states[i].core_frequency = 0;
continue;
}
......@@ -409,23 +411,31 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
for (i=0; i<p.state_count; i++) {
centrino_model->op_points[i].index = p.states[i].control;
centrino_model->op_points[i].frequency = p.states[i].core_frequency * 1000;
dprintk("adding state %i with frequency %u and control value %04x\n",
i, centrino_model->op_points[i].frequency, centrino_model->op_points[i].index);
}
centrino_model->op_points[p.state_count].frequency = CPUFREQ_TABLE_END;
cur_freq = get_cur_freq(policy->cpu);
for (i=0; i<p.state_count; i++) {
if (!p.states[i].core_frequency) {
dprintk("skipping state %u\n", i);
centrino_model->op_points[i].frequency = CPUFREQ_ENTRY_INVALID;
continue;
}
if (extract_clock(centrino_model->op_points[i].index) !=
(centrino_model->op_points[i].frequency)) {
printk(KERN_DEBUG "Invalid encoded frequency\n");
dprintk("Invalid encoded frequency (%u vs. %u)\n",
extract_clock(centrino_model->op_points[i].index),
centrino_model->op_points[i].frequency);
result = -EINVAL;
goto err_kfree_all;
}
if (cur_freq == centrino_model->op_points[i].frequency)
p.state = i;
if (!p.states[i].core_frequency)
centrino_model->op_points[i].frequency = CPUFREQ_ENTRY_INVALID;
}
/* notify BIOS that we exist */
......@@ -439,6 +449,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
kfree(centrino_model);
err_unreg:
acpi_processor_unregister_performance(&p, policy->cpu);
printk(KERN_INFO PFX "invalid ACPI data\n");
return (result);
}
#else
......@@ -486,6 +497,7 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
if (!(l & (1<<16))) {
l |= (1<<16);
dprintk("trying to enable Enhanced SpeedStep (%x)\n", l);
wrmsr(MSR_IA32_MISC_ENABLE, l, h);
/* check to see if it stuck */
......@@ -502,8 +514,7 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
policy->cpuinfo.transition_latency = 10000; /* 10uS transition latency */
policy->cur = freq;
dprintk(KERN_INFO PFX "centrino_cpu_init: policy=%d cur=%dkHz\n",
policy->policy, policy->cur);
dprintk("centrino_cpu_init: cur=%dkHz\n", policy->cur);
ret = cpufreq_frequency_table_cpuinfo(policy, centrino_model->op_points);
if (ret)
......@@ -523,6 +534,7 @@ static int centrino_cpu_exit(struct cpufreq_policy *policy)
#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
if (!centrino_model->model_name) {
dprintk("unregistering and freeing ACPI data\n");
acpi_processor_unregister_performance(&p, policy->cpu);
kfree(centrino_model->op_points);
kfree(centrino_model);
......@@ -574,6 +586,7 @@ static int centrino_target (struct cpufreq_policy *policy,
saved_mask = current->cpus_allowed;
set_cpus_allowed(current, policy->cpus);
if (smp_processor_id() != policy->cpu) {
dprintk("couldn't limit to CPUs in this domain\n");
return(-EAGAIN);
}
......@@ -588,26 +601,15 @@ static int centrino_target (struct cpufreq_policy *policy,
if (msr == (oldmsr & 0xffff)) {
retval = 0;
dprintk("no change needed - msr was and needs to be %x\n", oldmsr);
goto migrate_end;
}
/* Hm, old frequency can either be the last value we put in
PERF_CTL, or whatever it is now. The trouble is that TM2
can change it behind our back, which means we never get to
see the speed change. Reading back the current speed would
tell us something happened, but it may leave the things on
the notifier chain confused; we therefore stick to using
the last programmed speed rather than the current speed for
"old".
TODO: work out how the TCC interrupts work, and try to
catch the CPU changing things under us.
*/
freqs.cpu = policy->cpu;
freqs.old = extract_clock(oldmsr);
freqs.new = extract_clock(msr);
dprintk(KERN_INFO PFX "target=%dkHz old=%d new=%d msr=%04x\n",
dprintk("target=%dkHz old=%d new=%d msr=%04x\n",
target_freq, freqs.old, freqs.new, msr);
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
......
......@@ -52,16 +52,7 @@ static struct cpufreq_frequency_table speedstep_freqs[] = {
};
/* 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-ich", msg)
/**
......@@ -83,13 +74,13 @@ static void speedstep_set_state (unsigned int state)
/* get PMBASE */
pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
if (!(pmbase & 0x01)) {
printk(KERN_ERR "cpufreq: could not find speedstep register\n");
printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
return;
}
pmbase &= 0xFFFFFFFE;
if (!pmbase) {
printk(KERN_ERR "cpufreq: could not find speedstep register\n");
printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
return;
}
......@@ -99,13 +90,13 @@ static void speedstep_set_state (unsigned int state)
/* read state */
value = inb(pmbase + 0x50);
dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
dprintk("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
/* write new state */
value &= 0xFE;
value |= state;
dprintk(KERN_DEBUG "cpufreq: writing 0x%x to pmbase 0x%x + 0x50\n", value, pmbase);
dprintk("writing 0x%x to pmbase 0x%x + 0x50\n", value, pmbase);
/* Disable bus master arbitration */
pm2_blk = inb(pmbase + 0x20);
......@@ -125,10 +116,10 @@ static void speedstep_set_state (unsigned int state)
/* Enable IRQs */
local_irq_restore(flags);
dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
dprintk("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", (speedstep_get_processor_frequency(speedstep_processor) / 1000));
dprintk("change to %u MHz succeeded\n", (speedstep_get_processor_frequency(speedstep_processor) / 1000));
} else {
printk (KERN_ERR "cpufreq: change failed - I/O error\n");
}
......@@ -153,7 +144,7 @@ static int speedstep_activate (void)
pci_read_config_word(speedstep_chipset_dev, 0x00A0, &value);
if (!(value & 0x08)) {
value |= 0x08;
dprintk(KERN_DEBUG "cpufreq: activating SpeedStep (TM) registers\n");
dprintk("activating SpeedStep (TM) registers\n");
pci_write_config_word(speedstep_chipset_dev, 0x00A0, value);
}
......@@ -212,7 +203,7 @@ static unsigned int speedstep_detect_chipset (void)
pci_read_config_byte(hostbridge, PCI_REVISION_ID, &rev);
if (rev < 5) {
dprintk(KERN_INFO "cpufreq: hostbridge does not support speedstep\n");
dprintk("hostbridge does not support speedstep\n");
speedstep_chipset_dev = NULL;
pci_dev_put(hostbridge);
return 0;
......@@ -234,6 +225,7 @@ static unsigned int _speedstep_get(cpumask_t cpus)
set_cpus_allowed(current, cpus);
speed = speedstep_get_processor_frequency(speedstep_processor);
set_cpus_allowed(current, cpus_allowed);
dprintk("detected %u kHz as current frequency\n", speed);
return speed;
}
......@@ -266,6 +258,8 @@ static int speedstep_target (struct cpufreq_policy *policy,
freqs.new = speedstep_freqs[newstate].frequency;
freqs.cpu = policy->cpu;
dprintk("transiting from %u to %u kHz\n", freqs.old, freqs.new);
/* no transition necessary */
if (freqs.old == freqs.new)
return 0;
......@@ -335,7 +329,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
if (!speed)
return -EIO;
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));
......@@ -389,12 +383,14 @@ static int __init speedstep_init(void)
{
/* detect processor */
speedstep_processor = speedstep_detect_processor();
if (!speedstep_processor)
if (!speedstep_processor) {
dprintk("Intel(R) SpeedStep(TM) capable processor not found\n");
return -ENODEV;
}
/* detect chipset */
if (!speedstep_detect_chipset()) {
printk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) for this chipset not (yet) available.\n");
dprintk("Intel(R) SpeedStep(TM) for this chipset not (yet) available.\n");
return -ENODEV;
}
......
......@@ -19,17 +19,7 @@
#include <asm/msr.h>
#include "speedstep-lib.h"
/* 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-lib", msg)
#ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
static int relaxed_check = 0;
......@@ -83,7 +73,7 @@ static unsigned int pentium3_get_frequency (unsigned int processor)
/* read MSR 0x2a - we only need the low 32 bits */
rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
dprintk(KERN_DEBUG "speedstep-lib: P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
dprintk("P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
msr_tmp = msr_lo;
/* decode the FSB */
......@@ -96,9 +86,10 @@ static unsigned int pentium3_get_frequency (unsigned int processor)
}
/* decode the multiplier */
if (processor == SPEEDSTEP_PROCESSOR_PIII_C_EARLY)
if (processor == SPEEDSTEP_PROCESSOR_PIII_C_EARLY) {
dprintk("workaround for early PIIIs\n");
msr_lo &= 0x03c00000;
else
} else
msr_lo &= 0x0bc00000;
msr_lo >>= 22;
while (msr_lo != msr_decode_mult[j].bitmap) {
......@@ -107,6 +98,8 @@ static unsigned int pentium3_get_frequency (unsigned int processor)
j++;
}
dprintk("speed is %u\n", (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100));
return (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100);
}
......@@ -116,7 +109,7 @@ static unsigned int pentiumM_get_frequency(void)
u32 msr_lo, msr_tmp;
rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
dprintk(KERN_DEBUG "speedstep-lib: PM - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
dprintk("PM - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
/* see table B-2 of 24547212.pdf */
if (msr_lo & 0x00040000) {
......@@ -125,7 +118,7 @@ static unsigned int pentiumM_get_frequency(void)
}
msr_tmp = (msr_lo >> 22) & 0x1f;
dprintk(KERN_DEBUG "speedstep-lib: bits 22-26 are 0x%x\n", msr_tmp);
dprintk("bits 22-26 are 0x%x, speed is %u\n", msr_tmp, (msr_tmp * 100 * 1000));
return (msr_tmp * 100 * 1000);
}
......@@ -139,7 +132,7 @@ static unsigned int pentium4_get_frequency(void)
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);
dprintk("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,
......@@ -169,7 +162,7 @@ static unsigned int pentium4_get_frequency(void)
/* Multiplier. */
mult = msr_lo >> 24;
dprintk(KERN_DEBUG "speedstep-lib: P4 - FSB %u kHz; Multiplier %u\n", fsb, mult);
dprintk("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n", fsb, mult, (fsb * mult));
return (fsb * mult);
}
......@@ -204,6 +197,8 @@ unsigned int speedstep_detect_processor (void)
struct cpuinfo_x86 *c = cpu_data;
u32 ebx, msr_lo, msr_hi;
dprintk("x86: %x, model: %x\n", c->x86, c->x86_model);
if ((c->x86_vendor != X86_VENDOR_INTEL) ||
((c->x86 != 6) && (c->x86 != 0xF)))
return 0;
......@@ -217,7 +212,7 @@ unsigned int speedstep_detect_processor (void)
ebx = cpuid_ebx(0x00000001);
ebx &= 0x000000FF;
dprintk(KERN_INFO "ebx value is %x, x86_mask is %x\n", ebx, c->x86_mask);
dprintk("ebx value is %x, x86_mask is %x\n", ebx, c->x86_mask);
switch (c->x86_mask) {
case 4:
......@@ -269,6 +264,7 @@ unsigned int speedstep_detect_processor (void)
/* cpuid_ebx(1) is 0x04 for desktop PIII,
0x06 for mobile PIII-M */
ebx = cpuid_ebx(0x00000001);
dprintk("ebx is %x\n", ebx);
ebx &= 0x000000FF;
......@@ -286,7 +282,7 @@ unsigned int speedstep_detect_processor (void)
/* all mobile PIII Coppermines have FSB 100 MHz
* ==> sort out a few desktop PIIIs. */
rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi);
dprintk(KERN_DEBUG "cpufreq: Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n", msr_lo, msr_hi);
dprintk("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n", msr_lo, msr_hi);
msr_lo &= 0x00c0000;
if (msr_lo != 0x0080000)
return 0;
......@@ -298,11 +294,12 @@ unsigned int speedstep_detect_processor (void)
* bit 56 or 57 is set
*/
rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi);
dprintk(KERN_DEBUG "cpufreq: Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n", msr_lo, msr_hi);
dprintk("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n", msr_lo, msr_hi);
if ((msr_hi & (1<<18)) && (relaxed_check ? 1 : (msr_hi & (3<<24)))) {
if (c->x86_mask == 0x01)
if (c->x86_mask == 0x01) {
dprintk("early PIII version\n");
return SPEEDSTEP_PROCESSOR_PIII_C_EARLY;
else
} else
return SPEEDSTEP_PROCESSOR_PIII_C;
}
......@@ -329,11 +326,15 @@ unsigned int speedstep_get_freqs(unsigned int processor,
if ((!processor) || (!low_speed) || (!high_speed) || (!set_state))
return -EINVAL;
dprintk("trying to determine both speeds\n");
/* get current speed */
prev_speed = speedstep_get_processor_frequency(processor);
if (!prev_speed)
return -EIO;
dprintk("previous seped is %u\n", prev_speed);
local_irq_save(flags);
/* switch to low state */
......@@ -344,6 +345,8 @@ unsigned int speedstep_get_freqs(unsigned int processor,
goto out;
}
dprintk("low seped is %u\n", *low_speed);
/* switch to high state */
set_state(SPEEDSTEP_HIGH);
*high_speed = speedstep_get_processor_frequency(processor);
......@@ -352,6 +355,8 @@ unsigned int speedstep_get_freqs(unsigned int processor,
goto out;
}
dprintk("high seped is %u\n", *high_speed);
if (*low_speed == *high_speed) {
ret = -ENODEV;
goto out;
......
......@@ -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,24 +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");
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));
......@@ -313,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;
}
......@@ -356,11 +362,11 @@ static int __init speedstep_init(void)
}
if (!speedstep_processor) {
dprintk (KERN_INFO PFX "No supported Intel CPU detected.\n");
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);
......
......@@ -189,18 +189,6 @@ config MATH_EMULATION
here. Saying Y here will not hurt performance (on any machine) but
will increase the size of the kernel.
config CPU_FREQ
bool "CPU Frequency scaling"
help
Clock scaling allows you to change the clock speed of CPUs on the
fly. This is a nice method to save battery power on notebooks,
because the lower the clock speed, the less power the CPU consumes.
For more information, take a look at <file:Documentation/cpu-freq> or
at <http://www.brodo.de/cpufreq/>
If in doubt, say N.
source "drivers/cpufreq/Kconfig"
config CPU_FREQ_PMAC
......
......@@ -645,16 +645,6 @@ config SH_PCLK_FREQ
menu "CPU Frequency scaling"
config CPU_FREQ
bool "CPU Frequency scaling"
help
CPU clock scaling allows you to change the clock speed of the
running CPU on the fly.
For details, take a look at <file:Documentation/cpu-freq>.
If unsure, say N.
source "drivers/cpufreq/Kconfig"
config CPU_FREQ_TABLE
......
......@@ -135,16 +135,7 @@ config NR_CPUS
depends on SMP
default "32"
config CPU_FREQ
bool "CPU Frequency scaling"
help
Clock scaling allows you to change the clock speed of CPUs on the
fly. Currently there are only sparc64 drivers for UltraSPARC-III
and UltraSPARC-IIe processors.
For details, take a look at <file:Documentation/cpu-freq>.
If in doubt, say N.
source "drivers/cpufreq/Kconfig"
config CPU_FREQ_TABLE
tristate "CPU frequency table helpers"
......@@ -176,8 +167,6 @@ config US2E_FREQ
If in doubt, say N.
source "drivers/cpufreq/Kconfig"
# Identify this as a Sparc64 build
config SPARC64
bool
......
......@@ -4,18 +4,6 @@
menu "CPU Frequency scaling"
config CPU_FREQ
bool "CPU Frequency scaling"
help
Clock scaling allows you to change the clock speed of CPUs on the
fly. This is a nice method to save battery power on notebooks,
because the lower the clock speed, the less power the CPU consumes.
For more information, take a look at <file:Documentation/cpu-freq/>
or at <http://www.codemonkey.org.uk/projects/cpufreq/>
If in doubt, say N.
source "drivers/cpufreq/Kconfig"
config CPU_FREQ_TABLE
......
......@@ -6,12 +6,12 @@ SRCDIR := ../../../i386/kernel/cpu/cpufreq
obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi.o
obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o
obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o
powernow-k8-objs := ${SRCDIR}/powernow-k8.o
speedstep-centrino-objs := ${SRCDIR}/speedstep-centrino.o
acpi-objs := ${SRCDIR}/acpi.o
acpi-cpufreq-objs := ${SRCDIR}/acpi-cpufreq.o
p4-clockmod-objs := ${SRCDIR}/p4-clockmod.o
speedstep-lib-objs := ${SRCDIR}/speedstep-lib.o
config CPU_FREQ
bool "CPU Frequency scaling"
help
CPU Frequency scaling allows you to change the clock speed of
CPUs on the fly. This is a nice method to save power, because
the lower the CPU clock speed, the less power the CPU consumes.
Note that this driver doesn't automatically change the CPU
clock speed, you need to either enable a dynamic cpufreq governor
(see below) after boot, or use a userspace tool.
For details, take a look at <file:Documentation/cpu-freq>.
If in doubt, say N.
config CPU_FREQ_DEBUG
bool "Enable CPUfreq debugging"
depends on CPU_FREQ
help
Say Y here to enable CPUfreq subsystem (including drivers)
debugging. You will need to activate it via the kernel
command line by passing
cpufreq.debug=<value>
To get <value>, add
1 to activate CPUfreq core debugging,
2 to activate CPUfreq drivers debugging, and
4 to activate CPUfreq governor debugging
config CPU_FREQ_PROC_INTF
tristate "/proc/cpufreq interface (deprecated)"
depends on CPU_FREQ && PROC_FS
......
......@@ -24,6 +24,8 @@
#include <linux/cpu.h>
#include <linux/completion.h>
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "cpufreq-core", msg)
/**
* The "cpufreq driver" - the arch- or hardware-dependend low
* level driver of CPUFreq support, and its spinlock. This lock
......@@ -107,6 +109,90 @@ static void cpufreq_cpu_put(struct cpufreq_policy *data)
module_put(cpufreq_driver->owner);
}
/*********************************************************************
* UNIFIED DEBUG HELPERS *
*********************************************************************/
#ifdef CONFIG_CPU_FREQ_DEBUG
/* what part(s) of the CPUfreq subsystem are debugged? */
static unsigned int debug;
/* is the debug output ratelimit'ed using printk_ratelimit? User can
* set or modify this value.
*/
static unsigned int debug_ratelimit = 1;
/* is the printk_ratelimit'ing enabled? It's enabled after a successful
* loading of a cpufreq driver, temporarily disabled when a new policy
* is set, and disabled upon cpufreq driver removal
*/
static unsigned int disable_ratelimit = 1;
static spinlock_t disable_ratelimit_lock = SPIN_LOCK_UNLOCKED;
static inline void cpufreq_debug_enable_ratelimit(void)
{
unsigned long flags;
spin_lock_irqsave(&disable_ratelimit_lock, flags);
if (disable_ratelimit)
disable_ratelimit--;
spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
}
static inline void cpufreq_debug_disable_ratelimit(void)
{
unsigned long flags;
spin_lock_irqsave(&disable_ratelimit_lock, flags);
disable_ratelimit++;
spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
}
void cpufreq_debug_printk(unsigned int type, const char *prefix, const char *fmt, ...)
{
char s[256];
va_list args;
unsigned int len;
unsigned long flags;
WARN_ON(!prefix);
if (type & debug) {
spin_lock_irqsave(&disable_ratelimit_lock, flags);
if (!disable_ratelimit && debug_ratelimit && !printk_ratelimit()) {
spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
return;
}
spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
len = snprintf(s, 256, KERN_DEBUG "%s: ", prefix);
va_start(args, fmt);
len += vsnprintf(&s[len], (256 - len), fmt, args);
va_end(args);
printk(s);
WARN_ON(len < 5);
}
}
EXPORT_SYMBOL(cpufreq_debug_printk);
module_param(debug, uint, 0644);
MODULE_PARM_DESC(debug, "CPUfreq debugging: add 1 to debug core, 2 to debug drivers, and 4 to debug governors.");
module_param(debug_ratelimit, uint, 0644);
MODULE_PARM_DESC(debug_ratelimit, "CPUfreq debugging: set to 0 to disable ratelimiting.");
#else /* !CONFIG_CPU_FREQ_DEBUG */
static inline void cpufreq_debug_enable_ratelimit(void) { return; }
static inline void cpufreq_debug_disable_ratelimit(void) { return; }
#endif /* CONFIG_CPU_FREQ_DEBUG */
/*********************************************************************
* EXTERNALLY AFFECTING FREQUENCY CHANGES *
*********************************************************************/
......@@ -131,11 +217,14 @@ static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
if (!l_p_j_ref_freq) {
l_p_j_ref = loops_per_jiffy;
l_p_j_ref_freq = ci->old;
dprintk("saving %lu as reference value for loops_per_jiffy; freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
}
if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) ||
(val == CPUFREQ_POSTCHANGE && ci->old > ci->new) ||
(val == CPUFREQ_RESUMECHANGE))
(val == CPUFREQ_RESUMECHANGE)) {
loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new);
dprintk("scaling loops_per_jiffy to %lu for frequency %u kHz\n", loops_per_jiffy, ci->new);
}
}
#else
static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) { return; }
......@@ -153,6 +242,7 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
BUG_ON(irqs_disabled());
freqs->flags = cpufreq_driver->flags;
dprintk("notification %u of frequency transition to %u kHz\n", state, freqs->new);
down_read(&cpufreq_notifier_rwsem);
switch (state) {
......@@ -363,26 +453,37 @@ static ssize_t show_scaling_available_governors (struct cpufreq_policy * policy,
i += sprintf(&buf[i], "\n");
return i;
}
/**
* show_affected_cpus - show the CPUs affected by each transition
*/
static ssize_t show_affected_cpus (struct cpufreq_policy * policy, char *buf)
{
ssize_t i = 0;
unsigned int cpu;
for_each_cpu_mask(cpu, policy->cpus) {
if (i)
i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
if (i >= (PAGE_SIZE - 5))
break;
}
i += sprintf(&buf[i], "\n");
return i;
}
#define define_one_ro(_name) \
struct freq_attr _name = { \
.attr = { .name = __stringify(_name), .mode = 0444 }, \
.show = show_##_name, \
}
static struct freq_attr _name = \
__ATTR(_name, 0444, show_##_name, NULL)
#define define_one_ro0400(_name) \
struct freq_attr _name = { \
.attr = { .name = __stringify(_name), .mode = 0400 }, \
.show = show_##_name, \
}
static struct freq_attr _name = \
__ATTR(_name, 0400, show_##_name, NULL)
#define define_one_rw(_name) \
struct freq_attr _name = { \
.attr = { .name = __stringify(_name), .mode = 0644 }, \
.show = show_##_name, \
.store = store_##_name, \
}
static struct freq_attr _name = \
__ATTR(_name, 0644, show_##_name, store_##_name)
define_one_ro0400(cpuinfo_cur_freq);
define_one_ro(cpuinfo_min_freq);
......@@ -390,6 +491,7 @@ define_one_ro(cpuinfo_max_freq);
define_one_ro(scaling_available_governors);
define_one_ro(scaling_driver);
define_one_ro(scaling_cur_freq);
define_one_ro(affected_cpus);
define_one_rw(scaling_min_freq);
define_one_rw(scaling_max_freq);
define_one_rw(scaling_governor);
......@@ -399,6 +501,7 @@ static struct attribute * default_attrs[] = {
&cpuinfo_max_freq.attr,
&scaling_min_freq.attr,
&scaling_max_freq.attr,
&affected_cpus.attr,
&scaling_governor.attr,
&scaling_driver.attr,
&scaling_available_governors.attr,
......@@ -438,6 +541,7 @@ static ssize_t store(struct kobject * kobj, struct attribute * attr,
static void cpufreq_sysfs_release(struct kobject * kobj)
{
struct cpufreq_policy * policy = to_policy(kobj);
dprintk("last reference is dropped\n");
complete(&policy->kobj_unregister);
}
......@@ -468,19 +572,26 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
unsigned long flags;
unsigned int j;
cpufreq_debug_disable_ratelimit();
dprintk("adding CPU %u\n", cpu);
#ifdef CONFIG_SMP
/* check whether a different CPU already registered this
* CPU because it is in the same boat. */
policy = cpufreq_cpu_get(cpu);
if (unlikely(policy)) {
cpu_sys_devices[cpu] = sys_dev;
dprintk("CPU already managed, adding link\n");
sysfs_create_link(&sys_dev->kobj, &policy->kobj, "cpufreq");
cpufreq_debug_enable_ratelimit();
return 0;
}
#endif
if (!try_module_get(cpufreq_driver->owner))
return -EINVAL;
if (!try_module_get(cpufreq_driver->owner)) {
ret = -EINVAL;
goto module_out;
}
policy = kmalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
if (!policy) {
......@@ -500,8 +611,10 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
* to accept all calls to ->verify and ->setpolicy for this CPU
*/
ret = cpufreq_driver->init(policy);
if (ret)
if (ret) {
dprintk("initialization failed\n");
goto err_out;
}
memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
......@@ -536,11 +649,16 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
/* set default policy */
ret = cpufreq_set_policy(&new_policy);
if (ret)
if (ret) {
dprintk("setting policy failed\n");
goto err_out_unregister;
}
module_put(cpufreq_driver->owner);
cpu_sys_devices[cpu] = sys_dev;
dprintk("initialization complete\n");
cpufreq_debug_enable_ratelimit();
return 0;
......@@ -558,6 +676,8 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
nomem_out:
module_put(cpufreq_driver->owner);
module_out:
cpufreq_debug_enable_ratelimit();
return ret;
}
......@@ -576,12 +696,16 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
unsigned int j;
#endif
cpufreq_debug_disable_ratelimit();
dprintk("unregistering CPU %u\n", cpu);
spin_lock_irqsave(&cpufreq_driver_lock, flags);
data = cpufreq_cpu_data[cpu];
if (!data) {
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
cpu_sys_devices[cpu] = NULL;
cpufreq_debug_enable_ratelimit();
return -EINVAL;
}
cpufreq_cpu_data[cpu] = NULL;
......@@ -592,10 +716,12 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
* only need to unlink, put and exit
*/
if (unlikely(cpu != data->cpu)) {
dprintk("removing link\n");
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
sysfs_remove_link(&sys_dev->kobj, "cpufreq");
cpu_sys_devices[cpu] = NULL;
cpufreq_cpu_put(data);
cpufreq_debug_enable_ratelimit();
return 0;
}
#endif
......@@ -604,6 +730,7 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
if (!kobject_get(&data->kobj)) {
spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
cpufreq_debug_enable_ratelimit();
return -EFAULT;
}
......@@ -627,7 +754,7 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
for_each_cpu_mask(j, data->cpus) {
if (j == cpu)
continue;
dprintk("removing link for cpu %u\n", j);
sysfs_remove_link(&cpu_sys_devices[j]->kobj, "cpufreq");
cpufreq_cpu_put(data);
}
......@@ -647,13 +774,17 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
* not referenced anymore by anybody before we proceed with
* unloading.
*/
dprintk("waiting for dropping of refcount\n");
wait_for_completion(&data->kobj_unregister);
dprintk("wait complete\n");
if (cpufreq_driver->exit)
cpufreq_driver->exit(data);
kfree(data);
cpufreq_debug_enable_ratelimit();
return 0;
}
......@@ -661,6 +792,7 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev)
static void handle_update(void *data)
{
unsigned int cpu = (unsigned int)(long)data;
dprintk("handle_update for cpu %u called\n", cpu);
cpufreq_update_policy(cpu);
}
......@@ -741,6 +873,8 @@ static int cpufreq_resume(struct sys_device * sysdev)
unsigned int ret = 0;
struct cpufreq_policy *cpu_policy;
dprintk("resuming cpu %u\n", cpu);
if (!cpu_online(cpu))
return 0;
......@@ -882,6 +1016,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
{
int retval = -EINVAL;
lock_cpu_hotplug();
dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
target_freq, relation);
if (cpu_online(policy->cpu))
retval = cpufreq_driver->target(policy, target_freq, relation);
unlock_cpu_hotplug();
......@@ -920,6 +1056,7 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
if (!try_module_get(policy->governor->owner))
return -EINVAL;
dprintk("__cpufreq_governor for CPU %u, event %u\n", policy->cpu, event);
ret = policy->governor->governor(policy, event);
/* we keep one module reference alive for each CPU governed by this CPU */
......@@ -1024,6 +1161,10 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
{
int ret = 0;
cpufreq_debug_disable_ratelimit();
dprintk("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
policy->min, policy->max);
memcpy(&policy->cpuinfo,
&data->cpuinfo,
sizeof(struct cpufreq_cpuinfo));
......@@ -1060,14 +1201,19 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
data->min = policy->min;
data->max = policy->max;
dprintk("new min and max freqs are %u - %u kHz\n", data->min, data->max);
if (cpufreq_driver->setpolicy) {
data->policy = policy->policy;
dprintk("setting range\n");
ret = cpufreq_driver->setpolicy(policy);
} else {
if (policy->governor != data->governor) {
/* save old, working values */
struct cpufreq_governor *old_gov = data->governor;
dprintk("governor switch\n");
/* end old governor */
if (data->governor)
__cpufreq_governor(data, CPUFREQ_GOV_STOP);
......@@ -1076,6 +1222,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
data->governor = policy->governor;
if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
/* new governor failed, so re-start old one */
dprintk("starting governor %s failed\n", data->governor->name);
if (old_gov) {
data->governor = old_gov;
__cpufreq_governor(data, CPUFREQ_GOV_START);
......@@ -1085,10 +1232,12 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_poli
}
/* might be a policy change, too, so fall through */
}
dprintk("governor: change or update limits\n");
__cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
}
error_out:
cpufreq_debug_enable_ratelimit();
return ret;
}
......@@ -1145,6 +1294,7 @@ int cpufreq_update_policy(unsigned int cpu)
down(&data->lock);
dprintk("updating policy for CPU %u\n", cpu);
memcpy(&policy,
data,
sizeof(struct cpufreq_policy));
......@@ -1186,6 +1336,8 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
((!driver_data->setpolicy) && (!driver_data->target)))
return -EINVAL;
dprintk("trying to register driver %s\n", driver_data->name);
if (driver_data->setpolicy)
driver_data->flags |= CPUFREQ_CONST_LOOPS;
......@@ -1210,6 +1362,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
/* if all ->init() calls failed, unregister */
if (ret) {
dprintk("no CPU initialized for driver %s\n", driver_data->name);
sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
spin_lock_irqsave(&cpufreq_driver_lock, flags);
......@@ -1218,6 +1371,11 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
}
}
if (!ret) {
dprintk("driver %s up and running\n", driver_data->name);
cpufreq_debug_enable_ratelimit();
}
return (ret);
}
EXPORT_SYMBOL_GPL(cpufreq_register_driver);
......@@ -1235,8 +1393,14 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
{
unsigned long flags;
if (!cpufreq_driver || (driver != cpufreq_driver))
cpufreq_debug_disable_ratelimit();
if (!cpufreq_driver || (driver != cpufreq_driver)) {
cpufreq_debug_enable_ratelimit();
return -EINVAL;
}
dprintk("unregistering driver %s\n", driver->name);
sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
......
......@@ -10,7 +10,6 @@
* published by the Free Software Foundation.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/smp.h>
......@@ -26,7 +25,6 @@
#include <linux/kmod.h>
#include <linux/workqueue.h>
#include <linux/jiffies.h>
#include <linux/config.h>
#include <linux/kernel_stat.h>
#include <linux/percpu.h>
......@@ -83,7 +81,7 @@ struct dbs_tuners {
unsigned int down_threshold;
};
struct dbs_tuners dbs_tuners_ins = {
static struct dbs_tuners dbs_tuners_ins = {
.up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
.down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD,
.sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR,
......@@ -101,10 +99,8 @@ static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
}
#define define_one_ro(_name) \
static struct freq_attr _name = { \
.attr = { .name = __stringify(_name), .mode = 0444 }, \
.show = show_##_name, \
}
static struct freq_attr _name = \
__ATTR(_name, 0444, show_##_name, NULL)
define_one_ro(sampling_rate_max);
define_one_ro(sampling_rate_min);
......@@ -127,13 +123,13 @@ static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused,
unsigned int input;
int ret;
ret = sscanf (buf, "%u", &input);
down(&dbs_sem);
if (ret != 1 )
goto out;
return -EINVAL;
down(&dbs_sem);
dbs_tuners_ins.sampling_down_factor = input;
out:
up(&dbs_sem);
return count;
}
......@@ -143,13 +139,16 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
unsigned int input;
int ret;
ret = sscanf (buf, "%u", &input);
down(&dbs_sem);
if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE)
goto out;
if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) {
up(&dbs_sem);
return -EINVAL;
}
dbs_tuners_ins.sampling_rate = input;
out:
up(&dbs_sem);
return count;
}
......@@ -159,15 +158,18 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
unsigned int input;
int ret;
ret = sscanf (buf, "%u", &input);
down(&dbs_sem);
if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD ||
input < MIN_FREQUENCY_UP_THRESHOLD ||
input <= dbs_tuners_ins.down_threshold)
goto out;
input <= dbs_tuners_ins.down_threshold) {
up(&dbs_sem);
return -EINVAL;
}
dbs_tuners_ins.up_threshold = input;
out:
up(&dbs_sem);
return count;
}
......@@ -177,24 +179,24 @@ static ssize_t store_down_threshold(struct cpufreq_policy *unused,
unsigned int input;
int ret;
ret = sscanf (buf, "%u", &input);
down(&dbs_sem);
if (ret != 1 || input > MAX_FREQUENCY_DOWN_THRESHOLD ||
input < MIN_FREQUENCY_DOWN_THRESHOLD ||
input >= dbs_tuners_ins.up_threshold)
goto out;
input >= dbs_tuners_ins.up_threshold) {
up(&dbs_sem);
return -EINVAL;
}
dbs_tuners_ins.down_threshold = input;
out:
up(&dbs_sem);
return count;
}
#define define_one_rw(_name) \
static struct freq_attr _name = { \
.attr = { .name = __stringify(_name), .mode = 0644 }, \
.show = show_##_name, \
.store = store_##_name, \
}
static struct freq_attr _name = \
__ATTR(_name, 0644, show_##_name, store_##_name)
define_one_rw(sampling_rate);
define_one_rw(sampling_down_factor);
......
......@@ -15,12 +15,16 @@
#include <linux/cpufreq.h>
#include <linux/init.h>
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "performance", msg)
static int cpufreq_governor_performance(struct cpufreq_policy *policy,
unsigned int event)
{
switch (event) {
case CPUFREQ_GOV_START:
case CPUFREQ_GOV_LIMITS:
dprintk("setting to %u kHz because of event %u\n", policy->max, event);
__cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H);
break;
default:
......
......@@ -15,12 +15,15 @@
#include <linux/cpufreq.h>
#include <linux/init.h>
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "powersave", msg)
static int cpufreq_governor_powersave(struct cpufreq_policy *policy,
unsigned int event)
{
switch (event) {
case CPUFREQ_GOV_START:
case CPUFREQ_GOV_LIMITS:
dprintk("setting to %u kHz because of event %u\n", policy->min, event);
__cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L);
break;
default:
......
......@@ -68,12 +68,14 @@
*/
static unsigned int cpu_max_freq[NR_CPUS];
static unsigned int cpu_min_freq[NR_CPUS];
static unsigned int cpu_cur_freq[NR_CPUS];
static unsigned int cpu_cur_freq[NR_CPUS]; /* current CPU freq */
static unsigned int cpu_set_freq[NR_CPUS]; /* CPU freq desired by userspace */
static unsigned int cpu_is_managed[NR_CPUS];
static struct cpufreq_policy current_policy[NR_CPUS];
static DECLARE_MUTEX (userspace_sem);
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "userspace", msg)
/* keep track of frequency transitions */
static int
......@@ -82,13 +84,7 @@ userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
{
struct cpufreq_freqs *freq = data;
/* Don't update cur_freq if CPU is managed and we're
* waking up: else we won't remember what frequency
* we need to set the CPU to.
*/
if (cpu_is_managed[freq->cpu] && (val == CPUFREQ_RESUMECHANGE))
return 0;
dprintk("saving cpu_cur_freq of cpu %u to be %u kHz\n", freq->cpu, freq->new);
cpu_cur_freq[freq->cpu] = freq->new;
return 0;
......@@ -100,20 +96,24 @@ static struct notifier_block userspace_cpufreq_notifier_block = {
/**
* cpufreq_set - set the CPU frequency
* _cpufreq_set - set the CPU frequency
* @freq: target frequency in kHz
* @cpu: CPU for which the frequency is to be set
*
* Sets the CPU frequency to freq.
*/
int cpufreq_set(unsigned int freq, unsigned int cpu)
static int _cpufreq_set(unsigned int freq, unsigned int cpu)
{
int ret = -EINVAL;
dprintk("_cpufreq_set for cpu %u, freq %u kHz\n", cpu, freq);
down(&userspace_sem);
if (!cpu_is_managed[cpu])
goto err;
cpu_set_freq[cpu] = freq;
if (freq < cpu_min_freq[cpu])
freq = cpu_min_freq[cpu];
if (freq > cpu_max_freq[cpu])
......@@ -133,6 +133,18 @@ int cpufreq_set(unsigned int freq, unsigned int cpu)
up(&userspace_sem);
return ret;
}
#ifdef CONFIG_CPU_FREQ_24_API
#warning The /proc/sys/cpu/ and sysctl interface to cpufreq will be removed from the 2.6. kernel series soon after 2005-01-01
static unsigned int warning_print = 0;
int __deprecated cpufreq_set(unsigned int freq, unsigned int cpu)
{
return _cpufreq_set(freq, cpu);
}
EXPORT_SYMBOL_GPL(cpufreq_set);
......@@ -143,21 +155,14 @@ EXPORT_SYMBOL_GPL(cpufreq_set);
* Sets the CPU frequency to the maximum frequency supported by
* this CPU.
*/
int cpufreq_setmax(unsigned int cpu)
int __deprecated cpufreq_setmax(unsigned int cpu)
{
if (!cpu_is_managed[cpu] || !cpu_online(cpu))
return -EINVAL;
return cpufreq_set(cpu_max_freq[cpu], cpu);
return _cpufreq_set(cpu_max_freq[cpu], cpu);
}
EXPORT_SYMBOL_GPL(cpufreq_setmax);
#ifdef CONFIG_CPU_FREQ_24_API
#warning The /proc/sys/cpu/ and sysctl interface to cpufreq will be removed from the 2.6. kernel series soon after 2005-01-01
static unsigned int warning_print = 0;
/*********************** cpufreq_sysctl interface ********************/
static int
cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
......@@ -190,7 +195,7 @@ cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
buf[sizeof(buf) - 1] = '\0';
freq = simple_strtoul(buf, &p, 0);
cpufreq_set(freq, cpu);
_cpufreq_set(freq, cpu);
} else {
len = sprintf(buf, "%d\n", cpufreq_get(cpu));
if (len > left)
......@@ -243,7 +248,7 @@ cpufreq_sysctl(ctl_table *table, int __user *name, int nlen,
if (get_user(freq, (unsigned int __user *)newval))
return -EFAULT;
cpufreq_set(freq, cpu);
_cpufreq_set(freq, cpu);
}
return 1;
}
......@@ -464,7 +469,7 @@ static ctl_table ctl_cpu[2] = {
}
};
struct ctl_table_header *cpufreq_sysctl_table;
static struct ctl_table_header *cpufreq_sysctl_table;
static inline void cpufreq_sysctl_init(void)
{
......@@ -498,13 +503,14 @@ store_speed (struct cpufreq_policy *policy, const char *buf, size_t count)
if (ret != 1)
return -EINVAL;
cpufreq_set(freq, policy->cpu);
_cpufreq_set(freq, policy->cpu);
return count;
}
static struct freq_attr freq_attr_scaling_setspeed = {
.attr = { .name = "scaling_setspeed", .mode = 0644 },
static struct freq_attr freq_attr_scaling_setspeed =
{
.attr = { .name = "scaling_setspeed", .mode = 0644, .owner = THIS_MODULE },
.show = show_speed,
.store = store_speed,
};
......@@ -523,8 +529,10 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
cpu_min_freq[cpu] = policy->min;
cpu_max_freq[cpu] = policy->max;
cpu_cur_freq[cpu] = policy->cur;
cpu_set_freq[cpu] = policy->cur;
sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr);
memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]);
up(&userspace_sem);
break;
case CPUFREQ_GOV_STOP:
......@@ -532,22 +540,26 @@ static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
cpu_is_managed[cpu] = 0;
cpu_min_freq[cpu] = 0;
cpu_max_freq[cpu] = 0;
cpu_set_freq[cpu] = 0;
sysfs_remove_file (&policy->kobj, &freq_attr_scaling_setspeed.attr);
dprintk("managing cpu %u stopped\n", cpu);
up(&userspace_sem);
break;
case CPUFREQ_GOV_LIMITS:
down(&userspace_sem);
cpu_min_freq[cpu] = policy->min;
cpu_max_freq[cpu] = policy->max;
if (policy->max < cpu_cur_freq[cpu])
dprintk("limit event for cpu %u: %u - %u kHz, currently %u kHz, last set to %u kHz\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu], cpu_set_freq[cpu]);
if (policy->max < cpu_set_freq[cpu]) {
__cpufreq_driver_target(&current_policy[cpu], policy->max,
CPUFREQ_RELATION_H);
else if (policy->min > cpu_cur_freq[cpu])
} else if (policy->min > cpu_set_freq[cpu]) {
__cpufreq_driver_target(&current_policy[cpu], policy->min,
CPUFREQ_RELATION_L);
else
__cpufreq_driver_target(&current_policy[cpu], cpu_cur_freq[cpu],
} else {
__cpufreq_driver_target(&current_policy[cpu], cpu_set_freq[cpu],
CPUFREQ_RELATION_L);
}
memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
up(&userspace_sem);
break;
......
......@@ -9,6 +9,8 @@
#include <linux/init.h>
#include <linux/cpufreq.h>
#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "freq-table", msg)
/*********************************************************************
* FREQUENCY TABLE HELPERS *
*********************************************************************/
......@@ -22,8 +24,12 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
unsigned int freq = table[i].frequency;
if (freq == CPUFREQ_ENTRY_INVALID)
if (freq == CPUFREQ_ENTRY_INVALID) {
dprintk("table entry %u is invalid, skipping\n", i);
continue;
}
dprintk("table entry %u: %u kHz, %u index\n", i, freq, table[i].index);
if (freq < min_freq)
min_freq = freq;
if (freq > max_freq)
......@@ -48,6 +54,8 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
unsigned int i = 0;
unsigned int count = 0;
dprintk("request for verification of policy (%u - %u kHz) for cpu %u\n", policy->min, policy->max, policy->cpu);
if (!cpu_online(policy->cpu))
return -EINVAL;
......@@ -72,6 +80,8 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
policy->cpuinfo.min_freq,
policy->cpuinfo.max_freq);
dprintk("verification lead to (%u - %u kHz) for cpu %u\n", policy->min, policy->max, policy->cpu);
return 0;
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify);
......@@ -87,6 +97,8 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
struct cpufreq_frequency_table suboptimal = { .index = ~0, };
unsigned int i;
dprintk("request for target %u kHz (relation: %u) for cpu %u\n", target_freq, relation, policy->cpu);
switch (relation) {
case CPUFREQ_RELATION_H:
optimal.frequency = 0;
......@@ -143,6 +155,9 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
} else
*index = optimal.index;
dprintk("target is %u (%u kHz, %u)\n", *index, table[*index].frequency,
table[*index].index);
return 0;
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
......@@ -175,7 +190,7 @@ static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf)
}
struct freq_attr cpufreq_freq_attr_scaling_available_freqs = {
.attr = { .name = "scaling_available_frequencies", .mode = 0444 },
.attr = { .name = "scaling_available_frequencies", .mode = 0444, .owner=THIS_MODULE },
.show = show_available_freqs,
};
EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs);
......@@ -187,12 +202,14 @@ EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs);
void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
unsigned int cpu)
{
dprintk("setting show_table for cpu %u to %p\n", cpu, table);
show_table[cpu] = table;
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_attr);
void cpufreq_frequency_table_put_attr(unsigned int cpu)
{
dprintk("clearing show_table for cpu %u\n", cpu);
show_table[cpu] = NULL;
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr);
......
......@@ -261,8 +261,8 @@ int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpu
*********************************************************************/
#ifdef CONFIG_CPU_FREQ_24_API
int cpufreq_setmax(unsigned int cpu);
int cpufreq_set(unsigned int kHz, unsigned int cpu);
int __deprecated cpufreq_setmax(unsigned int cpu);
int __deprecated cpufreq_set(unsigned int kHz, unsigned int cpu);
/* /proc/sys/cpu */
......@@ -360,4 +360,23 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
void cpufreq_frequency_table_put_attr(unsigned int cpu);
/*********************************************************************
* UNIFIED DEBUG HELPERS *
*********************************************************************/
#define CPUFREQ_DEBUG_CORE 1
#define CPUFREQ_DEBUG_DRIVER 2
#define CPUFREQ_DEBUG_GOVERNOR 4
#ifdef CONFIG_CPU_FREQ_DEBUG
extern void cpufreq_debug_printk(unsigned int type, const char *prefix,
const char *fmt, ...);
#else
#define cpufreq_debug_printk(msg...) do { } while(0)
#endif /* CONFIG_CPU_FREQ_DEBUG */
#endif /* _LINUX_CPUFREQ_H */
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