>From 391908867c2a500a9068aa9f2a8e74663fff75ac Mon Sep 17 00:00:00 2001 From: Zhang Rui <rui.zhang@xxxxxxxxx> Date: Fri, 23 Nov 2012 09:25:10 +0800 Subject: [PATCH] ACPI thermal: _TMP and _CRT/_HOT/_PSV/_ACx dependency fix On some platforms, _TMP and _CRT/_HOT/_PSV/_ACx have dependency. And there is no way for OS to detect this dependency. commit 9bcb8118965ab4631a65ee0726e6518f75cda6c5 shows us a problem that _TMP must be evaluate after _CRT/_HOT/_PSV/_ACx, or esle firmware will shutdown the system. But the machins in https://bugzilla.kernel.org/show_bug.cgi?id=43284 shows us that _PSV would return valid value only if _TMP has been evaluated once. With this patch, all of the control methods will be evaluated once, in the order of _CRT/_HOT/_PSV/_CRT, _TMP, before they are actually used. Signed-off-by: Zhang Rui <rui.zhang@xxxxxxxxx> Tested-by: katabami <katabami@xxxxxxxxxxx> --- drivers/acpi/thermal.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 804204d..1cb08db 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -984,6 +984,35 @@ 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) +{ + unsigned long long value; + acpi_status status = AE_OK; + int i; + + acpi_evaluate_integer(tz->device->handle, "_CRT", NULL, &value); + acpi_evaluate_integer(tz->device->handle, "_HOT", NULL, &value); + acpi_evaluate_integer(tz->device->handle, "_PSV", NULL, &value); + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && status != AE_NOT_FOUND; i++ ) { + char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; + + status = acpi_evaluate_integer(tz->device->handle, + name, NULL, &value); + } + acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &value); +} + static int acpi_thermal_get_info(struct acpi_thermal *tz) { int result = 0; @@ -992,6 +1021,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) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html