bk://linux-dj.bkbits.net/cpufreq
davej@redhat.com|ChangeSet|20040803150128|56348 davej

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/08/08 02:12:22-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cpufreq
# 
# drivers/cpufreq/cpufreq_userspace.c
#   2004/08/08 02:12:18-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/03 16:01:28+01:00 davej@redhat.com 
#   [CPUFREQ] Whitespace/CodingStyle fixes for speedstep-ich
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
#   2004/08/03 16:01:20+01:00 davej@redhat.com +41 -45
#   [CPUFREQ] Whitespace/CodingStyle fixes for speedstep-ich
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/08/03 15:56:53+01:00 davej@redhat.com 
#   [CPUFREQ] Better fix for previous speedstep-ich breakage.
#   
#   Do away with the prototype by just moving some code around.
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
#   2004/08/03 15:56:44+01:00 davej@redhat.com +17 -20
#   [CPUFREQ] Better fix for previous speedstep-ich breakage.
#   
#   Do away with the prototype by just moving some code around.
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/08/03 15:29:15+01:00 davej@redhat.com 
#   [CPUFREQ] Whitespace cleanup for centrino speedstep.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2004/08/03 15:29:08+01:00 davej@redhat.com +28 -30
#   [CPUFREQ] Whitespace cleanup for centrino speedstep.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/08/03 15:25:52+01:00 davej@redhat.com 
#   [CPUFREQ] Adding SMP capability to MSR based Enhanced Speedstep.
#   
#   At present, MSR based Enhanced Speedstep Technology (EST) is handled by
#   speedstep-centrino.c. The attached patch adds more features to
#   speedstep-centrino, making it more generic. With these changes, it can
#   run on SMP systems which supports EST, based on the information provided
#   by ACPI. The non-ACPI (static table based) driver will still be UP only.
#   
#   From: "Pallipadi, Venkatesh" <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# include/asm-i386/acpi.h
#   2004/08/03 15:25:44+01:00 davej@redhat.com +5 -0
#   [CPUFREQ] Adding SMP capability to MSR based Enhanced Speedstep.
#   
#   At present, MSR based Enhanced Speedstep Technology (EST) is handled by
#   speedstep-centrino.c. The attached patch adds more features to
#   speedstep-centrino, making it more generic. With these changes, it can
#   run on SMP systems which supports EST, based on the information provided
#   by ACPI. The non-ACPI (static table based) driver will still be UP only.
#   
#   From: "Pallipadi, Venkatesh" <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2004/08/03 15:25:44+01:00 davej@redhat.com +95 -40
#   [CPUFREQ] Adding SMP capability to MSR based Enhanced Speedstep.
#   
#   At present, MSR based Enhanced Speedstep Technology (EST) is handled by
#   speedstep-centrino.c. The attached patch adds more features to
#   speedstep-centrino, making it more generic. With these changes, it can
#   run on SMP systems which supports EST, based on the information provided
#   by ACPI. The non-ACPI (static table based) driver will still be UP only.
#   
#   From: "Pallipadi, Venkatesh" <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/08/02 22:56:33+01:00 davej@redhat.com 
#   [CPUFREQ] compile fix
#   
#   Compile fix for speedstep-ich.c: missing forward declaration.
#   
#   Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
#   2004/08/02 22:56:25+01:00 davej@redhat.com +2 -0
#   [CPUFREQ] compile fix
#   
#   Compile fix for speedstep-ich.c: missing forward declaration.
#   
#   Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/08/02 22:35:43+01:00 davej@redhat.com 
#   [CPUFREQ] fix HT oops on speedstep-ich system
#   
#   Bugfix for #3012 @ http://bugme.osdl.org/show_bug.cgi?id=3012
#   
#   The speedstep-ich driver only registers for CPU0 (which is a sane thing to
#   do). However, cpufreq_notify_transition() currently assumes the CPU
#   specified in the freqs.cpu parameter has actually been registered with the
#   CPUfreq core. This is obviously not the case for HT speedstep-ich CPUs,
#   causing an OOPS. The long-term solution will be to merge the "cpufreq
#   CPU group awareness patches" already RFC'ed to this list; but they still
#   need a bit of polishing and testing.
#   
#   Thanks to Boris Fersing for reporting the bug and testing this fix.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq.c
#   2004/08/02 22:35:36+01:00 davej@redhat.com +4 -2
#   [CPUFREQ] fix HT oops on speedstep-ich system
#   
#   Bugfix for #3012 @ http://bugme.osdl.org/show_bug.cgi?id=3012
#   
#   The speedstep-ich driver only registers for CPU0 (which is a sane thing to
#   do). However, cpufreq_notify_transition() currently assumes the CPU
#   specified in the freqs.cpu parameter has actually been registered with the
#   CPUfreq core. This is obviously not the case for HT speedstep-ich CPUs,
#   causing an OOPS. The long-term solution will be to merge the "cpufreq
#   CPU group awareness patches" already RFC'ed to this list; but they still
#   need a bit of polishing and testing.
#   
#   Thanks to Boris Fersing for reporting the bug and testing this fix.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/08/02 21:27:47+01:00 davej@redhat.com 
#   [CPUFREQ] speedstep-centrino: Remove unnecessary vendor checks.
#   
#   This is only used on Intel, and if some other vendor ever clones speedstep,
#   we can add an additional check in the init routine.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2004/08/02 21:27:39+01:00 davej@redhat.com +3 -5
#   [CPUFREQ] speedstep-centrino: Remove unnecessary vendor checks.
#   
#   This is only used on Intel, and if some other vendor ever clones speedstep,
#   we can add an additional check in the init routine.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/08/02 20:42:11+01:00 davej@delerium.codemonkey.org.uk 
#   Merge
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2004/08/02 20:42:05+01:00 davej@delerium.codemonkey.org.uk +0 -1
#   SCCS merged
# 
# ChangeSet
#   2004/08/02 20:23:58+01:00 davej@redhat.com 
#   [CPUFREQ] A reduce-Jeremy's-mail patch:
#   - Only Intel makes EST CPUs.  (Some Cyrix M IIs have the EST bit set -
#     I don't know what it means, but it isn't Enhanced Speedstep.)
#   
#   - If it's a known Dothan, but we're looking in the tables, give a
#      useful message about using ACPI rather than mailing me.
#   
#   - Code cleanups:
#     - Make the CPU ID stuff table driven
#     - Turn centrino_verify_cpu_id into a proper boolean predicate
#   
#    - Diddle some whitespace
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2004/08/02 20:23:50+01:00 davej@redhat.com +49 -37
#   [CPUFREQ] A reduce-Jeremy's-mail patch:
#   - Only Intel makes EST CPUs.  (Some Cyrix M IIs have the EST bit set -
#     I don't know what it means, but it isn't Enhanced Speedstep.)
#   
#   - If it's a known Dothan, but we're looking in the tables, give a
#      useful message about using ACPI rather than mailing me.
#   
#   - Code cleanups:
#     - Make the CPU ID stuff table driven
#     - Turn centrino_verify_cpu_id into a proper boolean predicate
#   
#    - Diddle some whitespace
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/08/02 20:14:21+01:00 davej@redhat.com 
#   [CPUFREQ] speedstep-ich SMT support.
#   i have noticed that the most recent vanilla kernel oopses on a P4M-HT
#   (because only one CPU is registered in sysfs but 2 are informed of a
#   change of state). also there are some returns out of subroutines before
#   set_cpus_allowed() is performed to restore the mask prior to entering
#   the subroutine (this should not matter on uniprocessor systems, but
#   still...).
#                                                                                  
#   this patch should fix these 2 issues. for the first one, it registers
#   all logical cpu's and a tiny modification is made in cpufreq.c to
#   perform a policy change on all siblings.
#   
#   From: Christian Hoelbling
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
#   2004/08/02 20:14:14+01:00 davej@redhat.com +20 -8
#   [CPUFREQ] speedstep-ich SMT support.
#   i have noticed that the most recent vanilla kernel oopses on a P4M-HT
#   (because only one CPU is registered in sysfs but 2 are informed of a
#   change of state). also there are some returns out of subroutines before
#   set_cpus_allowed() is performed to restore the mask prior to entering
#   the subroutine (this should not matter on uniprocessor systems, but
#   still...).
#                                                                                  
#   this patch should fix these 2 issues. for the first one, it registers
#   all logical cpu's and a tiny modification is made in cpufreq.c to
#   perform a policy change on all siblings.
#   
#   From: Christian Hoelbling
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/08/02 20:11:43+01:00 davej@redhat.com 
#   [CPUFREQ] speedstep-centrino: ignore 0xffff'ed P-States
#   
#   Some ACPI tables contain 0xffff'ed entries for "P-States". This is
#   obviously incorrect according to the ACPI specifications, nonetheless
#   it should "just work". So, simply ignore such invalid P-States instead
#   of aborting. Thanks to Frederik Reiss for testing (and fixing) this
#   patch.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2004/08/02 20:11:36+01:00 davej@redhat.com +8 -0
#   [CPUFREQ] speedstep-centrino: ignore 0xffff'ed P-States
#   
#   Some ACPI tables contain 0xffff'ed entries for "P-States". This is
#   obviously incorrect according to the ACPI specifications, nonetheless
#   it should "just work". So, simply ignore such invalid P-States instead
#   of aborting. Thanks to Frederik Reiss for testing (and fixing) this
#   patch.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/08/02 20:09:25+01:00 davej@redhat.com 
#   [CPUFREQ] speedstep-smi: GET_SPEEDSTEP_FREQS may return bogus values
#   
#   On at least one system, the GET_SPEEDSTEP_FREQS call to the BIOS
#   returns obviously incorrect data (0 and 4 MHz...). So, check whether
#   the results look sane, if not, use the already existing workaround
#   for ancient speedstep systems. Thanks to Pierre Maziere for reporting
#   this issue and testing the fix.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
#   2004/08/02 20:09:18+01:00 davej@redhat.com +6 -1
#   [CPUFREQ] speedstep-smi: GET_SPEEDSTEP_FREQS may return bogus values
#   
#   On at least one system, the GET_SPEEDSTEP_FREQS call to the BIOS
#   returns obviously incorrect data (0 and 4 MHz...). So, check whether
#   the results look sane, if not, use the already existing workaround
#   for ancient speedstep systems. Thanks to Pierre Maziere for reporting
#   this issue and testing the fix.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/08/02 20:08:20+01:00 davej@redhat.com 
#   [CPUFREQ] Longhaul compile fixes.
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/longhaul.c
#   2004/08/02 20:08:12+01:00 davej@redhat.com +14 -13
#   [CPUFREQ] Longhaul compile fixes.
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/07/23 21:33:26-04:00 davej@redhat.com 
#   [CPUFREQ] disable interrupts around transitions in longhaul.
#   Re-reading the spec revealed this omission.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/longhaul.c
#   2004/07/23 21:32:46-04:00 davej@redhat.com +8 -0
#   [CPUFREQ] disable interrupts around transitions in longhaul.
#   Re-reading the spec revealed this omission.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/07/23 20:02:20-04:00 davej@redhat.com 
#   [CPUFREQ] abstract out powersaver code in longhaul driver.
#   99% of these two implementations are the same, so abstract it out into a
#   seperate function.  Also add another bunch of comments.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
#   
# 
# arch/i386/kernel/cpu/cpufreq/longhaul.c
#   2004/07/23 20:01:50-04:00 davej@redhat.com +31 -32
#   [CPUFREQ] abstract out powersaver code in longhaul driver.
#   99% of these two implementations are the same, so abstract it out into a
#   seperate function.  Also add another bunch of comments.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
#   
# 
# ChangeSet
#   2004/07/23 19:31:03-04:00 davej@redhat.com 
#   [CPUFREQ] Fix up some comments in longhaul.
#   Some of this stuff is very wrong, time to sit down with datasheets
#   and fix up some of this mess. The problem is this driver pulls info
#   from multiple datasheets, and some of them conflict.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/longhaul.c
#   2004/07/23 19:30:22-04:00 davej@redhat.com +18 -7
#   [CPUFREQ] Fix up some comments in longhaul.
#   Some of this stuff is very wrong, time to sit down with datasheets
#   and fix up some of this mess. The problem is this driver pulls info
#   from multiple datasheets, and some of them conflict.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/07/13 00:18:00+01:00 davej@redhat.com 
#   [CPUFREQ] powernowk8_cpu_exit may not be __exit but can be __devexit.
#   Thanks to Arjan for noticing this bug.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k8.c
#   2004/07/13 00:17:52+01:00 davej@redhat.com +2 -2
#   [CPUFREQ] powernowk8_cpu_exit may not be __exit but can be __devexit.
#   Thanks to Arjan for noticing this bug.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/07/13 00:15:08+01:00 davej@redhat.com 
#   [CPUFREQ] fix CONFIG_ACPI_PROCESSOR="m", CONFIG_X86_POWERNOW_K{7,8}="y" build issue
#   Fix the build dependency between powernow-k{7,8} and acpi/processor.o by
#   adding a CONFIG_X86_POWERNOW_K{7,8}_ACPI bool, just like SPEEDSTEP_CENTRINO
#   does it. See http://forums.gentoo.org/viewtopic.php?t=186887 for a
#   bugreport.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/x86_64/kernel/cpufreq/Kconfig
#   2004/07/13 00:14:59+01:00 davej@redhat.com +5 -0
#   [CPUFREQ] fix CONFIG_ACPI_PROCESSOR="m", CONFIG_X86_POWERNOW_K{7,8}="y" build issue
#   Fix the build dependency between powernow-k{7,8} and acpi/processor.o by
#   adding a CONFIG_X86_POWERNOW_K{7,8}_ACPI bool, just like SPEEDSTEP_CENTRINO
#   does it. See http://forums.gentoo.org/viewtopic.php?t=186887 for a
#   bugreport.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k8.c
#   2004/07/13 00:14:59+01:00 davej@redhat.com +2 -2
#   [CPUFREQ] fix CONFIG_ACPI_PROCESSOR="m", CONFIG_X86_POWERNOW_K{7,8}="y" build issue
#   Fix the build dependency between powernow-k{7,8} and acpi/processor.o by
#   adding a CONFIG_X86_POWERNOW_K{7,8}_ACPI bool, just like SPEEDSTEP_CENTRINO
#   does it. See http://forums.gentoo.org/viewtopic.php?t=186887 for a
#   bugreport.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k7.c
#   2004/07/13 00:14:59+01:00 davej@redhat.com +5 -5
#   [CPUFREQ] fix CONFIG_ACPI_PROCESSOR="m", CONFIG_X86_POWERNOW_K{7,8}="y" build issue
#   Fix the build dependency between powernow-k{7,8} and acpi/processor.o by
#   adding a CONFIG_X86_POWERNOW_K{7,8}_ACPI bool, just like SPEEDSTEP_CENTRINO
#   does it. See http://forums.gentoo.org/viewtopic.php?t=186887 for a
#   bugreport.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/Kconfig
#   2004/07/13 00:14:59+01:00 davej@redhat.com +10 -0
#   [CPUFREQ] fix CONFIG_ACPI_PROCESSOR="m", CONFIG_X86_POWERNOW_K{7,8}="y" build issue
#   Fix the build dependency between powernow-k{7,8} and acpi/processor.o by
#   adding a CONFIG_X86_POWERNOW_K{7,8}_ACPI bool, just like SPEEDSTEP_CENTRINO
#   does it. See http://forums.gentoo.org/viewtopic.php?t=186887 for a
#   bugreport.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/07/11 11:55:46+01:00 davej@redhat.com 
#   [CPUFREQ] reorder cpufreq.c for inlining
#   
#   Trying to compile drivers/cpufreq/cpufreq.c with gcc 3.4 and
#     # define inline         __inline__ __attribute__((always_inline))
#   results in the following compile error:
#     CC      drivers/cpufreq/cpufreq.o
#   drivers/cpufreq/cpufreq.c: In function `cpufreq_resume':
#   drivers/cpufreq/cpufreq.c:39: sorry, unimplemented: inlining failed in
#   call to 'adjust_jiffies': function body not available
#   drivers/cpufreq/cpufreq.c:628: sorry, unimplemented: called from here
#   make[2]: *** [drivers/cpufreq/cpufreq.o] Error 1
#   
#   Signed-off-by: Adrian Bunk <bunk@fs.tum.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq.c
#   2004/07/11 11:55:38+01:00 davej@redhat.com +80 -80
#   [CPUFREQ] reorder cpufreq.c for inlining
#   
#   Trying to compile drivers/cpufreq/cpufreq.c with gcc 3.4 and
#     # define inline         __inline__ __attribute__((always_inline))
#   results in the following compile error:
#     CC      drivers/cpufreq/cpufreq.o
#   drivers/cpufreq/cpufreq.c: In function `cpufreq_resume':
#   drivers/cpufreq/cpufreq.c:39: sorry, unimplemented: inlining failed in
#   call to 'adjust_jiffies': function body not available
#   drivers/cpufreq/cpufreq.c:628: sorry, unimplemented: called from here
#   make[2]: *** [drivers/cpufreq/cpufreq.o] Error 1
#   
#   Signed-off-by: Adrian Bunk <bunk@fs.tum.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/07/08 14:08:47+01:00 davej@redhat.com 
#   [CPUFREQ] fix whitespace after merge.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k7.c
#   2004/07/08 14:07:31+01:00 davej@redhat.com +1 -1
#   [CPUFREQ] fix whitespace after merge.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/07/08 13:59:21+01:00 davej@delerium.codemonkey.org.uk 
#   Merge delerium.codemonkey.org.uk:/mnt/data/src/bk/bk-linus
#   into delerium.codemonkey.org.uk:/mnt/data/src/bk/cpufreq
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k7.c
#   2004/07/08 13:59:14+01:00 davej@delerium.codemonkey.org.uk +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/07/05 01:36:09+01:00 davej@redhat.com 
#   [CPUFREQ] Remove out of date comment from powernow-k7
#   This has had significant amount of testing since it got merged, and
#   nothing nasty has actually ever happened.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k7.c
#   2004/07/05 01:36:00+01:00 davej@redhat.com +0 -2
#   [CPUFREQ] Remove out of date comment from powernow-k7
#   This has had significant amount of testing since it got merged, and
#   nothing nasty has actually ever happened.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/07/05 01:34:47+01:00 davej@redhat.com 
#   [CPUFREQ] REmove more trailing whitespace
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k7.c
#   2004/07/05 01:34:40+01:00 davej@redhat.com +9 -9
#   [CPUFREQ] REmove more trailing whitespace
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/07/05 01:20:53+01:00 davej@redhat.com 
#   [CPUFREQ] Make powernow-k7 debug printk a runtime option.
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k7.c
#   2004/07/05 01:20:44+01:00 davej@redhat.com +19 -9
#   [CPUFREQ] Make powernow-k7 debug printk a runtime option.
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/07/04 01:18:17+01:00 davej@redhat.com 
#   [CPUFREQ] fix userspace resume support.
#   
#   Fix resume support in the userspace cpufreq governor: we need to set the
#   CPU to the frequency last echo'ed by userspace into this governor's files.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq_userspace.c
#   2004/07/04 01:18:10+01:00 davej@redhat.com +10 -0
#   [CPUFREQ] fix userspace resume support.
#   
#   Fix resume support in the userspace cpufreq governor: we need to set the
#   CPU to the frequency last echo'ed by userspace into this governor's files.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/07/04 01:16:06+01:00 davej@redhat.com 
#   [CPUFREQ] fix double "out-of-sync" warning on resume.
#   
#   - Rephrase "out-of-sync" warning (partly) based upon Gerald Britton's suggestion
#   - Also update cpufreq's opinion of current cpu frequency upon resume, else the
#     "out-of-sync" warning will appear twice. Thanks to Gerald Britton for noting this.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq.c
#   2004/07/04 01:15:58+01:00 davej@redhat.com +6 -5
#   [CPUFREQ] fix double "out-of-sync" warning on resume.
#   
#   - Rephrase "out-of-sync" warning (partly) based upon Gerald Britton's suggestion
#   - Also update cpufreq's opinion of current cpu frequency upon resume, else the
#     "out-of-sync" warning will appear twice. Thanks to Gerald Britton for noting this.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/07/03 18:05:50+01:00 davej@redhat.com 
#   [CPUFREQ] Fix FSB calculation in powernow-k7
#   
#   use the maximum fid instead of the current fid.
#   
#   From: Bruno Ducrot
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k7.c
#   2004/07/03 18:05:42+01:00 davej@redhat.com +1 -1
#   [CPUFREQ] Fix FSB calculation in powernow-k7
#   
#   use the maximum fid instead of the current fid.
#   
#   From: Bruno Ducrot
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/07/03 17:17:16+01:00 davej@redhat.com 
#   [CPUFREQ] Trailing whitespace removal in longrun driver.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/longrun.c
#   2004/07/03 17:17:09+01:00 davej@redhat.com +21 -21
#   [CPUFREQ] Trailing whitespace removal in longrun driver.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/06/29 23:43:48+01:00 davej@redhat.com 
#   [CPUFREQ] Fix sparse NULL ptr warning.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2004/06/29 23:43:41+01:00 davej@redhat.com +1 -1
#   [CPUFREQ] Fix sparse NULL ptr warning.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/06/20 00:04:48+01:00 davej@redhat.com 
#   [CPUFREQ] Stop powernow-k7 printk'ing tab characters.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k7.c
#   2004/06/20 00:04:29+01:00 davej@redhat.com +5 -5
#   [CPUFREQ] Stop powernow-k7 printk'ing tab characters.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/06/16 17:58:22+01:00 davej@redhat.com 
#   [CPUFREQ] new Dothan variant for speedstep-centrino
#   
#   Add support for new Dothan variant (CPUID 0x6d6) to speedstep-centrino.
#   Noted to be missing and tested by Athul Acharya.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2004/06/16 17:58:14+01:00 davej@redhat.com +9 -1
#   [CPUFREQ] new Dothan variant for speedstep-centrino
#   
#   Add support for new Dothan variant (CPUID 0x6d6) to speedstep-centrino.
#   Noted to be missing and tested by Athul Acharya.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
diff -Nru a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig
--- a/arch/i386/kernel/cpu/cpufreq/Kconfig	2004-08-08 12:43:24 -07:00
+++ b/arch/i386/kernel/cpu/cpufreq/Kconfig	2004-08-08 12:43:24 -07:00
@@ -88,6 +88,11 @@
 
 	  If in doubt, say N.
 
