[PATCH 1/3][v2] Thermal: initialize thermal zone device correctly

2015-10-25 Thread Chen Yu
From: Zhang Rui 

After thermal zone device registered, as we have not read any
temperature before, thus tz->temperature should not be 0,
which actually means 0C, and thermal trend is not available.
In this case, we need specially handling for the first
thermal_zone_device_update().

Both thermal core framework and step_wise governor is
enhanced to handle this. And since the step_wise governor
is the only one that uses trends, so it's the only thermal
governor that needs to be updated.

CC:  #3.18+
Tested-by: Manuel Krause 
Tested-by: szegad 
Tested-by: prash 
Tested-by: amish 
Tested-by: Matthias 
Reviewed-by: Javi Merino 
Signed-off-by: Zhang Rui 
Signed-off-by: Chen Yu 
---
 drivers/thermal/step_wise.c| 17 +++--
 drivers/thermal/thermal_core.c | 19 +--
 drivers/thermal/thermal_core.h |  1 +
 include/linux/thermal.h|  3 +++
 4 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c
index 2f9f708..ea9366a 100644
--- a/drivers/thermal/step_wise.c
+++ b/drivers/thermal/step_wise.c
@@ -63,6 +63,19 @@ static unsigned long get_target_state(struct 
thermal_instance *instance,
next_target = instance->target;
dev_dbg(>device, "cur_state=%ld\n", cur_state);
 
+   if (!instance->initialized) {
+   if (throttle) {
+   next_target = (cur_state + 1) >= instance->upper ?
+   instance->upper :
+   ((cur_state + 1) < instance->lower ?
+   instance->lower : (cur_state + 1));
+   } else {
+   next_target = THERMAL_NO_TARGET;
+   }
+
+   return next_target;
+   }
+
switch (trend) {
case THERMAL_TREND_RAISING:
if (throttle) {
@@ -149,7 +162,7 @@ static void thermal_zone_trip_update(struct 
thermal_zone_device *tz, int trip)
dev_dbg(>cdev->device, "old_target=%d, target=%d\n",
old_target, (int)instance->target);
 
-   if (old_target == instance->target)
+   if (instance->initialized && old_target == instance->target)
continue;
 
/* Activate a passive thermal instance */
@@ -161,7 +174,7 @@ static void thermal_zone_trip_update(struct 
thermal_zone_device *tz, int trip)
instance->target == THERMAL_NO_TARGET)
update_passive_instance(tz, trip_type, -1);
 
-
+   instance->initialized = true;
instance->cdev->updated = false; /* cdev needs update */
}
 
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index d9e525c..682bc1e 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -532,8 +532,22 @@ static void update_temperature(struct thermal_zone_device 
*tz)
mutex_unlock(>lock);
 
trace_thermal_temperature(tz);
-   dev_dbg(>device, "last_temperature=%d, current_temperature=%d\n",
-   tz->last_temperature, tz->temperature);
+   if (tz->last_temperature == THERMAL_TEMP_INVALID)
+   dev_dbg(>device, "last_temperature N/A, 
current_temperature=%d\n",
+   tz->temperature);
+   else
+   dev_dbg(>device, "last_temperature=%d, 
current_temperature=%d\n",
+   tz->last_temperature, tz->temperature);
+}
+
+static void thermal_zone_device_reset(struct thermal_zone_device *tz)
+{
+   struct thermal_instance *pos;
+
+   tz->temperature = THERMAL_TEMP_INVALID;
+   tz->passive = 0;
+   list_for_each_entry(pos, >thermal_instances, tz_node)
+   pos->initialized = false;
 }
 
 void thermal_zone_device_update(struct thermal_zone_device *tz)
