bk://linux-dj.bkbits.net/cpufreq davej@delerium.codemonkey.org.uk|ChangeSet|20040810010124|57948 davej # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/08/10 02:01:24+01:00 davej@delerium.codemonkey.org.uk # Cset exclude: davej@redhat.com|ChangeSet|20040809142517|56351 # # arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c # 2004/08/10 02:01:06+01:00 davej@delerium.codemonkey.org.uk +0 -0 # Exclude # # 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 # # 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 # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # ChangeSet # 2004/08/03 15:29:15+01:00 davej@redhat.com # [CPUFREQ] Whitespace cleanup for centrino speedstep. # # Signed-off-by: Dave Jones # # 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 # # 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" # Signed-off-by: Dave Jones # # 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" # Signed-off-by: Dave Jones # # 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" # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # ChangeSet # 2004/08/02 20:08:20+01:00 davej@redhat.com # [CPUFREQ] Longhaul compile fixes. # # Signed-off-by: Andrew Morton # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # # 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 # # 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 # # # 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 # # # 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 # # 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 # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # ChangeSet # 2004/07/08 14:08:47+01:00 davej@redhat.com # [CPUFREQ] fix whitespace after merge. # # Signed-off-by: Dave Jones # # 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 # # 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 # # 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 # # ChangeSet # 2004/07/05 01:34:47+01:00 davej@redhat.com # [CPUFREQ] REmove more trailing whitespace # # Signed-off-by: Dave Jones # # 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 # # 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 # # 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 # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # # 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 # # ChangeSet # 2004/07/03 17:17:16+01:00 davej@redhat.com # [CPUFREQ] Trailing whitespace removal in longrun driver. # # Signed-off-by: Dave Jones # # 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 # # ChangeSet # 2004/06/29 23:43:48+01:00 davej@redhat.com # [CPUFREQ] Fix sparse NULL ptr warning. # # Signed-off-by: Dave Jones # # 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 # # 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 # # 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 # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # 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-09 21:32:45 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/Kconfig 2004-08-09 21:32:45 -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 . 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-09 21:32:45 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c 2004-08-09 21:32:45 -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-09 21:32:45 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/longrun.c 2004-08-09 21:32:45 -07:00 @@ -7,7 +7,7 @@ */ #include -#include +#include #include #include #include @@ -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-09 21:32:45 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c 2004-08-09 21:32:45 -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 #include -#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE) +#ifdef CONFIG_X86_POWERNOW_K7_ACPI #include #include #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 "); 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-09 21:32:45 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c 2004-08-09 21:32:45 -07:00 @@ -32,7 +32,7 @@ #include #include -#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE) +#ifdef CONFIG_X86_POWERNOW_K8_ACPI #include #include #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-09 21:32:45 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2004-08-09 21:32:45 -07:00 @@ -10,7 +10,7 @@ * Copyright (C) 2003 Jeremy Fitzhardinge * * 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 #include +#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI +#include +#include +#endif + #include #include #include @@ -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 -#include - -#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; iop_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; iop_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-09 21:32:45 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c 2004-08-09 21:32:45 -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 -#include +#include #include #include #include @@ -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-09 21:32:45 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c 2004-08-09 21:32:45 -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-09 21:32:45 -07:00 +++ b/arch/x86_64/kernel/cpufreq/Kconfig 2004-08-09 21:32:45 -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-09 21:32:45 -07:00 +++ b/drivers/cpufreq/cpufreq.c 2004-08-09 21:32:45 -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-09 21:32:45 -07:00 +++ b/drivers/cpufreq/cpufreq_userspace.c 2004-08-09 21:32:45 -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(¤t_policy[cpu], policy->min, + CPUFREQ_RELATION_L); + else + __cpufreq_driver_target(¤t_policy[cpu], cpu_cur_freq[cpu], CPUFREQ_RELATION_L); memcpy (¤t_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-09 21:32:45 -07:00 +++ b/include/asm-i386/acpi.h 2004-08-09 21:32:45 -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;