From d0c9109408001d1b6180872cea36f16256a6b107 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 23 Jun 2014 10:06:48 +0800 Subject: [PATCH 1/3] THERMAL: initialize thermal zone device correctly Currently, after a thermal zone device registered, tz->temperature is 0. This is wrong because 0 actually means 0 degree celsius but we have never read the real temperature. Fix this problem by initializing the tz->temperature to -274C. Signed-off-by: Zhang Rui --- drivers/thermal/thermal_core.c | 27 ++++++++++++++++++++++++--- include/linux/thermal.h | 3 +++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 71b0ec0..61d0f5a 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -169,6 +169,13 @@ int get_tz_trend(struct thermal_zone_device *tz, int trip) { enum thermal_trend trend; + /* + * If it's the first time to read the temperature, pretend it is DECREASING + * -- otherwise we'd get 100% fan speed (emergency level) after resume. + */ + if (tz->last_temperature == THERMAL_TEMP_INVALID) + return THERMAL_TREND_DROPPING; + if (tz->emul_temperature || !tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) { if (tz->temperature > tz->last_temperature) @@ -463,8 +470,12 @@ static void update_temperature(struct thermal_zone_device *tz) mutex_unlock(&tz->lock); trace_thermal_temperature(tz); - dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n", - tz->last_temperature, tz->temperature); + if (tz->last_temperature == THERMAL_TEMP_INVALID) + dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n", + tz->temperature); + else + dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n", + tz->last_temperature, tz->temperature); } void thermal_zone_device_update(struct thermal_zone_device *tz) @@ -1417,6 +1428,16 @@ static void remove_trip_attrs(struct thermal_zone_device *tz) kfree(tz->trip_hyst_attrs); } +static void thermal_zone_device_reset(struct thermal_zone_device *tz) +{ + struct thermal_instance *pos; + + tz->temperature = THERMAL_TEMP_INVALID; + list_for_each_entry(pos, &tz->thermal_instances, tz_node) + pos->target = THERMAL_NO_TARGET; + thermal_zone_device_update(tz); +} + /** * thermal_zone_device_register() - register a new thermal zone device * @type: the thermal zone device type @@ -1566,7 +1587,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, if (!tz->ops->get_temp) thermal_zone_device_set_polling(tz, 0); - thermal_zone_device_update(tz); + thermal_zone_device_reset(tz); return tz; rmal.h b/include/linux/thermal.h index 0305cde..0e8f08b 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -40,6 +40,9 @@ /* No upper/lower limit requirement */ #define THERMAL_NO_LIMIT THERMAL_CSTATE_INVALID +/* Invalid/uninitialized temperature */ +#define THERMAL_TEMP_INVALID -27400 + /* Unit conversion macros */ #define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732 >= 0) ? \ ((long)t-2732+5)/10 : ((long)t-2732-5)/10) -- 1.8.3.2