+config X86_POWERNOW_K7_ACPI
+	bool
+	depends on ((X86_POWERNOW_K7 = "m" && ACPI_PROCESSOR) || (X86_POWERNOW_K7 = "y" && ACPI_PROCESSOR = "y"))
+	default y
+
 config X86_POWERNOW_K8
 	tristate "AMD Opteron/Athlon64 PowerNow!"
 	depends on CPU_FREQ && EXPERIMENTAL
@@ -97,6 +102,11 @@
 	  For details, take a look at <file:Documentation/cpu-freq/>.
 
 	  If in doubt, say N.
+
+config X86_POWERNOW_K8_ACPI
+	bool
+	depends on ((X86_POWERNOW_K8 = "m" && ACPI_PROCESSOR) || (X86_POWERNOW_K8 = "y" && ACPI_PROCESSOR = "y"))
+	default y
 
 config X86_GX_SUSPMOD
 	tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
diff -Nru a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c	2004-08-08 12:43:24 -07:00
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c	2004-08-08 12:43:24 -07:00
@@ -5,14 +5,19 @@
  *  Licensed under the terms of the GNU GPL License version 2.
  *  Based upon datasheets & sample CPUs kindly provided by VIA.
  *
- *  VIA have currently 2 different versions of Longhaul.
+ *  VIA have currently 3 different versions of Longhaul.
  *  Version 1 (Longhaul) uses the BCR2 MSR at 0x1147.
