|
@@ -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)
|