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

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/12/29 18:00:53-08:00 akpm@bix.(none) 
#   Merge bk://linux-dj.bkbits.net/cpufreq
#   into bix.(none):/usr/src/bk-cpufreq
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2004/12/29 18:00:49-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/12/29 03:00:38-05:00 davej@redhat.com 
#   [CPUFREQ] proc_cpufreq: remove /proc/cpufreq interface
#   
#   Remove the deprecated /proc/cpufreq interface. The same input is available
#   using cpufreq-info --proc from cpufrequtils.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# include/linux/cpufreq.h
#   2004/12/29 03:00:17-05:00 davej@redhat.com +0 -3
#   [CPUFREQ] proc_cpufreq: remove /proc/cpufreq interface
#   
#   Remove the deprecated /proc/cpufreq interface. The same input is available
#   using cpufreq-info --proc from cpufrequtils.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/proc_intf.c
#   2004/12/29 03:00:17-05:00 davej@redhat.com +0 -263
#   [CPUFREQ] proc_cpufreq: remove /proc/cpufreq interface
#   
#   Remove the deprecated /proc/cpufreq interface. The same input is available
#   using cpufreq-info --proc from cpufrequtils.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq.c
#   2004/12/29 03:00:17-05:00 davej@redhat.com +1 -1
#   [CPUFREQ] proc_cpufreq: remove /proc/cpufreq interface
#   
#   Remove the deprecated /proc/cpufreq interface. The same input is available
#   using cpufreq-info --proc from cpufrequtils.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/Makefile
#   2004/12/29 03:00:17-05:00 davej@redhat.com +0 -1
#   [CPUFREQ] proc_cpufreq: remove /proc/cpufreq interface
#   
#   Remove the deprecated /proc/cpufreq interface. The same input is available
#   using cpufreq-info --proc from cpufrequtils.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/Kconfig
#   2004/12/29 03:00:17-05:00 davej@redhat.com +0 -12
#   [CPUFREQ] proc_cpufreq: remove /proc/cpufreq interface
#   
#   Remove the deprecated /proc/cpufreq interface. The same input is available
#   using cpufreq-info --proc from cpufrequtils.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:58:59-05:00 davej@redhat.com 
#   [CPUFREQ] userspace: remove /proc/sys/cpu/ interface
#   
#   Remove the deprecated /proc/sys/cpu/ interface to cpufreq.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# include/linux/cpufreq.h
#   2004/12/29 02:58:39-05:00 davej@redhat.com +0 -56
#   [CPUFREQ] userspace: remove /proc/sys/cpu/ interface
#   
#   Remove the deprecated /proc/sys/cpu/ interface to cpufreq.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq_userspace.c
#   2004/12/29 02:58:39-05:00 davej@redhat.com +4 -396
#   [CPUFREQ] userspace: remove /proc/sys/cpu/ interface
#   
#   Remove the deprecated /proc/sys/cpu/ interface to cpufreq.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/Kconfig
#   2004/12/29 02:58:39-05:00 davej@redhat.com +0 -15
#   [CPUFREQ] userspace: remove /proc/sys/cpu/ interface
#   
#   Remove the deprecated /proc/sys/cpu/ interface to cpufreq.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:57:21-05:00 davej@redhat.com 
#   [CPUFREQ] speedstep-centrino: quieten driver (Venkatesh Pallipadi)
#   
#   Patch to remove speedstep-centrino error messages getting printed by default.
#   Print them only when debug flags are enabled.
#   
#   The reason for this patch is -
#   With the multiple drivers model that we have now, any installation will try
#   different drivers one after the other, until one of them succeeds. So,
#   failure to add speedstep-centrino alone doesn't mean error, as some other
#   driver (say acpi.ko) can succeed later and system will still be able to use
#   speedstep. Printing the error whenever speedstep-centrino fails can confuse
#   the enduser.
#   
#   Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2004/12/29 02:57:03-05:00 davej@redhat.com +6 -6
#   [CPUFREQ] speedstep-centrino: quieten driver (Venkatesh Pallipadi)
#   
#   Patch to remove speedstep-centrino error messages getting printed by default.
#   Print them only when debug flags are enabled.
#   
#   The reason for this patch is -
#   With the multiple drivers model that we have now, any installation will try
#   different drivers one after the other, until one of them succeeds. So,
#   failure to add speedstep-centrino alone doesn't mean error, as some other
#   driver (say acpi.ko) can succeed later and system will still be able to use
#   speedstep. Printing the error whenever speedstep-centrino fails can confuse
#   the enduser.
#   
#   Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:55:56-05:00 davej@redhat.com 
#   [CPUFREQ] speedstep-centrino: transient MSR values (Venkatesh Pallipadi)
#   
#   On some CPUs, we can see transient MSR values (which are not present in _PSS)
#   in IA32_PERF_STATUS MSR, while CPU is doing some automatic P-state transition
#   (like TM2).
#   Current code will return frequency as 0 in such cases. Fix it by retrying the
#   get after a delay and use lowest possible frequency as the current frequency
#   in worst case.
#   
#   Thanks to Matt Domsch for identifying and root-causing this failure.
#   
#   Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2004/12/29 02:55:38-05:00 davej@redhat.com +40 -8
#   [CPUFREQ] speedstep-centrino: transient MSR values (Venkatesh Pallipadi)
#   
#   On some CPUs, we can see transient MSR values (which are not present in _PSS)
#   in IA32_PERF_STATUS MSR, while CPU is doing some automatic P-state transition
#   (like TM2).
#   Current code will return frequency as 0 in such cases. Fix it by retrying the
#   get after a delay and use lowest possible frequency as the current frequency
#   in worst case.
#   
#   Thanks to Matt Domsch for identifying and root-causing this failure.
#   
#   Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:54:41-05:00 davej@redhat.com 
#   [CPUFREQ] Check in missing file for cpufreq stats.
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq_stats.c
#   2004/12/29 02:54:22-05:00 davej@redhat.com +334 -0
# 
# drivers/cpufreq/cpufreq_stats.c
#   2004/12/29 02:54:22-05:00 davej@redhat.com +0 -0
#   BitKeeper file /home/davej/bk/cpufreq/drivers/cpufreq/cpufreq_stats.c
# 
# ChangeSet
#   2004/12/29 02:53:28-05:00 davej@redhat.com 
#   [CPUFREQ] speedstep-centrino: fix SMP memory leak
#   
#   Venkatesh Pallipadi made me aware of a memory leak in speedstep-centrino:
#   centrino_model is allocated for all CPUs. There were two possibilities: either
#   make the centrino_model data per-CPU, or to share it across CPUs. I chose the
#   former variant, as ACPI data may be broken and/or different for multiple CPUs.
#   
#   Additionally, I made centrino_cpu per-CPU, and removed a check whether setting
#   allowed_cpus to policy->cpus resulted in smp_processor_id() == policy->cpu:
#   if policy->cpus has more than one bit set, this check will fail very often.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
#   2004/12/29 02:53:13-05:00 davej@redhat.com +57 -54
#   [CPUFREQ] speedstep-centrino: fix SMP memory leak
#   
#   Venkatesh Pallipadi made me aware of a memory leak in speedstep-centrino:
#   centrino_model is allocated for all CPUs. There were two possibilities: either
#   make the centrino_model data per-CPU, or to share it across CPUs. I chose the
#   former variant, as ACPI data may be broken and/or different for multiple CPUs.
#   
#   Additionally, I made centrino_cpu per-CPU, and removed a check whether setting
#   allowed_cpus to policy->cpus resulted in smp_processor_id() == policy->cpu:
#   if policy->cpus has more than one bit set, this check will fail very often.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:51:32-05:00 davej@redhat.com 
#   [CPUFREQ] cpufreq stat output in sysfs
#   
#   From:  "Zou, Nanhai" <nanhai.zou@intel.com>
#   
#   Export cpufreq transition information for drivers using the freq-table helpers
#   via sysfs.
#   
#   Two minor updates from Dominik Brodowski:
#   s/translation/transition
#   Kconfig re-ordering
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# include/linux/cpufreq.h
#   2004/12/29 02:51:14-05:00 davej@redhat.com +5 -0
#   [CPUFREQ] cpufreq stat output in sysfs
#   
#   From:  "Zou, Nanhai" <nanhai.zou@intel.com>
#   
#   Export cpufreq transition information for drivers using the freq-table helpers
#   via sysfs.
#   
#   Two minor updates from Dominik Brodowski:
#   s/translation/transition
#   Kconfig re-ordering
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/freq_table.c
#   2004/12/29 02:51:14-05:00 davej@redhat.com +5 -0
#   [CPUFREQ] cpufreq stat output in sysfs
#   
#   From:  "Zou, Nanhai" <nanhai.zou@intel.com>
#   
#   Export cpufreq transition information for drivers using the freq-table helpers
#   via sysfs.
#   
#   Two minor updates from Dominik Brodowski:
#   s/translation/transition
#   Kconfig re-ordering
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq.c
#   2004/12/29 02:51:14-05:00 davej@redhat.com +4 -2
#   [CPUFREQ] cpufreq stat output in sysfs
#   
#   From:  "Zou, Nanhai" <nanhai.zou@intel.com>
#   
#   Export cpufreq transition information for drivers using the freq-table helpers
#   via sysfs.
#   
#   Two minor updates from Dominik Brodowski:
#   s/translation/transition
#   Kconfig re-ordering
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/Makefile
#   2004/12/29 02:51:14-05:00 davej@redhat.com +2 -0
#   [CPUFREQ] cpufreq stat output in sysfs
#   
#   From:  "Zou, Nanhai" <nanhai.zou@intel.com>
#   
#   Export cpufreq transition information for drivers using the freq-table helpers
#   via sysfs.
#   
#   Two minor updates from Dominik Brodowski:
#   s/translation/transition
#   Kconfig re-ordering
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/Kconfig
#   2004/12/29 02:51:13-05:00 davej@redhat.com +16 -0
#   [CPUFREQ] cpufreq stat output in sysfs
#   
#   From:  "Zou, Nanhai" <nanhai.zou@intel.com>
#   
#   Export cpufreq transition information for drivers using the freq-table helpers
#   via sysfs.
#   
#   Two minor updates from Dominik Brodowski:
#   s/translation/transition
#   Kconfig re-ordering
#   
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:49:58-05:00 davej@redhat.com 
#   [CPUFREQ] powernow-k8: handle invalid initial frequency/voltage pairs correctly
#   
#   From: Paul Devriendt
#   
#   patch for powernow-k8 problem (Mobile Sempron 2800+, Acer Aspire 1362 )
#   
#   If the initial frequency/voltage pair are not valid in the frequency table,
#   the first requested transition is to make them valid. Fix the code doing so.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k8.c
#   2004/12/29 02:49:41-05:00 davej@redhat.com +1 -1
#   [CPUFREQ] powernow-k8: handle invalid initial frequency/voltage pairs correctly
#   
#   From: Paul Devriendt
#   
#   patch for powernow-k8 problem (Mobile Sempron 2800+, Acer Aspire 1362 )
#   
#   If the initial frequency/voltage pair are not valid in the frequency table,
#   the first requested transition is to make them valid. Fix the code doing so.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:48:47-05:00 davej@redhat.com 
#   [CPUFREQ] nforce2: use unified cpufreq debug infrastructure
#   
#   Use the unified cpufreq debug infrastructure in the cpufreq-nforce2 driver.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
#   2004/12/29 02:48:24-05:00 davej@redhat.com +1 -10
#   [CPUFREQ] nforce2: use unified cpufreq debug infrastructure
#   
#   Use the unified cpufreq debug infrastructure in the cpufreq-nforce2 driver.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:47:36-05:00 davej@redhat.com 
#   [CPUFREQ] core: CPUFREQ_GOV_STOP needs to be last
#   
#   Assert that the call to the cpufreq governor with CPUFREQ_GOV_STOP is really
#   the last. Without this patch, some strange in-kernel preemption combined with
#   the scheduler disliking the "removing" task may cause the opposite.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq.c
#   2004/12/29 02:47:18-05:00 davej@redhat.com +4 -1
#   [CPUFREQ] core: CPUFREQ_GOV_STOP needs to be last
#   
#   Assert that the call to the cpufreq governor with CPUFREQ_GOV_STOP is really
#   the last. Without this patch, some strange in-kernel preemption combined with
#   the scheduler disliking the "removing" task may cause the opposite.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:46:18-05:00 davej@redhat.com 
#   [CPUFREQ] powernow-k8: small cleanups / documentation additions (Pavel Machek)
#   
#   From: Pavel Machek <pavel (AT) ucw.cz>
#   
#   These are very small cleanups / documentation additions. It avoids
#   using different names for same fields in different structures.
#   
#   Updated to latest cpufreq-bk by Dominik Brodowski, and ack'ed by Mark
#   Langsdorf, Paul Devriendt and Pavel Machek.
#   
#   Signed-off-by: Pavel Machek <pavel@suse.cz>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k8.h
#   2004/12/29 02:46:01-05:00 davej@redhat.com +4 -5
#   [CPUFREQ] powernow-k8: small cleanups / documentation additions (Pavel Machek)
#   
#   From: Pavel Machek <pavel (AT) ucw.cz>
#   
#   These are very small cleanups / documentation additions. It avoids
#   using different names for same fields in different structures.
#   
#   Updated to latest cpufreq-bk by Dominik Brodowski, and ack'ed by Mark
#   Langsdorf, Paul Devriendt and Pavel Machek.
#   
#   Signed-off-by: Pavel Machek <pavel@suse.cz>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k8.c
#   2004/12/29 02:46:00-05:00 davej@redhat.com +15 -10
#   [CPUFREQ] powernow-k8: small cleanups / documentation additions (Pavel Machek)
#   
#   From: Pavel Machek <pavel (AT) ucw.cz>
#   
#   These are very small cleanups / documentation additions. It avoids
#   using different names for same fields in different structures.
#   
#   Updated to latest cpufreq-bk by Dominik Brodowski, and ack'ed by Mark
#   Langsdorf, Paul Devriendt and Pavel Machek.
#   
#   Signed-off-by: Pavel Machek <pavel@suse.cz>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:44:51-05:00 davej@redhat.com 
#   [CPUFREQ] acpi-cpufreq: force setting of P-State upon resume
#   
#   Upon resuming from sleep or swsusp, the ACPI P-States driver can't determine
#   the current CPU frequency, as the ACPI specification doesn't contain a method
#   to determine the current P-State.
#   
#   Therefore, _always_ re-set the CPU to the P-State it was before suspending,
#   and don't abort early if this is the same state as the CPU was put to
#   before (like it does make sense when using the ondemand governor, for example).
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
#   2004/12/29 02:44:34-05:00 davej@redhat.com +24 -3
#   [CPUFREQ] acpi-cpufreq: force setting of P-State upon resume
#   
#   Upon resuming from sleep or swsusp, the ACPI P-States driver can't determine
#   the current CPU frequency, as the ACPI specification doesn't contain a method
#   to determine the current P-State.
#   
#   Therefore, _always_ re-set the CPU to the P-State it was before suspending,
#   and don't abort early if this is the same state as the CPU was put to
#   before (like it does make sense when using the ondemand governor, for example).
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:42:43-05:00 davej@redhat.com 
#   [CPUFREQ] re-add call to cpufreq_driver->resume()
#   
#   (if anyone has a brown spare paper bag, feel free to send it to me:)
#   
#   The call to cpufreq_driver->resume() got lost in 2.6.6. Re-add it at the
#   proper place.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq.c
#   2004/12/29 02:42:27-05:00 davej@redhat.com +7 -0
#   [CPUFREQ] re-add call to cpufreq_driver->resume()
#   
#   (if anyone has a brown spare paper bag, feel free to send it to me:)
#   
#   The call to cpufreq_driver->resume() got lost in 2.6.6. Re-add it at the
#   proper place.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:41:40-05:00 davej@redhat.com 
#   [CPUFREQ] powernow-k8: unregister from ACPI perflib in error path
#   
#   If something fails in the per-CPU initialization in powernow-k8, it should
#   unregister itself from the ACPI performance library.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k8.c
#   2004/12/29 02:41:24-05:00 davej@redhat.com +2 -0
#   [CPUFREQ] powernow-k8: unregister from ACPI perflib in error path
#   
#   If something fails in the per-CPU initialization in powernow-k8, it should
#   unregister itself from the ACPI performance library.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:40:22-05:00 davej@redhat.com 
#   [CPUFREQ] powernow-k7: ACPI perflib unregistration cleanup
#   
#   The unregistration of the ACPI performance library should be done in the
#   CPU exit function, and the cleanup too.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# arch/i386/kernel/cpu/cpufreq/powernow-k7.c
#   2004/12/29 02:40:04-05:00 davej@redhat.com +11 -8
#   [CPUFREQ] powernow-k7: ACPI perflib unregistration cleanup
#   
#   The unregistration of the ACPI performance library should be done in the
#   CPU exit function, and the cleanup too.
#   
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# ChangeSet
#   2004/12/29 02:39:04-05:00 davej@redhat.com 
#   [CPUFREQ] make ondemand governor aware of CPU domains
#   
#   The following patch makes ondemand governor aware of policy->cpus.
#   
#   policy->cpus mask lets multiple cpu use the same policy (useful where cpus
#   share the frequency state), a recent change in cpufreq core.
#   
#   Now ondemand governor looks at all cpus in policy->cpus and takes its
#   frequency increase/decrease decisions based on most lightly loaded cpu in
#   the group. This patch will not affect systems where policy->cpus contain
#   only one cpu.
#   
#   Signed-off-by: "Venkatesh Pallipadi" <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
# drivers/cpufreq/cpufreq_ondemand.c
#   2004/12/29 02:38:49-05:00 davej@redhat.com +64 -13
#   [CPUFREQ] make ondemand governor aware of CPU domains
#   
#   The following patch makes ondemand governor aware of policy->cpus.
#   
#   policy->cpus mask lets multiple cpu use the same policy (useful where cpus
#   share the frequency state), a recent change in cpufreq core.
#   
#   Now ondemand governor looks at all cpus in policy->cpus and takes its
#   frequency increase/decrease decisions based on most lightly loaded cpu in
#   the group. This patch will not affect systems where policy->cpus contain
#   only one cpu.
#   
#   Signed-off-by: "Venkatesh Pallipadi" <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Dominik Brodowski <linux@brodo.de>
#   Signed-off-by: Dave Jones <davej@redhat.com>
# 
diff -Nru a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c	2005-01-02 23:08:21 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c	2005-01-02 23:08:21 -08:00
@@ -48,6 +48,7 @@
 struct cpufreq_acpi_io {
 	struct acpi_processor_performance	acpi_data;
 	struct cpufreq_frequency_table		*freq_table;
+	unsigned int				resume;
 };
 
 static struct cpufreq_acpi_io	*acpi_io_data[NR_CPUS];