- *   It is present only in Samuel 1, Samuel 2 and Ezra.
- *  Version 2 (Powersaver) uses the POWERSAVER MSR at 0x110a.
- *   It is present in Ezra-T, Nehemiah and above.
- *   In addition to scaling multiplier, it can also scale voltage.
- *   There is provision for scaling FSB too, but this doesn't work
- *   too well in practice.
+ *   It is present only in Samuel 1 (C5A), Samuel 2 (C5B) stepping 0.
+ *  Version 2 of longhaul is the same as v1, but adds voltage scaling.
+ *   Present in Samuel 2 (steppings 1-7 only) (C5B), and Ezra (C5C)
+ *   voltage scaling support has currently been disabled in this driver
+ *   until we have code that gets it right.
+ *  Version 3 of longhaul got renamed to Powersaver and redesigned
+ *   to use the POWERSAVER MSR at 0x110a.
+ *   It is present in Ezra-T (C5M), Nehemiah (C5X) and above.
+ *   It's pretty much the same feature wise to longhaul v2, though
+ *   there is provision for scaling FSB too, but this doesn't work
+ *   too well in practice so we don't even try to use this.
  *
  *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
  */
@@ -95,6 +100,27 @@
 }
 
 
+static void do_powersaver(union msr_longhaul *longhaul,
+			unsigned int clock_ratio_index, int version)
+{
+	rdmsrl(MSR_VIA_LONGHAUL, longhaul->val);
+	longhaul->bits.SoftBusRatio = clock_ratio_index & 0xf;
+	longhaul->bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
+	longhaul->bits.EnableSoftBusRatio = 1;
+	longhaul->bits.RevisionKey = 0;
+	local_irq_disable();
+	wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
+	local_irq_enable();
+	__hlt();
+
+	rdmsrl(MSR_VIA_LONGHAUL, longhaul->val);
+	longhaul->bits.EnableSoftBusRatio = 0;
+	longhaul->bits.RevisionKey = version;
+	local_irq_disable();
+	wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
+	local_irq_enable();
+}
+
 /**
  * longhaul_set_cpu_frequency()
  * @clock_ratio_index : bitpattern of the new multiplier.
@@ -126,61 +152,54 @@
 	dprintk (KERN_INFO PFX "FSB:%d Mult:%d.%dx\n", fsb, mult/10, mult%10);
 
 	switch (longhaul_version) {
+
+	/*
+	 * Longhaul v1. (Samuel[C5A] and Samuel2 stepping 0[C5B])
+	 * Software controlled multipliers only.
+	 *
+	 * *NB* Until we get voltage scaling working v1 & v2 are the same code.
+	 * Longhaul v2 appears in Samuel2 Steppings 1->7 [C5b] and Ezra [C5C]
+	 */
 	case 1:
 		rdmsrl (MSR_VIA_BCR2, bcr2.val);
 		/* Enable software clock multiplier */
 		bcr2.bits.ESOFTBF = 1;
 		bcr2.bits.CLOCKMUL = clock_ratio_index;
+		local_irq_disable();
 		wrmsrl (MSR_VIA_BCR2, bcr2.val);
+		local_irq_enable();
 
 		__hlt();
 
 		/* Disable software clock multiplier */
 		rdmsrl (MSR_VIA_BCR2, bcr2.val);
 		bcr2.bits.ESOFTBF = 0;
+		local_irq_disable();
 		wrmsrl (MSR_VIA_BCR2, bcr2.val);
+		local_irq_enable();
 		break;
 
 	/*
-	 * Powersaver. (Ezra-T [C5M], Nehemiah [C5N])
+	 * Longhaul v3 (aka Powersaver). (Ezra-T [C5M])
 	 * We can scale voltage with this too, but that's currently
 	 * disabled until we come up with a decent 'match freq to voltage'
 	 * algorithm.
-	 * We also need to do the voltage/freq setting in order depending
-	 * on the direction of scaling (like we do in powernow-k7.c)
-	 * Ezra-T was alleged to do FSB scaling too, but it never worked in practice.
+	 * When we add voltage scaling, we will also need to do the
+	 * voltage/freq setting in order depending on the direction
+	 * of scaling (like we do in powernow-k7.c)
 	 */
 	case 2:
-		rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
-		longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
-		longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
-		longhaul.bits.EnableSoftBusRatio = 1;
-		/* We must program the revision key only with values we
-		 * know about, not blindly copy it from 0:3 */
-		longhaul.bits.RevisionKey = 3;	/* SoftVID & SoftBSEL */
-		wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
-		__hlt();
-
-		rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
-		longhaul.bits.EnableSoftBusRatio = 0;
-		longhaul.bits.RevisionKey = 3;
-		wrmsrl (MSR_VIA_LONGHAUL, longhaul.val);
+		do_powersaver(&longhaul, clock_ratio_index, 3);
 		break;
-	case 3:
-		rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
-		longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
-		longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
-		longhaul.bits.EnableSoftBusRatio = 1;
-
-		longhaul.bits.RevisionKey = 0x0;
-
-		wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
-		__hlt();
 
-		rdmsrl (MSR_VIA_LONGHAUL, longhaul.val);
-		longhaul.bits.EnableSoftBusRatio = 0;
-		longhaul.bits.RevisionKey = 0xf;
-		wrmsrl (MSR_VIA_LONGHAUL, longhaul.val);
+	/*
+	 * Powersaver. (Nehemiah [C5N])
+	 * As for Ezra-T, we don't do voltage yet.
+	 * This can do FSB scaling too, but it has never been proven
+	 * to work in practice.
+	 */
+	case 3:
+		do_powersaver(&longhaul, clock_ratio_index, 0xf);
 		break;
 	}
 
