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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # 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 # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # ChangeSet # 2004/12/29 02:51:32-05:00 davej@redhat.com # [CPUFREQ] cpufreq stat output in sysfs # # From: "Zou, Nanhai" # # 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 # # 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" # # 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 # # 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" # # 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 # # 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" # # 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 # # 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" # # 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 # # 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" # # 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 # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # ChangeSet # 2004/12/29 02:46:18-05:00 davej@redhat.com # [CPUFREQ] powernow-k8: small cleanups / documentation additions (Pavel Machek) # # From: Pavel Machek # # 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 # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # 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 # # 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 # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # 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 # # 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 # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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 # Signed-off-by: Dave Jones # # 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" # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # # 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" # Signed-off-by: Dominik Brodowski # Signed-off-by: Dave Jones # 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 @@ -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 #include #include +#include +#include #ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI #include @@ -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; iop_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; iop_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 . - - 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 . 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" 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 . + * (C) 2004 Zou Nan hai . + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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(¬ifier_policy_block, + CPUFREQ_POLICY_NOTIFIER))) + return ret; + + if ((ret = cpufreq_register_notifier(¬ifier_trans_block, + CPUFREQ_TRANSITION_NOTIFIER))) { + cpufreq_unregister_notifier(¬ifier_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(¬ifier_policy_block, + CPUFREQ_POLICY_NOTIFIER); + cpufreq_unregister_notifier(¬ifier_trans_block, + CPUFREQ_TRANSITION_NOTIFIER); + for_each_cpu(cpu) + cpufreq_stats_free_table(cpu); +} + +MODULE_AUTHOR ("Zou Nan hai "); +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 #include #include -#include #include -#include #include #include #include #include -#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 "); 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 -#include -#include -#include -#include -#include -#include - -#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(¤t_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(¤t_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;iname); - } -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; iread_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 "); -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;