aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/thermal.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index e8c143caf0fd..ddbb7c8f994d 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -192,6 +192,7 @@ struct acpi_thermal {
192 struct acpi_handle_list devices; 192 struct acpi_handle_list devices;
193 struct thermal_zone_device *thermal_zone; 193 struct thermal_zone_device *thermal_zone;
194 int tz_enabled; 194 int tz_enabled;
195 int kelvin_offset;
195 struct mutex lock; 196 struct mutex lock;
196}; 197};
197 198
@@ -581,7 +582,7 @@ static void acpi_thermal_check(void *data)
581} 582}
582 583
583/* sys I/F for generic thermal sysfs support */ 584/* sys I/F for generic thermal sysfs support */
584#define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200) 585#define KELVIN_TO_MILLICELSIUS(t, off) (((t) - (off)) * 100)
585 586
586static int thermal_get_temp(struct thermal_zone_device *thermal, 587static int thermal_get_temp(struct thermal_zone_device *thermal,
587 unsigned long *temp) 588 unsigned long *temp)
@@ -596,7 +597,7 @@ static int thermal_get_temp(struct thermal_zone_device *thermal,
596 if (result) 597 if (result)
597 return result; 598 return result;
598 599
599 *temp = KELVIN_TO_MILLICELSIUS(tz->temperature); 600 *temp = KELVIN_TO_MILLICELSIUS(tz->temperature, tz->kelvin_offset);
600 return 0; 601 return 0;
601} 602}
602 603
@@ -702,7 +703,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
702 if (tz->trips.critical.flags.valid) { 703 if (tz->trips.critical.flags.valid) {
703 if (!trip) { 704 if (!trip) {
704 *temp = KELVIN_TO_MILLICELSIUS( 705 *temp = KELVIN_TO_MILLICELSIUS(
705 tz->trips.critical.temperature); 706 tz->trips.critical.temperature,
707 tz->kelvin_offset);
706 return 0; 708 return 0;
707 } 709 }
708 trip--; 710 trip--;
@@ -711,7 +713,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
711 if (tz->trips.hot.flags.valid) { 713 if (tz->trips.hot.flags.valid) {
712 if (!trip) { 714 if (!trip) {
713 *temp = KELVIN_TO_MILLICELSIUS( 715 *temp = KELVIN_TO_MILLICELSIUS(
714 tz->trips.hot.temperature); 716 tz->trips.hot.temperature,
717 tz->kelvin_offset);
715 return 0; 718 return 0;
716 } 719 }
717 trip--; 720 trip--;
@@ -720,7 +723,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
720 if (tz->trips.passive.flags.valid) { 723 if (tz->trips.passive.flags.valid) {
721 if (!trip) { 724 if (!trip) {
722 *temp = KELVIN_TO_MILLICELSIUS( 725 *temp = KELVIN_TO_MILLICELSIUS(
723 tz->trips.passive.temperature); 726 tz->trips.passive.temperature,
727 tz->kelvin_offset);
724 return 0; 728 return 0;
725 } 729 }
726 trip--; 730 trip--;
@@ -730,7 +734,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
730 tz->trips.active[i].flags.valid; i++) { 734 tz->trips.active[i].flags.valid; i++) {
731 if (!trip) { 735 if (!trip) {
732 *temp = KELVIN_TO_MILLICELSIUS( 736 *temp = KELVIN_TO_MILLICELSIUS(
733 tz->trips.active[i].temperature); 737 tz->trips.active[i].temperature,
738 tz->kelvin_offset);
734 return 0; 739 return 0;
735 } 740 }
736 trip--; 741 trip--;
@@ -745,7 +750,8 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
745 750
746 if (tz->trips.critical.flags.valid) { 751 if (tz->trips.critical.flags.valid) {
747 *temperature = KELVIN_TO_MILLICELSIUS( 752 *temperature = KELVIN_TO_MILLICELSIUS(
748 tz->trips.critical.temperature); 753 tz->trips.critical.temperature,
754 tz->kelvin_offset);
749 return 0; 755 return 0;
750 } else 756 } else
751 return -EINVAL; 757 return -EINVAL;
@@ -1334,6 +1340,25 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz)
1334 return 0; 1340 return 0;
1335} 1341}
1336 1342
1343/*
1344 * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI
1345 * handles temperature values with a single decimal place. As a consequence,
1346 * some implementations use an offset of 273.1 and others use an offset of
1347 * 273.2. Try to find out which one is being used, to present the most
1348 * accurate and visually appealing number.
1349 *
1350 * The heuristic below should work for all ACPI thermal zones which have a
1351 * critical trip point with a value being a multiple of 0.5 degree Celsius.
1352 */
1353static void acpi_thermal_guess_offset(struct acpi_thermal *tz)
1354{
1355 if (tz->trips.critical.flags.valid &&
1356 (tz->trips.critical.temperature % 5) == 1)
1357 tz->kelvin_offset = 2731;
1358 else
1359 tz->kelvin_offset = 2732;
1360}
1361
1337static int acpi_thermal_add(struct acpi_device *device) 1362static int acpi_thermal_add(struct acpi_device *device)
1338{ 1363{
1339 int result = 0; 1364 int result = 0;
@@ -1360,6 +1385,8 @@ static int acpi_thermal_add(struct acpi_device *device)
1360 if (result) 1385 if (result)
1361 goto free_memory; 1386 goto free_memory;
1362 1387
1388 acpi_thermal_guess_offset(tz);
1389
1363 result = acpi_thermal_register_thermal_zone(tz); 1390 result = acpi_thermal_register_thermal_zone(tz);
1364 if (result) 1391 if (result)
1365 goto free_memory; 1392 goto free_memory;