| From jejb@kernel.org Wed Jul 30 14:14:28 2008 |
| From: Thomas Renninger <trenn@suse.de> |
| Date: Wed, 30 Jul 2008 18:20:10 GMT |
| Subject: cpufreq acpi: only call _PPC after cpufreq ACPI init funcs got called already |
| To: jejb@kernel.org, stable@kernel.org |
| Message-ID: <200807301820.m6UIKAtd025816@hera.kernel.org> |
| |
| From: Thomas Renninger <trenn@suse.de> |
| |
| commit a1531acd43310a7e4571d52e8846640667f4c74b upstream |
| |
| Ingo Molnar provided a fix to not call _PPC at processor driver |
| initialization time in "[PATCH] ACPI: fix cpufreq regression" (git |
| commit e4233dec749a3519069d9390561b5636a75c7579) |
| |
| But it can still happen that _PPC is called at processor driver |
| initialization time. |
| |
| This patch should make sure that this is not possible anymore. |
| |
| Signed-off-by: Thomas Renninger <trenn@suse.de> |
| Cc: Andi Kleen <andi@firstfloor.org> |
| Cc: Len Brown <lenb@kernel.org> |
| Cc: Dave Jones <davej@codemonkey.org.uk> |
| Cc: Ingo Molnar <mingo@elte.hu> |
| Cc: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c | 6 ++++++ |
| drivers/acpi/processor_perflib.c | 15 +++++++++++++-- |
| drivers/cpufreq/cpufreq.c | 3 +++ |
| include/linux/cpufreq.h | 1 + |
| 4 files changed, 23 insertions(+), 2 deletions(-) |
| |
| --- a/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c |
| +++ b/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c |
| @@ -96,6 +96,12 @@ static int pmi_notifier(struct notifier_ |
| struct cpufreq_frequency_table *cbe_freqs; |
| u8 node; |
| |
| + /* Should this really be called for CPUFREQ_ADJUST, CPUFREQ_INCOMPATIBLE |
| + * and CPUFREQ_NOTIFY policy events?) |
| + */ |
| + if (event == CPUFREQ_START) |
| + return 0; |
| + |
| cbe_freqs = cpufreq_frequency_get_table(policy->cpu); |
| node = cbe_cpu_to_node(policy->cpu); |
| |
| --- a/drivers/acpi/processor_perflib.c |
| +++ b/drivers/acpi/processor_perflib.c |
| @@ -64,7 +64,13 @@ static DEFINE_MUTEX(performance_mutex); |
| * policy is adjusted accordingly. |
| */ |
| |
| -static unsigned int ignore_ppc = 0; |
| +/* ignore_ppc: |
| + * -1 -> cpufreq low level drivers not initialized -> _PSS, etc. not called yet |
| + * ignore _PPC |
| + * 0 -> cpufreq low level drivers initialized -> consider _PPC values |
| + * 1 -> ignore _PPC totally -> forced by user through boot param |
| + */ |
| +static unsigned int ignore_ppc = -1; |
| module_param(ignore_ppc, uint, 0644); |
| MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \ |
| "limited by BIOS, this should help"); |
| @@ -72,7 +78,7 @@ MODULE_PARM_DESC(ignore_ppc, "If the fre |
| #define PPC_REGISTERED 1 |
| #define PPC_IN_USE 2 |
| |
| -static int acpi_processor_ppc_status = 0; |
| +static int acpi_processor_ppc_status; |
| |
| static int acpi_processor_ppc_notifier(struct notifier_block *nb, |
| unsigned long event, void *data) |
| @@ -81,6 +87,11 @@ static int acpi_processor_ppc_notifier(s |
| struct acpi_processor *pr; |
| unsigned int ppc = 0; |
| |
| + if (event == CPUFREQ_START && ignore_ppc <= 0) { |
| + ignore_ppc = 0; |
| + return 0; |
| + } |
| + |
| if (ignore_ppc) |
| return 0; |
| |
| --- a/drivers/cpufreq/cpufreq.c |
| +++ b/drivers/cpufreq/cpufreq.c |
| @@ -806,6 +806,9 @@ static int cpufreq_add_dev (struct sys_d |
| policy->user_policy.min = policy->cpuinfo.min_freq; |
| policy->user_policy.max = policy->cpuinfo.max_freq; |
| |
| + blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
| + CPUFREQ_START, policy); |
| + |
| #ifdef CONFIG_SMP |
| |
| #ifdef CONFIG_HOTPLUG_CPU |
| --- a/include/linux/cpufreq.h |
| +++ b/include/linux/cpufreq.h |
| @@ -108,6 +108,7 @@ struct cpufreq_policy { |
| #define CPUFREQ_ADJUST (0) |
| #define CPUFREQ_INCOMPATIBLE (1) |
| #define CPUFREQ_NOTIFY (2) |
| +#define CPUFREQ_START (3) |
| |
| #define CPUFREQ_SHARED_TYPE_NONE (0) /* None */ |
| #define CPUFREQ_SHARED_TYPE_HW (1) /* HW does needed coordination */ |