@@ -119,9 +120,14 @@
 	}
 	
 	if (state == data->acpi_data.state) {
-		dprintk("Already at target state (P%d)\n", state);
-		retval = 0;
-		goto migrate_end;
+		if (unlikely(data->resume)) {
+			dprintk("Called after resume, resetting to P%d\n", state);
+			data->resume = 0;
+		} else {
+			dprintk("Already at target state (P%d)\n", state);
+			retval = 0;
+			goto migrate_end;
+		}
 	}
 
 	dprintk("Transitioning from P%d to P%d\n",
@@ -462,6 +468,20 @@
 	return (0);
 }
 
+static int
+acpi_cpufreq_resume (
+	struct cpufreq_policy   *policy)
+{
+	struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
+
+
+	dprintk("acpi_cpufreq_resume\n");
+
+	data->resume = 1;
+
+	return (0);
+}
+
 
 static struct freq_attr* acpi_cpufreq_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
@@ -473,6 +493,7 @@
 	.target 	= acpi_cpufreq_target,
 	.init		= acpi_cpufreq_cpu_init,
 	.exit		= acpi_cpufreq_cpu_exit,
+	.resume		= acpi_cpufreq_resume,
 	.name		= "acpi-cpufreq",
 	.owner		= THIS_MODULE,
 	.attr           = acpi_cpufreq_attr,
diff -Nru a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
--- a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c	2005-01-02 23:08:21 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c	2005-01-02 23:08:21 -08:00
@@ -55,16 +55,7 @@
 MODULE_PARM_DESC(min_fsb,
                  "Minimum FSB to use, if not defined: current FSB - 50");
 
-/* DEBUG
- *   Define it if you want verbose debug output, e.g. for bug reporting
- */
-//#define NFORCE2_DEBUG
-
-#ifdef NFORCE2_DEBUG
-#define dprintk(msg...) printk(msg)
-#else
-#define dprintk(msg...) do { } while(0)
-#endif
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "cpufreq-nforce2", msg)
 
 /*
  * nforce2_calc_fsb - calculate FSB
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	2005-01-02 23:08:21 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	2005-01-02 23:08:21 -08:00
@@ -635,6 +635,17 @@
 
 static int powernow_cpu_exit (struct cpufreq_policy *policy) {
 	cpufreq_frequency_table_put_attr(policy->cpu);
+
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
+	if (acpi_processor_perf) {
+		acpi_processor_unregister_performance(acpi_processor_perf, 0);
+		kfree(acpi_processor_perf);
+	}
+#endif
+
+	if (powernow_table)
+		kfree(powernow_table);
+
 	return 0;
 }
 
@@ -664,15 +675,7 @@
 
 static void __exit powernow_exit (void)
 {
-#ifdef CONFIG_X86_POWERNOW_K7_ACPI
-	if (acpi_processor_perf) {
-		acpi_processor_unregister_performance(acpi_processor_perf, 0);
-		kfree(acpi_processor_perf);
-	}
-#endif
 	cpufreq_unregister_driver(&powernow_driver);
-	if (powernow_table)
-		kfree(powernow_table);
 }
 
 module_param(acpi_force,  int, 0444);
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	2005-01-02 23:08:21 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c	2005-01-02 23:08:21 -08:00
@@ -18,6 +18,9 @@
  *  Processor information obtained from Chapter 9 (Power and Thermal Management)
  *  of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
  *  Opteron Processors" available for download from www.amd.com
+ *
+ *  Tables for specific CPUs can be infrerred from
+ *	http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf
  */
 
 #include <linux/kernel.h>
@@ -65,7 +68,12 @@
 	return 1550-vid*25;
 }
 
-/* Return the vco fid for an input fid */
+/* Return the vco fid for an input fid
+ *
+ * Each "low" fid has corresponding "high" fid, and you can get to "low" fids
+ * only from corresponding high fids. This returns "high" fid corresponding to
+ * "low" one.
+ */
 static u32 convert_fid_to_vco_fid(u32 fid)
 {
 	if (fid < HI_FID_TABLE_BOTTOM) {
@@ -278,7 +286,7 @@
 			return 1;
 	}
 
-	while (rvosteps > 0) {
+	while ((rvosteps > 0)  && ((data->rvo + data->currvid) > reqvid)) {
 		if (data->currvid == 0) {
 			rvosteps = 0;
 		} else {
@@ -307,10 +315,7 @@
 /* Phase 2 - core frequency transition */
 static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
 {
-	u32 vcoreqfid;
-	u32 vcocurrfid;
-	u32 vcofiddiff;
-	u32 savevid = data->currvid;
+	u32 vcoreqfid, vcocurrfid, vcofiddiff, savevid = data->currvid;
 
 	if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
 		printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n",
@@ -498,7 +503,7 @@
 		    || (pst[j].fid & 1)
 		    || (j && (pst[j].fid < HI_FID_TABLE_BOTTOM))) {
 			/* Only first fid is allowed to be in "low" range */
-			printk(KERN_ERR PFX "fid %d invalid : 0x%x\n", j, pst[j].fid);
+			printk(KERN_ERR PFX "two low fids - %d : 0x%x\n", j, pst[j].fid);
 			return -EINVAL;
 		}
 		if (pst[j].fid < lastfid)
@@ -618,7 +623,7 @@
 			return -ENODEV;
 		}
 
-		data->vstable = psb->voltagestabilizationtime;
+		data->vstable = psb->vstable;
 		dprintk("voltage stabilization time: %d(*20us)\n", data->vstable);
 
 		dprintk("flags2: 0x%x\n", psb->flags2);
@@ -632,8 +637,8 @@
 		dprintk("isochronous relief time: %d\n", data->irt);
 		dprintk("maximum voltage step: %d - 0x%x\n", mvs, data->vidmvs);
 
-		dprintk("numpst: 0x%x\n", psb->numpst);
-		cpst = psb->numpst;
+		dprintk("numpst: 0x%x\n", psb->numps);
+		cpst = psb->numps;
 		if ((psb->cpuid == 0x00000fc0) || (psb->cpuid == 0x00000fe0) ){
 			thiscpuid = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
 			if ((thiscpuid == 0x00000fc0) || (thiscpuid == 0x00000fe0) ) {
@@ -651,7 +656,7 @@
 		dprintk("maxvid: 0x%x\n", psb->maxvid);
 		maxvid = psb->maxvid;
 
-		data->numps = psb->numpstates;
+		data->numps = psb->numps;
 		dprintk("numpstates: 0x%x\n", data->numps);
 		return fill_powernow_table(data, (struct pst_s *)(psb+1), maxvid);
 	}
@@ -1010,6 +1015,7 @@
 	/* min/max the cpu is capable of */
 	if (cpufreq_frequency_table_cpuinfo(pol, data->powernow_table)) {
 		printk(KERN_ERR PFX "invalid powernow_table\n");
+		powernow_k8_cpu_exit_acpi(data);
 		kfree(data->powernow_table);
 		kfree(data);
 		return -EINVAL;
@@ -1027,6 +1033,7 @@
 err_out:
 	set_cpus_allowed(current, oldmask);
 	schedule();
+	powernow_k8_cpu_exit_acpi(data);
 
 	kfree(data);
 	return -ENODEV;
diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h	2005-01-02 23:08:21 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h	2005-01-02 23:08:21 -08:00
@@ -21,8 +21,7 @@
 	u32 plllock; /* pll lock time, units 1 us */
 
 	/* keep track of the current fid / vid */
-	u32 currvid;
-	u32 currfid;
+	u32 currvid, currfid;
 
 	/* the powernow_table includes all frequency and vid/fid pairings:
 	 * fid are the lower 8 bits of the index, vid are the upper 8 bits.
@@ -152,14 +151,14 @@
 	u8 signature[10];
 	u8 tableversion;
 	u8 flags1;
-	u16 voltagestabilizationtime;
+	u16 vstable;
 	u8 flags2;
-	u8 numpst;
+	u8 num_tables;
 	u32 cpuid;
 	u8 plllocktime;
 	u8 maxfid;
 	u8 maxvid;
-	u8 numpstates;
+	u8 numps;
 };
 
 /* Pairs of fid/vid values are appended to the version 1.4 PSB table. */
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	2005-01-02 23:08:21 -08:00
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c	2005-01-02 23:08:21 -08:00
@@ -22,6 +22,8 @@
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 #include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/compiler.h>
 
 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
 #include <linux/acpi.h>
@@ -71,8 +73,8 @@
 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 const struct cpu_id *centrino_cpu;
+static struct cpu_model *centrino_model[NR_CPUS];
+static const struct cpu_id *centrino_cpu[NR_CPUS];
 
 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE
 
@@ -239,7 +241,7 @@
 
 	if (model->cpu_id == NULL) {
 		/* No match at all */
-		printk(KERN_INFO PFX "no support for CPU model \"%s\": "
+		dprintk(KERN_INFO PFX "no support for CPU model \"%s\": "
 		       "send /proc/cpuinfo to " MAINTAINER "\n",
 		       cpu->x86_model_id);
 		return -ENOENT;
@@ -247,15 +249,15 @@
 
 	if (model->op_points == NULL) {
 		/* Matched a non-match */
-		printk(KERN_INFO PFX "no table support for CPU model \"%s\": \n",
+		dprintk(KERN_INFO PFX "no table support for CPU model \"%s\": \n",
 		       cpu->x86_model_id);
 #ifndef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
-		printk(KERN_INFO PFX "try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n");
+		dprintk(KERN_INFO PFX "try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n");
 #endif
 		return -ENOENT;
 	}
 
-	centrino_model = model;
+	centrino_model[policy->cpu] = model;
 
 	dprintk("found \"%s\": max frequency: %dkHz\n",
 	       model->model_name, model->max_freq);
@@ -277,7 +279,7 @@
 }
 
 /* To be called only after centrino_model is initialized */
-static unsigned extract_clock(unsigned msr)
+static unsigned extract_clock(unsigned msr, unsigned int cpu, int failsafe)
 {
 	int i;
 
@@ -286,28 +288,32 @@
 	 * for centrino, as some DSDTs are buggy.
 	 * Ideally, this can be done using the acpi_data structure.
 	 */
-	if ((centrino_cpu == &cpu_ids[CPU_BANIAS]) ||
-	    (centrino_cpu == &cpu_ids[CPU_DOTHAN_A1]) ||
-	    (centrino_cpu == &cpu_ids[CPU_DOTHAN_B0])) {
+	if ((centrino_cpu[cpu] == &cpu_ids[CPU_BANIAS]) ||
+	    (centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_A1]) ||
+	    (centrino_cpu[cpu] == &cpu_ids[CPU_DOTHAN_B0])) {
 		msr = (msr >> 8) & 0xff;
 		return msr * 100000;
 	}
 
-	if ((!centrino_model) || (!centrino_model->op_points))
+	if ((!centrino_model[cpu]) || (!centrino_model[cpu]->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;
+	for (i=0;centrino_model[cpu]->op_points[i].frequency != CPUFREQ_TABLE_END; i++) {
+		if (msr == centrino_model[cpu]->op_points[i].index)
+			return centrino_model[cpu]->op_points[i].frequency;
+	}
+	if (failsafe)
+		return centrino_model[cpu]->op_points[i-1].frequency;
+	else
+		return 0;
 }
 
 /* Return the current CPU frequency in kHz */
 static unsigned int get_cur_freq(unsigned int cpu)
 {
 	unsigned l, h;
+	unsigned clock_freq;
 	cpumask_t saved_mask;
 
 	saved_mask = current->cpus_allowed;
@@ -316,8 +322,34 @@
 		return 0;
 
 	rdmsr(MSR_IA32_PERF_STATUS, l, h);
+	clock_freq = extract_clock(l, cpu, 0);
+
+	if (unlikely(clock_freq == 0)) {
+		/*
+		 * On some CPUs, we can see transient MSR values (which are
+		 * not present in _PSS), while CPU is doing some automatic
+		 * P-state transition (like TM2). Allow CPU to stabilize at
+		 * some freq and retry.
+		 * If we continue to see transients for long time, just return
+		 * the lowest possible frequency as best guess.
+		 */
+		int retries = 0;
+#define MAX_EXTRACT_CLOCK_RETRIES	5
+		while (clock_freq == 0 && retries < MAX_EXTRACT_CLOCK_RETRIES) {
+			udelay(100);
+			retries++;
+			rdmsr(MSR_IA32_PERF_STATUS, l, h);
+			clock_freq = extract_clock(l, cpu, 0);
+		}
+
+		if (clock_freq == 0) {
+			rdmsr(MSR_IA32_PERF_STATUS, l, h);
+			clock_freq = extract_clock(l, cpu, 1);
+		}
+	}
+
 	set_cpus_allowed(current, saved_mask);
-	return extract_clock(l);
+	return clock_freq;
 }
 
 
@@ -339,6 +371,7 @@
 	struct acpi_object_list		arg_list = {1, &arg0};
 	unsigned long			cur_freq;
 	int				result = 0, i;
+	unsigned int			cpu = policy->cpu;
 
 	/* _PDC settings */
 	arg0.buffer.length = 12;
@@ -350,8 +383,8 @@
 	p.pdc = &arg_list;
 
 	/* register with ACPI core */
-	if (acpi_processor_register_performance(&p, policy->cpu)) {
-		printk(KERN_INFO PFX "obtaining ACPI data failed\n");
+	if (acpi_processor_register_performance(&p, cpu)) {
+		dprintk(KERN_INFO PFX "obtaining ACPI data failed\n");
 		return -EIO;
 	}
 
@@ -392,49 +425,49 @@
 		}
 	}
 
-	centrino_model = kmalloc(sizeof(struct cpu_model), GFP_KERNEL);
-	if (!centrino_model) {
+	centrino_model[cpu] = kmalloc(sizeof(struct cpu_model), GFP_KERNEL);
+	if (!centrino_model[cpu]) {
 		result = -ENOMEM;
 		goto err_unreg;
 	}
-	memset(centrino_model, 0, sizeof(struct cpu_model));
+	memset(centrino_model[cpu], 0, sizeof(struct cpu_model));
 
-	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[cpu]->model_name=NULL;
+	centrino_model[cpu]->max_freq = p.states[0].core_frequency * 1000;
+	centrino_model[cpu]->op_points =  kmalloc(sizeof(struct cpufreq_frequency_table) *
 					     (p.state_count + 1), GFP_KERNEL);
-        if (!centrino_model->op_points) {
+        if (!centrino_model[cpu]->op_points) {
                 result = -ENOMEM;
                 goto err_kfree;
         }
 
         for (i=0; i<p.state_count; i++) {
-		centrino_model->op_points[i].index = p.states[i].control;
-		centrino_model->op_points[i].frequency = p.states[i].core_frequency * 1000;
+		centrino_model[cpu]->op_points[i].index = p.states[i].control;
+		centrino_model[cpu]->op_points[i].frequency = p.states[i].core_frequency * 1000;
 		dprintk("adding state %i with frequency %u and control value %04x\n", 
-			i, centrino_model->op_points[i].frequency, centrino_model->op_points[i].index);
+			i, centrino_model[cpu]->op_points[i].frequency, centrino_model[cpu]->op_points[i].index);
 	}
-	centrino_model->op_points[p.state_count].frequency = CPUFREQ_TABLE_END;
+	centrino_model[cpu]->op_points[p.state_count].frequency = CPUFREQ_TABLE_END;
 
-	cur_freq = get_cur_freq(policy->cpu);
+	cur_freq = get_cur_freq(cpu);
 
 	for (i=0; i<p.state_count; i++) {
 		if (!p.states[i].core_frequency) {
 			dprintk("skipping state %u\n", i);
-			centrino_model->op_points[i].frequency = CPUFREQ_ENTRY_INVALID;
+			centrino_model[cpu]->op_points[i].frequency = CPUFREQ_ENTRY_INVALID;
 			continue;
 		}
 		
-		if (extract_clock(centrino_model->op_points[i].index) !=
-		    (centrino_model->op_points[i].frequency)) {
+		if (extract_clock(centrino_model[cpu]->op_points[i].index, cpu, 0) !=
+		    (centrino_model[cpu]->op_points[i].frequency)) {
 			dprintk("Invalid encoded frequency (%u vs. %u)\n",
-				extract_clock(centrino_model->op_points[i].index),
-				centrino_model->op_points[i].frequency);
+				extract_clock(centrino_model[cpu]->op_points[i].index, cpu, 0),
+				centrino_model[cpu]->op_points[i].frequency);
 			result = -EINVAL;
 			goto err_kfree_all;
 		}
 
-		if (cur_freq == centrino_model->op_points[i].frequency)
+		if (cur_freq == centrino_model[cpu]->op_points[i].frequency)
 			p.state = i;
 	}
 
@@ -444,12 +477,12 @@
 	return 0;
 
  err_kfree_all:
-	kfree(centrino_model->op_points);
+	kfree(centrino_model[cpu]->op_points);
  err_kfree:
-	kfree(centrino_model);
+	kfree(centrino_model[cpu]);
  err_unreg:
-	acpi_processor_unregister_performance(&p, policy->cpu);
-	printk(KERN_INFO PFX "invalid ACPI data\n");
+	acpi_processor_unregister_performance(&p, cpu);
+	dprintk(KERN_INFO PFX "invalid ACPI data\n");
 	return (result);
 }
 #else
@@ -473,14 +506,14 @@
 			break;
 
 	if (i != N_IDS)
-		centrino_cpu = &cpu_ids[i];
+		centrino_cpu[policy->cpu] = &cpu_ids[i];
 
 	if (centrino_cpu_init_acpi(policy)) {
 		if (policy->cpu != 0)
 			return -ENODEV;
 
-		if (!centrino_cpu) {
-			printk(KERN_INFO PFX "found unsupported CPU with "
+		if (!centrino_cpu[policy->cpu]) {
+			dprintk(KERN_INFO PFX "found unsupported CPU with "
 			"Enhanced SpeedStep: send /proc/cpuinfo to "
 			MAINTAINER "\n");
 			return -ENODEV;
@@ -516,32 +549,34 @@
 
 	dprintk("centrino_cpu_init: cur=%dkHz\n", policy->cur);
 
-	ret = cpufreq_frequency_table_cpuinfo(policy, centrino_model->op_points);
+	ret = cpufreq_frequency_table_cpuinfo(policy, centrino_model[policy->cpu]->op_points);
 	if (ret)
 		return (ret);
 
-	cpufreq_frequency_table_get_attr(centrino_model->op_points, policy->cpu);
+	cpufreq_frequency_table_get_attr(centrino_model[policy->cpu]->op_points, policy->cpu);
 
 	return 0;
 }
 
 static int centrino_cpu_exit(struct cpufreq_policy *policy)
 {
-	if (!centrino_model)
+	unsigned int cpu = policy->cpu;
+
+	if (!centrino_model[cpu])
 		return -ENODEV;
 
-	cpufreq_frequency_table_put_attr(policy->cpu);
+	cpufreq_frequency_table_put_attr(cpu);
 
 #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
-	if (!centrino_model->model_name) {
+	if (!centrino_model[cpu]->model_name) {
 		dprintk("unregistering and freeing ACPI data\n");
-		acpi_processor_unregister_performance(&p, policy->cpu);
-		kfree(centrino_model->op_points);
-		kfree(centrino_model);
+		acpi_processor_unregister_performance(&p, cpu);
+		kfree(centrino_model[cpu]->op_points);
+		kfree(centrino_model[cpu]);
 	}
 #endif
 
-	centrino_model = NULL;
+	centrino_model[cpu] = NULL;
 
 	return 0;
 }
@@ -555,7 +590,7 @@
  */
 static int centrino_verify (struct cpufreq_policy *policy)
 {
-	return cpufreq_frequency_table_verify(policy, centrino_model->op_points);
+	return cpufreq_frequency_table_verify(policy, centrino_model[policy->cpu]->op_points);
 }
 
 /**
@@ -571,12 +606,12 @@
 			    unsigned int relation)
 {
 	unsigned int    newstate = 0;
-	unsigned int	msr, oldmsr, h;
+	unsigned int	msr, oldmsr, h, cpu = policy->cpu;
 	struct cpufreq_freqs	freqs;
 	cpumask_t		saved_mask;
 	int			retval;
 
-	if (centrino_model == NULL)
+	if (centrino_model[cpu] == NULL)
 		return -ENODEV;
 
 	/*
@@ -585,18 +620,18 @@
 	 */
 	saved_mask = current->cpus_allowed;
 	set_cpus_allowed(current, policy->cpus);
-	if (smp_processor_id() != policy->cpu) {
+	if (!cpu_isset(smp_processor_id(), policy->cpus)) {
 		dprintk("couldn't limit to CPUs in this domain\n");
 		return(-EAGAIN);
 	}
 
-	if (cpufreq_frequency_table_target(policy, centrino_model->op_points, target_freq,
+	if (cpufreq_frequency_table_target(policy, centrino_model[cpu]->op_points, target_freq,
 					   relation, &newstate)) {
 		retval = -EINVAL;
 		goto migrate_end;
 	}
 
-	msr = centrino_model->op_points[newstate].index;
+	msr = centrino_model[cpu]->op_points[newstate].index;
 	rdmsr(MSR_IA32_PERF_CTL, oldmsr, h);
 
 	if (msr == (oldmsr & 0xffff)) {
@@ -605,9 +640,9 @@
 		goto migrate_end;
 	}
 
-	freqs.cpu = policy->cpu;
-	freqs.old = extract_clock(oldmsr);
-	freqs.new = extract_clock(msr);
+	freqs.cpu = cpu;
+	freqs.old = extract_clock(oldmsr, cpu, 0);
+	freqs.new = extract_clock(msr, cpu, 0);
 
 	dprintk("target=%dkHz old=%d new=%d msr=%04x\n",
 		target_freq, freqs.old, freqs.new, msr);
diff -Nru a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
--- a/drivers/cpufreq/Kconfig	2005-01-02 23:08:21 -08:00
+++ b/drivers/cpufreq/Kconfig	2005-01-02 23:08:21 -08:00
@@ -27,17 +27,21 @@
 	       2 to activate CPUfreq drivers debugging, and
 	       4 to activate CPUfreq governor debugging
 
-config CPU_FREQ_PROC_INTF
-	tristate "/proc/cpufreq interface (deprecated)"
-	depends on CPU_FREQ && PROC_FS
-	help
-	  This enables the /proc/cpufreq interface for controlling
-	  CPUFreq. Please note that it is recommended to use the sysfs
-	  interface instead (which is built automatically). 
-	  
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-	  
-	  If in doubt, say N.
+config CPU_FREQ_STAT
+       tristate "CPU frequency translation statistics"
+       depends on CPU_FREQ && CPU_FREQ_TABLE
+       default y
+       help
+         This driver exports CPU frequency statistics information through sysfs
+         file system
+
+config CPU_FREQ_STAT_DETAILS
+       bool "CPU frequency translation statistics details"
+       depends on CPU_FREQ && CPU_FREQ_STAT
+       default n
+       help
+         This will show detail CPU frequency translation table in sysfs file
+         system
 
 choice
 	prompt "Default CPUFreq governor"
@@ -97,21 +101,6 @@
 	  For details, take a look at <file:Documentation/cpu-freq/>.
 
 	  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 <file:Documentation/cpu-freq/>.
-
-	  If in doubt, say N.
 
 config CPU_FREQ_GOV_ONDEMAND
 	tristate "'ondemand' cpufreq policy governor"
diff -Nru a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
--- a/drivers/cpufreq/Makefile	2005-01-02 23:08:21 -08:00
+++ b/drivers/cpufreq/Makefile	2005-01-02 23:08:21 -08:00
@@ -1,5 +1,7 @@
 # CPUfreq core
 obj-$(CONFIG_CPU_FREQ)			+= cpufreq.o
+# CPUfreq stats
+obj-$(CONFIG_CPU_FREQ_STAT)             += cpufreq_stats.o
 
 # CPUfreq governors 
 obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE)	+= cpufreq_performance.o
@@ -9,5 +11,4 @@
 
 # CPUfreq cross-arch helpers
 obj-$(CONFIG_CPU_FREQ_TABLE)		+= freq_table.o
-obj-$(CONFIG_CPU_FREQ_PROC_INTF)	+= proc_intf.o
 
diff -Nru a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
--- a/drivers/cpufreq/cpufreq.c	2005-01-02 23:08:21 -08:00
+++ b/drivers/cpufreq/cpufreq.c	2005-01-02 23:08:21 -08:00
@@ -63,7 +63,7 @@
 static LIST_HEAD(cpufreq_governor_list);
 static DECLARE_MUTEX		(cpufreq_governor_sem);
 
-static struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu)
+struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu)
 {
 	struct cpufreq_policy *data;
 	unsigned long flags;
@@ -102,12 +102,14 @@
  err_out:
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
 
-static void cpufreq_cpu_put(struct cpufreq_policy *data)
+void cpufreq_cpu_put(struct cpufreq_policy *data)
 {
 	kobject_put(&data->kobj);
 	module_put(cpufreq_driver->owner);
 }
+EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
 
 
 /*********************************************************************
@@ -285,7 +287,7 @@
 /**
  * cpufreq_parse_governor - parse a governor string
  */
-int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
+static int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
 				struct cpufreq_governor **governor)
 {
 	if (!cpufreq_driver)
@@ -763,8 +765,11 @@
 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 #endif
 
+	down(&data->lock);
 	if (cpufreq_driver->target)
 		__cpufreq_governor(data, CPUFREQ_GOV_STOP);
+	cpufreq_driver->target = NULL;
+	up(&data->lock);
 
 	kobject_unregister(&data->kobj);
 
@@ -893,6 +898,13 @@
 		return 0;
 	}
 
+	if (cpufreq_driver->resume) {
+		ret = cpufreq_driver->resume(cpu_policy);
+		printk(KERN_ERR "cpufreq: resume failed in ->resume step on CPU %u\n", cpu_policy->cpu);
+		cpufreq_cpu_put(cpu_policy);
+		return (ret);
+	}
+
 	if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
 		unsigned int cur_freq = 0;
 
@@ -1018,7 +1030,7 @@
 	lock_cpu_hotplug();
 	dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
 		target_freq, relation);
-	if (cpu_online(policy->cpu))
+	if (cpu_online(policy->cpu) && cpufreq_driver->target)
 		retval = cpufreq_driver->target(policy, target_freq, relation);
 	unlock_cpu_hotplug();
 	return retval;
diff -Nru a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
--- a/drivers/cpufreq/cpufreq_ondemand.c	2005-01-02 23:08:21 -08:00
+++ b/drivers/cpufreq/cpufreq_ondemand.c	2005-01-02 23:08:21 -08:00
@@ -229,10 +229,14 @@
 	static int down_skip[NR_CPUS];
 	struct cpu_dbs_info_s *this_dbs_info;
 
+	struct cpufreq_policy *policy;
+	unsigned int j;
+
 	this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
 	if (!this_dbs_info->enable)
 		return;
 
+	policy = this_dbs_info->cur_policy;
 	/* 
 	 * The default safe range is 20% to 80% 
 	 * Every sampling_rate, we check
@@ -246,12 +250,33 @@
 	 * Frequency reduction happens at minimum steps of 
 	 * 5% of max_frequency 
 	 */
+
 	/* Check for frequency increase */
 	total_idle_ticks = kstat_cpu(cpu).cpustat.idle +
 		kstat_cpu(cpu).cpustat.iowait;
 	idle_ticks = total_idle_ticks -
 		this_dbs_info->prev_cpu_idle_up;
 	this_dbs_info->prev_cpu_idle_up = total_idle_ticks;
+	
+
+	for_each_cpu_mask(j, policy->cpus) {
+		unsigned int tmp_idle_ticks;
+		struct cpu_dbs_info_s *j_dbs_info;
+
+		if (j == cpu)
+			continue;
+
+		j_dbs_info = &per_cpu(cpu_dbs_info, j);
+		/* Check for frequency increase */
+		total_idle_ticks = kstat_cpu(j).cpustat.idle +
+			kstat_cpu(j).cpustat.iowait;
+		tmp_idle_ticks = total_idle_ticks -
+			j_dbs_info->prev_cpu_idle_up;
+		j_dbs_info->prev_cpu_idle_up = total_idle_ticks;
+
+		if (tmp_idle_ticks < idle_ticks)
+			idle_ticks = tmp_idle_ticks;
+	}
 
 	/* Scale idle ticks by 100 and compare with up and down ticks */
 	idle_ticks *= 100;
@@ -259,8 +284,7 @@
 			sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate);
 
 	if (idle_ticks < up_idle_ticks) {
-		__cpufreq_driver_target(this_dbs_info->cur_policy,
-			this_dbs_info->cur_policy->max, 
+		__cpufreq_driver_target(policy, policy->max, 
 			CPUFREQ_RELATION_H);
 		down_skip[cpu] = 0;
 		this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
@@ -272,12 +296,34 @@
 	if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor)
 		return;
 
+	total_idle_ticks = kstat_cpu(cpu).cpustat.idle +
+		kstat_cpu(cpu).cpustat.iowait;
 	idle_ticks = total_idle_ticks -
 		this_dbs_info->prev_cpu_idle_down;
+	this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
+
+	for_each_cpu_mask(j, policy->cpus) {
+		unsigned int tmp_idle_ticks;
+		struct cpu_dbs_info_s *j_dbs_info;
+
+		if (j == cpu)
+			continue;
+
+		j_dbs_info = &per_cpu(cpu_dbs_info, j);
+		/* Check for frequency increase */
+		total_idle_ticks = kstat_cpu(j).cpustat.idle +
+			kstat_cpu(j).cpustat.iowait;
+		tmp_idle_ticks = total_idle_ticks -
+			j_dbs_info->prev_cpu_idle_down;
+		j_dbs_info->prev_cpu_idle_down = total_idle_ticks;
+
+		if (tmp_idle_ticks < idle_ticks)
+			idle_ticks = tmp_idle_ticks;
+	}
+
 	/* Scale idle ticks by 100 and compare with up and down ticks */
 	idle_ticks *= 100;
 	down_skip[cpu] = 0;
-	this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
 
 	freq_down_sampling_rate = dbs_tuners_ins.sampling_rate *
 		dbs_tuners_ins.sampling_down_factor;
@@ -285,14 +331,14 @@
 			sampling_rate_in_HZ(freq_down_sampling_rate);
 
 	if (idle_ticks > down_idle_ticks ) {
-		freq_down_step = (5 * this_dbs_info->cur_policy->max) / 100;
+		freq_down_step = (5 * policy->max) / 100;
 
 		/* max freq cannot be less than 100. But who knows.... */
 		if (unlikely(freq_down_step == 0))
 			freq_down_step = 5;
 
-		__cpufreq_driver_target(this_dbs_info->cur_policy,
-			this_dbs_info->cur_policy->cur - freq_down_step, 
+		__cpufreq_driver_target(policy,
+			policy->cur - freq_down_step, 
 			CPUFREQ_RELATION_H);
 		return;
 	}
@@ -328,6 +374,7 @@
 {
 	unsigned int cpu = policy->cpu;
 	struct cpu_dbs_info_s *this_dbs_info;
+	unsigned int j;
 
 	this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
 
@@ -344,14 +391,18 @@
 			break;
 		 
 		down(&dbs_sem);
-		this_dbs_info->cur_policy = policy;
+		for_each_cpu_mask(j, policy->cpus) {
+			struct cpu_dbs_info_s *j_dbs_info;
+			j_dbs_info = &per_cpu(cpu_dbs_info, j);
+			j_dbs_info->cur_policy = policy;
 		
-		this_dbs_info->prev_cpu_idle_up = 
-				kstat_cpu(cpu).cpustat.idle +
-				kstat_cpu(cpu).cpustat.iowait;
-		this_dbs_info->prev_cpu_idle_down = 
-				kstat_cpu(cpu).cpustat.idle +
-				kstat_cpu(cpu).cpustat.iowait;
+			j_dbs_info->prev_cpu_idle_up = 
+				kstat_cpu(j).cpustat.idle +
+				kstat_cpu(j).cpustat.iowait;
+			j_dbs_info->prev_cpu_idle_down = 
+				kstat_cpu(j).cpustat.idle +
+				kstat_cpu(j).cpustat.iowait;
+		}
 		this_dbs_info->enable = 1;
 		sysfs_create_group(&policy->kobj, &dbs_attr_group);
 		dbs_enable++;
diff -Nru a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/cpufreq/cpufreq_stats.c	2005-01-02 23:08:21 -08:00
@@ -0,0 +1,334 @@
+/*
+ *  drivers/cpufreq/cpufreq_stats.c
+ *
+ *  Copyright (C) 2003-2004 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
+ *  	      (C) 2004 Zou Nan hai <nanhai.zou@intel.com>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/cpu.h>
+#include <linux/sysfs.h>
+#include <linux/cpufreq.h>
+#include <linux/jiffies.h>
+#include <linux/percpu.h>
+#include <linux/kobject.h>
+#include <linux/spinlock.h>
+
+static spinlock_t cpufreq_stats_lock;
+
+#define CPUFREQ_STATDEVICE_ATTR(_name,_mode,_show) \
+static struct freq_attr _attr_##_name = {\
+	.attr = {.name = __stringify(_name), .owner = THIS_MODULE, \
+		.mode = _mode, }, \
+	.show = _show,\
+};
+
+static unsigned long
+delta_time(unsigned long old, unsigned long new)
+{
+	return (old > new) ? (old - new): (new + ~old + 1);
+}
+
+struct cpufreq_stats {
+	unsigned int cpu;
+	unsigned int total_trans;
+	unsigned long long last_time;
+	unsigned int max_state;
+	unsigned int state_num;
+	unsigned int last_index;
+	unsigned long long *time_in_state;
+	unsigned int *freq_table;
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+	unsigned int *trans_table;
+#endif
+};
+
+static struct cpufreq_stats *cpufreq_stats_table[NR_CPUS];
+
+struct cpufreq_stats_attribute {
+	struct attribute attr;
+	ssize_t(*show) (struct cpufreq_stats *, char *);
+};
+
+static int
+cpufreq_stats_update (unsigned int cpu)
+{
+	struct cpufreq_stats *stat;
+	spin_lock(&cpufreq_stats_lock);
+	stat = cpufreq_stats_table[cpu];
+	if (stat->time_in_state)
+		stat->time_in_state[stat->last_index] +=
+			delta_time(stat->last_time, jiffies);
+	stat->last_time = jiffies;
+	spin_unlock(&cpufreq_stats_lock);
+	return 0;
+}
+
+static ssize_t
+show_total_trans(struct cpufreq_policy *policy, char *buf)
+{
+	struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu];
+	if(!stat)
+		return 0;
+	return sprintf(buf, "%d\n",
+			cpufreq_stats_table[stat->cpu]->total_trans);
+}
+
+static ssize_t
+show_time_in_state(struct cpufreq_policy *policy, char *buf)
+{
+	ssize_t len = 0;
+	int i;
+	struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu];
+	if(!stat)
+		return 0;
+	cpufreq_stats_update(stat->cpu);
+	for (i = 0; i < stat->state_num; i++) {
+		len += sprintf(buf + len, "%u %llu\n",
+			stat->freq_table[i], stat->time_in_state[i]);
+	}
+	return len;
+}
+
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+static ssize_t
+show_trans_table(struct cpufreq_policy *policy, char *buf)
+{
+	ssize_t len = 0;
+	int i, j;
+
+	struct cpufreq_stats *stat = cpufreq_stats_table[policy->cpu];
+	if(!stat)
+		return 0;
+	cpufreq_stats_update(stat->cpu);
+	for (i = 0; i < stat->state_num; i++) {
+		if (len >= PAGE_SIZE)
+			break;
+		len += snprintf(buf + len, PAGE_SIZE - len, "%9u:\t",
+				stat->freq_table[i]);
+
+		for (j = 0; j < stat->state_num; j++)   {
+			if (len >= PAGE_SIZE)
+				break;
+			len += snprintf(buf + len, PAGE_SIZE - len, "%u\t",
+					stat->trans_table[i*stat->max_state+j]);
+		}
+		len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+	}
+	return len;
+}
+CPUFREQ_STATDEVICE_ATTR(trans_table,0444,show_trans_table);
+#endif
+
+CPUFREQ_STATDEVICE_ATTR(total_trans,0444,show_total_trans);
+CPUFREQ_STATDEVICE_ATTR(time_in_state,0444,show_time_in_state);
+
+static struct attribute *default_attrs[] = {
+	&_attr_total_trans.attr,
+	&_attr_time_in_state.attr,
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+	&_attr_trans_table.attr,
+#endif
+	NULL
+};
+static struct attribute_group stats_attr_group = {
+	.attrs = default_attrs,
+	.name = "stats"
+};
+
+static int
+freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq)
+{
+	int index;
+	for (index = 0; index < stat->max_state; index++)
+		if (stat->freq_table[index] == freq)
+			return index;
+	return -1;
+}
+
+static void
+cpufreq_stats_free_table (unsigned int cpu)
+{
+	struct cpufreq_stats *stat = cpufreq_stats_table[cpu];
+	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+	if (policy && policy->cpu == cpu)	
+		sysfs_remove_group(&policy->kobj, &stats_attr_group);
+	if (stat) {
+		kfree(stat->time_in_state);
+		kfree(stat);
+	}
+	cpufreq_stats_table[cpu] = NULL;
+	if (policy)
+		cpufreq_cpu_put(policy);
+}
+
+static int
+cpufreq_stats_create_table (struct cpufreq_policy *policy,
+		struct cpufreq_frequency_table *table)
+{
+	unsigned int i, j, count = 0, ret = 0;
+	struct cpufreq_stats *stat;
+	struct cpufreq_policy *data;
+	unsigned int alloc_size;
+	unsigned int cpu = policy->cpu;
+	if (cpufreq_stats_table[cpu])
+		return -EBUSY;
+	if ((stat = kmalloc(sizeof(struct cpufreq_stats), GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+	memset(stat, 0, sizeof (struct cpufreq_stats));
+
+	data = cpufreq_cpu_get(cpu);
+	if ((ret = sysfs_create_group(&data->kobj, &stats_attr_group)))
+		goto error_out;
+
+	stat->cpu = cpu;
+	cpufreq_stats_table[cpu] = stat;
+
+	for (i=0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+		unsigned int freq = table[i].frequency;
+		if (freq == CPUFREQ_ENTRY_INVALID)
+			continue;
+		count++;
+	}
+
+	alloc_size = count * sizeof(int) + count * sizeof(long long);
+
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+	alloc_size += count * count * sizeof(int);
+#endif
+	stat->max_state = count;
+	stat->time_in_state = kmalloc(alloc_size, GFP_KERNEL);
+	if (!stat->time_in_state) {
+		ret = -ENOMEM;
+		goto error_out;
+	}
+	memset(stat->time_in_state, 0, alloc_size);
+	stat->freq_table = (unsigned int *)(stat->time_in_state + count);
+
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+	stat->trans_table = stat->freq_table + count;
+#endif
+	j = 0;
+	for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+		unsigned int freq = table[i].frequency;
+		if (freq == CPUFREQ_ENTRY_INVALID)
+			continue;
+		if (freq_table_get_index(stat, freq) == -1)
+			stat->freq_table[j++] = freq;
+	}
+	stat->state_num = j;
+	spin_lock(&cpufreq_stats_lock);
+	stat->last_time = jiffies;
+	stat->last_index = freq_table_get_index(stat, policy->cur);
+	spin_unlock(&cpufreq_stats_lock);
+	cpufreq_cpu_put(data);
+	return 0;
+error_out:
+	cpufreq_cpu_put(data);
+	kfree(stat);
+	cpufreq_stats_table[cpu] = NULL;
+	return ret;
+}
+
+static int
+cpufreq_stat_notifier_policy (struct notifier_block *nb, unsigned long val,
+		void *data)
+{
+	int ret;
+	struct cpufreq_policy *policy = data;
+	struct cpufreq_frequency_table *table;
+	unsigned int cpu = policy->cpu;
+	if (val != CPUFREQ_NOTIFY)
+		return 0;
+	table = cpufreq_frequency_get_table(cpu);
+	if (!table)
+		return 0;
+	if ((ret = cpufreq_stats_create_table(policy, table)))
+		return ret;
+	return 0;
+}
+
+static int
+cpufreq_stat_notifier_trans (struct notifier_block *nb, unsigned long val,
+		void *data)
+{
+	struct cpufreq_freqs *freq = data;
+	struct cpufreq_stats *stat;
+	int old_index, new_index;
+
+	if (val != CPUFREQ_POSTCHANGE)
+		return 0;
+
+	stat = cpufreq_stats_table[freq->cpu];
+	if (!stat)
+		return 0;
+	old_index = freq_table_get_index(stat, freq->old);
+	new_index = freq_table_get_index(stat, freq->new);
+
+	cpufreq_stats_update(freq->cpu);
+	if (old_index == new_index)
+		return 0;
+
+	spin_lock(&cpufreq_stats_lock);
+	stat->last_index = new_index;
+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
+	stat->trans_table[old_index * stat->max_state + new_index]++;
+#endif
+	stat->total_trans++;
+	spin_unlock(&cpufreq_stats_lock);
+	return 0;
+}
+
+static struct notifier_block notifier_policy_block = {
+	.notifier_call = cpufreq_stat_notifier_policy
+};
+
+static struct notifier_block notifier_trans_block = {
+	.notifier_call = cpufreq_stat_notifier_trans
+};
+
+static int
+__init cpufreq_stats_init(void)
+{
+	int ret;
+	unsigned int cpu;
+	spin_lock_init(&cpufreq_stats_lock);
+	if ((ret = cpufreq_register_notifier(&notifier_policy_block,
+				CPUFREQ_POLICY_NOTIFIER)))
+		return ret;
+
+	if ((ret = cpufreq_register_notifier(&notifier_trans_block,
+				CPUFREQ_TRANSITION_NOTIFIER))) {
+		cpufreq_unregister_notifier(&notifier_policy_block,
+				CPUFREQ_POLICY_NOTIFIER);
+		return ret;
+	}
+
+	for_each_cpu(cpu)
+		cpufreq_update_policy(cpu);
+	return 0;
+}
+static void
+__exit cpufreq_stats_exit(void)
+{
+	unsigned int cpu;
+	cpufreq_unregister_notifier(&notifier_policy_block,
+			CPUFREQ_POLICY_NOTIFIER);
+	cpufreq_unregister_notifier(&notifier_trans_block,
+			CPUFREQ_TRANSITION_NOTIFIER);
+	for_each_cpu(cpu)
+		cpufreq_stats_free_table(cpu);
+}
+
+MODULE_AUTHOR ("Zou Nan hai <nanhai.zou@intel.com>");
+MODULE_DESCRIPTION ("'cpufreq_stats' - A driver to export cpufreq stats through sysfs filesystem");
+MODULE_LICENSE ("GPL");
+
+module_init(cpufreq_stats_init);
+module_exit(cpufreq_stats_exit);
diff -Nru a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
--- a/drivers/cpufreq/cpufreq_userspace.c	2005-01-02 23:08:21 -08:00
+++ b/drivers/cpufreq/cpufreq_userspace.c	2005-01-02 23:08:21 -08:00
@@ -17,51 +17,13 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
-#include <linux/ctype.h>
 #include <linux/cpufreq.h>
-#include <linux/sysctl.h>
 #include <linux/types.h>
 #include <linux/fs.h>
 #include <linux/sysfs.h>
 
 #include <asm/uaccess.h>
 
-#define CTL_CPU_VARS_SPEED_MAX(cpunr) { \
-                .ctl_name	= CPU_NR_FREQ_MAX, \
-                .data		= &cpu_max_freq[cpunr], \
-                .procname	= "speed-max", \
-                .maxlen		= sizeof(cpu_max_freq[cpunr]),\
-                .mode		= 0444, \
-                .proc_handler	= proc_dointvec, }
-
-#define CTL_CPU_VARS_SPEED_MIN(cpunr) { \
-                .ctl_name	= CPU_NR_FREQ_MIN, \
-                .data		= &cpu_min_freq[cpunr], \
-                .procname	= "speed-min", \
-                .maxlen		= sizeof(cpu_min_freq[cpunr]),\
-                .mode		= 0444, \
-                .proc_handler	= proc_dointvec, }
-
-#define CTL_CPU_VARS_SPEED(cpunr) { \
-                .ctl_name	= CPU_NR_FREQ, \
-                .procname	= "speed", \
-                .mode		= 0644, \
-                .proc_handler	= cpufreq_procctl, \
-                .strategy	= cpufreq_sysctl, \
-                .extra1		= (void*) (cpunr), }
-
-#define CTL_TABLE_CPU_VARS(cpunr) static ctl_table ctl_cpu_vars_##cpunr[] = {\
-                CTL_CPU_VARS_SPEED_MAX(cpunr), \
-                CTL_CPU_VARS_SPEED_MIN(cpunr), \
-                CTL_CPU_VARS_SPEED(cpunr),  \
-                { .ctl_name = 0, }, }
-
-/* the ctl_table entry for each CPU */
-#define CPU_ENUM(s) { \
-                .ctl_name	= (CPU_NR + s), \
-                .procname	= #s, \
-                .mode		= 0555, \
-                .child		= ctl_cpu_vars_##s }
 
 /**
  * A few values needed by the userspace governor
@@ -96,17 +58,17 @@
 
 
 /** 
- * _cpufreq_set - set the CPU frequency
+ * cpufreq_set - set the CPU frequency
  * @freq: target frequency in kHz
  * @cpu: CPU for which the frequency is to be set
  *
  * Sets the CPU frequency to freq.
  */
-static int _cpufreq_set(unsigned int freq, unsigned int cpu)
+static int cpufreq_set(unsigned int freq, unsigned int cpu)
 {
 	int ret = -EINVAL;
 
-	dprintk("_cpufreq_set for cpu %u, freq %u kHz\n", cpu, freq);
+	dprintk("cpufreq_set for cpu %u, freq %u kHz\n", cpu, freq);
 
 	down(&userspace_sem);
 	if (!cpu_is_managed[cpu])
@@ -135,358 +97,6 @@
 }
 
 
-#ifdef CONFIG_CPU_FREQ_24_API
-
-#warning The /proc/sys/cpu/ and sysctl interface to cpufreq will be removed from the 2.6. kernel series soon after 2005-01-01
-
-static unsigned int warning_print = 0;
-
-int __deprecated cpufreq_set(unsigned int freq, unsigned int cpu)
-{
-	return _cpufreq_set(freq, cpu);
-}
-EXPORT_SYMBOL_GPL(cpufreq_set);
-
-
-/** 
- * cpufreq_setmax - set the CPU to the maximum frequency
- * @cpu - affected cpu;
- *
- * Sets the CPU frequency to the maximum frequency supported by
- * this CPU.
- */
-int __deprecated cpufreq_setmax(unsigned int cpu)
-{
-	if (!cpu_is_managed[cpu] || !cpu_online(cpu))
-		return -EINVAL;
-	return _cpufreq_set(cpu_max_freq[cpu], cpu);
-}
-EXPORT_SYMBOL_GPL(cpufreq_setmax);
-
-/*********************** cpufreq_sysctl interface ********************/
-static int
-cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
-		void __user *buffer, size_t *lenp, loff_t *ppos)
-{
-	char buf[16], *p;
-	int cpu = (long) ctl->extra1;
-	unsigned int len, left = *lenp;
-
-	if (!left || (*ppos && !write) || !cpu_online(cpu)) {
-		*lenp = 0;
-		return 0;
-	}
-
-	if (!warning_print) {
-		warning_print++;
-		printk(KERN_INFO "Access to /proc/sys/cpu/ is deprecated and "
-			"will be removed from (new) 2.6. kernels soon "
-			"after 2005-01-01\n");
-	}
-
-	if (write) {
-		unsigned int freq;
-
-		len = left;
-		if (left > sizeof(buf))
-			left = sizeof(buf);
-		if (copy_from_user(buf, buffer, left))
-			return -EFAULT;
-		buf[sizeof(buf) - 1] = '\0';
-
-		freq = simple_strtoul(buf, &p, 0);
-		_cpufreq_set(freq, cpu);
-	} else {
-		len = sprintf(buf, "%d\n", cpufreq_get(cpu));
-		if (len > left)
-			len = left;
-		if (copy_to_user(buffer, buf, len))
-			return -EFAULT;
-	}
-
-	*lenp = len;
-	*ppos += len;
-	return 0;
-}
-
-static int
-cpufreq_sysctl(ctl_table *table, int __user *name, int nlen,
-	       void __user *oldval, size_t __user *oldlenp,
-	       void __user *newval, size_t newlen, void **context)
-{
-	int cpu = (long) table->extra1;
-
-	if (!cpu_online(cpu))
-		return -EINVAL;
-
-	if (!warning_print) {
-		warning_print++;
-		printk(KERN_INFO "Access to /proc/sys/cpu/ is deprecated and "
-			"will be removed from (new) 2.6. kernels soon "
-			"after 2005-01-01\n");
-	}
-
-	if (oldval && oldlenp) {
-		size_t oldlen;
-
-		if (get_user(oldlen, oldlenp))
-			return -EFAULT;
-
-		if (oldlen != sizeof(unsigned int))
-			return -EINVAL;
-
-		if (put_user(cpufreq_get(cpu), (unsigned int __user *)oldval) ||
-		    put_user(sizeof(unsigned int), oldlenp))
-			return -EFAULT;
-	}
-	if (newval && newlen) {
-		unsigned int freq;
-
-		if (newlen != sizeof(unsigned int))
-			return -EINVAL;
-
-		if (get_user(freq, (unsigned int __user *)newval))
-			return -EFAULT;
-
-		_cpufreq_set(freq, cpu);
-	}
-	return 1;
-}
-
-/* ctl_table ctl_cpu_vars_{0,1,...,(NR_CPUS-1)} */
-/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
-        CTL_TABLE_CPU_VARS(0);
-#if NR_CPUS > 1
-	CTL_TABLE_CPU_VARS(1);
-#endif
-#if NR_CPUS > 2
-	CTL_TABLE_CPU_VARS(2);
-#endif
-#if NR_CPUS > 3
-	CTL_TABLE_CPU_VARS(3);
-#endif
-#if NR_CPUS > 4
-	CTL_TABLE_CPU_VARS(4);
-#endif
-#if NR_CPUS > 5
-	CTL_TABLE_CPU_VARS(5);
-#endif
-#if NR_CPUS > 6
-	CTL_TABLE_CPU_VARS(6);
-#endif
-#if NR_CPUS > 7
-	CTL_TABLE_CPU_VARS(7);
-#endif
-#if NR_CPUS > 8
-	CTL_TABLE_CPU_VARS(8);
-#endif
-#if NR_CPUS > 9
-	CTL_TABLE_CPU_VARS(9);
-#endif
-#if NR_CPUS > 10
-	CTL_TABLE_CPU_VARS(10);
-#endif
-#if NR_CPUS > 11
-	CTL_TABLE_CPU_VARS(11);
-#endif
-#if NR_CPUS > 12
-	CTL_TABLE_CPU_VARS(12);
-#endif
-#if NR_CPUS > 13
-	CTL_TABLE_CPU_VARS(13);
-#endif
-#if NR_CPUS > 14
-	CTL_TABLE_CPU_VARS(14);
-#endif
-#if NR_CPUS > 15
-	CTL_TABLE_CPU_VARS(15);
-#endif
-#if NR_CPUS > 16
-	CTL_TABLE_CPU_VARS(16);
-#endif
-#if NR_CPUS > 17
-	CTL_TABLE_CPU_VARS(17);
-#endif
-#if NR_CPUS > 18
-	CTL_TABLE_CPU_VARS(18);
-#endif
-#if NR_CPUS > 19
-	CTL_TABLE_CPU_VARS(19);
-#endif
-#if NR_CPUS > 20
-	CTL_TABLE_CPU_VARS(20);
-#endif
-#if NR_CPUS > 21
-	CTL_TABLE_CPU_VARS(21);
-#endif
-#if NR_CPUS > 22
-	CTL_TABLE_CPU_VARS(22);
-#endif
-#if NR_CPUS > 23
-	CTL_TABLE_CPU_VARS(23);
-#endif
-#if NR_CPUS > 24
-	CTL_TABLE_CPU_VARS(24);
-#endif
-#if NR_CPUS > 25
-	CTL_TABLE_CPU_VARS(25);
-#endif
-#if NR_CPUS > 26
-	CTL_TABLE_CPU_VARS(26);
-#endif
-#if NR_CPUS > 27
-	CTL_TABLE_CPU_VARS(27);
-#endif
-#if NR_CPUS > 28
-	CTL_TABLE_CPU_VARS(28);
-#endif
-#if NR_CPUS > 29
-	CTL_TABLE_CPU_VARS(29);
-#endif
-#if NR_CPUS > 30
-	CTL_TABLE_CPU_VARS(30);
-#endif
-#if NR_CPUS > 31
-	CTL_TABLE_CPU_VARS(31);
-#endif
-#if NR_CPUS > 32
-#error please extend CPU enumeration
-#endif
-
-/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
-static ctl_table ctl_cpu_table[NR_CPUS + 1] = {
-	CPU_ENUM(0),
-#if NR_CPUS > 1
-	CPU_ENUM(1),
-#endif
-#if NR_CPUS > 2
-	CPU_ENUM(2),
-#endif
-#if NR_CPUS > 3
-	CPU_ENUM(3),
-#endif
-#if NR_CPUS > 4
-	CPU_ENUM(4),
-#endif
-#if NR_CPUS > 5
-	CPU_ENUM(5),
-#endif
-#if NR_CPUS > 6
-	CPU_ENUM(6),
-#endif
-#if NR_CPUS > 7
-	CPU_ENUM(7),
-#endif
-#if NR_CPUS > 8
-	CPU_ENUM(8),
-#endif
-#if NR_CPUS > 9
-	CPU_ENUM(9),
-#endif
-#if NR_CPUS > 10
-	CPU_ENUM(10),
-#endif
-#if NR_CPUS > 11
-	CPU_ENUM(11),
-#endif
-#if NR_CPUS > 12
-	CPU_ENUM(12),
-#endif
-#if NR_CPUS > 13
-	CPU_ENUM(13),
-#endif
-#if NR_CPUS > 14
-	CPU_ENUM(14),
-#endif
-#if NR_CPUS > 15
-	CPU_ENUM(15),
-#endif
-#if NR_CPUS > 16
-	CPU_ENUM(16),
-#endif
-#if NR_CPUS > 17
-	CPU_ENUM(17),
-#endif
-#if NR_CPUS > 18
-	CPU_ENUM(18),
-#endif
-#if NR_CPUS > 19
-	CPU_ENUM(19),
-#endif
-#if NR_CPUS > 20
-	CPU_ENUM(20),
-#endif
-#if NR_CPUS > 21
-	CPU_ENUM(21),
-#endif
-#if NR_CPUS > 22
-	CPU_ENUM(22),
-#endif
-#if NR_CPUS > 23
-	CPU_ENUM(23),
-#endif
-#if NR_CPUS > 24
-	CPU_ENUM(24),
-#endif
-#if NR_CPUS > 25
-	CPU_ENUM(25),
-#endif
-#if NR_CPUS > 26
-	CPU_ENUM(26),
-#endif
-#if NR_CPUS > 27
-	CPU_ENUM(27),
-#endif
-#if NR_CPUS > 28
-	CPU_ENUM(28),
-#endif
-#if NR_CPUS > 29
-	CPU_ENUM(29),
-#endif
-#if NR_CPUS > 30
-	CPU_ENUM(30),
-#endif
-#if NR_CPUS > 31
-	CPU_ENUM(31),
-#endif
-#if NR_CPUS > 32
-#error please extend CPU enumeration
-#endif
-	{
-		.ctl_name	= 0,
-	}
-};
-
-static ctl_table ctl_cpu[2] = {
-	{
-		.ctl_name	= CTL_CPU,
-		.procname	= "cpu",
-		.mode		= 0555,
-		.child		= ctl_cpu_table,
-	},
-	{
-		.ctl_name	= 0,
-	}
-};
-
-static struct ctl_table_header *cpufreq_sysctl_table;
-
-static inline void cpufreq_sysctl_init(void)
-{
-	cpufreq_sysctl_table = register_sysctl_table(ctl_cpu, 0);
-}
-
-static inline void cpufreq_sysctl_exit(void)
-{
-	unregister_sysctl_table(cpufreq_sysctl_table);
-}
-
-#else
-#define cpufreq_sysctl_init() do {} while(0)
-#define cpufreq_sysctl_exit() do {} while(0)
-#endif /* CONFIG_CPU_FREQ_24API */
-
-
 /************************** sysfs interface ************************/
 static ssize_t show_speed (struct cpufreq_policy *policy, char *buf)
 {
@@ -503,7 +113,7 @@
 	if (ret != 1)
 		return -EINVAL;
 
-	_cpufreq_set(freq, policy->cpu);
+	cpufreq_set(freq, policy->cpu);
 
 	return count;
 }
@@ -577,7 +187,6 @@
 
 static int __init cpufreq_gov_userspace_init(void)
 {
-	cpufreq_sysctl_init();
 	cpufreq_register_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
 	return cpufreq_register_governor(&cpufreq_gov_userspace);
 }
@@ -587,7 +196,6 @@
 {
 	cpufreq_unregister_governor(&cpufreq_gov_userspace);
         cpufreq_unregister_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
-	cpufreq_sysctl_exit();
 }
 
 
diff -Nru a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
--- a/drivers/cpufreq/freq_table.c	2005-01-02 23:08:21 -08:00
+++ b/drivers/cpufreq/freq_table.c	2005-01-02 23:08:21 -08:00
@@ -214,6 +214,11 @@
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr);
 
+struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
+{
+	return show_table[cpu];
+}
+EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);
 
 MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
 MODULE_DESCRIPTION ("CPUfreq frequency table helpers");
diff -Nru a/drivers/cpufreq/proc_intf.c b/drivers/cpufreq/proc_intf.c
--- a/drivers/cpufreq/proc_intf.c	2005-01-02 23:08:21 -08:00
+++ b/drivers/cpufreq/proc_intf.c	2005-01-02 23:08:21 -08:00
@@ -1,263 +0,0 @@
-/*
- * linux/drivers/cpufreq/proc_intf.c
- *
- * Copyright (C) 2002 - 2003 Dominik Brodowski
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/ctype.h>
-#include <linux/proc_fs.h>
-#include <asm/uaccess.h>
-
-#warning This module will be removed from the 2.6. kernel series soon after 2005-01-01
-
-#define CPUFREQ_ALL_CPUS		((NR_CPUS))
-
-static unsigned int warning_print = 0;
-
-/**
- * cpufreq_parse_policy - parse a policy string
- * @input_string: the string to parse.
- * @policy: the policy written inside input_string
- *
- * This function parses a "policy string" - something the user echo'es into
- * /proc/cpufreq or gives as boot parameter - into a struct cpufreq_policy.
- * If there are invalid/missing entries, they are replaced with current
- * cpufreq policy.
- */
-static int cpufreq_parse_policy(char input_string[42], struct cpufreq_policy *policy)
-{
-	unsigned int            min = 0;
-	unsigned int            max = 0;
-	unsigned int            cpu = 0;
-	char			str_governor[16];
-	struct cpufreq_policy   current_policy;
-	unsigned int            result = -EFAULT;
-
-	if (!policy)
-		return -EINVAL;
-
-	policy->min = 0;
-	policy->max = 0;
-	policy->policy = 0;
-	policy->cpu = CPUFREQ_ALL_CPUS;
-
-	if (sscanf(input_string, "%d:%d:%d:%15s", &cpu, &min, &max, str_governor) == 4) 
-	{
-		policy->min = min;
-		policy->max = max;
-		policy->cpu = cpu;
-		result = 0;
-		goto scan_policy;
-	}
-	if (sscanf(input_string, "%d%%%d%%%d%%%15s", &cpu, &min, &max, str_governor) == 4)
-	{
-		if (!cpufreq_get_policy(&current_policy, cpu)) {
-			policy->min = (min * current_policy.cpuinfo.max_freq) / 100;
-			policy->max = (max * current_policy.cpuinfo.max_freq) / 100;
-			policy->cpu = cpu;
-			result = 0;
-			goto scan_policy;
-		}
-	}
-
-	if (sscanf(input_string, "%d:%d:%15s", &min, &max, str_governor) == 3) 
-	{
-		policy->min = min;
-		policy->max = max;
-		result = 0;
-		goto scan_policy;
-	}
-
-	if (sscanf(input_string, "%d%%%d%%%15s", &min, &max, str_governor) == 3)
-	{
-		if (!cpufreq_get_policy(&current_policy, cpu)) {
-			policy->min = (min * current_policy.cpuinfo.max_freq) / 100;
-			policy->max = (max * current_policy.cpuinfo.max_freq) / 100;
-			result = 0;
-			goto scan_policy;
-		}
-	}
-
-	return -EINVAL;
-
-scan_policy:
-	result = cpufreq_parse_governor(str_governor, &policy->policy, &policy->governor);
-
-	return result;
-}
-
-/**
- * cpufreq_proc_read - read /proc/cpufreq
- *
- * This function prints out the current cpufreq policy.
- */
-static int cpufreq_proc_read (
-	char			*page,
-	char			**start,
-	off_t			off,
-	int 			count,
-	int 			*eof,
-	void			*data)
-{
-	char			*p = page;
-	int			len = 0;
-	struct cpufreq_policy   policy;
-	unsigned int            min_pctg = 0;
-	unsigned int            max_pctg = 0;
-	unsigned int            i = 0;
-
-	if (off != 0)
-		goto end;
-
-	if (!warning_print) {
-		warning_print++;
-		printk(KERN_INFO "Access to /proc/cpufreq is deprecated and "
-			"will be removed from (new) 2.6. kernels soon "
-			"after 2005-01-01\n");
-	}
-
-	p += sprintf(p, "          minimum CPU frequency  -  maximum CPU frequency  -  policy\n");
-	for (i=0;i<NR_CPUS;i++) {
-		if (!cpu_online(i))
-			continue;
-
-		if (cpufreq_get_policy(&policy, i))
-			continue;
-
-		if (!policy.cpuinfo.max_freq)
-			continue;
-
-		min_pctg = (policy.min * 100) / policy.cpuinfo.max_freq;
-		max_pctg = (policy.max * 100) / policy.cpuinfo.max_freq;
-
-		p += sprintf(p, "CPU%3d    %9d kHz (%3d %%)  -  %9d kHz (%3d %%)  -  ",
-			     i , policy.min, min_pctg, policy.max, max_pctg);
-		if (policy.policy) {
-			switch (policy.policy) {
-				case CPUFREQ_POLICY_POWERSAVE:
-				p += sprintf(p, "powersave\n");
-				break;	
-			case CPUFREQ_POLICY_PERFORMANCE:
-				p += sprintf(p, "performance\n");
-				break;
-			default:
-				p += sprintf(p, "INVALID\n");
-				break;
-			} 
-		} else
-			p += scnprintf(p, CPUFREQ_NAME_LEN, "%s\n", policy.governor->name);
-	}
-end:
-	len = (p - page);
-	if (len <= off+count) 
-		*eof = 1;
-	*start = page + off;
-	len -= off;
-	if (len>count) 
-		len = count;
-	if (len<0) 
-		len = 0;
-
-	return len;
-}
-
-
-/**
- * cpufreq_proc_write - handles writing into /proc/cpufreq
- *
- * This function calls the parsing script and then sets the policy
- * accordingly.
- */
-static int cpufreq_proc_write (
-        struct file		*file,
-        const char		__user *buffer,
-        unsigned long		count,
-        void			*data)
-{
-	int                     result = 0;
-	char			proc_string[42] = {'\0'};
-	struct cpufreq_policy   policy;
-	unsigned int            i = 0;
-
-
-	if ((count > sizeof(proc_string) - 1))
-		return -EINVAL;
-	
-	if (copy_from_user(proc_string, buffer, count))
-		return -EFAULT;
-
-	if (!warning_print) {
-		warning_print++;
-		printk(KERN_INFO "Access to /proc/cpufreq is deprecated and "
-			"will be removed from (new) 2.6. kernels soon "
-			"after 2005-01-01\n");
-	}
-	
-	proc_string[count] = '\0';
-
-	result = cpufreq_parse_policy(proc_string, &policy);
-	if (result)
-		return -EFAULT;
-
-	if (policy.cpu == CPUFREQ_ALL_CPUS)
-	{
-		for (i=0; i<NR_CPUS; i++) 
-		{
-			policy.cpu = i;
-			if (cpu_online(i))
-				cpufreq_set_policy(&policy);
-		}
-	} 
-	else
-		cpufreq_set_policy(&policy);
-
-	return count;
-}
-
-
-/**
- * cpufreq_proc_init - add "cpufreq" to the /proc root directory
- *
- * This function adds "cpufreq" to the /proc root directory.
- */
-static int __init cpufreq_proc_init (void)
-{
-	struct proc_dir_entry *entry = NULL;
-
-	/* are these acceptable values? */
-	entry = create_proc_entry("cpufreq", S_IFREG|S_IRUGO|S_IWUSR, 
-				  &proc_root);
-
-	if (!entry) {
-		printk(KERN_ERR "unable to create /proc/cpufreq entry\n");
-		return -EIO;
-	} else {
-		entry->read_proc = cpufreq_proc_read;
-		entry->write_proc = cpufreq_proc_write;
-	}
-
-	return 0;
-}
-
-
-/**
- * cpufreq_proc_exit - removes "cpufreq" from the /proc root directory.
- *
- * This function removes "cpufreq" from the /proc root directory.
- */
-static void __exit cpufreq_proc_exit (void)
-{
-	remove_proc_entry("cpufreq", &proc_root);
-	return;
-}
-
-MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION ("CPUfreq /proc/cpufreq interface");
-MODULE_LICENSE ("GPL");
-
-module_init(cpufreq_proc_init);
-module_exit(cpufreq_proc_exit);
diff -Nru a/include/linux/cpufreq.h b/include/linux/cpufreq.h
--- a/include/linux/cpufreq.h	2005-01-02 23:08:21 -08:00
+++ b/include/linux/cpufreq.h	2005-01-02 23:08:21 -08:00
@@ -252,65 +252,6 @@
 /* query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it */
 unsigned int cpufreq_get(unsigned int cpu);
 
-/* the proc_intf.c needs this */
-int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor);
-
-
-/*********************************************************************
- *                      CPUFREQ USERSPACE GOVERNOR                   *
- *********************************************************************/
-#ifdef CONFIG_CPU_FREQ_24_API
-
-int __deprecated cpufreq_setmax(unsigned int cpu);
-int __deprecated cpufreq_set(unsigned int kHz, unsigned int cpu);
-
-
-/* /proc/sys/cpu */
-enum {
-	CPU_NR   = 1,           /* compatibilty reasons */
-	CPU_NR_0 = 1,
-	CPU_NR_1 = 2,
-	CPU_NR_2 = 3,
-	CPU_NR_3 = 4,
-	CPU_NR_4 = 5,
-	CPU_NR_5 = 6,
-	CPU_NR_6 = 7,
-	CPU_NR_7 = 8,
-	CPU_NR_8 = 9,
-	CPU_NR_9 = 10,
-	CPU_NR_10 = 11,
-	CPU_NR_11 = 12,
-	CPU_NR_12 = 13,
-	CPU_NR_13 = 14,
-	CPU_NR_14 = 15,
-	CPU_NR_15 = 16,
-	CPU_NR_16 = 17,
-	CPU_NR_17 = 18,
-	CPU_NR_18 = 19,
-	CPU_NR_19 = 20,
-	CPU_NR_20 = 21,
-	CPU_NR_21 = 22,
-	CPU_NR_22 = 23,
-	CPU_NR_23 = 24,
-	CPU_NR_24 = 25,
-	CPU_NR_25 = 26,
-	CPU_NR_26 = 27,
-	CPU_NR_27 = 28,
-	CPU_NR_28 = 29,
-	CPU_NR_29 = 30,
-	CPU_NR_30 = 31,
-	CPU_NR_31 = 32,
-};
-
-/* /proc/sys/cpu/{0,1,...,(NR_CPUS-1)} */
-enum {
-	CPU_NR_FREQ_MAX = 1,
-	CPU_NR_FREQ_MIN = 2,
-	CPU_NR_FREQ = 3,
-};
-
-#endif /* CONFIG_CPU_FREQ_24_API */
-
 
 /*********************************************************************
  *                       CPUFREQ DEFAULT GOVERNOR                    *
@@ -350,6 +291,11 @@
 				   unsigned int target_freq,
 				   unsigned int relation,
 				   unsigned int *index);
+
+/* the following 3 funtions are for cpufreq core use only */
+struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
+struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu);
+void   cpufreq_cpu_put (struct cpufreq_policy *data);
 
 /* the following are really really optional */
 extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;