Commit d81c45e1 authored by Zhao Yakui's avatar Zhao Yakui Committed by Len Brown

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: default avatarZhao Yakui <yakui.zhao@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent b419148e
...@@ -722,7 +722,7 @@ static void acpi_processor_notify(struct acpi_device *device, u32 event) ...@@ -722,7 +722,7 @@ static void acpi_processor_notify(struct acpi_device *device, u32 event)
switch (event) { switch (event) {
case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
saved = pr->performance_platform_limit; saved = pr->performance_platform_limit;
acpi_processor_ppc_has_changed(pr); acpi_processor_ppc_has_changed(pr, 1);
if (saved == pr->performance_platform_limit) if (saved == pr->performance_platform_limit)
break; break;
acpi_bus_generate_proc_event(device, event, acpi_bus_generate_proc_event(device, event,
...@@ -758,7 +758,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, ...@@ -758,7 +758,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
struct acpi_processor *pr = per_cpu(processors, cpu); struct acpi_processor *pr = per_cpu(processors, cpu);
if (action == CPU_ONLINE && pr) { if (action == CPU_ONLINE && pr) {
acpi_processor_ppc_has_changed(pr); acpi_processor_ppc_has_changed(pr, 0);
acpi_processor_cst_has_changed(pr); acpi_processor_cst_has_changed(pr);
acpi_processor_tstate_has_changed(pr); acpi_processor_tstate_has_changed(pr);
} }
...@@ -830,7 +830,7 @@ static int acpi_processor_add(struct acpi_device *device) ...@@ -830,7 +830,7 @@ static int acpi_processor_add(struct acpi_device *device)
arch_acpi_processor_cleanup_pdc(pr); arch_acpi_processor_cleanup_pdc(pr);
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
acpi_processor_ppc_has_changed(pr); acpi_processor_ppc_has_changed(pr, 0);
#endif #endif
acpi_processor_get_throttling_info(pr); acpi_processor_get_throttling_info(pr);
acpi_processor_get_limit_info(pr); acpi_processor_get_limit_info(pr);
......
...@@ -152,15 +152,59 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) ...@@ -152,15 +152,59 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
return 0; return 0;
} }
int acpi_processor_ppc_has_changed(struct acpi_processor *pr) #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
/*
* acpi_processor_ppc_ost: Notify firmware the _PPC evaluation status
* @handle: ACPI processor handle
* @status: the status code of _PPC evaluation
* 0: success. OSPM is now using the performance state specificed.
* 1: failure. OSPM has not changed the number of P-states in use
*/
static void acpi_processor_ppc_ost(acpi_handle handle, int status)
{
union acpi_object params[2] = {
{.type = ACPI_TYPE_INTEGER,},
{.type = ACPI_TYPE_INTEGER,},
};
struct acpi_object_list arg_list = {2, params};
acpi_handle temp;
params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE;
params[1].integer.value = status;
/* when there is no _OST , skip it */
if (ACPI_FAILURE(acpi_get_handle(handle, "_OST", &temp)))
return;
acpi_evaluate_object(handle, "_OST", &arg_list, NULL);
return;
}
int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag)
{ {
int ret; int ret;
if (ignore_ppc) if (ignore_ppc) {
/*
* Only when it is notification event, the _OST object
* will be evaluated. Otherwise it is skipped.
*/
if (event_flag)
acpi_processor_ppc_ost(pr->handle, 1);
return 0; return 0;
}
ret = acpi_processor_get_platform_limit(pr); ret = acpi_processor_get_platform_limit(pr);
/*
* Only when it is notification event, the _OST object
* will be evaluated. Otherwise it is skipped.
*/
if (event_flag) {
if (ret < 0)
acpi_processor_ppc_ost(pr->handle, 1);
else
acpi_processor_ppc_ost(pr->handle, 0);
}
if (ret < 0) if (ret < 0)
return (ret); return (ret);
else else
......
...@@ -294,7 +294,7 @@ static inline void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx ...@@ -294,7 +294,7 @@ static inline void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
void acpi_processor_ppc_init(void); void acpi_processor_ppc_init(void);
void acpi_processor_ppc_exit(void); void acpi_processor_ppc_exit(void);
int acpi_processor_ppc_has_changed(struct acpi_processor *pr); int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag);
#else #else
static inline void acpi_processor_ppc_init(void) static inline void acpi_processor_ppc_init(void)
{ {
...@@ -304,7 +304,8 @@ static inline void acpi_processor_ppc_exit(void) ...@@ -304,7 +304,8 @@ static inline void acpi_processor_ppc_exit(void)
{ {
return; return;
} }
static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr) static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr,
int event_flag)
{ {
static unsigned int printout = 1; static unsigned int printout = 1;
if (printout) { if (printout) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment