bk://linux-dj.bkbits.net/cpufreq davej@redhat.com|ChangeSet|20040914204202|14090 davej # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/09/14 14:32:44-07:00 akpm@bix.(none) # Merge bk://linux-dj.bkbits.net/cpufreq # into bix.(none):/usr/src/bk-cpufreq # # drivers/cpufreq/cpufreq_userspace.c # 2004/09/14 14:32:40-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/arm/Kconfig # 2004/09/14 14:32:40-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/09/14 21:42:02+01:00 davej@redhat.com # [CPUFREQ][4/4] cpufreq "cpu group" awareness: remove FIXME in speedstep-ich # # Remove the FIXME in speedstep-ich. # # arch/i386/kernel/cpu/cpufreq/speedstep-ich.c | 8 ++------ # 1 files changed, 2 insertions(+), 6 deletions(-) # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # arch/i386/kernel/cpu/cpufreq/speedstep-ich.c # 2004/09/14 21:41:11+01:00 davej@redhat.com +2 -6 # [CPUFREQ][4/4] cpufreq "cpu group" awareness: remove FIXME in speedstep-ich # # Remove the FIXME in speedstep-ich. # # arch/i386/kernel/cpu/cpufreq/speedstep-ich.c | 8 ++------ # 1 files changed, 2 insertions(+), 6 deletions(-) # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # ChangeSet # 2004/09/14 21:39:24+01:00 davej@redhat.com # [CPUFREQ][3/4] cpufreq "cpu group" awareness: do symlinks for other CPUs instead of registering kobjects # # Only register each "affected_cpu_mask" once, and do symlinks for those # CPUs not directly registered to the driver model. # # Zwane Mwaikambo tested it, and here is the result: # # root@morocco cpu {0:0} pwd # /sys/devices/system/cpu # root@morocco cpu {0:0} tree # . # |-- cpu0 # | |-- cpufreq # | | |-- cpuinfo_cur_freq # | | |-- ... # | | -- scaling_setspeed # | -- online # -- cpu1 # |-- cpufreq -> ../../../../devices/system/cpu/cpu0/cpufreq # -- online # # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # drivers/cpufreq/cpufreq.c # 2004/09/14 21:38:48+01:00 davej@redhat.com +77 -7 # [CPUFREQ][3/4] cpufreq "cpu group" awareness: do symlinks for other CPUs instead of registering kobjects # # Only register each "affected_cpu_mask" once, and do symlinks for those # CPUs not directly registered to the driver model. # # Zwane Mwaikambo tested it, and here is the result: # # root@morocco cpu {0:0} pwd # /sys/devices/system/cpu # root@morocco cpu {0:0} tree # . # |-- cpu0 # | |-- cpufreq # | | |-- cpuinfo_cur_freq # | | |-- ... # | | -- scaling_setspeed # | -- online # -- cpu1 # |-- cpufreq -> ../../../../devices/system/cpu/cpu0/cpufreq # -- online # # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # ChangeSet # 2004/09/14 21:37:00+01:00 davej@redhat.com # [CPUFREQ][2/4] cpufreq "cpu group" awareness: save sysdev for all CPUs # # Save a copy of each CPU's struct sys_device in drivers/cpufreq/cpufreq.c # so that symlinks can be removed even outside the specific sys_device's # ->remove() function. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # drivers/cpufreq/cpufreq.c # 2004/09/14 21:35:46+01:00 davej@redhat.com +11 -0 # [CPUFREQ][2/4] cpufreq "cpu group" awareness: save sysdev for all CPUs # # Save a copy of each CPU's struct sys_device in drivers/cpufreq/cpufreq.c # so that symlinks can be removed even outside the specific sys_device's # ->remove() function. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # ChangeSet # 2004/09/14 21:34:11+01:00 davej@redhat.com # [CPUFREQ][1/4] cpufreq "cpu group" awareness: add policy->cpus # # Save the "affected_cpu_map" used in SMT-aware drivers in struct # cpufreq_policy->(cpumask_t) cpus, and use it wherever possible. In # most cases, the ->get() function is only allowed to run on one CPU [the # one passed as argument] to keep code simpler, and as that code path # isn't executed often, and only root can do it anyway. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # include/linux/cpufreq.h # 2004/09/14 21:33:41+01:00 davej@redhat.com +3 -1 # [CPUFREQ][1/4] cpufreq "cpu group" awareness: add policy->cpus # # Save the "affected_cpu_map" used in SMT-aware drivers in struct # cpufreq_policy->(cpumask_t) cpus, and use it wherever possible. In # most cases, the ->get() function is only allowed to run on one CPU [the # one passed as argument] to keep code simpler, and as that code path # isn't executed often, and only root can do it anyway. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # drivers/cpufreq/cpufreq.c # 2004/09/14 21:33:41+01:00 davej@redhat.com +2 -0 # [CPUFREQ][1/4] cpufreq "cpu group" awareness: add policy->cpus # # Save the "affected_cpu_map" used in SMT-aware drivers in struct # cpufreq_policy->(cpumask_t) cpus, and use it wherever possible. In # most cases, the ->get() function is only allowed to run on one CPU [the # one passed as argument] to keep code simpler, and as that code path # isn't executed often, and only root can do it anyway. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # arch/i386/kernel/cpu/cpufreq/speedstep-ich.c # 2004/09/14 21:33:41+01:00 davej@redhat.com +18 -28 # [CPUFREQ][1/4] cpufreq "cpu group" awareness: add policy->cpus # # Save the "affected_cpu_map" used in SMT-aware drivers in struct # cpufreq_policy->(cpumask_t) cpus, and use it wherever possible. In # most cases, the ->get() function is only allowed to run on one CPU [the # one passed as argument] to keep code simpler, and as that code path # isn't executed often, and only root can do it anyway. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c # 2004/09/14 21:33:41+01:00 davej@redhat.com +1 -1 # [CPUFREQ][1/4] cpufreq "cpu group" awareness: add policy->cpus # # Save the "affected_cpu_map" used in SMT-aware drivers in struct # cpufreq_policy->(cpumask_t) cpus, and use it wherever possible. In # most cases, the ->get() function is only allowed to run on one CPU [the # one passed as argument] to keep code simpler, and as that code path # isn't executed often, and only root can do it anyway. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # arch/i386/kernel/cpu/cpufreq/p4-clockmod.c # 2004/09/14 21:33:41+01:00 davej@redhat.com +13 -19 # [CPUFREQ][1/4] cpufreq "cpu group" awareness: add policy->cpus # # Save the "affected_cpu_map" used in SMT-aware drivers in struct # cpufreq_policy->(cpumask_t) cpus, and use it wherever possible. In # most cases, the ->get() function is only allowed to run on one CPU [the # one passed as argument] to keep code simpler, and as that code path # isn't executed often, and only root can do it anyway. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # ChangeSet # 2004/09/14 21:32:02+01:00 davej@redhat.com # [CPUFREQ] remove double calls to module_get/put in userspace governor # # The cpufreq core properly gets and puts the modules it calls, including # governors. So there's no need to keep the racy in-module calls in # cpufreq_userspace denoting otherwise. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # drivers/cpufreq/cpufreq_userspace.c # 2004/09/14 21:31:09+01:00 davej@redhat.com +1 -2 # [CPUFREQ] remove double calls to module_get/put in userspace governor # # The cpufreq core properly gets and puts the modules it calls, including # governors. So there's no need to keep the racy in-module calls in # cpufreq_userspace denoting otherwise. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # ChangeSet # 2004/09/14 21:29:55+01:00 davej@redhat.com # [CPUFREQ] speedstep-centrino should only decode MSR on certain CPUs # # The encoding of the MSR only works as described in extract_clock() on # certain EST-enabled CPUs. So, limit the actual MSR check to these CPUs. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c # 2004/09/14 21:28:38+01:00 davej@redhat.com +5 -3 # [CPUFREQ] speedstep-centrino should only decode MSR on certain CPUs # # The encoding of the MSR only works as described in extract_clock() on # certain EST-enabled CPUs. So, limit the actual MSR check to these CPUs. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # ChangeSet # 2004/09/14 21:22:09+01:00 davej@redhat.com # [CPUFREQ] core Kconfig fix # # cpufreq core Kconfig fix: # - 24_API is a part of the userspace governor, so keep it directly below the userspace governor # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # drivers/cpufreq/Kconfig # 2004/09/14 21:21:31+01:00 davej@redhat.com +15 -14 # [CPUFREQ] core Kconfig fix # # cpufreq core Kconfig fix: # - 24_API is a part of the userspace governor, so keep it directly below the userspace governor # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # ChangeSet # 2004/09/14 21:20:00+01:00 davej@redhat.com # [CPUFREQ] arm Kconfig fixes # # arm cpufreq Kconfig enhancements: # - don't force the deprecated 24_API on SA11x0 any more, as it will be removed # ~2005-01-01 and different interfaces have been available for a long time # - don't mark CPU_FREQ as being EXPERIMENTAL any longer # - re-order it in the same way other arches are ordered # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # arch/arm/Kconfig # 2004/09/14 21:18:33+01:00 davej@redhat.com +4 -10 # [CPUFREQ] arm Kconfig fixes # # arm cpufreq Kconfig enhancements: # - don't force the deprecated 24_API on SA11x0 any more, as it will be removed # ~2005-01-01 and different interfaces have been available for a long time # - don't mark CPU_FREQ as being EXPERIMENTAL any longer # - re-order it in the same way other arches are ordered # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # ChangeSet # 2004/09/14 21:09:56+01:00 davej@redhat.com # [CPUFREQ] x86_64 Kconfig fixes # # x86_64 cpufreq Kconfig fixes: # - SPEEDSTEP_CENTRINO _needs_ the ACPI perflib as the tables are for # Banias only, and the Banias is only 32bit # - SPEEDSTEP_CENTRINO_TABLE won't be built in any longer as it only wastes space # - /proc/acpi/processor/../performance is available for all ACPI perflib drivers # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # arch/x86_64/kernel/cpufreq/Kconfig # 2004/09/14 21:00:44+01:00 davej@redhat.com +7 -13 # [CPUFREQ] x86_64 Kconfig fixes # # x86_64 cpufreq Kconfig fixes: # - SPEEDSTEP_CENTRINO _needs_ the ACPI perflib as the tables are for # Banias only, and the Banias is only 32bit # - SPEEDSTEP_CENTRINO_TABLE won't be built in any longer as it only wastes space # - /proc/acpi/processor/../performance is available for all ACPI perflib drivers # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # ChangeSet # 2004/09/14 20:52:52+01:00 davej@redhat.com # [CPUFREQ] i386 Kconfig fixes # # i386 cpufreq Kconfig fixes: # - /proc/acpi/processor/../performance is available for all ACPI perflib drivers # - powernow-k8 depends on FREQ_TABLE # - clarify the heavy dependency of SPEEDSTEP_CENTRINO on ACPI # - remove the EXPERIMENTAL tag of SPEEDSTEP_CENTRINO_ACPI # - allow to disable SPEEDSTEP_CENTRINO_TABLE # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # arch/i386/kernel/cpu/cpufreq/Kconfig # 2004/09/14 20:50:26+01:00 davej@redhat.com +51 -35 # [CPUFREQ] i386 Kconfig fixes # # i386 cpufreq Kconfig fixes: # - /proc/acpi/processor/../performance is available for all ACPI perflib drivers # - powernow-k8 depends on FREQ_TABLE # - clarify the heavy dependency of SPEEDSTEP_CENTRINO on ACPI # - remove the EXPERIMENTAL tag of SPEEDSTEP_CENTRINO_ACPI # - allow to disable SPEEDSTEP_CENTRINO_TABLE # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # ChangeSet # 2004/09/13 09:53:34+01:00 davej@redhat.com # [CPUFREQ] Fix numerous typos in drivers/cpufreq/Kconfig # # Signed-off-by: Dave Jones # # drivers/cpufreq/Kconfig # 2004/09/13 09:53:06+01:00 davej@redhat.com +5 -5 # [CPUFREQ] Fix numerous typos in drivers/cpufreq/Kconfig # # Signed-off-by: Dave Jones # # ChangeSet # 2004/09/10 14:20:20+01:00 davej@redhat.com # [CPUFREQ] Work around AMD64 2nd identical PST errata # # AMD recently errata'd the definition of the PSB/PST for recent Athlon 64 and Opteron parts. The errata # allows for a second, identical PST for those parts. # The current powernow-k8 driver will not work in PST/PSB mode on those parts because it requires # there be 1 and only 1 PST. # # From: Mark Langsdorf # Signed-off-by: Dave Jones # # arch/i386/kernel/cpu/cpufreq/powernow-k8.c # 2004/09/10 14:19:12+01:00 davej@redhat.com +11 -2 # [CPUFREQ] Work around AMD64 2nd identical PST errata # # AMD recently errata'd the definition of the PSB/PST for recent Athlon 64 and Opteron parts. The errata # allows for a second, identical PST for those parts. # The current powernow-k8 driver will not work in PST/PSB mode on those parts because it requires # there be 1 and only 1 PST. # # From: Mark Langsdorf # Signed-off-by: Dave Jones # # ChangeSet # 2004/09/08 11:45:22-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cpufreq # # arch/i386/kernel/smpboot.c # 2004/09/08 11:45:18-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/09/03 21:23:19+01:00 davej@redhat.com # [CPUFREQ] speedstep-smi: only allow it to run on mobile Intel Pentium III # # speedstep-smi only makes sense on Intel mobile Pentium III systems. # So, unify the distributed checks for speedstep_processor there, # and disallow P4s. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # arch/i386/kernel/cpu/cpufreq/speedstep-smi.c # 2004/09/03 21:23:10+01:00 davej@redhat.com +12 -13 # [CPUFREQ] speedstep-smi: only allow it to run on mobile Intel Pentium III # # speedstep-smi only makes sense on Intel mobile Pentium III systems. # So, unify the distributed checks for speedstep_processor there, # and disallow P4s. # # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # ChangeSet # 2004/08/25 14:07:34-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cpufreq # # arch/i386/kernel/smpboot.c # 2004/08/25 14:07:30-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/24 17:39:15-07:00 akpm@bix.(none) # Merge bk://linux-dj.bkbits.net/cpufreq # into bix.(none):/usr/src/bk-cpufreq # # include/asm-i386/acpi.h # 2004/08/24 17:39:11-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/cpufreq/cpufreq_userspace.c # 2004/08/24 17:39:11-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/smpboot.c # 2004/08/24 17:39:11-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/24 17:37:54-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cpufreq # # arch/i386/kernel/smpboot.c # 2004/08/24 17:37:47-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/23 13:53:34-07:00 akpm@bix.(none) # Merge bk://linux-dj.bkbits.net/cpufreq # into bix.(none):/usr/src/bk-cpufreq # # include/asm-i386/acpi.h # 2004/08/23 13:53:31-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/cpufreq/cpufreq_userspace.c # 2004/08/23 13:53:31-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/smpboot.c # 2004/08/23 13:53:31-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/22 21:09:40-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cpufreq # # include/asm-i386/acpi.h # 2004/08/22 21:09:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # drivers/cpufreq/cpufreq_userspace.c # 2004/08/22 21:09:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # arch/i386/kernel/smpboot.c # 2004/08/22 21:09:36-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/20 02:10:39-07:00 akpm@bix.(none) # Merge bk://linux-dj.bkbits.net/cpufreq # into bix.(none):/usr/src/bk-cpufreq # # drivers/cpufreq/cpufreq_userspace.c # 2004/08/20 02:10:35-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/17 14:12:14-07:00 akpm@bix.(none) # Merge bk://linux-dj.bkbits.net/cpufreq # into bix.(none):/usr/src/bk-cpufreq # # arch/i386/kernel/smpboot.c # 2004/08/17 14:12:10-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/15 01:01:43-07:00 akpm@bix.(none) # Merge bk://linux-dj.bkbits.net/cpufreq # into bix.(none):/usr/src/bk-cpufreq # # drivers/cpufreq/cpufreq_userspace.c # 2004/08/15 01:01:40-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/08/15 01:00:46-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cpufreq # # include/asm-i386/acpi.h # 2004/08/15 01:00:42-07:00 akpm@bix.(none) +0 -0 # Auto merged # # 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 # diff -Nru a/arch/arm/Kconfig b/arch/arm/Kconfig --- a/arch/arm/Kconfig 2004-10-01 19:15:57 -07:00 +++ b/arch/arm/Kconfig 2004-10-01 19:15:57 -07:00 @@ -348,9 +348,10 @@ while the decompressor is running. Unless you have special requirements, you should not change this value. +if (ARCH_SA1100 || ARCH_INTEGRATOR) + config CPU_FREQ - bool "Support CPU clock change (EXPERIMENTAL)" - depends on (ARCH_SA1100 || ARCH_INTEGRATOR) && EXPERIMENTAL + bool "Support CPU clock change" help CPU clock scaling allows you to change the clock speed of the running CPU on the fly. This is a nice method to save battery power, @@ -360,20 +361,17 @@ written) to implement the policy. If you don't understand what this is all about, it's safe to say 'N'. - -# CPUfreq on SA11x0 is special -- it _needs_ the userspace governor +source "drivers/cpufreq/Kconfig" config CPU_FREQ_SA1100 bool depends on CPU_FREQ && SA1100_LART default y - select CPU_FREQ_24_API if SYSCTL config CPU_FREQ_SA1110 bool depends on CPU_FREQ && (SA1100_ASSABET || SA1100_CERF || SA1100_PT_SYSTEM3) default y - select CPU_FREQ_24_API if SYSCTL config CPU_FREQ_INTEGRATOR tristate "CPUfreq driver for ARM Integrator CPUs" @@ -385,10 +383,6 @@ For details, take a look at . If in doubt, say Y. - -if (CPU_FREQ_INTEGRATOR) || (CPU_FREQ_SA1110) || (CPU_FREQ_SA1100) - -source "drivers/cpufreq/Kconfig" endif diff -Nru a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig --- a/arch/i386/kernel/cpu/cpufreq/Kconfig 2004-10-01 19:15:57 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/Kconfig 2004-10-01 19:15:57 -07:00 @@ -42,16 +42,6 @@ If in doubt, say N. -config X86_ACPI_CPUFREQ_PROC_INTF - bool "/proc/acpi/processor/../performance interface (deprecated)" - depends on X86_ACPI_CPUFREQ && PROC_FS - help - This enables the deprecated /proc/acpi/processor/../performance - interface. While it is helpful for debugging, the generic, - cross-architecture cpufreq interfaces should be used. - - If in doubt, say N. - config ELAN_CPUFREQ tristate "AMD Elan" depends on CPU_FREQ_TABLE && X86_ELAN @@ -95,7 +85,7 @@ config X86_POWERNOW_K8 tristate "AMD Opteron/Athlon64 PowerNow!" - depends on CPU_FREQ && EXPERIMENTAL + depends on CPU_FREQ_TABLE && EXPERIMENTAL help This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors. @@ -122,29 +112,40 @@ config X86_SPEEDSTEP_CENTRINO tristate "Intel Enhanced SpeedStep" depends on CPU_FREQ_TABLE + select X86_SPEEDSTEP_CENTRINO_TABLE if (!X86_SPEEDSTEP_CENTRINO_ACPI) help This adds the CPUFreq driver for Enhanced SpeedStep enabled - mobile CPUs. This means Intel Pentium M (Centrino) CPUs. + mobile CPUs. This means Intel Pentium M (Centrino) CPUs. However, + you also need to say Y to "Use ACPI tables to decode..." below + [which might imply enabling ACPI] if you want to use this driver + on non-Banias CPUs. For details, take a look at . If in doubt, say N. -config X86_SPEEDSTEP_CENTRINO_TABLE - bool - depends on X86_SPEEDSTEP_CENTRINO - default y - config X86_SPEEDSTEP_CENTRINO_ACPI - bool "Use ACPI tables to decode valid frequency/voltage pairs (EXPERIMENTAL)" - depends on EXPERIMENTAL + bool "Use ACPI tables to decode valid frequency/voltage pairs" + depends on X86_SPEEDSTEP_CENTRINO depends on ((X86_SPEEDSTEP_CENTRINO = "m" && ACPI_PROCESSOR) || (X86_SPEEDSTEP_CENTRINO = "y" && ACPI_PROCESSOR = "y")) + default y help Use primarily the information provided in the BIOS ACPI tables - to determine valid CPU frequency and voltage pairings. + to determine valid CPU frequency and voltage pairings. It is + required for the driver to work on non-Banias CPUs. If in doubt, say Y. +config X86_SPEEDSTEP_CENTRINO_TABLE + bool "Built-in tables for Banias CPUs" + depends on X86_SPEEDSTEP_CENTRINO + default y + help + Use built-in tables for Banias CPUs if ACPI encoding + is not available. + + If in doubt, say N. + config X86_SPEEDSTEP_ICH tristate "Intel Speedstep on ICH-M chipsets (ioport interface)" depends on CPU_FREQ_TABLE @@ -181,21 +182,6 @@ If in doubt, say N. -config X86_SPEEDSTEP_LIB - tristate - depends on (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD) - default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD) - -config X86_SPEEDSTEP_RELAXED_CAP_CHECK - bool "Relaxed speedstep capability checks" - depends on (X86_SPEEDSTEP_SMI || X86_SPEEDSTEP_ICH) - help - Don't perform all checks for a speedstep capable system which would - normally be done. Some ancient or strange systems, though speedstep - capable, don't always indicate that they are speedstep capable. This - option let's the probing code bypass some of those checks if the - parameter "relaxed_check=1" is passed to the module. - config X86_LONGRUN tristate "Transmeta LongRun" depends on CPU_FREQ @@ -218,5 +204,35 @@ For details, take a look at . If in doubt, say N. + +comment "shared options" + depends on CPU_FREQ + +config X86_ACPI_CPUFREQ_PROC_INTF + bool "/proc/acpi/processor/../performance interface (deprecated)" + depends on PROC_FS + depends on X86_ACPI_CPUFREQ || X86_SPEEDSTEP_CENTRINO_ACPI || X86_POWERNOW_K7_ACPI || X86_POWERNOW_K8_ACPI + help + This enables the deprecated /proc/acpi/processor/../performance + interface. While it is helpful for debugging, the generic, + cross-architecture cpufreq interfaces should be used. + + If in doubt, say N. + +config X86_SPEEDSTEP_LIB + tristate + depends on (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD) + default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD) + +config X86_SPEEDSTEP_RELAXED_CAP_CHECK + bool "Relaxed speedstep capability checks" + depends on (X86_SPEEDSTEP_SMI || X86_SPEEDSTEP_ICH) + help + Don't perform all checks for a speedstep capable system which would + normally be done. Some ancient or strange systems, though speedstep + capable, don't always indicate that they are speedstep capable. This + option lets the probing code bypass some of those checks if the + parameter "relaxed_check=1" is passed to the module. + endmenu diff -Nru a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c --- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c 2004-10-01 19:15:57 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c 2004-10-01 19:15:57 -07:00 @@ -110,7 +110,7 @@ { unsigned int newstate = DC_RESV; struct cpufreq_freqs freqs; - cpumask_t cpus_allowed, affected_cpu_map; + cpumask_t cpus_allowed; int i; if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0], target_freq, relation, &newstate)) @@ -122,18 +122,8 @@ if (freqs.new == freqs.old) return 0; - /* switch to physical CPU where state is to be changed*/ - cpus_allowed = current->cpus_allowed; - - /* only run on CPU to be set, or on its sibling */ -#ifdef CONFIG_SMP - affected_cpu_map = cpu_sibling_map[policy->cpu]; -#else - affected_cpu_map = cpumask_of_cpu(policy->cpu); -#endif - /* notifiers */ - for_each_cpu_mask(i, affected_cpu_map) { + for_each_cpu_mask(i, policy->cpus) { freqs.cpu = i; cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); } @@ -141,7 +131,9 @@ /* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software * Developer's Manual, Volume 3 */ - for_each_cpu_mask(i, affected_cpu_map) { + cpus_allowed = current->cpus_allowed; + + for_each_cpu_mask(i, policy->cpus) { cpumask_t this_cpu = cpumask_of_cpu(i); set_cpus_allowed(current, this_cpu); @@ -152,7 +144,7 @@ set_cpus_allowed(current, cpus_allowed); /* notifiers */ - for_each_cpu_mask(i, affected_cpu_map) { + for_each_cpu_mask(i, policy->cpus) { freqs.cpu = i; cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); } @@ -219,6 +211,10 @@ int cpuid = 0; unsigned int i; +#ifdef CONFIG_SMP + policy->cpus = cpu_sibling_map[policy->cpu]; +#endif + /* Errata workaround */ cpuid = (c->x86 << 8) | (c->x86_model << 4) | c->x86_mask; switch (cpuid) { @@ -260,14 +256,13 @@ static unsigned int cpufreq_p4_get(unsigned int cpu) { - cpumask_t cpus_allowed, affected_cpu_map; + cpumask_t cpus_allowed; u32 l, h; cpus_allowed = current->cpus_allowed; - affected_cpu_map = cpumask_of_cpu(cpu); - set_cpus_allowed(current, affected_cpu_map); - BUG_ON(!cpu_isset(smp_processor_id(), affected_cpu_map)); + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + BUG_ON(smp_processor_id() != cpu); rdmsr(MSR_IA32_THERM_CONTROL, l, h); @@ -335,4 +330,3 @@ late_initcall(cpufreq_p4_init); module_exit(cpufreq_p4_exit); - 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-10-01 19:15:57 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c 2004-10-01 19:15:57 -07:00 @@ -39,7 +39,7 @@ #define PFX "powernow-k8: " #define BFX PFX "BIOS error: " -#define VERSION "version 1.00.09b" +#define VERSION "version 1.00.09e" #include "powernow-k8.h" /* serialize freq changes */ @@ -596,6 +596,8 @@ unsigned int i; u32 mvs; u8 maxvid; + u32 cpst = 0; + u32 thiscpuid; for (i = 0xc0000; i < 0xffff0; i += 0x10) { /* Scan BIOS looking for the signature. */ @@ -634,7 +636,14 @@ dprintk(KERN_INFO PFX "maximum voltage step: %d - 0x%x\n", mvs, data->vidmvs); dprintk(KERN_DEBUG PFX "numpst: 0x%x\n", psb->numpst); - if (psb->numpst != 1) { + cpst = psb->numpst; + if ((psb->cpuid == 0x00000fc0) || (psb->cpuid == 0x00000fe0) ){ + thiscpuid = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); + if ((thiscpuid == 0x00000fc0) || (thiscpuid == 0x00000fe0) ) { + cpst = 1; + } + } + if (cpst != 1) { printk(KERN_ERR BFX "numpst must be 1\n"); return -ENODEV; } 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-10-01 19:15:57 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2004-10-01 19:15:57 -07:00 @@ -77,7 +77,7 @@ /* Operating points for current CPU */ static struct cpu_model *centrino_model; -static int centrino_cpu; +static const struct cpu_id *centrino_cpu; #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE @@ -289,7 +289,9 @@ * for centrino, as some DSDTs are buggy. * Ideally, this can be done using the acpi_data structure. */ - if (centrino_cpu) { + if ((centrino_cpu == &cpu_ids[CPU_BANIAS]) || + (centrino_cpu == &cpu_ids[CPU_DOTHAN_A1]) || + (centrino_cpu == &cpu_ids[CPU_DOTHAN_B0])) { msr = (msr >> 8) & 0xff; return msr * 100000; } @@ -457,7 +459,7 @@ break; if (i != N_IDS) - centrino_cpu = 1; + centrino_cpu = &cpu_ids[i]; if (centrino_cpu_init_acpi(policy)) { if (policy->cpu != 0) @@ -567,7 +569,7 @@ * 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)); + set_cpus_allowed(current, policy->cpus); if (smp_processor_id() != policy->cpu) { return(-EAGAIN); } 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-10-01 19:15:57 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c 2004-10-01 19:15:57 -07:00 @@ -223,24 +223,23 @@ return 0; } -static unsigned int speedstep_get(unsigned int cpu) +static unsigned int _speedstep_get(cpumask_t cpus) { unsigned int speed; - cpumask_t cpus_allowed,affected_cpu_map; + cpumask_t cpus_allowed; - /* 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); + speed = speedstep_get_processor_frequency(speedstep_processor); set_cpus_allowed(current, cpus_allowed); return speed; } +static unsigned int speedstep_get(unsigned int cpu) +{ + return _speedstep_get(cpumask_of_cpu(cpu)); +} + /** * speedstep_target - set a new CPUFreq policy * @policy: new policy @@ -255,13 +254,13 @@ { unsigned int newstate = 0; struct cpufreq_freqs freqs; - cpumask_t cpus_allowed, affected_cpu_map; + cpumask_t cpus_allowed; int i; if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate)) return -EINVAL; - freqs.old = speedstep_get(policy->cpu); + freqs.old = _speedstep_get(policy->cpus); freqs.new = speedstep_freqs[newstate].frequency; freqs.cpu = policy->cpu; @@ -271,27 +270,20 @@ cpus_allowed = current->cpus_allowed; - /* only run on CPU to be set, or on its sibling */ -#ifdef CONFIG_SMP - affected_cpu_map = cpu_sibling_map[policy->cpu]; -#else - affected_cpu_map = cpumask_of_cpu(policy->cpu); -#endif - - for_each_cpu_mask(i, affected_cpu_map) { + for_each_cpu_mask(i, policy->cpus) { freqs.cpu = i; cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); } /* switch to physical CPU where state is to be changed */ - set_cpus_allowed(current, affected_cpu_map); + set_cpus_allowed(current, policy->cpus); speedstep_set_state(newstate); /* allow to be run on all CPUs */ set_cpus_allowed(current, cpus_allowed); - for_each_cpu_mask(i, affected_cpu_map) { + for_each_cpu_mask(i, policy->cpus) { freqs.cpu = i; cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); } @@ -317,21 +309,15 @@ { int result = 0; unsigned int speed; - cpumask_t cpus_allowed,affected_cpu_map; - - - /* capability check */ - if (policy->cpu != 0) /* FIXME: better support for SMT in cpufreq core. Up until then, it's better to register only one CPU */ - return -ENODEV; + cpumask_t cpus_allowed; /* 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[policy->cpu]; -#else - affected_cpu_map = cpumask_of_cpu(policy->cpu); + policy->cpus = cpu_sibling_map[policy->cpu]; #endif - set_cpus_allowed(current, affected_cpu_map); + + cpus_allowed = current->cpus_allowed; + set_cpus_allowed(current, policy->cpus); /* detect low and high frequency */ result = speedstep_get_freqs(speedstep_processor, @@ -343,7 +329,7 @@ return result; /* get current speed setting */ - speed = speedstep_get(policy->cpu); + speed = _speedstep_get(policy->cpus); if (!speed) return -EIO; 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-10-01 19:15:57 -07:00 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c 2004-10-01 19:15:57 -07:00 @@ -260,12 +260,6 @@ if (result) { /* fall back to speedstep_lib.c dection mechanism: try both states out */ dprintk(KERN_INFO PFX "could not detect low and high frequencies by SMI call.\n"); - if (!speedstep_processor) - speedstep_processor = speedstep_detect_processor(); - - if (!speedstep_processor) - return -ENODEV; - result = speedstep_get_freqs(speedstep_processor, &speedstep_freqs[SPEEDSTEP_LOW].frequency, &speedstep_freqs[SPEEDSTEP_HIGH].frequency, @@ -310,10 +304,6 @@ { if (cpu) return -ENODEV; - if (!speedstep_processor) - speedstep_processor = speedstep_detect_processor(); - if (!speedstep_processor) - return 0; return speedstep_get_processor_frequency(speedstep_processor); } @@ -354,10 +344,19 @@ */ static int __init speedstep_init(void) { - struct cpuinfo_x86 *c = cpu_data; + speedstep_processor = speedstep_detect_processor(); + + switch (speedstep_processor) { + case SPEEDSTEP_PROCESSOR_PIII_T: + case SPEEDSTEP_PROCESSOR_PIII_C: + case SPEEDSTEP_PROCESSOR_PIII_C_EARLY: + break; + default: + speedstep_processor = 0; + } - if (c->x86_vendor != X86_VENDOR_INTEL) { - printk (KERN_INFO PFX "No Intel CPU detected.\n"); + if (!speedstep_processor) { + dprintk (KERN_INFO PFX "No supported Intel CPU detected.\n"); return -ENODEV; } diff -Nru a/arch/x86_64/kernel/cpufreq/Kconfig b/arch/x86_64/kernel/cpufreq/Kconfig --- a/arch/x86_64/kernel/cpufreq/Kconfig 2004-10-01 19:15:57 -07:00 +++ b/arch/x86_64/kernel/cpufreq/Kconfig 2004-10-01 19:15:57 -07:00 @@ -48,7 +48,7 @@ config X86_SPEEDSTEP_CENTRINO tristate "Intel Enhanced SpeedStep" - depends on CPU_FREQ_TABLE + depends on CPU_FREQ_TABLE && ACPI_PROCESSOR help This adds the CPUFreq driver for Enhanced SpeedStep enabled mobile CPUs. This means Intel Pentium M (Centrino) CPUs @@ -58,21 +58,11 @@ If in doubt, say N. -config X86_SPEEDSTEP_CENTRINO_TABLE +config X86_SPEEDSTEP_CENTRINO_ACPI bool depends on X86_SPEEDSTEP_CENTRINO default y -config X86_SPEEDSTEP_CENTRINO_ACPI - bool "Use ACPI tables to decode valid frequency/voltage pairs (EXPERIMENTAL)" - depends on EXPERIMENTAL - depends on ((X86_SPEEDSTEP_CENTRINO = "m" && ACPI_PROCESSOR) || (X86_SPEEDSTEP_CENTRINO = "y" && ACPI_PROCESSOR = "y")) - help - Use primarily the information provided in the BIOS ACPI tables - to determine valid CPU frequency and voltage pairings. - - If in doubt, say Y. - config X86_ACPI_CPUFREQ tristate "ACPI Processor P-States driver" depends on CPU_FREQ_TABLE && ACPI_PROCESSOR @@ -84,9 +74,13 @@ If in doubt, say N. +comment "shared options" + depends on CPU_FREQ + config X86_ACPI_CPUFREQ_PROC_INTF bool "/proc/acpi/processor/../performance interface (deprecated)" - depends on X86_ACPI_CPUFREQ && PROC_FS + depends on PROC_FS + depends on X86_ACPI_CPUFREQ || X86_SPEEDSTEP_CENTRINO_ACPI || X86_POWERNOW_K8_ACPI help This enables the deprecated /proc/acpi/processor/../performance interface. While it is helpful for debugging, the generic, diff -Nru a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig --- a/drivers/cpufreq/Kconfig 2004-10-01 19:15:57 -07:00 +++ b/drivers/cpufreq/Kconfig 2004-10-01 19:15:57 -07:00 @@ -33,7 +33,7 @@ help Use the CPUFreq governor 'userspace' as default. This allows you to set the CPU frequency manually or when an userspace - programm shall be able to set the CPU dynamically without having + program shall be able to set the CPU dynamically without having to enable the userspace governor manually. endchoice @@ -42,7 +42,7 @@ tristate "'performance' governor" depends on CPU_FREQ help - This cpufreq governors set the frequency statically to the + This cpufreq governor sets the frequency statically to the highest available CPU frequency. If in doubt, say Y. @@ -51,7 +51,7 @@ tristate "'powersave' governor" depends on CPU_FREQ help - Theis cpufreq governors set the frequency statically to the + This cpufreq governor sets the frequency statically to the lowest available CPU frequency. If in doubt, say Y. @@ -61,14 +61,29 @@ depends on CPU_FREQ help Enable this cpufreq governor when you either want to set the - CPU frequency manually or when an userspace programm shall - be able to set the CPU dynamically, like on LART + CPU frequency manually or when an userspace program shall + be able to set the CPU dynamically, like on LART For details, take a look at . If in doubt, say Y. +config CPU_FREQ_24_API + bool "/proc/sys/cpu/ interface (2.4. / OLD)" + depends on CPU_FREQ_GOV_USERSPACE + depends on SYSCTL + help + This enables the /proc/sys/cpu/ sysctl interface for controlling + the CPUFreq,"userspace" governor. This is the same interface + as known from the 2.4.-kernel patches for CPUFreq, and offers + the same functionality as long as "userspace" is the + selected governor for the specified CPU. + + For details, take a look at . + + If in doubt, say N. + config CPU_FREQ_GOV_ONDEMAND tristate "'ondemand' cpufreq policy governor" depends on CPU_FREQ @@ -81,19 +96,5 @@ transitions). For details, take a look at linux/Documentation/cpu-freq. - - If in doubt, say N. - -config CPU_FREQ_24_API - bool "/proc/sys/cpu/ interface (2.4. / OLD)" - depends on CPU_FREQ && SYSCTL && CPU_FREQ_GOV_USERSPACE - help - This enables the /proc/sys/cpu/ sysctl interface for controlling - the CPUFreq,"userspace" governor. This is the same interface - as known from the 2.4.-kernel patches for CPUFreq, and offers - the same functionality as long as "userspace" is the - selected governor for the specified CPU. - - For details, take a look at . If in doubt, say N. diff -Nru a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c --- a/drivers/cpufreq/cpufreq.c 2004-10-01 19:15:57 -07:00 +++ b/drivers/cpufreq/cpufreq.c 2004-10-01 19:15:57 -07:00 @@ -33,6 +33,14 @@ static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS]; static spinlock_t cpufreq_driver_lock = SPIN_LOCK_UNLOCKED; + +/* we keep a copy of all ->add'ed CPU's struct sys_device here; + * as it is only accessed in ->add and ->remove, no lock or reference + * count is necessary. + */ +static struct sys_device *cpu_sys_devices[NR_CPUS]; + + /* internal prototypes */ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); static void handle_update(void *data); @@ -154,6 +162,7 @@ */ if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { if ((likely(cpufreq_cpu_data[freqs->cpu])) && + (likely(cpufreq_cpu_data[freqs->cpu]->cpu == freqs->cpu)) && (likely(cpufreq_cpu_data[freqs->cpu]->cur)) && (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur))) { @@ -168,7 +177,8 @@ 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])) + if ((likely(cpufreq_cpu_data[freqs->cpu])) && + (likely(cpufreq_cpu_data[freqs->cpu]->cpu == freqs->cpu))) cpufreq_cpu_data[freqs->cpu]->cur = freqs->new; break; } @@ -456,6 +466,18 @@ struct cpufreq_policy *policy; struct freq_attr **drv_attr; unsigned long flags; + unsigned int j; + +#ifdef CONFIG_SMP + /* check whether a different CPU already registered this + * CPU because it is in the same boat. */ + policy = cpufreq_cpu_get(cpu); + if (unlikely(policy)) { + cpu_sys_devices[cpu] = sys_dev; + sysfs_create_link(&sys_dev->kobj, &policy->kobj, "cpufreq"); + return 0; + } +#endif if (!try_module_get(cpufreq_driver->owner)) return -EINVAL; @@ -468,6 +490,8 @@ memset(policy, 0, sizeof(struct cpufreq_policy)); policy->cpu = cpu; + policy->cpus = cpumask_of_cpu(cpu); + init_MUTEX_LOCKED(&policy->lock); init_completion(&policy->kobj_unregister); INIT_WORK(&policy->update, handle_update, (void *)(long)cpu); @@ -502,7 +526,8 @@ sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); spin_lock_irqsave(&cpufreq_driver_lock, flags); - cpufreq_cpu_data[cpu] = policy; + for_each_cpu_mask(j, policy->cpus) + cpufreq_cpu_data[j] = policy; spin_unlock_irqrestore(&cpufreq_driver_lock, flags); policy->governor = NULL; /* to assure that the starting sequence is * run in cpufreq_set_policy */ @@ -515,12 +540,14 @@ goto err_out_unregister; module_put(cpufreq_driver->owner); + cpu_sys_devices[cpu] = sys_dev; return 0; err_out_unregister: spin_lock_irqsave(&cpufreq_driver_lock, flags); - cpufreq_cpu_data[cpu] = NULL; + for_each_cpu_mask(j, policy->cpus) + cpufreq_cpu_data[j] = NULL; spin_unlock_irqrestore(&cpufreq_driver_lock, flags); kobject_unregister(&policy->kobj); @@ -545,19 +572,69 @@ unsigned int cpu = sys_dev->id; unsigned long flags; struct cpufreq_policy *data; +#ifdef CONFIG_SMP + unsigned int j; +#endif spin_lock_irqsave(&cpufreq_driver_lock, flags); data = cpufreq_cpu_data[cpu]; if (!data) { spin_unlock_irqrestore(&cpufreq_driver_lock, flags); + cpu_sys_devices[cpu] = NULL; return -EINVAL; } cpufreq_cpu_data[cpu] = NULL; + + +#ifdef CONFIG_SMP + /* if this isn't the CPU which is the parent of the kobj, we + * only need to unlink, put and exit + */ + if (unlikely(cpu != data->cpu)) { + spin_unlock_irqrestore(&cpufreq_driver_lock, flags); + sysfs_remove_link(&sys_dev->kobj, "cpufreq"); + cpu_sys_devices[cpu] = NULL; + cpufreq_cpu_put(data); + return 0; + } +#endif + + cpu_sys_devices[cpu] = NULL; + + if (!kobject_get(&data->kobj)) { + spin_unlock_irqrestore(&cpufreq_driver_lock, flags); + return -EFAULT; + } + +#ifdef CONFIG_SMP + /* if we have other CPUs still registered, we need to unlink them, + * or else wait_for_completion below will lock up. Clean the + * cpufreq_cpu_data[] while holding the lock, and remove the sysfs + * links afterwards. + */ + if (unlikely(cpus_weight(data->cpus) > 1)) { + for_each_cpu_mask(j, data->cpus) { + if (j == cpu) + continue; + cpufreq_cpu_data[j] = NULL; + } + } + spin_unlock_irqrestore(&cpufreq_driver_lock, flags); - if (!kobject_get(&data->kobj)) - return -EFAULT; + if (unlikely(cpus_weight(data->cpus) > 1)) { + for_each_cpu_mask(j, data->cpus) { + if (j == cpu) + continue; + + sysfs_remove_link(&cpu_sys_devices[j]->kobj, "cpufreq"); + cpufreq_cpu_put(data); + } + } +#else + spin_unlock_irqrestore(&cpufreq_driver_lock, flags); +#endif if (cpufreq_driver->target) __cpufreq_governor(data, CPUFREQ_GOV_STOP); @@ -675,6 +752,12 @@ cpu_policy = cpufreq_cpu_get(cpu); if (!cpu_policy) return -EINVAL; + + /* only handle each CPU group once */ + if (unlikely(cpu_policy->cpu != cpu)) { + cpufreq_cpu_put(cpu_policy); + return 0; + } if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { unsigned int cur_freq = 0; diff -Nru a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c --- a/drivers/cpufreq/cpufreq_userspace.c 2004-10-01 19:15:57 -07:00 +++ b/drivers/cpufreq/cpufreq_userspace.c 2004-10-01 19:15:57 -07:00 @@ -515,7 +515,7 @@ unsigned int cpu = policy->cpu; switch (event) { case CPUFREQ_GOV_START: - if ((!cpu_online(cpu)) || (!try_module_get(THIS_MODULE))) + if (!cpu_online(cpu)) return -EINVAL; BUG_ON(!policy->cur); down(&userspace_sem); @@ -534,7 +534,6 @@ cpu_max_freq[cpu] = 0; sysfs_remove_file (&policy->kobj, &freq_attr_scaling_setspeed.attr); up(&userspace_sem); - module_put(THIS_MODULE); break; case CPUFREQ_GOV_LIMITS: down(&userspace_sem); diff -Nru a/include/linux/cpufreq.h b/include/linux/cpufreq.h --- a/include/linux/cpufreq.h 2004-10-01 19:15:57 -07:00 +++ b/include/linux/cpufreq.h 2004-10-01 19:15:57 -07:00 @@ -22,6 +22,7 @@ #include #include #include +#include #define CPUFREQ_NAME_LEN 16 @@ -69,7 +70,8 @@ }; struct cpufreq_policy { - unsigned int cpu; /* cpu nr */ + cpumask_t cpus; /* affected CPUs */ + unsigned int cpu; /* cpu nr of registered CPU */ struct cpufreq_cpuinfo cpuinfo;/* see above */ unsigned int min; /* in kHz */