diff -Nru a/arch/i386/kernel/cpu/cpufreq/longrun.c b/arch/i386/kernel/cpu/cpufreq/longrun.c
--- a/arch/i386/kernel/cpu/cpufreq/longrun.c	2004-08-08 12:43:24 -07:00
+++ b/arch/i386/kernel/cpu/cpufreq/longrun.c	2004-08-08 12:43:24 -07:00
@@ -7,7 +7,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/module.h> 
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/cpufreq.h>
@@ -19,7 +19,7 @@
 static struct cpufreq_driver	longrun_driver;
 
 /**
- * longrun_{low,high}_freq is needed for the conversion of cpufreq kHz 
+ * longrun_{low,high}_freq is needed for the conversion of cpufreq kHz
  * values into per cent values. In TMTA microcode, the following is valid:
  * performance_pctg = (current_freq - low_freq)/(high_freq - low_freq)
  */
@@ -42,18 +42,18 @@
 		policy->policy = CPUFREQ_POLICY_PERFORMANCE;
 	else
 		policy->policy = CPUFREQ_POLICY_POWERSAVE;
-	
+
 	rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
 	msr_lo &= 0x0000007F;
 	msr_hi &= 0x0000007F;
-	
+
 	if ( longrun_high_freq <= longrun_low_freq ) {
 		/* Assume degenerate Longrun table */
 		policy->min = policy->max = longrun_high_freq;
 	} else {
-		policy->min = longrun_low_freq + msr_lo * 
+		policy->min = longrun_low_freq + msr_lo *
 			((longrun_high_freq - longrun_low_freq) / 100);
-		policy->max = longrun_low_freq + msr_hi * 
+		policy->max = longrun_low_freq + msr_hi *
 			((longrun_high_freq - longrun_low_freq) / 100);
 	}
 	policy->cpu = 0;
@@ -79,9 +79,9 @@
 		/* Assume degenerate Longrun table */
 		pctg_lo = pctg_hi = 100;
 	} else {
-		pctg_lo = (policy->min - longrun_low_freq) / 
+		pctg_lo = (policy->min - longrun_low_freq) /
 			((longrun_high_freq - longrun_low_freq) / 100);
-		pctg_hi = (policy->max - longrun_low_freq) / 
+		pctg_hi = (policy->max - longrun_low_freq) /
 			((longrun_high_freq - longrun_low_freq) / 100);
 	}
 
@@ -118,7 +118,7 @@
  * longrun_verify_poliy - verifies a new CPUFreq policy
  * @policy: the policy to verify
  *
- * Validates a new CPUFreq policy. This function has to be called with 
+ * Validates a new CPUFreq policy. This function has to be called with
  * cpufreq_driver locked.
  */
 static int longrun_verify_policy(struct cpufreq_policy *policy)
@@ -127,8 +127,8 @@
 		return -EINVAL;
 
 	policy->cpu = 0;
-	cpufreq_verify_within_limits(policy, 
-		policy->cpuinfo.min_freq, 
+	cpufreq_verify_within_limits(policy,
+		policy->cpuinfo.min_freq,
 		policy->cpuinfo.max_freq);
 
 	if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) &&
@@ -160,7 +160,7 @@
  * TMTA rules:
  * performance_pctg = (target_freq - low_freq)/(high_freq - low_freq)
  */
-static unsigned int __init longrun_determine_freqs(unsigned int *low_freq, 
+static unsigned int __init longrun_determine_freqs(unsigned int *low_freq,
 						   unsigned int *high_freq)
 {
 	u32 msr_lo, msr_hi;
@@ -174,9 +174,9 @@
 
 	if (cpu_has(c, X86_FEATURE_LRTI)) {
 		/* if the LongRun Table Interface is present, the
-		 * detection is a bit easier: 
+		 * detection is a bit easier:
 		 * For minimum frequency, read out the maximum
-		 * level (msr_hi), write that into "currently 
+		 * level (msr_hi), write that into "currently
 		 * selected level", and read out the frequency.
 		 * For maximum frequency, read out level zero.
 		 */
@@ -223,7 +223,7 @@
 		cpuid(0x80860007, &eax, &ebx, &ecx, &edx);
 
 		/* restore values */
-		wrmsr(MSR_TMTA_LONGRUN_CTRL, save_lo, save_hi);	
+		wrmsr(MSR_TMTA_LONGRUN_CTRL, save_lo, save_hi);
 	}
 
 	/* performance_pctg = (current_freq - low_freq)/(high_freq - low_freq)
@@ -237,7 +237,7 @@
 	if ((ecx > 95) || (ecx == 0) || (eax < ebx))
 		return -EIO;
 
-	edx = (eax - ebx) / (100 - ecx); 
+	edx = (eax - ebx) / (100 - ecx);
 	*low_freq = edx * 1000; /* back to kHz */
 
 	if (*low_freq > *high_freq)
@@ -249,7 +249,7 @@
 
 static int __init longrun_cpu_init(struct cpufreq_policy *policy)
 {
-	int                     result = 0;
+	int result = 0;
 
 	/* capability check */
 	if (policy->cpu != 0)
@@ -265,15 +265,15 @@
 	policy->cpuinfo.max_freq = longrun_high_freq;
 	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
 	longrun_get_policy(policy);
-	
+
 	return 0;
 }
 
 
 static struct cpufreq_driver longrun_driver = {
 	.flags		= CPUFREQ_CONST_LOOPS,
-	.verify 	= longrun_verify_policy,
-	.setpolicy 	= longrun_set_policy,
+	.verify		= longrun_verify_policy,
+	.setpolicy	= longrun_set_policy,
 	.get		= longrun_get,
 	.init		= longrun_cpu_init,
 	.name		= "longrun",
@@ -290,7 +290,7 @@
 {
 	struct cpuinfo_x86 *c = cpu_data;
 
-	if (c->x86_vendor != X86_VENDOR_TRANSMETA || 
+	if (c->x86_vendor != X86_VENDOR_TRANSMETA ||
 	    !cpu_has(c, X86_FEATURE_LONGRUN))
 		return -ENODEV;
 
diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	2004-08-08 12:43:24 -07:00
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	2004-08-08 12:43:24 -07:00
@@ -6,8 +6,6 @@
  *  Licensed under the terms of the GNU GPL License version 2.
  *  Based upon datasheets & sample CPUs kindly provided by AMD.
  *
- *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
- *
  * Errata 5: Processor may fail to execute a FID/VID change in presence of interrupt.
  * - We cli/sti on stepping A0 CPUs around the FID/VID transition.
  * Errata 15: Processors with half frequency multipliers may hang upon wakeup from disconnect.
@@ -29,21 +27,13 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
 #include <linux/acpi.h>
 #include <acpi/processor.h>
 #endif
 
 #include "powernow-k7.h"
 
-#define DEBUG
-
-#ifdef DEBUG
-#define dprintk(msg...) printk(msg)
-#else
-#define dprintk(msg...) do { } while(0)
-#endif
-
 #define PFX "powernow: "
 
 
@@ -64,7 +54,7 @@
 	u8 numpstates;
 };
 
-#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
 union powernow_acpi_control_t {
 	struct {
 		unsigned long fid:5,
@@ -97,6 +87,7 @@
  */
 
 static int acpi_force;
+static int debug;
 
 static struct cpufreq_frequency_table *powernow_table;
 
@@ -109,6 +100,21 @@
 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);
+}
+
+
 static int check_fsb(unsigned int fsbspeed)
 {
 	int delta;
@@ -190,13 +196,13 @@
 		speed = powernow_table[j].frequency;
 
 		if ((fid_codes[fid] % 10)==5) {
-#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
 			if (have_a0 == 1)
 				powernow_table[j].frequency = CPUFREQ_ENTRY_INVALID;
 #endif
 		}
 
-		dprintk (KERN_INFO PFX "   FID: 0x%x (%d.%dx [%dMHz])\t", fid,
+		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)
@@ -285,7 +291,7 @@
 		change_VID(vid);
 		change_FID(fid);
 	}
-	
+
 
 	if (have_a0 == 1)
 		local_irq_enable();
@@ -294,7 +300,7 @@
 }
 
 
-#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
 
 struct acpi_processor_performance *acpi_processor_perf;
 
@@ -377,7 +383,7 @@
 				powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
 		}
 
-		dprintk (KERN_INFO PFX "   FID: 0x%x (%d.%dx [%dMHz])\t", fid,
+		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);
@@ -467,9 +473,9 @@
 				    (maxfid==pst->maxfid) && (startvid==pst->startvid))
 				{
 					dprintk (KERN_INFO PFX "PST:%d (@%p)\n", i, pst);
-					dprintk (KERN_INFO PFX " cpuid: 0x%x\t", pst->cpuid);
-					dprintk ("fsb: %d\t", pst->fsbspeed);
-					dprintk ("maxFID: 0x%x\t", pst->maxfid);
+					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);
 
 					ret = get_ranges ((char *) pst + sizeof (struct pst_s));
@@ -591,14 +597,14 @@
 	rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
 
 	/* A K7 with powernow technology is set to max frequency by BIOS */
-	fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID];
+	fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.MFID];
 	if (!fsb) {
 		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);
 
