diff options
Diffstat (limited to 'drivers/acpi/thermal.c')
| -rw-r--r-- | drivers/acpi/thermal.c | 34 | 
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 804204d4199..6e8cc16b54c 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -984,6 +984,38 @@ static void acpi_thermal_notify(struct acpi_device *device, u32 event)  	}  } +/* + * On some platforms, the AML code has dependency about + * the evaluating order of _TMP and _CRT/_HOT/_PSV/_ACx. + * 1. On HP Pavilion G4-1016tx, _TMP must be invoked after + *    /_CRT/_HOT/_PSV/_ACx, or else system will be power off. + * 2. On HP Compaq 6715b/6715s, the return value of _PSV is 0 + *    if _TMP has never been evaluated. + * + * As this dependency is totally transparent to OS, evaluate + * all of them once, in the order of _CRT/_HOT/_PSV/_ACx, + * _TMP, before they are actually used. + */ +static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz) +{ +	acpi_handle handle = tz->device->handle; +	unsigned long long value; +	int i; + +	acpi_evaluate_integer(handle, "_CRT", NULL, &value); +	acpi_evaluate_integer(handle, "_HOT", NULL, &value); +	acpi_evaluate_integer(handle, "_PSV", NULL, &value); +	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { +		char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; +		acpi_status status; + +		status = acpi_evaluate_integer(handle, name, NULL, &value); +		if (status == AE_NOT_FOUND) +			break; +	} +	acpi_evaluate_integer(handle, "_TMP", NULL, &value); +} +  static int acpi_thermal_get_info(struct acpi_thermal *tz)  {  	int result = 0; @@ -992,6 +1024,8 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz)  	if (!tz)  		return -EINVAL; +	acpi_thermal_aml_dependency_fix(tz); +  	/* Get trip points [_CRT, _PSV, etc.] (required) */  	result = acpi_thermal_get_trip_points(tz);  	if (result)  |