aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/processor_perflib.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-01-13 01:06:28 -0500
committerPaul Mundt <lethal@linux-sh.org>2011-01-13 01:06:28 -0500
commitf43dc23d5ea91fca257be02138a255f02d98e806 (patch)
treeb29722f6e965316e90ac97abf79923ced250dc21 /drivers/acpi/processor_perflib.c
parentf8e53553f452dcbf67cb89c8cba63a1cd6eb4cc0 (diff)
parent4162cf64973df51fc885825bc9ca4d055891c49f (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into common/serial-rework
Conflicts: arch/sh/kernel/cpu/sh2/setup-sh7619.c arch/sh/kernel/cpu/sh2a/setup-mxg.c arch/sh/kernel/cpu/sh2a/setup-sh7201.c arch/sh/kernel/cpu/sh2a/setup-sh7203.c arch/sh/kernel/cpu/sh2a/setup-sh7206.c arch/sh/kernel/cpu/sh3/setup-sh7705.c arch/sh/kernel/cpu/sh3/setup-sh770x.c arch/sh/kernel/cpu/sh3/setup-sh7710.c arch/sh/kernel/cpu/sh3/setup-sh7720.c arch/sh/kernel/cpu/sh4/setup-sh4-202.c arch/sh/kernel/cpu/sh4/setup-sh7750.c arch/sh/kernel/cpu/sh4/setup-sh7760.c arch/sh/kernel/cpu/sh4a/setup-sh7343.c arch/sh/kernel/cpu/sh4a/setup-sh7366.c arch/sh/kernel/cpu/sh4a/setup-sh7722.c arch/sh/kernel/cpu/sh4a/setup-sh7723.c arch/sh/kernel/cpu/sh4a/setup-sh7724.c arch/sh/kernel/cpu/sh4a/setup-sh7763.c arch/sh/kernel/cpu/sh4a/setup-sh7770.c arch/sh/kernel/cpu/sh4a/setup-sh7780.c arch/sh/kernel/cpu/sh4a/setup-sh7785.c arch/sh/kernel/cpu/sh4a/setup-sh7786.c arch/sh/kernel/cpu/sh4a/setup-shx3.c arch/sh/kernel/cpu/sh5/setup-sh5.c drivers/serial/sh-sci.c drivers/serial/sh-sci.h include/linux/serial_sci.h
Diffstat (limited to 'drivers/acpi/processor_perflib.c')
-rw-r--r--drivers/acpi/processor_perflib.c81
1 files changed, 72 insertions, 9 deletions
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 60e543d3234e..3a73a93596e8 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -30,6 +30,7 @@
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/cpufreq.h> 32#include <linux/cpufreq.h>
33#include <linux/slab.h>
33 34
34#ifdef CONFIG_X86 35#ifdef CONFIG_X86
35#include <asm/cpufeature.h> 36#include <asm/cpufeature.h>
@@ -39,6 +40,8 @@
39#include <acpi/acpi_drivers.h> 40#include <acpi/acpi_drivers.h>
40#include <acpi/processor.h> 41#include <acpi/processor.h>
41 42
43#define PREFIX "ACPI: "
44
42#define ACPI_PROCESSOR_CLASS "processor" 45#define ACPI_PROCESSOR_CLASS "processor"
43#define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" 46#define ACPI_PROCESSOR_FILE_PERFORMANCE "performance"
44#define _COMPONENT ACPI_PROCESSOR_COMPONENT 47#define _COMPONENT ACPI_PROCESSOR_COMPONENT
@@ -150,21 +153,78 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
150 return 0; 153 return 0;
151} 154}
152 155
153int acpi_processor_ppc_has_changed(struct acpi_processor *pr) 156#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
157/*
158 * acpi_processor_ppc_ost: Notify firmware the _PPC evaluation status
159 * @handle: ACPI processor handle
160 * @status: the status code of _PPC evaluation
161 * 0: success. OSPM is now using the performance state specificed.
162 * 1: failure. OSPM has not changed the number of P-states in use
163 */
164static void acpi_processor_ppc_ost(acpi_handle handle, int status)
165{
166 union acpi_object params[2] = {
167 {.type = ACPI_TYPE_INTEGER,},
168 {.type = ACPI_TYPE_INTEGER,},
169 };
170 struct acpi_object_list arg_list = {2, params};
171 acpi_handle temp;
172
173 params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE;
174 params[1].integer.value = status;
175
176 /* when there is no _OST , skip it */
177 if (ACPI_FAILURE(acpi_get_handle(handle, "_OST", &temp)))
178 return;
179
180 acpi_evaluate_object(handle, "_OST", &arg_list, NULL);
181 return;
182}
183
184int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag)
154{ 185{
155 int ret; 186 int ret;
156 187
157 if (ignore_ppc) 188 if (ignore_ppc) {
189 /*
190 * Only when it is notification event, the _OST object
191 * will be evaluated. Otherwise it is skipped.
192 */
193 if (event_flag)
194 acpi_processor_ppc_ost(pr->handle, 1);
158 return 0; 195 return 0;
196 }
159 197
160 ret = acpi_processor_get_platform_limit(pr); 198 ret = acpi_processor_get_platform_limit(pr);
161 199 /*
200 * Only when it is notification event, the _OST object
201 * will be evaluated. Otherwise it is skipped.
202 */
203 if (event_flag) {
204 if (ret < 0)
205 acpi_processor_ppc_ost(pr->handle, 1);
206 else
207 acpi_processor_ppc_ost(pr->handle, 0);
208 }
162 if (ret < 0) 209 if (ret < 0)
163 return (ret); 210 return (ret);
164 else 211 else
165 return cpufreq_update_policy(pr->id); 212 return cpufreq_update_policy(pr->id);
166} 213}
167 214
215int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
216{
217 struct acpi_processor *pr;
218
219 pr = per_cpu(processors, cpu);
220 if (!pr || !pr->performance || !pr->performance->state_count)
221 return -ENODEV;
222 *limit = pr->performance->states[pr->performance_platform_limit].
223 core_frequency * 1000;
224 return 0;
225}
226EXPORT_SYMBOL(acpi_processor_get_bios_limit);
227
168void acpi_processor_ppc_init(void) 228void acpi_processor_ppc_init(void)
169{ 229{
170 if (!cpufreq_register_notifier 230 if (!cpufreq_register_notifier
@@ -354,7 +414,11 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr)
354 if (result) 414 if (result)
355 goto update_bios; 415 goto update_bios;
356 416
357 return 0; 417 /* We need to call _PPC once when cpufreq starts */
418 if (ignore_ppc != 1)
419 result = acpi_processor_get_platform_limit(pr);
420
421 return result;
358 422
359 /* 423 /*
360 * Having _PPC but missing frequencies (_PSS, _PCT) is a very good hint that 424 * Having _PPC but missing frequencies (_PSS, _PCT) is a very good hint that
@@ -383,8 +447,8 @@ int acpi_processor_notify_smm(struct module *calling_module)
383 if (!try_module_get(calling_module)) 447 if (!try_module_get(calling_module))
384 return -EINVAL; 448 return -EINVAL;
385 449
386 /* is_done is set to negative if an error occured, 450 /* is_done is set to negative if an error occurred,
387 * and to postitive if _no_ error occured, but SMM 451 * and to postitive if _no_ error occurred, but SMM
388 * was already notified. This avoids double notification 452 * was already notified. This avoids double notification
389 * which might lead to unexpected results... 453 * which might lead to unexpected results...
390 */ 454 */
@@ -498,7 +562,7 @@ end:
498} 562}
499 563
500int acpi_processor_preregister_performance( 564int acpi_processor_preregister_performance(
501 struct acpi_processor_performance *performance) 565 struct acpi_processor_performance __percpu *performance)
502{ 566{
503 int count, count_target; 567 int count, count_target;
504 int retval = 0; 568 int retval = 0;
@@ -509,7 +573,7 @@ int acpi_processor_preregister_performance(
509 struct acpi_processor *match_pr; 573 struct acpi_processor *match_pr;
510 struct acpi_psd_package *match_pdomain; 574 struct acpi_psd_package *match_pdomain;
511 575
512 if (!alloc_cpumask_var(&covered_cpus, GFP_KERNEL)) 576 if (!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL))
513 return -ENOMEM; 577 return -ENOMEM;
514 578
515 mutex_lock(&performance_mutex); 579 mutex_lock(&performance_mutex);
@@ -556,7 +620,6 @@ int acpi_processor_preregister_performance(
556 * Now that we have _PSD data from all CPUs, lets setup P-state 620 * Now that we have _PSD data from all CPUs, lets setup P-state
557 * domain info. 621 * domain info.
558 */ 622 */
559 cpumask_clear(covered_cpus);
560 for_each_possible_cpu(i) { 623 for_each_possible_cpu(i) {
561 pr = per_cpu(processors, i); 624 pr = per_cpu(processors, i);
562 if (!pr) 625 if (!pr)