- 	if (dmi_check_system(powernow_dmi_table) || acpi_force) {
+	if (dmi_check_system(powernow_dmi_table) || acpi_force) {
 		printk (KERN_INFO PFX "PSB/PST known to be broken.  Trying ACPI instead\n");
 		result = powernow_acpi_init();
 	} else {
@@ -648,14 +654,14 @@
 };
 
 static struct cpufreq_driver powernow_driver = {
-	.verify 	= powernow_verify,
-	.target 	= powernow_target,
-	.get		= powernow_get,	
-	.init		= powernow_cpu_init,
-	.exit		= powernow_cpu_exit,
-	.name		= "powernow-k7",
-	.owner		= THIS_MODULE,
-	.attr		= powernow_table_attr,
+	.verify	= powernow_verify,
+	.target	= powernow_target,
+	.get	= powernow_get,
+	.init	= powernow_cpu_init,
+	.exit	= powernow_cpu_exit,
+	.name	= "powernow-k7",
+	.owner	= THIS_MODULE,
+	.attr	= powernow_table_attr,
 };
 
 static int __init powernow_init (void)
@@ -668,7 +674,7 @@
 
 static void __exit powernow_exit (void)
 {
-#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
 	if (acpi_processor_perf) {
 		acpi_processor_unregister_performance(acpi_processor_perf, 0);
 		kfree(acpi_processor_perf);
@@ -679,8 +685,10 @@
 		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");
+MODULE_PARM_DESC(acpi_force, "Force ACPI to be used.");
 
 MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
 MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c	2004-08-08 12:43:24 -07:00
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c	2004-08-08 12:43:24 -07:00
@@ -32,7 +32,7 @@
 #include <asm/io.h>
 #include <asm/delay.h>
 
-#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
+#ifdef CONFIG_X86_POWERNOW_K8_ACPI
 #include <linux/acpi.h>
 #include <acpi/processor.h>
 #endif
@@ -664,7 +664,7 @@
 	return -ENODEV;
 }
 
-#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
+#ifdef CONFIG_X86_POWERNOW_K8_ACPI
 static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index)
 {
 	if (!data->acpi_data.state_count)
@@ -1024,7 +1024,7 @@
 	return -ENODEV;
 }
 
-static int __exit powernowk8_cpu_exit (struct cpufreq_policy *pol)
+static int __devexit powernowk8_cpu_exit (struct cpufreq_policy *pol)
 {
 	struct powernow_k8_data *data = powernow_data[pol->cpu];
 
@@ -1076,7 +1076,7 @@
 	.verify = powernowk8_verify,
 	.target = powernowk8_target,
 	.init = powernowk8_cpu_init,
-	.exit = powernowk8_cpu_exit,
+	.exit = __devexit_p(powernowk8_cpu_exit),
 	.get = powernowk8_get,
 	.name = "powernow-k8",
 	.owner = THIS_MODULE,
diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2004-08-08 12:43:24 -07:00
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2004-08-08 12:43:24 -07:00
@@ -10,7 +10,7 @@
  * Copyright (C) 2003 Jeremy Fitzhardinge <jeremy@goop.org>
  *
  * WARNING WARNING WARNING
- * 
+ *
  * This driver manipulates the PERF_CTL MSR, which is only somewhat
  * documented.  While it seems to work on my laptop, it has not been
  * tested anywhere else, and it may not work for you, do strange
@@ -23,6 +23,11 @@
 #include <linux/cpufreq.h>
 #include <linux/config.h>
 
+#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
+#include <linux/acpi.h>
+#include <acpi/processor.h>
+#endif
+
 #include <asm/msr.h>
 #include <asm/processor.h>
 #include <asm/cpufeature.h>
@@ -41,24 +46,22 @@
 struct cpu_id
 {
 	__u8	x86;            /* CPU family */
-	__u8	x86_vendor;     /* CPU vendor */
 	__u8	x86_model;	/* model */
 	__u8	x86_mask;	/* stepping */
 };
 
-static const struct cpu_id cpu_id_banias = {
-	.x86_vendor = X86_VENDOR_INTEL,
-	.x86 = 6,
-	.x86_model = 9,
-	.x86_mask = 5,
+enum {
+	CPU_BANIAS,
+	CPU_DOTHAN_A1,
+	CPU_DOTHAN_B0,
 };
 
-static const struct cpu_id cpu_id_dothan_a1 = {
-	.x86_vendor = X86_VENDOR_INTEL,
-	.x86 = 6,
-	.x86_model = 13,
-	.x86_mask = 1,
+static const struct cpu_id cpu_ids[] = {
+	[CPU_BANIAS]	= { 6,  9, 5 },
+	[CPU_DOTHAN_A1]	= { 6, 13, 1 },
+	[CPU_DOTHAN_B0]	= { 6, 13, 6 },
 };
+#define N_IDS	(sizeof(cpu_ids)/sizeof(cpu_ids[0]))
 
 struct cpu_model
 {
@@ -68,10 +71,11 @@
 
 	struct cpufreq_frequency_table *op_points; /* clock/voltage pairs */
 };
-static int centrino_verify_cpu_id(struct cpuinfo_x86 *c, const struct cpu_id *x);
+static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, const struct cpu_id *x);
 
 /* Operating points for current CPU */
 static struct cpu_model *centrino_model;
+static int centrino_cpu;
 
 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE
 
@@ -84,7 +88,7 @@
 		.index = (((mhz)/100) << 8) | ((mv - 700) / 16)		\
 	}
 
-/* 
+/*
  * These voltage tables were derived from the Intel Pentium M
  * datasheet, document 25261202.pdf, Table 5.  I have verified they
  * are consistent with my IBM ThinkPad X31, which has a 1.3GHz Pentium
@@ -103,9 +107,9 @@
 /* Ultra Low Voltage Intel Pentium M processor 1000MHz (Banias) */
 static struct cpufreq_frequency_table banias_1000[] =
 {
-	OP(600,  844),
-	OP(800,  972),
-	OP(900,  988),
+	OP(600,   844),
+	OP(800,   972),
+	OP(900,   988),
 	OP(1000, 1004),
 	{ .frequency = CPUFREQ_TABLE_END }
 };
@@ -135,7 +139,7 @@
 };
 
 /* Intel Pentium M processor 1.30GHz (Banias) */
-static struct cpufreq_frequency_table banias_1300[] = 
+static struct cpufreq_frequency_table banias_1300[] =
 {
 	OP( 600,  956),
 	OP( 800, 1260),
@@ -146,7 +150,7 @@
 };
 
 /* Intel Pentium M processor 1.40GHz (Banias) */
-static struct cpufreq_frequency_table banias_1400[] = 
+static struct cpufreq_frequency_table banias_1400[] =
 {
 	OP( 600,  956),
 	OP( 800, 1180),
@@ -157,7 +161,7 @@
 };
 
 /* Intel Pentium M processor 1.50GHz (Banias) */
-static struct cpufreq_frequency_table banias_1500[] = 
+static struct cpufreq_frequency_table banias_1500[] =
 {
 	OP( 600,  956),
 	OP( 800, 1116),
@@ -169,7 +173,7 @@
 };
 
 /* Intel Pentium M processor 1.60GHz (Banias) */
-static struct cpufreq_frequency_table banias_1600[] = 
+static struct cpufreq_frequency_table banias_1600[] =
 {
 	OP( 600,  956),
 	OP( 800, 1036),
@@ -199,13 +203,13 @@
 	.max_freq	= (max)*1000,	\
 	.op_points	= banias_##max,	\
 }
-#define BANIAS(max)	_BANIAS(&cpu_id_banias, max, #max)
+#define BANIAS(max)	_BANIAS(&cpu_ids[CPU_BANIAS], max, #max)
 
 /* CPU models, their operating frequency range, and freq/voltage
    operating points */
-static struct cpu_model models[] = 
+static struct cpu_model models[] =
 {
-	_BANIAS(&cpu_id_banias, 900, " 900"),
+	_BANIAS(&cpu_ids[CPU_BANIAS], 900, " 900"),
 	BANIAS(1000),
 	BANIAS(1100),
 	BANIAS(1200),
@@ -214,6 +218,11 @@
 	BANIAS(1500),
 	BANIAS(1600),
 	BANIAS(1700),
+
+	/* NULL model_name is a wildcard */
+	{ &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL },
+	{ &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL },
+
 	{ NULL, }
 };
 #undef _BANIAS
@@ -224,19 +233,30 @@
 	struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
 	struct cpu_model *model;
 
-	for(model = models; model->model_name != NULL; model++)
-		if ((strcmp(cpu->x86_model_id, model->model_name) == 0) &&
-		    (!centrino_verify_cpu_id(cpu, model->cpu_id)))
+	for(model = models; model->cpu_id != NULL; model++)
+		if (centrino_verify_cpu_id(cpu, model->cpu_id) &&
+		    (model->model_name == NULL ||
+		     strcmp(cpu->x86_model_id, model->model_name) == 0))
 			break;
-	if (model->model_name == NULL) {
+
+	if (model->cpu_id == NULL) {
+		/* No match at all */
 		printk(KERN_INFO PFX "no support for CPU model \"%s\": "
 		       "send /proc/cpuinfo to " MAINTAINER "\n",
 		       cpu->x86_model_id);
 		return -ENOENT;
 	}
 
+	if (model->op_points == NULL) {
+		/* Matched a non-match */
+		printk(KERN_INFO PFX "no table support for CPU model \"%s\": \n",
+		       cpu->x86_model_id);
+		printk(KERN_INFO PFX "try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n");
+		return -ENOENT;
+	}
+
 	centrino_model = model;
-		
+
 	printk(KERN_INFO PFX "found \"%s\": max frequency: %dkHz\n",
 	       model->model_name, model->max_freq);
 
@@ -247,31 +267,54 @@
 static inline int centrino_cpu_init_table(struct cpufreq_policy *policy) { return -ENODEV; }
 #endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE */
 
-static int centrino_verify_cpu_id(struct cpuinfo_x86 *c, const struct cpu_id *x)
+static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c, const struct cpu_id *x)
 {
 	if ((c->x86 == x->x86) &&
-	    (c->x86_vendor == x->x86_vendor) &&
 	    (c->x86_model == x->x86_model) &&
 	    (c->x86_mask == x->x86_mask))
-		return 0;
-	return -ENODEV;
+		return 1;
+	return 0;
 }
 
-/* Extract clock in kHz from PERF_CTL value */
+/* To be called only after centrino_model is initialized */
 static unsigned extract_clock(unsigned msr)
 {
-	msr = (msr >> 8) & 0xff;
-	return msr * 100000;
+	int i;
+
+	/*
+	 * Extract clock in kHz from PERF_CTL value
+	 * for centrino, as some DSDTs are buggy.
+	 * Ideally, this can be done using the acpi_data structure.
+	 */
+	if (centrino_cpu) {
+		msr = (msr >> 8) & 0xff;
+		return msr * 100000;
+	}
+
+	if ((!centrino_model) || (!centrino_model->op_points))
+		return 0;
+
+	msr &= 0xffff;
+	for (i=0;centrino_model->op_points[i].frequency != CPUFREQ_TABLE_END; i++) {
+		if (msr == centrino_model->op_points[i].index)
+		return centrino_model->op_points[i].frequency;
+	}
+	return 0;
 }
 
 /* Return the current CPU frequency in kHz */
 static unsigned int get_cur_freq(unsigned int cpu)
 {
 	unsigned l, h;
-	if (cpu)
+	cpumask_t saved_mask;
+
+	saved_mask = current->cpus_allowed;
+	set_cpus_allowed(current, cpumask_of_cpu(cpu));
+	if (smp_processor_id() != cpu)
 		return 0;
 
 	rdmsr(MSR_IA32_PERF_STATUS, l, h);
+	set_cpus_allowed(current, saved_mask);
 	return extract_clock(l);
 }
 
@@ -280,13 +323,8 @@
 
 static struct acpi_processor_performance p;
 
-#include <linux/acpi.h>
-#include <acpi/processor.h>
-
-#define ACPI_PDC_CAPABILITY_ENHANCED_SPEEDSTEP 0x1
-
 /*
- * centrino_cpu_init_acpi - register with ACPI P-States library 
+ * centrino_cpu_init_acpi - register with ACPI P-States library
  *
  * Register with the ACPI P-States library (part of drivers/acpi/processor.c)
  * in order to determine correct frequency and voltage pairings by reading
@@ -296,7 +334,7 @@
 {
 	union acpi_object		arg0 = {ACPI_TYPE_BUFFER};
 	u32				arg0_buf[3];
-	struct acpi_object_list 	arg_list = {1, &arg0};
+	struct acpi_object_list		arg_list = {1, &arg0};
 	unsigned long			cur_freq;
 	int				result = 0, i;
 
@@ -305,12 +343,12 @@
         arg0.buffer.pointer = (u8 *) arg0_buf;
         arg0_buf[0] = ACPI_PDC_REVISION_ID;
         arg0_buf[1] = 1;
-        arg0_buf[2] = ACPI_PDC_CAPABILITY_ENHANCED_SPEEDSTEP;
+        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, 0))
+        if (acpi_processor_register_performance(&p, policy->cpu))
                 return -EIO;
 
 	/* verify the acpi_data */
@@ -318,7 +356,7 @@
                 printk(KERN_DEBUG "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)) {
@@ -340,11 +378,10 @@
 			goto err_unreg;
 		}
 
-		if (extract_clock(p.states[i].control) != 
-		    (p.states[i].core_frequency * 1000)) {
-			printk(KERN_DEBUG "Invalid encoded frequency\n");
-			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);
+			p.states[i].core_frequency = 0;
+			continue;
 		}
 	}
 
