Signed-off-by: Andrew Morton --- 25-akpm/Documentation/cpu-freq/cpufreq-nforce2.txt | 19 25-akpm/arch/arm/Kconfig | 11 25-akpm/arch/i386/kernel/cpu/cpufreq/Kconfig | 23 25-akpm/arch/i386/kernel/cpu/cpufreq/Makefile | 33 25-akpm/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 507 ++++++++++++++ 25-akpm/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c | 466 ++++++++++++ 25-akpm/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c | 16 25-akpm/arch/i386/kernel/cpu/cpufreq/longhaul.c | 34 25-akpm/arch/i386/kernel/cpu/cpufreq/longrun.c | 11 25-akpm/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c | 21 25-akpm/arch/i386/kernel/cpu/cpufreq/powernow-k7.c | 69 - 25-akpm/arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 105 +- 25-akpm/arch/i386/kernel/cpu/cpufreq/powernow-k8.h | 6 25-akpm/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | 80 +- 25-akpm/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c | 38 - 25-akpm/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c | 51 - 25-akpm/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c | 54 - 25-akpm/arch/ppc/Kconfig | 12 25-akpm/arch/sh/Kconfig | 10 25-akpm/arch/sparc64/Kconfig | 13 25-akpm/arch/x86_64/kernel/cpufreq/Kconfig | 12 25-akpm/arch/x86_64/kernel/cpufreq/Makefile | 5 25-akpm/drivers/cpufreq/Kconfig | 29 25-akpm/drivers/cpufreq/cpufreq.c | 204 +++++ 25-akpm/drivers/cpufreq/cpufreq_ondemand.c | 52 - 25-akpm/drivers/cpufreq/cpufreq_performance.c | 4 25-akpm/drivers/cpufreq/cpufreq_powersave.c | 3 25-akpm/drivers/cpufreq/cpufreq_userspace.c | 70 + 25-akpm/drivers/cpufreq/freq_table.c | 23 25-akpm/include/linux/cpufreq.h | 23 arch/i386/kernel/cpu/cpufreq/acpi.c | 0 31 files changed, 1581 insertions(+), 423 deletions(-) diff -puN arch/arm/Kconfig~bk-cpufreq arch/arm/Kconfig --- 25/arch/arm/Kconfig~bk-cpufreq 2004-11-09 01:18:45.983203464 -0800 +++ 25-akpm/arch/arm/Kconfig 2004-11-09 01:18:46.041194648 -0800 @@ -345,17 +345,6 @@ config ZBOOT_ROM_BSS 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 diff -puN arch/i386/kernel/cpu/cpufreq/acpi.c~bk-cpufreq arch/i386/kernel/cpu/cpufreq/acpi.c diff -puN /dev/null arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 2004-11-09 01:18:46.045194040 -0800 @@ -0,0 +1,507 @@ +/* + * acpi-cpufreq.c - ACPI Processor P-States Driver ($Revision: 1.3 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * Copyright (C) 2002 - 2004 Dominik Brodowski + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg) + +MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski"); +MODULE_DESCRIPTION("ACPI Processor P-States Driver"); +MODULE_LICENSE("GPL"); + + +struct cpufreq_acpi_io { + struct acpi_processor_performance acpi_data; + struct cpufreq_frequency_table *freq_table; +}; + +static struct cpufreq_acpi_io *acpi_io_data[NR_CPUS]; + + +static int +acpi_processor_write_port( + u16 port, + u8 bit_width, + u32 value) +{ + if (bit_width <= 8) { + outb(value, port); + } else if (bit_width <= 16) { + outw(value, port); + } else if (bit_width <= 32) { + outl(value, port); + } else { + return -ENODEV; + } + return 0; +} + +static int +acpi_processor_read_port( + u16 port, + u8 bit_width, + u32 *ret) +{ + *ret = 0; + if (bit_width <= 8) { + *ret = inb(port); + } else if (bit_width <= 16) { + *ret = inw(port); + } else if (bit_width <= 32) { + *ret = inl(port); + } else { + return -ENODEV; + } + return 0; +} + +static int +acpi_processor_set_performance ( + struct cpufreq_acpi_io *data, + unsigned int cpu, + int state) +{ + u16 port = 0; + u8 bit_width = 0; + int ret = 0; + u32 value = 0; + int i = 0; + struct cpufreq_freqs cpufreq_freqs; + cpumask_t saved_mask; + int retval; + + dprintk("acpi_processor_set_performance\n"); + + /* + * TBD: Use something other than set_cpus_allowed. + * As set_cpus_allowed is a bit racy, + * with any other set_cpus_allowed for this process. + */ + saved_mask = current->cpus_allowed; + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + if (smp_processor_id() != cpu) { + return (-EAGAIN); + } + + if (state == data->acpi_data.state) { + dprintk("Already at target state (P%d)\n", state); + retval = 0; + goto migrate_end; + } + + dprintk("Transitioning from P%d to P%d\n", + data->acpi_data.state, state); + + /* cpufreq frequency struct */ + cpufreq_freqs.cpu = cpu; + cpufreq_freqs.old = data->freq_table[data->acpi_data.state].frequency; + cpufreq_freqs.new = data->freq_table[state].frequency; + + /* notify cpufreq */ + cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE); + + /* + * First we write the target state's 'control' value to the + * control_register. + */ + + port = data->acpi_data.control_register.address; + bit_width = data->acpi_data.control_register.bit_width; + value = (u32) data->acpi_data.states[state].control; + + dprintk("Writing 0x%08x to port 0x%04x\n", value, port); + + ret = acpi_processor_write_port(port, bit_width, value); + if (ret) { + dprintk("Invalid port width 0x%04x\n", bit_width); + retval = ret; + goto migrate_end; + } + + /* + * Then we read the 'status_register' and compare the value with the + * target state's 'status' to make sure the transition was successful. + * Note that we'll poll for up to 1ms (100 cycles of 10us) before + * giving up. + */ + + port = data->acpi_data.status_register.address; + bit_width = data->acpi_data.status_register.bit_width; + + 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) { + dprintk("Invalid port width 0x%04x\n", bit_width); + retval = ret; + goto migrate_end; + } + if (value == (u32) data->acpi_data.states[state].status) + break; + udelay(10); + } + + /* notify cpufreq */ + cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); + + if (value != (u32) data->acpi_data.states[state].status) { + unsigned int tmp = cpufreq_freqs.new; + cpufreq_freqs.new = cpufreq_freqs.old; + cpufreq_freqs.old = tmp; + cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE); + cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE); + printk(KERN_WARNING "acpi-cpufreq: Transition failed\n"); + retval = -ENODEV; + goto migrate_end; + } + + 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 (retval); +} + + +static int +acpi_cpufreq_target ( + struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu]; + unsigned int next_state = 0; + unsigned int result = 0; + + dprintk("acpi_cpufreq_setpolicy\n"); + + result = cpufreq_frequency_table_target(policy, + data->freq_table, + target_freq, + relation, + &next_state); + if (result) + return (result); + + result = acpi_processor_set_performance (data, policy->cpu, next_state); + + return (result); +} + + +static int +acpi_cpufreq_verify ( + struct cpufreq_policy *policy) +{ + unsigned int result = 0; + struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu]; + + dprintk("acpi_cpufreq_verify\n"); + + result = cpufreq_frequency_table_verify(policy, + data->freq_table); + + return (result); +} + + +static unsigned long +acpi_cpufreq_guess_freq ( + struct cpufreq_acpi_io *data, + unsigned int cpu) +{ + if (cpu_khz) { + /* search the closest match to cpu_khz */ + unsigned int i; + unsigned long freq; + unsigned long freqn = data->acpi_data.states[0].core_frequency * 1000; + + for (i=0; i < (data->acpi_data.state_count - 1); i++) { + freq = freqn; + freqn = data->acpi_data.states[i+1].core_frequency * 1000; + if ((2 * cpu_khz) > (freqn + freq)) { + data->acpi_data.state = i; + return (freq); + } + } + data->acpi_data.state = data->acpi_data.state_count - 1; + return (freqn); + } else + /* assume CPU is at P0... */ + data->acpi_data.state = 0; + return data->acpi_data.states[0].core_frequency * 1000; + +} + + +/* + * acpi_processor_cpu_init_pdc_est - let BIOS know about the SMP capabilities + * of this driver + * @perf: processor-specific acpi_io_data struct + * @cpu: CPU being initialized + * + * To avoid issues with legacy OSes, some BIOSes require to be informed of + * the SMP capabilities of OS P-state driver. Here we set the bits in _PDC + * accordingly, for Enhanced Speedstep. Actual call to _PDC is done in + * driver/acpi/processor.c + */ +static void +acpi_processor_cpu_init_pdc_est( + struct acpi_processor_performance *perf, + unsigned int cpu, + struct acpi_object_list *obj_list + ) +{ + union acpi_object *obj; + u32 *buf; + struct cpuinfo_x86 *c = cpu_data + cpu; + dprintk("acpi_processor_cpu_init_pdc_est\n"); + + if (!cpu_has(c, X86_FEATURE_EST)) + return; + + /* Initialize pdc. It will be used later. */ + if (!obj_list) + return; + + if (!(obj_list->count && obj_list->pointer)) + return; + + obj = obj_list->pointer; + if ((obj->buffer.length == 12) && obj->buffer.pointer) { + buf = (u32 *)obj->buffer.pointer; + buf[0] = ACPI_PDC_REVISION_ID; + buf[1] = 1; + buf[2] = ACPI_PDC_EST_CAPABILITY_SMP; + perf->pdc = obj_list; + } + return; +} + + +/* CPU specific PDC initialization */ +static void +acpi_processor_cpu_init_pdc( + struct acpi_processor_performance *perf, + unsigned int cpu, + struct acpi_object_list *obj_list + ) +{ + struct cpuinfo_x86 *c = cpu_data + cpu; + 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; +} + + +static int +acpi_cpufreq_cpu_init ( + struct cpufreq_policy *policy) +{ + unsigned int i; + unsigned int cpu = policy->cpu; + struct cpufreq_acpi_io *data; + unsigned int result = 0; + + union acpi_object arg0 = {ACPI_TYPE_BUFFER}; + u32 arg0_buf[3]; + struct acpi_object_list arg_list = {1, &arg0}; + + 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 (-ENOMEM); + memset(data, 0, sizeof(struct cpufreq_acpi_io)); + + acpi_io_data[cpu] = data; + + acpi_processor_cpu_init_pdc(&data->acpi_data, cpu, &arg_list); + result = acpi_processor_register_performance(&data->acpi_data, cpu); + data->acpi_data.pdc = NULL; + + if (result) + goto err_free; + + /* capability check */ + if (data->acpi_data.state_count <= 1) { + 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)) { + dprintk("Unsupported address space [%d, %d]\n", + (u32) (data->acpi_data.control_register.space_id), + (u32) (data->acpi_data.status_register.space_id)); + result = -ENODEV; + goto err_unreg; + } + + /* alloc freq_table */ + data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) * (data->acpi_data.state_count + 1), GFP_KERNEL); + if (!data->freq_table) { + result = -ENOMEM; + goto err_unreg; + } + + /* detect transition latency */ + policy->cpuinfo.transition_latency = 0; + for (i=0; iacpi_data.state_count; i++) { + if ((data->acpi_data.states[i].transition_latency * 1000) > policy->cpuinfo.transition_latency) + policy->cpuinfo.transition_latency = data->acpi_data.states[i].transition_latency * 1000; + } + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + + /* The current speed is unknown and not detectable by ACPI... */ + policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu); + + /* table init */ + for (i=0; i<=data->acpi_data.state_count; i++) + { + data->freq_table[i].index = i; + if (iacpi_data.state_count) + data->freq_table[i].frequency = data->acpi_data.states[i].core_frequency * 1000; + else + data->freq_table[i].frequency = CPUFREQ_TABLE_END; + } + + result = cpufreq_frequency_table_cpuinfo(policy, data->freq_table); + if (result) { + goto err_freqfree; + } + + + printk(KERN_INFO "acpi-cpufreq: CPU%u - ACPI performance management activated.\n", + cpu); + for (i = 0; i < data->acpi_data.state_count; i++) + 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 (result); + + err_freqfree: + kfree(data->freq_table); + err_unreg: + acpi_processor_unregister_performance(&data->acpi_data, cpu); + err_free: + kfree(data); + acpi_io_data[cpu] = NULL; + + return (result); +} + + +static int +acpi_cpufreq_cpu_exit ( + struct cpufreq_policy *policy) +{ + struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu]; + + + dprintk("acpi_cpufreq_cpu_exit\n"); + + if (data) { + cpufreq_frequency_table_put_attr(policy->cpu); + acpi_io_data[policy->cpu] = NULL; + acpi_processor_unregister_performance(&data->acpi_data, policy->cpu); + kfree(data); + } + + return (0); +} + + +static struct freq_attr* acpi_cpufreq_attr[] = { + &cpufreq_freq_attr_scaling_available_freqs, + NULL, +}; + +static struct cpufreq_driver acpi_cpufreq_driver = { + .verify = acpi_cpufreq_verify, + .target = acpi_cpufreq_target, + .init = acpi_cpufreq_cpu_init, + .exit = acpi_cpufreq_cpu_exit, + .name = "acpi-cpufreq", + .owner = THIS_MODULE, + .attr = acpi_cpufreq_attr, +}; + + +static int __init +acpi_cpufreq_init (void) +{ + int result = 0; + + dprintk("acpi_cpufreq_init\n"); + + result = cpufreq_register_driver(&acpi_cpufreq_driver); + + return (result); +} + + +static void __exit +acpi_cpufreq_exit (void) +{ + dprintk("acpi_cpufreq_exit\n"); + + cpufreq_unregister_driver(&acpi_cpufreq_driver); + + return; +} + + +late_initcall(acpi_cpufreq_init); +module_exit(acpi_cpufreq_exit); + +MODULE_ALIAS("acpi"); diff -puN /dev/null arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c 2004-11-09 01:18:47.113031704 -0800 @@ -0,0 +1,466 @@ +/* + * (C) 2004 Sebastian Witt + * + * 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 +#include +#include +#include +#include +#include +#include + +#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 "); +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); + diff -puN arch/i386/kernel/cpu/cpufreq/gx-suspmod.c~bk-cpufreq arch/i386/kernel/cpu/cpufreq/gx-suspmod.c --- 25/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c~bk-cpufreq 2004-11-09 01:18:45.986203008 -0800 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c 2004-11-09 01:18:47.113031704 -0800 @@ -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_ /* 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_ } } - dprintk(KERN_INFO "gx-suspmod: error: no supported chipset found!\n"); + dprintk("error: no supported chipset found!\n"); return NULL; } diff -puN arch/i386/kernel/cpu/cpufreq/Kconfig~bk-cpufreq arch/i386/kernel/cpu/cpufreq/Kconfig --- 25/arch/i386/kernel/cpu/cpufreq/Kconfig~bk-cpufreq 2004-11-09 01:18:45.988202704 -0800 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/Kconfig 2004-11-09 01:18:46.042194496 -0800 @@ -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 - or at - - 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 . + + If in doubt, say N. + config X86_LONGRUN tristate "Transmeta LongRun" depends on CPU_FREQ diff -puN arch/i386/kernel/cpu/cpufreq/longhaul.c~bk-cpufreq arch/i386/kernel/cpu/cpufreq/longhaul.c --- 25/arch/i386/kernel/cpu/cpufreq/longhaul.c~bk-cpufreq 2004-11-09 01:18:45.989202552 -0800 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/longhaul.c 2004-11-09 01:18:47.114031552 -0800 @@ -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 i 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(vo } } - 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(vo 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_voltag } 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 "); MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors."); MODULE_LICENSE ("GPL"); diff -puN arch/i386/kernel/cpu/cpufreq/longrun.c~bk-cpufreq arch/i386/kernel/cpu/cpufreq/longrun.c --- 25/arch/i386/kernel/cpu/cpufreq/longrun.c~bk-cpufreq 2004-11-09 01:18:45.990202400 -0800 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/longrun.c 2004-11-09 01:18:47.115031400 -0800 @@ -16,6 +16,8 @@ #include #include +#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(st 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 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_deter 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_deter /* 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_deter /* 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_deter 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; diff -puN arch/i386/kernel/cpu/cpufreq/Makefile~bk-cpufreq arch/i386/kernel/cpu/cpufreq/Makefile --- 25/arch/i386/kernel/cpu/cpufreq/Makefile~bk-cpufreq 2004-11-09 01:18:45.992202096 -0800 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/Makefile 2004-11-09 01:18:46.042194496 -0800 @@ -1,19 +1,14 @@ -obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o -obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o -obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o -obj-$(CONFIG_X86_LONGHAUL) += longhaul.o -obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o -obj-$(CONFIG_X86_LONGRUN) += longrun.o -obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o -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_P4_CLOCKMOD) += p4-clockmod.o - -ifdef CONFIG_X86_ACPI_CPUFREQ - ifdef CONFIG_ACPI_DEBUG - EXTRA_CFLAGS += -DACPI_DEBUG_OUTPUT - endif -endif +obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o +obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o +obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o +obj-$(CONFIG_X86_LONGHAUL) += longhaul.o +obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o +obj-$(CONFIG_X86_LONGRUN) += longrun.o +obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o +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-cpufreq.o +obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o +obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o diff -puN arch/i386/kernel/cpu/cpufreq/p4-clockmod.c~bk-cpufreq arch/i386/kernel/cpu/cpufreq/p4-clockmod.c --- 25/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c~bk-cpufreq 2004-11-09 01:18:45.993201944 -0800 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c 2004-11-09 01:18:47.116031248 -0800 @@ -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 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 cp 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_ 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; - printk(KERN_INFO PFX "P4/Xeon(TM) CPU On-Demand Clock Modulation available\n"); + ret = cpufreq_register_driver(&p4clockmod_driver); + if (!ret) + printk(KERN_INFO PFX "P4/Xeon(TM) CPU On-Demand Clock Modulation available\n"); - return cpufreq_register_driver(&p4clockmod_driver); + return (ret); } diff -puN arch/i386/kernel/cpu/cpufreq/powernow-k7.c~bk-cpufreq arch/i386/kernel/cpu/cpufreq/powernow-k7.c --- 25/arch/i386/kernel/cpu/cpufreq/powernow-k7.c~bk-cpufreq 2004-11-09 01:18:45.995201640 -0800 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/powernow-k7.c 2004-11-09 01:18:47.118030944 -0800 @@ -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 *ps #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,8 +197,12 @@ static int get_ranges (unsigned char *ps vid = *pst++; powernow_table[j].index |= (vid << 8); /* upper 8 bits */ - dprintk ("VID: 0x%x (%d.%03dV)\n", vid, mobile_vid_table[vid]/1000, - 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; powernow_table[number_scales].index = 0; @@ -302,7 +291,7 @@ static void change_speed (unsigned int i #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,10 +372,11 @@ 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, - 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) latency = pc.bits.sgtc; @@ -439,21 +429,20 @@ static int powernow_decode_bios (int max 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 max "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 max 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 (str 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."); diff -puN arch/i386/kernel/cpu/cpufreq/powernow-k8.c~bk-cpufreq arch/i386/kernel/cpu/cpufreq/powernow-k8.c --- 25/arch/i386/kernel/cpu/cpufreq/powernow-k8.c~bk-cpufreq 2004-11-09 01:18:45.996201488 -0800 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/powernow-k8.c 2004-11-09 01:18:47.121030488 -0800 @@ -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 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 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 pow 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(s 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(s 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(s 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(str 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(str 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( 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( 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 po 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 po 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 powerno 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 powerno } 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(str 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(str 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(str 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(str /* 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(str 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 p 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,28 +824,25 @@ static int transition_frequency(struct p 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", - smp_processor_id(), fid, vid); + 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 cpuf 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 cpuf 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(st + (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(st 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); } diff -puN arch/i386/kernel/cpu/cpufreq/powernow-k8.h~bk-cpufreq arch/i386/kernel/cpu/cpufreq/powernow-k8.h --- 25/arch/i386/kernel/cpu/cpufreq/powernow-k8.h~bk-cpufreq 2004-11-09 01:18:45.998201184 -0800 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/powernow-k8.h 2004-11-09 01:18:47.121030488 -0800 @@ -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); diff -puN arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c~bk-cpufreq arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c --- 25/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c~bk-cpufreq 2004-11-09 01:18:45.999201032 -0800 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2004-11-09 01:18:47.123030184 -0800 @@ -35,13 +35,8 @@ #define PFX "speedstep-centrino: " #define MAINTAINER "Jeremy Fitzhardinge " -/*#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(struc /* 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; @@ -344,47 +341,52 @@ static int centrino_cpu_init_acpi(struct int result = 0, i; /* _PDC settings */ - arg0.buffer.length = 12; - arg0.buffer.pointer = (u8 *) arg0_buf; - arg0_buf[0] = ACPI_PDC_REVISION_ID; - arg0_buf[1] = 1; - arg0_buf[2] = ACPI_PDC_EST_CAPABILITY_SMP | ACPI_PDC_EST_CAPABILITY_MSR; + arg0.buffer.length = 12; + arg0.buffer.pointer = (u8 *) arg0_buf; + arg0_buf[0] = ACPI_PDC_REVISION_ID; + arg0_buf[1] = 1; + arg0_buf[2] = ACPI_PDC_EST_CAPABILITY_SMP | ACPI_PDC_EST_CAPABILITY_MSR; p.pdc = &arg_list; /* register with ACPI core */ - if (acpi_processor_register_performance(&p, policy->cpu)) - return -EIO; + 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"); - result = -ENODEV; - goto err_unreg; + 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.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 for (i=0; iop_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; iop_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 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 cpuf 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 cpuf 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 cpuf #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 cpufr 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 cpufr 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); diff -puN arch/i386/kernel/cpu/cpufreq/speedstep-ich.c~bk-cpufreq arch/i386/kernel/cpu/cpufreq/speedstep-ich.c --- 25/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c~bk-cpufreq 2004-11-09 01:18:46.001200728 -0800 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c 2004-11-09 01:18:47.125029880 -0800 @@ -52,16 +52,7 @@ static struct cpufreq_frequency_table sp }; -/* 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 (unsigne /* 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 (unsigne /* 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 (unsigne /* 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_chi 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(cpuma 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 cpuf 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 cpu 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; } diff -puN arch/i386/kernel/cpu/cpufreq/speedstep-lib.c~bk-cpufreq arch/i386/kernel/cpu/cpufreq/speedstep-lib.c --- 25/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c~bk-cpufreq 2004-11-09 01:18:46.002200576 -0800 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c 2004-11-09 01:18:47.126029728 -0800 @@ -19,17 +19,7 @@ #include #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_frequen /* 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_frequen } /* 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_frequen 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_frequen 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_frequen } 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_frequen 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_frequen /* 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 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 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 /* 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 /* 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 * 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,10 +326,14 @@ unsigned int speedstep_get_freqs(unsigne 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); @@ -344,6 +345,8 @@ unsigned int speedstep_get_freqs(unsigne 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(unsigne goto out; } + dprintk("high seped is %u\n", *high_speed); + if (*low_speed == *high_speed) { ret = -ENODEV; goto out; diff -puN arch/i386/kernel/cpu/cpufreq/speedstep-smi.c~bk-cpufreq arch/i386/kernel/cpu/cpufreq/speedstep-smi.c --- 25/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c~bk-cpufreq 2004-11-09 01:18:46.003200424 -0800 +++ 25-akpm/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c 2004-11-09 01:18:47.127029576 -0800 @@ -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 sp * 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 (unsigne 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 (unsigne 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 cpu 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 cpu &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 cpufr 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); diff -puN arch/ppc/Kconfig~bk-cpufreq arch/ppc/Kconfig --- 25/arch/ppc/Kconfig~bk-cpufreq 2004-11-09 01:18:46.005200120 -0800 +++ 25-akpm/arch/ppc/Kconfig 2004-11-09 01:18:47.128029424 -0800 @@ -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 or - at - - If in doubt, say N. - source "drivers/cpufreq/Kconfig" config CPU_FREQ_PMAC diff -puN arch/sh/Kconfig~bk-cpufreq arch/sh/Kconfig --- 25/arch/sh/Kconfig~bk-cpufreq 2004-11-09 01:18:46.006199968 -0800 +++ 25-akpm/arch/sh/Kconfig 2004-11-09 01:18:47.129029272 -0800 @@ -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 . - - If unsure, say N. - source "drivers/cpufreq/Kconfig" config CPU_FREQ_TABLE diff -puN arch/sparc64/Kconfig~bk-cpufreq arch/sparc64/Kconfig --- 25/arch/sparc64/Kconfig~bk-cpufreq 2004-11-09 01:18:46.008199664 -0800 +++ 25-akpm/arch/sparc64/Kconfig 2004-11-09 01:18:47.130029120 -0800 @@ -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 . - - 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 diff -puN arch/x86_64/kernel/cpufreq/Kconfig~bk-cpufreq arch/x86_64/kernel/cpufreq/Kconfig --- 25/arch/x86_64/kernel/cpufreq/Kconfig~bk-cpufreq 2004-11-09 01:18:46.009199512 -0800 +++ 25-akpm/arch/x86_64/kernel/cpufreq/Kconfig 2004-11-09 01:18:47.130029120 -0800 @@ -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 - or at - - If in doubt, say N. - source "drivers/cpufreq/Kconfig" config CPU_FREQ_TABLE diff -puN arch/x86_64/kernel/cpufreq/Makefile~bk-cpufreq arch/x86_64/kernel/cpufreq/Makefile --- 25/arch/x86_64/kernel/cpufreq/Makefile~bk-cpufreq 2004-11-09 01:18:46.010199360 -0800 +++ 25-akpm/arch/x86_64/kernel/cpufreq/Makefile 2004-11-09 01:18:47.130029120 -0800 @@ -6,12 +6,11 @@ SRCDIR := ../../../i386/kernel/cpu/cpufr 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_P4_CLOCKMOD) += p4-clockmod.o -obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o +obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o powernow-k8-objs := ${SRCDIR}/powernow-k8.o speedstep-centrino-objs := ${SRCDIR}/speedstep-centrino.o acpi-objs := ${SRCDIR}/acpi.o p4-clockmod-objs := ${SRCDIR}/p4-clockmod.o speedstep-lib-objs := ${SRCDIR}/speedstep-lib.o +acpi-cpufreq-objs := ${SRCDIR}/acpi-cpufreq.o diff -puN /dev/null Documentation/cpu-freq/cpufreq-nforce2.txt --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/Documentation/cpu-freq/cpufreq-nforce2.txt 2004-11-09 01:18:46.040194800 -0800 @@ -0,0 +1,19 @@ + +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. + + diff -puN drivers/cpufreq/cpufreq.c~bk-cpufreq drivers/cpufreq/cpufreq.c --- 25/drivers/cpufreq/cpufreq.c~bk-cpufreq 2004-11-09 01:18:46.021197688 -0800 +++ 25-akpm/drivers/cpufreq/cpufreq.c 2004-11-09 01:18:47.134028512 -0800 @@ -24,6 +24,8 @@ #include #include +#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 cpufr 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(unsign 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 cp 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_go 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 * ko 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_d 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_d * 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_d /* 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 @@ err_out: 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 sy 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 sy * 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 sy 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 sy 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 sy * 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 sy 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_dev 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 cpufr { 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 cpu 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 c { 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 c 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 c 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 c } /* 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 c 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 cpufr ((!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 cpufr /* 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 cpufr } } + 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 cpu { 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); diff -puN drivers/cpufreq/cpufreq_ondemand.c~bk-cpufreq drivers/cpufreq/cpufreq_ondemand.c --- 25/drivers/cpufreq/cpufreq_ondemand.c~bk-cpufreq 2004-11-09 01:18:46.022197536 -0800 +++ 25-akpm/drivers/cpufreq/cpufreq_ondemand.c 2004-11-09 01:18:47.135028360 -0800 @@ -10,7 +10,6 @@ * published by the Free Software Foundation. */ -#include #include #include #include @@ -26,7 +25,6 @@ #include #include #include -#include #include #include @@ -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(st } #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_facto 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(struc 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 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(stru 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, \ -} +#define define_one_rw(_name) \ +static struct freq_attr _name = \ +__ATTR(_name, 0644, show_##_name, store_##_name) define_one_rw(sampling_rate); define_one_rw(sampling_down_factor); diff -puN drivers/cpufreq/cpufreq_performance.c~bk-cpufreq drivers/cpufreq/cpufreq_performance.c --- 25/drivers/cpufreq/cpufreq_performance.c~bk-cpufreq 2004-11-09 01:18:46.024197232 -0800 +++ 25-akpm/drivers/cpufreq/cpufreq_performance.c 2004-11-09 01:18:47.135028360 -0800 @@ -15,12 +15,16 @@ #include #include +#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: diff -puN drivers/cpufreq/cpufreq_powersave.c~bk-cpufreq drivers/cpufreq/cpufreq_powersave.c --- 25/drivers/cpufreq/cpufreq_powersave.c~bk-cpufreq 2004-11-09 01:18:46.025197080 -0800 +++ 25-akpm/drivers/cpufreq/cpufreq_powersave.c 2004-11-09 01:18:47.136028208 -0800 @@ -15,12 +15,15 @@ #include #include +#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: diff -puN drivers/cpufreq/cpufreq_userspace.c~bk-cpufreq drivers/cpufreq/cpufreq_userspace.c --- 25/drivers/cpufreq/cpufreq_userspace.c~bk-cpufreq 2004-11-09 01:18:46.027196776 -0800 +++ 25-akpm/drivers/cpufreq/cpufreq_userspace.c 2004-11-09 01:18:47.137028056 -0800 @@ -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 notifi { 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_c /** - * 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, unsig 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 writ 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 __u 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 *poli 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(st 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 (¤t_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(st 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(¤t_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(¤t_policy[cpu], policy->min, CPUFREQ_RELATION_L); - else - __cpufreq_driver_target(¤t_policy[cpu], cpu_cur_freq[cpu], + } else { + __cpufreq_driver_target(¤t_policy[cpu], cpu_set_freq[cpu], CPUFREQ_RELATION_L); + } memcpy (¤t_policy[cpu], policy, sizeof(struct cpufreq_policy)); up(&userspace_sem); break; diff -puN drivers/cpufreq/freq_table.c~bk-cpufreq drivers/cpufreq/freq_table.c --- 25/drivers/cpufreq/freq_table.c~bk-cpufreq 2004-11-09 01:18:46.028196624 -0800 +++ 25-akpm/drivers/cpufreq/freq_table.c 2004-11-09 01:18:47.138027904 -0800 @@ -9,6 +9,8 @@ #include #include +#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "freq-table", msg) + /********************************************************************* * FREQUENCY TABLE HELPERS * *********************************************************************/ @@ -22,8 +24,12 @@ int cpufreq_frequency_table_cpuinfo(stru 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(struc 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(struc 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(struc 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; @@ -142,7 +154,10 @@ int cpufreq_frequency_table_target(struc *index = suboptimal.index; } 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 (str } 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_scal 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); diff -puN drivers/cpufreq/Kconfig~bk-cpufreq drivers/cpufreq/Kconfig --- 25/drivers/cpufreq/Kconfig~bk-cpufreq 2004-11-09 01:18:46.030196320 -0800 +++ 25-akpm/drivers/cpufreq/Kconfig 2004-11-09 01:18:47.131028968 -0800 @@ -1,3 +1,32 @@ +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 . + + 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= + + To get , 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 diff -puN include/linux/cpufreq.h~bk-cpufreq include/linux/cpufreq.h --- 25/include/linux/cpufreq.h~bk-cpufreq 2004-11-09 01:18:46.031196168 -0800 +++ 25-akpm/include/linux/cpufreq.h 2004-11-09 01:18:47.138027904 -0800 @@ -261,8 +261,8 @@ int cpufreq_parse_governor (char *str_go *********************************************************************/ #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(st 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 */ _