diff options
author | Zhao Yakui <yakui.zhao@intel.com> | 2009-10-15 21:20:41 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-11-06 01:58:07 -0500 |
commit | d81c45e1c9369855901420f79114852eba2ea16a (patch) | |
tree | 910e9b4044bee76568c9eaeff70aac2fbc2385ab /drivers/acpi | |
parent | b419148e567728f6af0c3b01965c1cc141e3e13a (diff) |
ACPI: Notify the _PPC evaluation status to the platform
According to the ACPI spec(section 8.4.4.3) OSPM should convey the _PPC
evaluations status to the platform if there exists the _OST object.
The _OST contains two arguments:
The first is the PERFORMANCE notificatin event.
The second is the status of _PPC object.
OSPM will convey the _PPC evaluation status to the platform.
Of course when the module parameter of "ignore_ppc" is added, OSPM won't
evaluate the _PPC object. But it will call the _OST object.
At the same time the _OST object will be evaluated only when the PERFORMANCE
notification event is received.
Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/processor_core.c | 6 | ||||
-rw-r--r-- | drivers/acpi/processor_perflib.c | 50 |
2 files changed, 50 insertions, 6 deletions
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index c567b46dfa0f..773d7e76f301 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -722,7 +722,7 @@ static void acpi_processor_notify(struct acpi_device *device, u32 event) | |||
722 | switch (event) { | 722 | switch (event) { |
723 | case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: | 723 | case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: |
724 | saved = pr->performance_platform_limit; | 724 | saved = pr->performance_platform_limit; |
725 | acpi_processor_ppc_has_changed(pr); | 725 | acpi_processor_ppc_has_changed(pr, 1); |
726 | if (saved == pr->performance_platform_limit) | 726 | if (saved == pr->performance_platform_limit) |
727 | break; | 727 | break; |
728 | acpi_bus_generate_proc_event(device, event, | 728 | acpi_bus_generate_proc_event(device, event, |
@@ -758,7 +758,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, | |||
758 | struct acpi_processor *pr = per_cpu(processors, cpu); | 758 | struct acpi_processor *pr = per_cpu(processors, cpu); |
759 | 759 | ||
760 | if (action == CPU_ONLINE && pr) { | 760 | if (action == CPU_ONLINE && pr) { |
761 | acpi_processor_ppc_has_changed(pr); | 761 | acpi_processor_ppc_has_changed(pr, 0); |
762 | acpi_processor_cst_has_changed(pr); | 762 | acpi_processor_cst_has_changed(pr); |
763 | acpi_processor_tstate_has_changed(pr); | 763 | acpi_processor_tstate_has_changed(pr); |
764 | } | 764 | } |
@@ -830,7 +830,7 @@ static int acpi_processor_add(struct acpi_device *device) | |||
830 | arch_acpi_processor_cleanup_pdc(pr); | 830 | arch_acpi_processor_cleanup_pdc(pr); |
831 | 831 | ||
832 | #ifdef CONFIG_CPU_FREQ | 832 | #ifdef CONFIG_CPU_FREQ |
833 | acpi_processor_ppc_has_changed(pr); | 833 | acpi_processor_ppc_has_changed(pr, 0); |
834 | #endif | 834 | #endif |
835 | acpi_processor_get_throttling_info(pr); | 835 | acpi_processor_get_throttling_info(pr); |
836 | acpi_processor_get_limit_info(pr); | 836 | acpi_processor_get_limit_info(pr); |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 8ba0ed0b9ddb..fc1f49bbbeef 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -152,15 +152,59 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) | |||
152 | return 0; | 152 | return 0; |
153 | } | 153 | } |
154 | 154 | ||
155 | int acpi_processor_ppc_has_changed(struct acpi_processor *pr) | 155 | #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 |
156 | /* | ||
157 | * acpi_processor_ppc_ost: Notify firmware the _PPC evaluation status | ||
158 | * @handle: ACPI processor handle | ||
159 | * @status: the status code of _PPC evaluation | ||
160 | * 0: success. OSPM is now using the performance state specificed. | ||
161 | * 1: failure. OSPM has not changed the number of P-states in use | ||
162 | */ | ||
163 | static void acpi_processor_ppc_ost(acpi_handle handle, int status) | ||
164 | { | ||
165 | union acpi_object params[2] = { | ||
166 | {.type = ACPI_TYPE_INTEGER,}, | ||
167 | {.type = ACPI_TYPE_INTEGER,}, | ||
168 | }; | ||
169 | struct acpi_object_list arg_list = {2, params}; | ||
170 | acpi_handle temp; | ||
171 | |||
172 | params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE; | ||
173 | params[1].integer.value = status; | ||
174 | |||
175 | /* when there is no _OST , skip it */ | ||
176 | if (ACPI_FAILURE(acpi_get_handle(handle, "_OST", &temp))) | ||
177 | return; | ||
178 | |||
179 | acpi_evaluate_object(handle, "_OST", &arg_list, NULL); | ||
180 | return; | ||
181 | } | ||
182 | |||
183 | int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag) | ||
156 | { | 184 | { |
157 | int ret; | 185 | int ret; |
158 | 186 | ||
159 | if (ignore_ppc) | 187 | if (ignore_ppc) { |
188 | /* | ||
189 | * Only when it is notification event, the _OST object | ||
190 | * will be evaluated. Otherwise it is skipped. | ||
191 | */ | ||
192 | if (event_flag) | ||
193 | acpi_processor_ppc_ost(pr->handle, 1); | ||
160 | return 0; | 194 | return 0; |
195 | } | ||
161 | 196 | ||
162 | ret = acpi_processor_get_platform_limit(pr); | 197 | ret = acpi_processor_get_platform_limit(pr); |
163 | 198 | /* | |
199 | * Only when it is notification event, the _OST object | ||
200 | * will be evaluated. Otherwise it is skipped. | ||
201 | */ | ||
202 | if (event_flag) { | ||
203 | if (ret < 0) | ||
204 | acpi_processor_ppc_ost(pr->handle, 1); | ||
205 | else | ||
206 | acpi_processor_ppc_ost(pr->handle, 0); | ||
207 | } | ||
164 | if (ret < 0) | 208 | if (ret < 0) |
165 | return (ret); | 209 | return (ret); |
166 | else | 210 | else |