@@ -357,29 +394,43 @@
 
 	centrino_model->model_name=NULL;
 	centrino_model->max_freq = p.states[0].core_frequency * 1000;
-	centrino_model->op_points =  kmalloc(sizeof(struct cpufreq_frequency_table) * 
+	centrino_model->op_points =  kmalloc(sizeof(struct cpufreq_frequency_table) *
 					     (p.state_count + 1), GFP_KERNEL);
         if (!centrino_model->op_points) {
                 result = -ENOMEM;
                 goto err_kfree;
         }
 
-	cur_freq = get_cur_freq(0);
-
         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;
+	}
+	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 (extract_clock(centrino_model->op_points[i].index) !=
+		    (centrino_model->op_points[i].frequency)) {
+			printk(KERN_DEBUG "Invalid encoded frequency\n");
+			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;
 	}
-	centrino_model->op_points[p.state_count].frequency = CPUFREQ_TABLE_END;
 
 	return 0;
 
+ err_kfree_all:
+	kfree(centrino_model->op_points);
  err_kfree:
 	kfree(centrino_model);
  err_unreg:
-	acpi_processor_unregister_performance(&p, 0);
+	acpi_processor_unregister_performance(&p, policy->cpu);
 	return (result);
 }
 #else
@@ -392,21 +443,30 @@
 	unsigned freq;
 	unsigned l, h;
 	int ret;
+	int i;
 
-	if (policy->cpu != 0)
+	/* Only Intel makes Enhanced Speedstep-capable CPUs */
+	if (cpu->x86_vendor != X86_VENDOR_INTEL || !cpu_has(cpu, X86_FEATURE_EST))
 		return -ENODEV;
 
-	if (!cpu_has(cpu, X86_FEATURE_EST))
-		return -ENODEV;
+	for (i = 0; i < N_IDS; i++)
+		if (centrino_verify_cpu_id(cpu, &cpu_ids[i]))
+			break;
 
-	if ((centrino_verify_cpu_id(cpu, &cpu_id_banias)) &&
-	    (centrino_verify_cpu_id(cpu, &cpu_id_dothan_a1))) {
-		printk(KERN_INFO PFX "found unsupported CPU with Enhanced SpeedStep: "
-		       "send /proc/cpuinfo to " MAINTAINER "\n");
-		return -ENODEV;
-	}
+	if (i != N_IDS)
+		centrino_cpu = 1;
 
 	if (centrino_cpu_init_acpi(policy)) {
+		if (policy->cpu != 0)
+			return -ENODEV;
+
+		if (!centrino_cpu) {
+			printk(KERN_INFO PFX "found unsupported CPU with "
+			"Enhanced SpeedStep: send /proc/cpuinfo to "
+			MAINTAINER "\n");
+			return -ENODEV;
+		}
+
 		if (centrino_cpu_init_table(policy)) {
 			return -ENODEV;
 		}
@@ -415,11 +475,11 @@
 	/* Check to see if Enhanced SpeedStep is enabled, and try to
 	   enable it if not. */
 	rdmsr(MSR_IA32_MISC_ENABLE, l, h);
-		
+
 	if (!(l & (1<<16))) {
 		l |= (1<<16);
 		wrmsr(MSR_IA32_MISC_ENABLE, l, h);
-		
+
 		/* check to see if it stuck */
 		rdmsr(MSR_IA32_MISC_ENABLE, l, h);
 		if (!(l & (1<<16))) {
@@ -428,7 +488,7 @@
 		}
 	}
 
-	freq = get_cur_freq(0);
+	freq = get_cur_freq(policy->cpu);
 
 	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
 	policy->cpuinfo.transition_latency = 10000; /* 10uS transition latency */
@@ -436,7 +496,7 @@
 
 	dprintk(KERN_INFO PFX "centrino_cpu_init: policy=%d cur=%dkHz\n",
 		policy->policy, policy->cur);
-	
+
 	ret = cpufreq_frequency_table_cpuinfo(policy, centrino_model->op_points);
 	if (ret)
 		return (ret);
@@ -455,7 +515,7 @@
 
 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
 	if (!centrino_model->model_name) {
-		acpi_processor_unregister_performance(&p, 0);
+		acpi_processor_unregister_performance(&p, policy->cpu);
 		kfree(centrino_model->op_points);
 		kfree(centrino_model);
 	}
@@ -493,19 +553,35 @@
 	unsigned int    newstate = 0;
 	unsigned int	msr, oldmsr, h;
 	struct cpufreq_freqs	freqs;
+	cpumask_t		saved_mask;
+	int			retval;
 
 	if (centrino_model == NULL)
 		return -ENODEV;
 
+	/*
+	 * Support for SMP systems.
+	 * Make sure we are running on the CPU that wants to change frequency
+	 */
+	saved_mask = current->cpus_allowed;
+	set_cpus_allowed(current, cpumask_of_cpu(policy->cpu));
+	if (smp_processor_id() != policy->cpu) {
+		return(-EAGAIN);
+	}
+
 	if (cpufreq_frequency_table_target(policy, centrino_model->op_points, target_freq,
-					   relation, &newstate))
-		return -EINVAL;
+					   relation, &newstate)) {
+		retval = -EINVAL;
+		goto migrate_end;
+	}
 
 	msr = centrino_model->op_points[newstate].index;
 	rdmsr(MSR_IA32_PERF_CTL, oldmsr, h);
 
-	if (msr == (oldmsr & 0xffff))
-		return 0;
+	if (msr == (oldmsr & 0xffff)) {
+		retval = 0;
+		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
@@ -514,31 +590,34 @@
 	   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". 
+	   "old".
 
 	   TODO: work out how the TCC interrupts work, and try to
 	   catch the CPU changing things under us.
 	*/
-	freqs.cpu = 0;
+	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",
 		target_freq, freqs.old, freqs.new, msr);
 
-	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);	
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 
 	/* all but 16 LSB are "reserved", so treat them with
 	   care */
 	oldmsr &= ~0xffff;
 	msr &= 0xffff;
 	oldmsr |= msr;
-	
+
 	wrmsr(MSR_IA32_PERF_CTL, oldmsr, h);
 
 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
