Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 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 <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2002 - 2004 Dominik Brodowski <linux@brodo.de>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  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 <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <asm/uaccess.h>
+
+#include <linux/acpi.h>
+#include <acpi/processor.h>
+
+#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; i<data->acpi_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 (i<data->acpi_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 <se.witt@gmx.net>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *  Based upon reverse engineered information
+ *
+ *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+
+#define NFORCE2_XTAL 25
+#define NFORCE2_BOOTFSB 0x48
+#define NFORCE2_PLLENABLE 0xa8
+#define NFORCE2_PLLREG 0xa4
+#define NFORCE2_PLLADR 0xa0
+#define NFORCE2_PLL(mul, div) (0x100000 | (mul << 8) | div)
+
+#define NFORCE2_MIN_FSB 50
+#define NFORCE2_SAFE_DISTANCE 50
+
+/* Delay in ms between FSB changes */
+//#define NFORCE2_DELAY 10
+
+/* nforce2_chipset:
+ * FSB is changed using the chipset
+ */
+static struct pci_dev *nforce2_chipset_dev;
+
+/* fid:
+ * multiplier * 10
+ */
+static int fid = 0;
+
+/* min_fsb, max_fsb:
+ * minimum and maximum FSB (= FSB at boot time) 
+ */
+static int min_fsb = 0;
+static int max_fsb = 0;
+
+MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>");
+MODULE_DESCRIPTION("nForce2 FSB changing cpufreq driver");
+MODULE_LICENSE("GPL");
+
+module_param(fid, int, 0444);
+module_param(min_fsb, int, 0444);
+
+MODULE_PARM_DESC(fid, "CPU multiplier to use (11.5 = 115)");
+MODULE_PARM_DESC(min_fsb,
+                 "Minimum FSB to use, if not defined: current FSB - 50");
+
+/* DEBUG
+ *   Define it if you want verbose debug output, e.g. for bug reporting
+ */
+//#define NFORCE2_DEBUG
+
+#ifdef NFORCE2_DEBUG
+#define dprintk(msg...) printk(msg)
+#else
+#define dprintk(msg...) do { } while(0)
+#endif
+
+/*
+ * nforce2_calc_fsb - calculate FSB
+ * @pll: PLL value
+ * 
+ *   Calculates FSB from PLL value
+ */
+static int nforce2_calc_fsb(int pll)
+{
+	unsigned char mul, div;
+
+	mul = (pll >> 8) & 0xff;
+	div = pll & 0xff;
+
+	if (div > 0)
+		return NFORCE2_XTAL * mul / div;
+
+	return 0;
+}
+
+/*
+ * nforce2_calc_pll - calculate PLL value
+ * @fsb: FSB
+ * 
+ *   Calculate PLL value for given FSB
+ */
+static int nforce2_calc_pll(unsigned int fsb)
+{
+	unsigned char xmul, xdiv;
+	unsigned char mul = 0, div = 0;
+	int tried = 0;
+
+	/* Try to calculate multiplier and divider up to 4 times */
+	while (((mul == 0) || (div == 0)) && (tried <= 3)) {
+		for (xdiv = 1; xdiv <= 0x80; xdiv++)
+			for (xmul = 1; xmul <= 0xfe; xmul++)
+				if (nforce2_calc_fsb(NFORCE2_PLL(xmul, xdiv)) ==
+				    fsb + tried) {
+					mul = xmul;
+					div = xdiv;
+				}
+		tried++;
+	}
+
+	if ((mul == 0) || (div == 0))
+		return -1;
+
+	return NFORCE2_PLL(mul, div);
+}
+
+/*
+ * nforce2_write_pll - write PLL value to chipset
+ * @pll: PLL value
+ * 
+ *   Writes new FSB PLL value to chipset
+ */
+static void nforce2_write_pll(int pll)
+{
+	int temp;
+
+	/* Set the pll addr. to 0x00 */
+	temp = 0x00;
+	pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLADR, temp);
+
+	/* Now write the value in all 64 registers */
+	for (temp = 0; temp <= 0x3f; temp++) {
+		pci_write_config_dword(nforce2_chipset_dev, 
+                                       NFORCE2_PLLREG, pll);
+	}
+
+	return;
+}
+
+/*
+ * nforce2_fsb_read - Read FSB
+ *
+ *   Read FSB from chipset
+ *   If bootfsb != 0, return FSB at boot-time
+ */
+static unsigned int nforce2_fsb_read(int bootfsb)
+{
+	struct pci_dev *nforce2_sub5;
+	u32 fsb, temp = 0;
+
+	
+	/* Get chipset boot FSB from subdevice 5 (FSB at boot-time) */
+	nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
+                                      0x01EF,
+                                      PCI_ANY_ID,
+                                      PCI_ANY_ID,
+                                      NULL);
+	
+	if (!nforce2_sub5)
+		return 0;
+
+	pci_read_config_dword(nforce2_sub5, NFORCE2_BOOTFSB, &fsb);
+	fsb /= 1000000;
+	
+	/* Check if PLL register is already set */
+	pci_read_config_byte(nforce2_chipset_dev, 
+                             NFORCE2_PLLENABLE, (u8 *)&temp);
+	
+	if(bootfsb || !temp)
+		return fsb;
+		
+	/* Use PLL register FSB value */
+	pci_read_config_dword(nforce2_chipset_dev, 
+                              NFORCE2_PLLREG, &temp);
+	fsb = nforce2_calc_fsb(temp);
+
+	return fsb;
+}
+
+/*
+ * nforce2_set_fsb - set new FSB
+ * @fsb: New FSB
+ * 
+ *   Sets new FSB
+ */
+static int nforce2_set_fsb(unsigned int fsb)
+{
+	u32 pll, temp = 0;
+	unsigned int tfsb;
+	int diff;
+
+	if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
+		printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb);
+		return -EINVAL;
+	}
+	
+	tfsb = nforce2_fsb_read(0);
+	if (!tfsb) {
+		printk(KERN_ERR "cpufreq: Error while reading the FSB\n");
+		return -EINVAL;
+	}
+
+	/* First write? Then set actual value */
+	pci_read_config_byte(nforce2_chipset_dev, 
+                             NFORCE2_PLLENABLE, (u8 *)&temp);
+	if (!temp) {
+		pll = nforce2_calc_pll(tfsb);
+
+		if (pll < 0)
+			return -EINVAL;
+
+		nforce2_write_pll(pll);
+	}
+
+	/* Enable write access */
+	temp = 0x01;
+	pci_write_config_byte(nforce2_chipset_dev, NFORCE2_PLLENABLE, (u8)temp);
+
+	diff = tfsb - fsb;
+
+	if (!diff)
+		return 0;
+
+	while ((tfsb != fsb) && (tfsb <= max_fsb) && (tfsb >= min_fsb)) {
+		if (diff < 0)
+			tfsb++;
+		else
+			tfsb--;
+
+		/* Calculate the PLL reg. value */
+		if ((pll = nforce2_calc_pll(tfsb)) == -1)
+			return -EINVAL;
+		
+		nforce2_write_pll(pll);
+#ifdef NFORCE2_DELAY
+		mdelay(NFORCE2_DELAY);
+#endif
+	}
+
+	temp = 0x40;
+	pci_write_config_byte(nforce2_chipset_dev, NFORCE2_PLLADR, (u8)temp);
+
+	return 0;
+}
+
+/**
+ * nforce2_get - get the CPU frequency
+ * @cpu: CPU number
+ * 
+ * Returns the CPU frequency
+ */
+static unsigned int nforce2_get(unsigned int cpu)
+{
+	if (cpu)
+		return 0;
+	return nforce2_fsb_read(0) * fid * 100;
+}
+
+/**
+ * nforce2_target - set a new CPUFreq policy
+ * @policy: new policy
+ * @target_freq: the target frequency
+ * @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
+ *
+ * Sets a new CPUFreq policy.
+ */
+static int nforce2_target(struct cpufreq_policy *policy,
+			  unsigned int target_freq, unsigned int relation)
+{
+//        unsigned long         flags;
+	struct cpufreq_freqs freqs;
+	unsigned int target_fsb;
+
+	if ((target_freq > policy->max) || (target_freq < policy->min))
+		return -EINVAL;
+
+	target_fsb = target_freq / (fid * 100);
+
+	freqs.old = nforce2_get(policy->cpu);
+	freqs.new = target_fsb * fid * 100;
+	freqs.cpu = 0;		/* Only one CPU on nForce2 plattforms */
+
+	if (freqs.old == freqs.new)
+		return 0;
+
+	dprintk(KERN_INFO "cpufreq: Old CPU frequency %d kHz, new %d kHz\n",
+	       freqs.old, freqs.new);
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	/* Disable IRQs */
+	//local_irq_save(flags);
+
+	if (nforce2_set_fsb(target_fsb) < 0)
+		printk(KERN_ERR "cpufreq: Changing FSB to %d failed\n",
+                       target_fsb);
+	else
+		dprintk(KERN_INFO "cpufreq: Changed FSB successfully to %d\n",
+                       target_fsb);
+
+	/* Enable IRQs */
+	//local_irq_restore(flags);
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	return 0;
+}
+
+/**
+ * nforce2_verify - verifies a new CPUFreq policy
+ * @policy: new policy
+ */
+static int nforce2_verify(struct cpufreq_policy *policy)
+{
+	unsigned int fsb_pol_max;
+
+	fsb_pol_max = policy->max / (fid * 100);
+
+	if (policy->min < (fsb_pol_max * fid * 100))
+		policy->max = (fsb_pol_max + 1) * fid * 100;
+
+	cpufreq_verify_within_limits(policy,
+                                     policy->cpuinfo.min_freq,
+                                     policy->cpuinfo.max_freq);
+	return 0;
+}
+
+static int nforce2_cpu_init(struct cpufreq_policy *policy)
+{
+	unsigned int fsb;
+	unsigned int rfid;
+
+	/* capability check */
+	if (policy->cpu != 0)
+		return -ENODEV;
+
+	/* Get current FSB */
+	fsb = nforce2_fsb_read(0);
+
+	if (!fsb)
+		return -EIO;
+
+	/* FIX: Get FID from CPU */
+	if (!fid) {
+		if (!cpu_khz) {
+			printk(KERN_WARNING
+			       "cpufreq: cpu_khz not set, can't calculate multiplier!\n");
+			return -ENODEV;
+		}
+
+		fid = cpu_khz / (fsb * 100);
+		rfid = fid % 5;
+
+		if (rfid) {
+			if (rfid > 2)
+				fid += 5 - rfid;
+			else
+				fid -= rfid;
+		}
+	}
+
+	printk(KERN_INFO "cpufreq: FSB currently at %i MHz, FID %d.%d\n", fsb,
+	       fid / 10, fid % 10);
+	
+	/* Set maximum FSB to FSB at boot time */
+	max_fsb = nforce2_fsb_read(1);
+	
+	if(!max_fsb)
+		return -EIO;
+
+	if (!min_fsb)
+		min_fsb = max_fsb - NFORCE2_SAFE_DISTANCE;
+
+	if (min_fsb < NFORCE2_MIN_FSB)
+		min_fsb = NFORCE2_MIN_FSB;
+
+	/* cpuinfo and default policy values */
+	policy->cpuinfo.min_freq = min_fsb * fid * 100;
+	policy->cpuinfo.max_freq = max_fsb * fid * 100;
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	policy->cur = nforce2_get(policy->cpu);
+	policy->min = policy->cpuinfo.min_freq;
+	policy->max = policy->cpuinfo.max_freq;
+	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+	return 0;
+}
+
+static int nforce2_cpu_exit(struct cpufreq_policy *policy)
+{
+	return 0;
+}
+
+static struct cpufreq_driver nforce2_driver = {
+	.name = "nforce2",
+	.verify = nforce2_verify,
+	.target = nforce2_target,
+	.get = nforce2_get,
+	.init = nforce2_cpu_init,
+	.exit = nforce2_cpu_exit,
+	.owner = THIS_MODULE,
+};
+
+/**
+ * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic
+ *
+ * Detects nForce2 A2 and C1 stepping
+ * 
+ */
+static unsigned int nforce2_detect_chipset(void)
+{
+	u8 revision;
+
+	nforce2_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
+                                             PCI_DEVICE_ID_NVIDIA_NFORCE2,
+                                             PCI_ANY_ID,
+                                             PCI_ANY_ID,
+                                             NULL);
+
+	if (nforce2_chipset_dev == NULL)
+		return -ENODEV;
+
+	pci_read_config_byte(nforce2_chipset_dev, PCI_REVISION_ID, &revision);
+
+	printk(KERN_INFO "cpufreq: Detected nForce2 chipset revision %X\n",
+	       revision);
+	printk(KERN_INFO
+	       "cpufreq: FSB changing is maybe unstable and can lead to crashes and data loss.\n");
+
+	return 0;
+}
+
+/**
+ * nforce2_init - initializes the nForce2 CPUFreq driver
+ *
+ * Initializes the nForce2 FSB support. Returns -ENODEV on unsupported
+ * devices, -EINVAL on problems during initiatization, and zero on
+ * success.
+ */
+static int __init nforce2_init(void)
+{
+	/* TODO: do we need to detect the processor? */
+
+	/* detect chipset */
+	if (nforce2_detect_chipset()) {
+		printk(KERN_ERR "cpufreq: No nForce2 chipset.\n");
+		return -ENODEV;
+	}
+
+	return cpufreq_register_driver(&nforce2_driver);
+}
+
+/**
+ * nforce2_exit - unregisters cpufreq module
+ *
+ *   Unregisters nForce2 FSB change support.
+ */
+static void __exit nforce2_exit(void)
+{
+	cpufreq_unregister_driver(&nforce2_driver);
+}
+
+module_init(nforce2_init);
+module_exit(nforce2_exit);
+
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 <file:Documentation/cpu-freq/>
-	  or at <http://www.codemonkey.org.uk/projects/cpufreq/>
-
-	  If in doubt, say N.
-
 source "drivers/cpufreq/Kconfig"
 
 config CPU_FREQ_TABLE
