ACPI: Enforce T-state limit changes immediately

When a T-state limit change notification is received,
Linux must evaluate _TPC and change its current
T-state immediately to comply with the new limit.

Previously, Linux would notice the new limit
only upon the next throttling change.

Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Li Shaohua <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
Zhao Yakui 2007-11-15 16:59:30 +08:00 committed by Len Brown
parent 8c0863403f
commit ef54d5ad2f

View file

@ -70,7 +70,55 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
{
return acpi_processor_get_platform_limit(pr);
int result = 0;
int throttling_limit;
int current_state;
struct acpi_processor_limit *limit;
int target_state;
result = acpi_processor_get_platform_limit(pr);
if (result) {
/* Throttling Limit is unsupported */
return result;
}
throttling_limit = pr->throttling_platform_limit;
if (throttling_limit >= pr->throttling.state_count) {
/* Uncorrect Throttling Limit */
return -EINVAL;
}
current_state = pr->throttling.state;
if (current_state > throttling_limit) {
/*
* The current state can meet the requirement of
* _TPC limit. But it is reasonable that OSPM changes
* t-states from high to low for better performance.
* Of course the limit condition of thermal
* and user should be considered.
*/
limit = &pr->limit;
target_state = throttling_limit;
if (limit->thermal.tx > target_state)
target_state = limit->thermal.tx;
if (limit->user.tx > target_state)
target_state = limit->user.tx;
} else if (current_state == throttling_limit) {
/*
* Unnecessary to change the throttling state
*/
return 0;
} else {
/*
* If the current state is lower than the limit of _TPC, it
* will be forced to switch to the throttling state defined
* by throttling_platfor_limit.
* Because the previous state meets with the limit condition
* of thermal and user, it is unnecessary to check it again.
*/
target_state = throttling_limit;
}
return acpi_processor_set_throttling(pr, target_state);
}
/*