-	return 0;
+	retval = 0;
+migrate_end:
+	set_cpus_allowed(current, saved_mask);
+	return (retval);
 }
 
 static struct freq_attr* centrino_attr[] = {
@@ -547,12 +626,12 @@
 };
 
 static struct cpufreq_driver centrino_driver = {
-	.name		= "centrino", /* should be speedstep-centrino, 
+	.name		= "centrino", /* should be speedstep-centrino,
 					 but there's a 16 char limit */
 	.init		= centrino_cpu_init,
 	.exit		= centrino_cpu_exit,
-	.verify 	= centrino_verify,
-	.target 	= centrino_target,
+	.verify		= centrino_verify,
+	.target		= centrino_target,
 	.get		= get_cur_freq,
 	.attr           = centrino_attr,
 	.owner		= THIS_MODULE,
diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c	2004-08-08 12:43:24 -07:00
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c	2004-08-08 12:43:24 -07:00
@@ -7,7 +7,7 @@
  *  for chipsets ICH2-M and ICH3-M.
  *
  *  Many thanks to Ducrot Bruno for finding and fixing the last
- *  "missing link" for ICH2-M/ICH3-M support, and to Thomas Winkler 
+ *  "missing link" for ICH2-M/ICH3-M support, and to Thomas Winkler
  *  for extensive testing.
  *
  *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
@@ -19,7 +19,7 @@
  *********************************************************************/
 
 #include <linux/kernel.h>
-#include <linux/module.h> 
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/pci.h>
@@ -29,24 +29,24 @@
 
 
 /* speedstep_chipset:
- *   It is necessary to know which chipset is used. As accesses to 
- * this device occur at various places in this module, we need a 
+ *   It is necessary to know which chipset is used. As accesses to
+ * this device occur at various places in this module, we need a
  * static struct pci_dev * pointing to that device.
  */
-static struct pci_dev			*speedstep_chipset_dev;
+static struct pci_dev *speedstep_chipset_dev;
 
 
 /* speedstep_processor
  */
-static unsigned int			speedstep_processor = 0;
+static unsigned int speedstep_processor = 0;
 
 
-/* 
+/*
  *   There are only two frequency states for each processor. Values
  * are in kHz for the time being.
  */
 static struct cpufreq_frequency_table speedstep_freqs[] = {
-	{SPEEDSTEP_HIGH, 	0},
+	{SPEEDSTEP_HIGH,	0},
 	{SPEEDSTEP_LOW,		0},
 	{0,			CPUFREQ_TABLE_END},
 };
@@ -68,22 +68,21 @@
  * speedstep_set_state - set the SpeedStep state
  * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
  *
- *   Tries to change the SpeedStep state. 
+ *   Tries to change the SpeedStep state.
  */
 static void speedstep_set_state (unsigned int state)
 {
-	u32			pmbase;
-	u8			pm2_blk;
-	u8			value;
-	unsigned long		flags;
+	u32 pmbase;
+	u8 pm2_blk;
+	u8 value;
+	unsigned long flags;
 
 	if (!speedstep_chipset_dev || (state > 0x1))
 		return;
 
 	/* get PMBASE */
 	pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
-	if (!(pmbase & 0x01))
-	{
+	if (!(pmbase & 0x01)) {
 		printk(KERN_ERR "cpufreq: could not find speedstep register\n");
 		return;
 	}
@@ -146,18 +145,16 @@
  */
 static int speedstep_activate (void)
 {
-	u16		value = 0;
+	u16 value = 0;
 
 	if (!speedstep_chipset_dev)
 		return -EINVAL;
 
-	pci_read_config_word(speedstep_chipset_dev, 
-			     0x00A0, &value);
+	pci_read_config_word(speedstep_chipset_dev, 0x00A0, &value);
 	if (!(value & 0x08)) {
 		value |= 0x08;
 		dprintk(KERN_DEBUG "cpufreq: activating SpeedStep (TM) registers\n");
-		pci_write_config_word(speedstep_chipset_dev, 
-				      0x00A0, value);
+		pci_write_config_word(speedstep_chipset_dev, 0x00A0, value);
 	}
 
 	return 0;
@@ -167,15 +164,15 @@
 /**
  * speedstep_detect_chipset - detect the Southbridge which contains SpeedStep logic
  *
- *   Detects ICH2-M, ICH3-M and ICH4-M so far. The pci_dev points to 
- * the LPC bridge / PM module which contains all power-management 
+ *   Detects ICH2-M, ICH3-M and ICH4-M so far. The pci_dev points to
+ * the LPC bridge / PM module which contains all power-management
  * functions. Returns the SPEEDSTEP_CHIPSET_-number for the detected
  * chipset, or zero on failure.
  */
 static unsigned int speedstep_detect_chipset (void)
 {
 	speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL,
-			      PCI_DEVICE_ID_INTEL_82801DB_12, 
+			      PCI_DEVICE_ID_INTEL_82801DB_12,
 			      PCI_ANY_ID,
 			      PCI_ANY_ID,
 			      NULL);
@@ -183,7 +180,7 @@
 		return 4; /* 4-M */
 
 	speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL,
-			      PCI_DEVICE_ID_INTEL_82801CA_12, 
+			      PCI_DEVICE_ID_INTEL_82801CA_12,
 			      PCI_ANY_ID,
 			      PCI_ANY_ID,
 			      NULL);
@@ -198,11 +195,11 @@
 			      NULL);
 	if (speedstep_chipset_dev) {
 		/* speedstep.c causes lockups on Dell Inspirons 8000 and
-		 * 8100 which use a pretty old revision of the 82815 
+		 * 8100 which use a pretty old revision of the 82815
 		 * host brige. Abort on these systems.
 		 */
-		static struct pci_dev	*hostbridge;
-		u8			rev = 0;
+		static struct pci_dev *hostbridge;
+		u8 rev = 0;
 
 		hostbridge  = pci_find_subsys(PCI_VENDOR_ID_INTEL,
 			      PCI_DEVICE_ID_INTEL_82815_MC,
@@ -212,7 +209,7 @@
 
 		if (!hostbridge)
 			return 2; /* 2-M */
-			
+
 		pci_read_config_byte(hostbridge, PCI_REVISION_ID, &rev);
 		if (rev < 5) {
 			dprintk(KERN_INFO "cpufreq: hostbridge does not support speedstep\n");
@@ -226,6 +223,23 @@
 	return 0;
 }
 
+static unsigned int speedstep_get(unsigned int cpu)
+{
+	unsigned int speed;
+	cpumask_t cpus_allowed,affected_cpu_map;
+
+	/* only run on CPU to be set, or on its sibling */
+	cpus_allowed = current->cpus_allowed;
+#ifdef CONFIG_SMP
+	affected_cpu_map = cpu_sibling_map[cpu];
+#else
+	affected_cpu_map = cpumask_of_cpu(cpu);
+#endif
+	set_cpus_allowed(current, affected_cpu_map);
+	speed=speedstep_get_processor_frequency(speedstep_processor);
+	set_cpus_allowed(current, cpus_allowed);
+	return speed;
+}
 
 /**
  * speedstep_target - set a new CPUFreq policy
@@ -239,7 +253,7 @@
 			     unsigned int target_freq,
 			     unsigned int relation)
 {
-	unsigned int	newstate = 0;
+	unsigned int newstate = 0;
 	struct cpufreq_freqs freqs;
 	cpumask_t cpus_allowed, affected_cpu_map;
 	int i;
@@ -247,14 +261,14 @@
 	if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate))
 		return -EINVAL;
 
+	freqs.old = speedstep_get(policy->cpu);
+	freqs.new = speedstep_freqs[newstate].frequency;
+	freqs.cpu = policy->cpu;
+
 	/* no transition necessary */
 	if (freqs.old == freqs.new)
 		return 0;
 
-	freqs.old = speedstep_get_processor_frequency(speedstep_processor);
-	freqs.new = speedstep_freqs[newstate].frequency;
-	freqs.cpu = policy->cpu;
-
 	cpus_allowed = current->cpus_allowed;
 
 	/* only run on CPU to be set, or on its sibling */
@@ -301,9 +315,9 @@
 
 static int speedstep_cpu_init(struct cpufreq_policy *policy)
 {
-	int		result = 0;
-	unsigned int	speed;
-	cpumask_t       cpus_allowed,affected_cpu_map;
+	int result = 0;
+	unsigned int speed;
+	cpumask_t cpus_allowed,affected_cpu_map;
 
 
 	/* capability check */
@@ -324,18 +338,16 @@
 				     &speedstep_freqs[SPEEDSTEP_LOW].frequency,
 				     &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
 				     &speedstep_set_state);
-	if (result) {
-		set_cpus_allowed(current, cpus_allowed);
+	set_cpus_allowed(current, cpus_allowed);
+	if (result)
 		return result;
-	}
 
 	/* get current speed setting */
-	speed = speedstep_get_processor_frequency(speedstep_processor);
-	set_cpus_allowed(current, cpus_allowed);
+	speed = speedstep_get(policy->cpu);
 	if (!speed)
 		return -EIO;
 
-	dprintk(KERN_INFO "cpufreq: currently at %s speed setting - %i MHz\n", 
+	dprintk(KERN_INFO "cpufreq: currently at %s speed setting - %i MHz\n",
 		(speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high",
 		(speed / 1000));
 
@@ -360,11 +372,6 @@
 	return 0;
 }
 
-static unsigned int speedstep_get(unsigned int cpu)
-{
-	return speedstep_get_processor_frequency(speedstep_processor);
-}
-
 static struct freq_attr* speedstep_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
 	NULL,
@@ -372,14 +379,14 @@
 
 
 static struct cpufreq_driver speedstep_driver = {
-	.name		= "speedstep-ich",
-	.verify 	= speedstep_verify,
-	.target 	= speedstep_target,
-	.init		= speedstep_cpu_init,
-	.exit		= speedstep_cpu_exit,
-	.get		= speedstep_get,
-	.owner		= THIS_MODULE,
-	.attr		= speedstep_attr,
+	.name	= "speedstep-ich",
+	.verify	= speedstep_verify,
+	.target	= speedstep_target,
+	.init	= speedstep_cpu_init,
+	.exit	= speedstep_cpu_exit,
+	.get	= speedstep_get,
+	.owner	= THIS_MODULE,
+	.attr	= speedstep_attr,
 };
 
 
diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c	2004-08-08 12:43:24 -07:00
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c	2004-08-08 12:43:24 -07:00
@@ -115,6 +115,11 @@
 		: "=a" (result), "=b" (high_mhz), "=c" (low_mhz), "=d" (state), "=D" (edi)
 		: "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0)
 	);
+
+	/* abort if results are obviously incorrect... */
+	if ((high_mhz + low_mhz) < 600)
+		return -EINVAL;
+
 	*high = high_mhz * 1000;
 	*low  = low_mhz  * 1000;
 
@@ -180,7 +185,7 @@
 	local_irq_restore(flags);
 
 	if (new_state == state) {
-		dprintk(KERN_INFO "cpufreq: change to %u MHz succeeded after %u tries with result %u\n", (freqs.new / 1000), retry, result);
+		dprintk(KERN_INFO "cpufreq: 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);
 	}
diff -Nru a/arch/x86_64/kernel/cpufreq/Kconfig b/arch/x86_64/kernel/cpufreq/Kconfig
--- a/arch/x86_64/kernel/cpufreq/Kconfig	2004-08-08 12:43:24 -07:00
+++ b/arch/x86_64/kernel/cpufreq/Kconfig	2004-08-08 12:43:24 -07:00
@@ -41,4 +41,9 @@
 
 	  If in doubt, say N.
 
+config X86_POWERNOW_K8_ACPI
+	bool
+	depends on ((X86_POWERNOW_K8 = "m" && ACPI_PROCESSOR) || (X86_POWERNOW_K8 = "y" && ACPI_PROCESSOR = "y"))
+	default y
+
 endmenu
diff -Nru a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
--- a/drivers/cpufreq/cpufreq.c	2004-08-08 12:43:24 -07:00
+++ b/drivers/cpufreq/cpufreq.c	2004-08-08 12:43:24 -07:00
@@ -100,6 +100,88 @@
 }
 
 /*********************************************************************
+ *            EXTERNALLY AFFECTING FREQUENCY CHANGES                 *
+ *********************************************************************/
+
+/**
+ * adjust_jiffies - adjust the system "loops_per_jiffy"
+ *
+ * This function alters the system "loops_per_jiffy" for the clock
+ * speed change. Note that loops_per_jiffy cannot be updated on SMP
+ * systems as each CPU might be scaled differently. So, use the arch 
+ * per-CPU loops_per_jiffy value wherever possible.
+ */
+#ifndef CONFIG_SMP
+static unsigned long l_p_j_ref;
+static unsigned int  l_p_j_ref_freq;
+
+static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
+{
+	if (ci->flags & CPUFREQ_CONST_LOOPS)
+		return;
+
+	if (!l_p_j_ref_freq) {
+		l_p_j_ref = loops_per_jiffy;
+		l_p_j_ref_freq = ci->old;
+	}
+	if ((val == CPUFREQ_PRECHANGE  && ci->old < ci->new) ||
+	    (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) ||
+	    (val == CPUFREQ_RESUMECHANGE))
+		loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new);
+}
+#else
+static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) { return; }
+#endif
+
+
+/**
+ * cpufreq_notify_transition - call notifier chain and adjust_jiffies on frequency transition
+ *
+ * This function calls the transition notifiers and the "adjust_jiffies" function. It is called
+ * twice on all CPU frequency changes that have external effects. 
+ */
+void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
+{
+	BUG_ON(irqs_disabled());
+
+	freqs->flags = cpufreq_driver->flags;
+
+	down_read(&cpufreq_notifier_rwsem);
+	switch (state) {
+	case CPUFREQ_PRECHANGE:
+		/* detect if the driver reported a value as "old frequency" which
+		 * is not equal to what the cpufreq core thinks is "old frequency".
+		 */
+		if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
+			if ((likely(cpufreq_cpu_data[freqs->cpu])) &&
+			    (likely(cpufreq_cpu_data[freqs->cpu]->cur)) &&
+			    (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur)))
+			{
+				if (cpufreq_driver->flags & CPUFREQ_PANIC_OUTOFSYNC)
+					panic("CPU Frequency is out of sync.");
+
+				printk(KERN_WARNING "Warning: CPU frequency is %u, "
+				       "cpufreq assumed %u kHz.\n", freqs->old, cpufreq_cpu_data[freqs->cpu]->cur);
+				freqs->old = cpufreq_cpu_data[freqs->cpu]->cur;
+			}
+		}
+		notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_PRECHANGE, freqs);
+		adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
+		break;
+	case CPUFREQ_POSTCHANGE:
+		adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
+		notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs);
+		if (likely(cpufreq_cpu_data[freqs->cpu]))
+			cpufreq_cpu_data[freqs->cpu]->cur = freqs->new;
+		break;
+	}
+	up_read(&cpufreq_notifier_rwsem);
+}
+EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
+
+
+
+/*********************************************************************
  *                          SYSFS INTERFACE                          *
  *********************************************************************/
 
@@ -617,8 +699,8 @@
 			if (cpufreq_driver->flags & CPUFREQ_PANIC_RESUME_OUTOFSYNC)
 				panic("CPU Frequency is out of sync.");
 
-			printk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing"
-			       "core thinks of %u, is %u kHz.\n", cpu_policy->cur, cur_freq);
+			printk(KERN_WARNING "Warning: CPU frequency is %u, "
+			       "cpufreq assumed %u kHz.\n", cur_freq, cpu_policy->cur);
 
 			freqs.cpu = cpu;
 			freqs.old = cpu_policy->cur;
@@ -626,6 +708,8 @@
 
 			notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_RESUMECHANGE, &freqs);
 			adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs);
+
+			cpu_policy->cur = cur_freq;
 		}
 	}
 
@@ -1003,87 +1087,6 @@
 	return ret;
 }
 EXPORT_SYMBOL(cpufreq_update_policy);
-
-
-/*********************************************************************
- *            EXTERNALLY AFFECTING FREQUENCY CHANGES                 *
- *********************************************************************/
-
-/**
- * adjust_jiffies - adjust the system "loops_per_jiffy"
- *
- * This function alters the system "loops_per_jiffy" for the clock
- * speed change. Note that loops_per_jiffy cannot be updated on SMP
- * systems as each CPU might be scaled differently. So, use the arch 
- * per-CPU loops_per_jiffy value wherever possible.
- */
-#ifndef CONFIG_SMP
-static unsigned long l_p_j_ref;
-static unsigned int  l_p_j_ref_freq;
-
-static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
-{
-	if (ci->flags & CPUFREQ_CONST_LOOPS)
-		return;
-
-	if (!l_p_j_ref_freq) {
-		l_p_j_ref = loops_per_jiffy;
-		l_p_j_ref_freq = ci->old;
-	}
-	if ((val == CPUFREQ_PRECHANGE  && ci->old < ci->new) ||
-	    (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) ||
-	    (val == CPUFREQ_RESUMECHANGE))
-		loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new);
-}
-#else
-static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) { return; }
-#endif
-
-
-/**
- * cpufreq_notify_transition - call notifier chain and adjust_jiffies on frequency transition
- *
- * This function calls the transition notifiers and the "adjust_jiffies" function. It is called
- * twice on all CPU frequency changes that have external effects. 
- */
-void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
-{
-	BUG_ON(irqs_disabled());
-
-	freqs->flags = cpufreq_driver->flags;
-
-	down_read(&cpufreq_notifier_rwsem);
-	switch (state) {
-	case CPUFREQ_PRECHANGE:
-		/* detect if the driver reported a value as "old frequency" which
-		 * is not equal to what the cpufreq core thinks is "old frequency".
-		 */
-		if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
-			if ((likely(cpufreq_cpu_data[freqs->cpu]->cur)) &&
-			    (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur)))
-			{
-				if (cpufreq_driver->flags & CPUFREQ_PANIC_OUTOFSYNC)
-					panic("CPU Frequency is out of sync.");
-
-				printk(KERN_WARNING "Warning: CPU frequency out of sync: "
-				       "cpufreq and timing core thinks of %u, is %u kHz.\n", 
-				       cpufreq_cpu_data[freqs->cpu]->cur, freqs->old);
-				freqs->old = cpufreq_cpu_data[freqs->cpu]->cur;
-			}
-		}
-		notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_PRECHANGE, freqs);
-		adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
-		break;
-	case CPUFREQ_POSTCHANGE:
-		adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
-		notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs);
-		cpufreq_cpu_data[freqs->cpu]->cur = freqs->new;
-		break;
-	}
-	up_read(&cpufreq_notifier_rwsem);
-}
-EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
-
 
 
 /*********************************************************************
diff -Nru a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
--- a/drivers/cpufreq/cpufreq_userspace.c	2004-08-08 12:43:24 -07:00
+++ b/drivers/cpufreq/cpufreq_userspace.c	2004-08-08 12:43:24 -07:00
@@ -82,6 +82,13 @@
 {
         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;
+
 	cpu_cur_freq[freq->cpu] = freq->new;
 
         return 0;
@@ -521,6 +528,9 @@
 			      CPUFREQ_RELATION_H);
 		else if (policy->min > cpu_cur_freq[cpu])
 			__cpufreq_driver_target(&current_policy[cpu], policy->min, 
+			      CPUFREQ_RELATION_L);
+		else
+			__cpufreq_driver_target(&current_policy[cpu], cpu_cur_freq[cpu],
 			      CPUFREQ_RELATION_L);
 		memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
 		up(&userspace_sem);
diff -Nru a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
--- a/include/asm-i386/acpi.h	2004-08-08 12:43:24 -07:00
+++ b/include/asm-i386/acpi.h	2004-08-08 12:43:24 -07:00
@@ -101,6 +101,11 @@
         :"=r"(n_hi), "=r"(n_lo)     \
         :"0"(n_hi), "1"(n_lo))
 
+/*
+ * Refer Intel ACPI _PDC support document for bit definitions
+ */
+#define ACPI_PDC_EST_CAPABILITY_SMP	0xa
+#define ACPI_PDC_EST_CAPABILITY_MSR	0x1
 
 #ifdef CONFIG_ACPI_BOOT 
 extern int acpi_lapic;