thermal: fix a bug in overheat algorithm 89/105389/3
authorlokilee73 <changjoo.lee@samsung.com>
Fri, 16 Dec 2016 10:21:39 +0000 (19:21 +0900)
committerTaeyoung Kim <ty317.kim@samsung.com>
Fri, 16 Dec 2016 11:03:16 +0000 (03:03 -0800)
Change-Id: I3262672daac675445be0704b57d6de1e40c1633f
Signed-off-by: lokilee73 <changjoo.lee@samsung.com>
src/thermal/thermal.c

index c70576a..b69729e 100755 (executable)
@@ -33,12 +33,18 @@ static int noti;
 
 #define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
 
-enum thermal_action_type {
+enum thermal_trend_type {
        NO_CHANGE,
        LOW_TO_HIGH,
        HIGH_TO_LOW,
-       HIGH_TO_CRITICAL,
-       NEED_TO_CHECK
+       HIGH_TO_HIGH
+};
+
+enum thermal_action_type {
+       NOTHING,
+       WARNING,
+       CRITICAL,
+       RECOVER
 };
 
 enum thermal_level_update_type {
@@ -66,24 +72,33 @@ static struct thermal_state temp_state[] = {
        { THERMAL_STATE_NORMAL, THERMAL_STATE_LOW,      NO_CHANGE},
        { THERMAL_STATE_NORMAL, THERMAL_STATE_NORMAL,   NO_CHANGE},
        { THERMAL_STATE_NORMAL, THERMAL_STATE_HIGH,     LOW_TO_HIGH},
-       { THERMAL_STATE_HIGH,   THERMAL_STATE_LOW,      NEED_TO_CHECK},
-       { THERMAL_STATE_HIGH,   THERMAL_STATE_NORMAL,   NEED_TO_CHECK},
-       { THERMAL_STATE_HIGH,   THERMAL_STATE_HIGH,     NEED_TO_CHECK}
+       { THERMAL_STATE_HIGH,   THERMAL_STATE_LOW,      HIGH_TO_LOW},
+       { THERMAL_STATE_HIGH,   THERMAL_STATE_NORMAL,   HIGH_TO_LOW},
+       { THERMAL_STATE_HIGH,   THERMAL_STATE_HIGH,     HIGH_TO_HIGH}
+};
+
+static struct thermal_level lowhigh_temp_level[] = {
+       { THERMAL_LEVEL_NORMAL, THERMAL_LEVEL_WARNING,  WARNING,        UPDATE},
+       { THERMAL_LEVEL_NORMAL, THERMAL_LEVEL_CRITICAL, CRITICAL,       UPDATE},
+       { THERMAL_LEVEL_NORMAL, THERMAL_LEVEL_POWEROFF, CRITICAL,       UPDATE}
+};
+
+static struct thermal_level highlow_temp_level[] = {
+       { THERMAL_LEVEL_POWEROFF,       THERMAL_LEVEL_NORMAL,   NOTHING,        KEEP},
+       { THERMAL_LEVEL_CRITICAL,       THERMAL_LEVEL_NORMAL,   NOTHING,        KEEP},
+       { THERMAL_LEVEL_WARNING,        THERMAL_LEVEL_NORMAL,   RECOVER,        UPDATE}
 };
 
-static struct thermal_level temp_level[] = {
-       { THERMAL_LEVEL_WARNING,        THERMAL_LEVEL_NORMAL,   HIGH_TO_LOW,            UPDATE},
-       { THERMAL_LEVEL_WARNING,        THERMAL_LEVEL_WARNING,  NO_CHANGE,              UPDATE},
-       { THERMAL_LEVEL_WARNING,        THERMAL_LEVEL_CRITICAL, HIGH_TO_CRITICAL,       UPDATE},
-       { THERMAL_LEVEL_WARNING,        THERMAL_LEVEL_POWEROFF, HIGH_TO_CRITICAL,       UPDATE},
-       { THERMAL_LEVEL_CRITICAL,       THERMAL_LEVEL_NORMAL,   NO_CHANGE,              KEEP},
-       { THERMAL_LEVEL_CRITICAL,       THERMAL_LEVEL_WARNING,  NO_CHANGE,              KEEP},
-       { THERMAL_LEVEL_CRITICAL,       THERMAL_LEVEL_CRITICAL, NO_CHANGE,              UPDATE},
-       { THERMAL_LEVEL_CRITICAL,       THERMAL_LEVEL_POWEROFF, NO_CHANGE,              UPDATE},
-       { THERMAL_LEVEL_POWEROFF,       THERMAL_LEVEL_NORMAL,   NO_CHANGE,              KEEP},
-       { THERMAL_LEVEL_POWEROFF,       THERMAL_LEVEL_WARNING,  NO_CHANGE,              KEEP},
-       { THERMAL_LEVEL_POWEROFF,       THERMAL_LEVEL_CRITICAL, NO_CHANGE,              KEEP},
-       { THERMAL_LEVEL_POWEROFF,       THERMAL_LEVEL_POWEROFF, NO_CHANGE,              UPDATE}
+static struct thermal_level highhigh_temp_level[] = {
+       { THERMAL_LEVEL_WARNING,        THERMAL_LEVEL_WARNING,  NOTHING,        UPDATE},
+       { THERMAL_LEVEL_WARNING,        THERMAL_LEVEL_CRITICAL, CRITICAL,       UPDATE},
+       { THERMAL_LEVEL_WARNING,        THERMAL_LEVEL_POWEROFF, CRITICAL,       UPDATE},
+       { THERMAL_LEVEL_CRITICAL,       THERMAL_LEVEL_WARNING,  NOTHING,        KEEP},
+       { THERMAL_LEVEL_CRITICAL,       THERMAL_LEVEL_CRITICAL, NOTHING,        UPDATE},
+       { THERMAL_LEVEL_CRITICAL,       THERMAL_LEVEL_POWEROFF, NOTHING,        UPDATE},
+       { THERMAL_LEVEL_POWEROFF,       THERMAL_LEVEL_WARNING,  NOTHING,        KEEP},
+       { THERMAL_LEVEL_POWEROFF,       THERMAL_LEVEL_CRITICAL, NOTHING,        KEEP},
+       { THERMAL_LEVEL_POWEROFF,       THERMAL_LEVEL_POWEROFF, NOTHING,        UPDATE}
 };
 
 static int thermal_state_check(int old_state, int new_state)
@@ -101,15 +116,43 @@ static int thermal_state_check(int old_state, int new_state)
        return ret;
 }
 
-static void thermal_level_check(int old_level, int new_level, int *out_status, int *out_level)
+static void thermal_up_check(int old_level, int new_level, int *out_status, int *out_level)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(lowhigh_temp_level); i++) {
+               if (old_level == lowhigh_temp_level[i].old_level &&
+                       new_level == lowhigh_temp_level[i].new_level) {
+                       *out_status = lowhigh_temp_level[i].status;
+                       *out_level = lowhigh_temp_level[i].level;
+                       break;
+               }
+       }
+}
+
+static void thermal_down_check(int old_level, int new_level, int *out_status, int *out_level)
 {
        int i;
 
-       for (i = 0; i < ARRAY_SIZE(temp_level); i++) {
-               if (old_level == temp_level[i].old_level &&
-                       new_level == temp_level[i].new_level) {
-                       *out_status = temp_level[i].status;
-                       *out_level = temp_level[i].level;
+       for (i = 0; i < ARRAY_SIZE(highlow_temp_level); i++) {
+               if (old_level == highlow_temp_level[i].old_level &&
+                       new_level == highlow_temp_level[i].new_level) {
+                       *out_status = highlow_temp_level[i].status;
+                       *out_level = highlow_temp_level[i].level;
+                       break;
+               }
+       }
+}
+
+static void thermal_high_check(int old_level, int new_level, int *out_status, int *out_level)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(highhigh_temp_level); i++) {
+               if (old_level == highhigh_temp_level[i].old_level &&
+                       new_level == highhigh_temp_level[i].new_level) {
+                       *out_status = highhigh_temp_level[i].status;
+                       *out_level = highhigh_temp_level[i].level;
                        break;
                }
        }
@@ -150,7 +193,7 @@ static void thermal_add_recovery_popup(void)
 static void thermal_action(struct thermal_info *info, void *data)
 {
        static int old_state = -1, old_level = -1;
-       static int status, high_status, update;
+       static int therm_state = -1, therm_action = -1, update = -1;
 
        if (!info)
                return;
@@ -160,23 +203,31 @@ static void thermal_action(struct thermal_info *info, void *data)
                old_level = info->level;
        }
 
-       status = thermal_state_check(old_state, info->state);
+       therm_state = thermal_state_check(old_state, info->state);
 
-       if (status == NO_CHANGE)
+       if (therm_state == NO_CHANGE)
                update = UPDATE;
-       else if (status == LOW_TO_HIGH) {
+       else if (therm_state == LOW_TO_HIGH) {
+               thermal_up_check(old_level, info->level, &therm_action, &update);
+               if (therm_action == WARNING) {
                thermal_remove_noti();
                thermal_remove_popup();
                thermal_add_noti();
-               update = UPDATE;
-       } else if (status == NEED_TO_CHECK) {
-               thermal_level_check(old_level, info->level, &high_status, &update);
-               _I("high_status = %d update = %d", high_status, update);
-               if (high_status == HIGH_TO_LOW) {
+               } else if (therm_action == CRITICAL) {
+                       thermal_remove_noti();
+                       thermal_remove_popup();
+                       thermal_add_popup();
+               }
+       } else if (therm_state == HIGH_TO_LOW) {
+               thermal_down_check(old_level, info->level, &therm_action, &update);
+               if (therm_action == RECOVER) {
                        thermal_remove_popup();
                        thermal_remove_noti();
                        thermal_add_recovery_popup();
-               } else if (high_status == HIGH_TO_CRITICAL) {
+               }
+       } else if (therm_state == HIGH_TO_HIGH) {
+               thermal_high_check(old_level, info->level, &therm_action, &update);
+               if (therm_action == CRITICAL) {
                        thermal_remove_noti();
                        thermal_remove_popup();
                        thermal_add_popup();