diff options
Diffstat (limited to 'drivers/acpi/thermal.c')
-rw-r--r-- | drivers/acpi/thermal.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 804204d41999..506fbd4b5733 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -900,14 +900,14 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) | |||
900 | if (tz->trips.passive.flags.valid) | 900 | if (tz->trips.passive.flags.valid) |
901 | tz->thermal_zone = | 901 | tz->thermal_zone = |
902 | thermal_zone_device_register("acpitz", trips, 0, tz, | 902 | thermal_zone_device_register("acpitz", trips, 0, tz, |
903 | &acpi_thermal_zone_ops, | 903 | &acpi_thermal_zone_ops, NULL, |
904 | tz->trips.passive.tsp*100, | 904 | tz->trips.passive.tsp*100, |
905 | tz->polling_frequency*100); | 905 | tz->polling_frequency*100); |
906 | else | 906 | else |
907 | tz->thermal_zone = | 907 | tz->thermal_zone = |
908 | thermal_zone_device_register("acpitz", trips, 0, tz, | 908 | thermal_zone_device_register("acpitz", trips, 0, tz, |
909 | &acpi_thermal_zone_ops, 0, | 909 | &acpi_thermal_zone_ops, NULL, |
910 | tz->polling_frequency*100); | 910 | 0, tz->polling_frequency*100); |
911 | if (IS_ERR(tz->thermal_zone)) | 911 | if (IS_ERR(tz->thermal_zone)) |
912 | return -ENODEV; | 912 | return -ENODEV; |
913 | 913 | ||
@@ -984,6 +984,38 @@ static void acpi_thermal_notify(struct acpi_device *device, u32 event) | |||
984 | } | 984 | } |
985 | } | 985 | } |
986 | 986 | ||
987 | /* | ||
988 | * On some platforms, the AML code has dependency about | ||
989 | * the evaluating order of _TMP and _CRT/_HOT/_PSV/_ACx. | ||
990 | * 1. On HP Pavilion G4-1016tx, _TMP must be invoked after | ||
991 | * /_CRT/_HOT/_PSV/_ACx, or else system will be power off. | ||
992 | * 2. On HP Compaq 6715b/6715s, the return value of _PSV is 0 | ||
993 | * if _TMP has never been evaluated. | ||
994 | * | ||
995 | * As this dependency is totally transparent to OS, evaluate | ||
996 | * all of them once, in the order of _CRT/_HOT/_PSV/_ACx, | ||
997 | * _TMP, before they are actually used. | ||
998 | */ | ||
999 | static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz) | ||
1000 | { | ||
1001 | acpi_handle handle = tz->device->handle; | ||
1002 | unsigned long long value; | ||
1003 | int i; | ||
1004 | |||
1005 | acpi_evaluate_integer(handle, "_CRT", NULL, &value); | ||
1006 | acpi_evaluate_integer(handle, "_HOT", NULL, &value); | ||
1007 | acpi_evaluate_integer(handle, "_PSV", NULL, &value); | ||
1008 | for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { | ||
1009 | char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; | ||
1010 | acpi_status status; | ||
1011 | |||
1012 | status = acpi_evaluate_integer(handle, name, NULL, &value); | ||
1013 | if (status == AE_NOT_FOUND) | ||
1014 | break; | ||
1015 | } | ||
1016 | acpi_evaluate_integer(handle, "_TMP", NULL, &value); | ||
1017 | } | ||
1018 | |||
987 | static int acpi_thermal_get_info(struct acpi_thermal *tz) | 1019 | static int acpi_thermal_get_info(struct acpi_thermal *tz) |
988 | { | 1020 | { |
989 | int result = 0; | 1021 | int result = 0; |
@@ -992,6 +1024,8 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz) | |||
992 | if (!tz) | 1024 | if (!tz) |
993 | return -EINVAL; | 1025 | return -EINVAL; |
994 | 1026 | ||
1027 | acpi_thermal_aml_dependency_fix(tz); | ||
1028 | |||
995 | /* Get trip points [_CRT, _PSV, etc.] (required) */ | 1029 | /* Get trip points [_CRT, _PSV, etc.] (required) */ |
996 | result = acpi_thermal_get_trip_points(tz); | 1030 | result = acpi_thermal_get_trip_points(tz); |
997 | if (result) | 1031 | if (result) |