@@ -182,6 +170,17 @@ config X86_P4_CLOCKMOD
 
 	  If in doubt, say N.
 
+config X86_CPUFREQ_NFORCE2
+	tristate "nVidia nForce2 FSB changing"
+	depends on CPU_FREQ && EXPERIMENTAL
+	help
+	  This adds the CPUFreq driver for FSB changing on nVidia nForce2
+	  plattforms.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  If in doubt, say N.
+
 config X86_LONGRUN
 	tristate "Transmeta LongRun"
 	depends on CPU_FREQ
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 <davej@codemonkey.org.uk>");
 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 <asm/processor.h>
 #include <asm/timex.h>
 
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longrun", msg)
+
 static struct cpufreq_driver	longrun_driver;
 
 /**
@@ -38,12 +40,14 @@ static void __init longrun_get_policy(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 <jeremy@goop.org>"
 
-/*#define CENTRINO_DEBUG*/
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg)
 
-#ifdef CENTRINO_DEBUG
-#define dprintk(msg...) printk(msg)
-#else
-#define dprintk(msg...) do { } while(0)
-#endif
 
 struct cpu_id
 {
@@ -254,13 +249,15 @@ static int centrino_cpu_init_table(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.state_count; i++) {
 		if (p.states[i].control != p.states[i].status) {
-			printk(KERN_DEBUG "Different control and status values\n");
+			dprintk("Different control (%x) and status values (%x)\n",
+				p.states[i].control, p.states[i].status);
 			result = -EINVAL;
 			goto err_unreg;
 		}
 
 		if (!p.states[i].core_frequency) {
-			printk(KERN_DEBUG "Zero core frequency\n");
+			dprintk("Zero core frequency for state %u\n", i);
 			result = -EINVAL;
 			goto err_unreg;
 		}
 
 		if (p.states[i].core_frequency > p.states[0].core_frequency) {
-			printk(KERN_DEBUG "P%u has larger frequency than P0, skipping\n", i);
+			dprintk("P%u has larger frequency (%u) than P0 (%u), skipping\n", i,
+				p.states[i].core_frequency, p.states[0].core_frequency);
 			p.states[i].core_frequency = 0;
 			continue;
 		}
@@ -409,23 +411,31 @@ static int centrino_cpu_init_acpi(struct
         for (i=0; i<p.state_count; i++) {
 		centrino_model->op_points[i].index = p.states[i].control;
 		centrino_model->op_points[i].frequency = p.states[i].core_frequency * 1000;
+		dprintk("adding state %i with frequency %u and control value %04x\n", 
+			i, centrino_model->op_points[i].frequency, centrino_model->op_points[i].index);
 	}
 	centrino_model->op_points[p.state_count].frequency = CPUFREQ_TABLE_END;
 
 	cur_freq = get_cur_freq(policy->cpu);
 
 	for (i=0; i<p.state_count; i++) {
+		if (!p.states[i].core_frequency) {
+			dprintk("skipping state %u\n", i);
+			centrino_model->op_points[i].frequency = CPUFREQ_ENTRY_INVALID;
+			continue;
+		}
+		
 		if (extract_clock(centrino_model->op_points[i].index) !=
 		    (centrino_model->op_points[i].frequency)) {
-			printk(KERN_DEBUG "Invalid encoded frequency\n");
+			dprintk("Invalid encoded frequency (%u vs. %u)\n",
+				extract_clock(centrino_model->op_points[i].index),
+				centrino_model->op_points[i].frequency);
 			result = -EINVAL;
 			goto err_kfree_all;
 		}
 
 		if (cur_freq == centrino_model->op_points[i].frequency)
 			p.state = i;
-		if (!p.states[i].core_frequency)
-			centrino_model->op_points[i].frequency = CPUFREQ_ENTRY_INVALID;
 	}
 
 	/* notify BIOS that we exist */
@@ -439,6 +449,7 @@ static int centrino_cpu_init_acpi(struct
 	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 <asm/msr.h>
 #include "speedstep-lib.h"
 
-
-/* DEBUG
- *   Define it if you want verbose debug output, e.g. for bug reporting
- */
-//#define SPEEDSTEP_DEBUG
-
-#ifdef SPEEDSTEP_DEBUG
-#define dprintk(msg...) printk(msg)
-#else
-#define dprintk(msg...) do { } while(0)
-#endif
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-lib", msg)
 
 #ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
 static int relaxed_check = 0;
@@ -83,7 +73,7 @@ static unsigned int pentium3_get_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 <file:Documentation/cpu-freq> or
-	  at <http://www.brodo.de/cpufreq/>
-
-	  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 <file:Documentation/cpu-freq>.
-
-	  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 <file:Documentation/cpu-freq>.
-
-	  If in doubt, say N.
+source "drivers/cpufreq/Kconfig"
 
 config CPU_FREQ_TABLE
        tristate "CPU frequency table helpers"
@@ -176,8 +167,6 @@ config US2E_FREQ
 
 	  If in doubt, say N.
 
-source "drivers/cpufreq/Kconfig"
-
 # Identify this as a Sparc64 build
 config SPARC64
 	bool
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 <file:Documentation/cpu-freq/>
-	  or at <http://www.codemonkey.org.uk/projects/cpufreq/>
-
-	  If in doubt, say N.
-
 source "drivers/cpufreq/Kconfig"
 
 config CPU_FREQ_TABLE
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 <linux/cpu.h>
 #include <linux/completion.h>
 
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "cpufreq-core", msg)
+
 /**
  * The "cpufreq driver" - the arch- or hardware-dependend low
  * level driver of CPUFreq support, and its spinlock. This lock
@@ -107,6 +109,90 @@ static void cpufreq_cpu_put(struct 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 <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/smp.h>
@@ -26,7 +25,6 @@
 #include <linux/kmod.h>
 #include <linux/workqueue.h>
 #include <linux/jiffies.h>
-#include <linux/config.h>
 #include <linux/kernel_stat.h>
 #include <linux/percpu.h>
 
@@ -83,7 +81,7 @@ struct dbs_tuners {
 	unsigned int		down_threshold;
 };
 
-struct dbs_tuners dbs_tuners_ins = {
+static struct dbs_tuners dbs_tuners_ins = {
 	.up_threshold 		= DEF_FREQUENCY_UP_THRESHOLD,
 	.down_threshold 	= DEF_FREQUENCY_DOWN_THRESHOLD,
 	.sampling_down_factor 	= DEF_SAMPLING_DOWN_FACTOR,
@@ -101,10 +99,8 @@ static ssize_t show_sampling_rate_min(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 <linux/cpufreq.h>
 #include <linux/init.h>
 
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "performance", msg)
+
+
 static int cpufreq_governor_performance(struct cpufreq_policy *policy,
 					unsigned int event)
 {
 	switch (event) {
 	case CPUFREQ_GOV_START:
 	case CPUFREQ_GOV_LIMITS:
+		dprintk("setting to %u kHz because of event %u\n", policy->max, event);
 		__cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H);
 		break;
 	default:
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 <linux/cpufreq.h>
 #include <linux/init.h>
 
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "powersave", msg)
+
 static int cpufreq_governor_powersave(struct cpufreq_policy *policy,
 					unsigned int event)
 {
 	switch (event) {
 	case CPUFREQ_GOV_START:
 	case CPUFREQ_GOV_LIMITS:
+		dprintk("setting to %u kHz because of event %u\n", policy->min, event);
 		__cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L);
 		break;
 	default:
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 (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
+		dprintk("managing cpu %u started (%u - %u kHz, currently %u kHz)\n", cpu, cpu_min_freq[cpu], cpu_max_freq[cpu], cpu_cur_freq[cpu]);
 		up(&userspace_sem);
 		break;
 	case CPUFREQ_GOV_STOP:
@@ -532,22 +540,26 @@ static int cpufreq_governor_userspace(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(&current_policy[cpu], policy->max, 
 			      CPUFREQ_RELATION_H);
-		else if (policy->min > cpu_cur_freq[cpu])
+		} else if (policy->min > cpu_set_freq[cpu]) {
 			__cpufreq_driver_target(&current_policy[cpu], policy->min, 
 			      CPUFREQ_RELATION_L);
-		else
-			__cpufreq_driver_target(&current_policy[cpu], cpu_cur_freq[cpu],
+		} else {
+			__cpufreq_driver_target(&current_policy[cpu], cpu_set_freq[cpu],
 			      CPUFREQ_RELATION_L);
+		}
 		memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
 		up(&userspace_sem);
 		break;
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 <linux/init.h>
 #include <linux/cpufreq.h>
 
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "freq-table", msg)
+
 /*********************************************************************
  *                     FREQUENCY TABLE HELPERS                       *
  *********************************************************************/
@@ -22,8 +24,12 @@ int cpufreq_frequency_table_cpuinfo(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 <file:Documentation/cpu-freq>.
+
+	  If in doubt, say N.
+
+config CPU_FREQ_DEBUG
+	bool "Enable CPUfreq debugging"
+	depends on CPU_FREQ
+	help
+	  Say Y here to enable CPUfreq subsystem (including drivers)
+	  debugging. You will need to activate it via the kernel
+	  command line by passing
+	     cpufreq.debug=<value>
+
+	  To get <value>, add 
+	       1 to activate CPUfreq core debugging,
+	       2 to activate CPUfreq drivers debugging, and
+	       4 to activate CPUfreq governor debugging
+
 config CPU_FREQ_PROC_INTF
 	tristate "/proc/cpufreq interface (deprecated)"
 	depends on CPU_FREQ && PROC_FS
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 */
_