@@ -1900,6 +1914,7 @@ struct thermal_zone_device 
*thermal_zone_device_register(const char *type,
 
INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
 
+   thermal_zone_device_reset(tz);
thermal_zone_device_update(tz);
 
return tz;
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index d7ac1fc..749d41a 100644
--- a/drivers/thermal/thermal_core.h
+++ b/drivers/thermal/thermal_core.h
@@ -41,6 +41,7 @@ struct thermal_instance {
struct thermal_zone_device *tz;
struct thermal_cooling_device *cdev;
int trip;
+   bool initialized;
unsigned long upper;/* Highest cooling state for this trip point */
unsigned long lower;/* Lowest cooling state for this trip point */
unsigned long target;   /* expected cooling state */
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 157d366..5bcabc7 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -43,6 +43,9 @@
 /* Default weight of a bound cooling device */
 #define 

[PATCH 1/3][v2] Thermal: initialize thermal zone device correctly

2015-10-25 Thread Chen Yu
From: Zhang Rui 

After thermal zone device registered, as we have not read any
temperature before, thus tz->temperature should not be 0,
which actually means 0C, and thermal trend is not available.
In this case, we need specially handling for the first
thermal_zone_device_update().

Both thermal core framework and step_wise governor is
enhanced to handle this. And since the step_wise governor
is the only one that uses trends, so it's the only thermal
governor that needs to be updated.

CC:  #3.18+
Tested-by: Manuel Krause 
Tested-by: szegad 
Tested-by: prash 
Tested-by: amish 
Tested-by: Matthias 
Reviewed-by: Javi Merino 
Signed-off-by: Zhang Rui 
Signed-off-by: Chen Yu 
---
 drivers/thermal/step_wise.c| 17 +++--
 drivers/thermal/thermal_core.c | 19 +--
 drivers/thermal/thermal_core.h |  1 +
 include/linux/thermal.h|  3 +++
 4 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c
index 2f9f708..ea9366a 100644
--- a/drivers/thermal/step_wise.c
+++ b/drivers/thermal/step_wise.c
@@ -63,6 +63,19 @@ static unsigned long get_target_state(struct 
thermal_instance *instance,
next_target = instance->target;
dev_dbg(>device, "cur_state=%ld\n", cur_state);
 
+   if (!instance->initialized) {
+   if (throttle) {
+   next_target = (cur_state + 1) >= instance->upper ?
+   instance->upper :
+   ((cur_state + 1) < instance->lower ?
+   instance->lower : (cur_state + 1));
+   } else {
+   next_target = THERMAL_NO_TARGET;
+   }
+
+   return next_target;
+   }
+
switch (trend) {
case THERMAL_TREND_RAISING:
if (throttle) {
@@ -149,7 +162,7 @@ static void thermal_zone_trip_update(struct 
thermal_zone_device *tz, int trip)
dev_dbg(>cdev->device, "old_target=%d, target=%d\n",
old_target, (int)instance->target);
 
-   if (old_target == instance->target)
+   if (instance->initialized && old_target == instance->target)
continue;
 
/* Activate a passive thermal instance */
@@ -161,7 +174,7 @@ static void thermal_zone_trip_update(struct 
thermal_zone_device *tz, int trip)
instance->target == THERMAL_NO_TARGET)
update_passive_instance(tz, trip_type, -1);
 
-
+   instance->initialized = true;
instance->cdev->updated = false; /* cdev needs update */
}
 
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index d9e525c..682bc1e 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -532,8 +532,22 @@ static void update_temperature(struct thermal_zone_device 
*tz)
mutex_unlock(>lock);
 
trace_thermal_temperature(tz);
-   dev_dbg(>device, "last_temperature=%d, current_temperature=%d\n",
-   tz->last_temperature, tz->temperature);
+   if (tz->last_temperature == THERMAL_TEMP_INVALID)
+   dev_dbg(>device, "last_temperature N/A, 
current_temperature=%d\n",
+   tz->temperature);
+   else
+   dev_dbg(>device, "last_temperature=%d, 
current_temperature=%d\n",
+   tz->last_temperature, tz->temperature);
+}
+
+static void thermal_zone_device_reset(struct thermal_zone_device *tz)
+{
+   struct thermal_instance *pos;
+
+   tz->temperature = THERMAL_TEMP_INVALID;
+   tz->passive = 0;
+   list_for_each_entry(pos, >thermal_instances, tz_node)
+   pos->initialized = false;
 }
 
 void thermal_zone_device_update(struct thermal_zone_device *tz)
@@ -1900,6 +1914,7 @@ struct thermal_zone_device 
*thermal_zone_device_register(const char *type,
 
INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
 
+   thermal_zone_device_reset(tz);
thermal_zone_device_update(tz);
 
return tz;
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h
index d7ac1fc..749d41a 100644
--- a/drivers/thermal/thermal_core.h
+++ b/drivers/thermal/thermal_core.h
@@ -41,6 +41,7 @@ struct thermal_instance {
struct thermal_zone_device *tz;
struct thermal_cooling_device *cdev;
int trip;
+   bool initialized;
unsigned long upper;/* Highest cooling state for this trip point */
unsigned long lower;/* Lowest cooling state for this trip point */
unsigned long target;   /* expected cooling state