misc: nct1008: Apply hysteresis to trip_temp
Jinyoung Park [Tue, 25 Dec 2012 22:53:58 +0000 (07:53 +0900)]
Apply hysteresis to trip_temp in nct1008_update and() and
nct1008_ext_get_trip_temp() to be more accurate.

Bug 1200202

Change-Id: I35b0e721659e520c312c20230403578b78f15782
Signed-off-by: Jinyoung Park <jinyoungp@nvidia.com>
Reviewed-on: http://git-master/r/174182
Reviewed-by: Riham Haidar <rhaidar@nvidia.com>
Tested-by: Riham Haidar <rhaidar@nvidia.com>

drivers/misc/nct1008.c
include/linux/nct1008.h

index 6ea6745..8656fca 100644 (file)
@@ -474,7 +474,9 @@ static int nct1008_thermal_set_limits(struct nct1008_data *data,
 static void nct1008_update(struct nct1008_data *data)
 {
        struct thermal_zone_device *thz = data->nct_ext;
-       long temp, trip_temp, low_temp = 0, high_temp = NCT1008_MAX_TEMP * 1000;
+       long low_temp = 0, high_temp = NCT1008_MAX_TEMP * 1000;
+       struct nct_trip_temp *trip_state;
+       long temp, trip_temp, hysteresis_temp;
        int count;
        enum events type = 0;
 
@@ -486,16 +488,18 @@ static void nct1008_update(struct nct1008_data *data)
        thz->ops->get_temp(thz, &temp);
 
        for (count = 0; count < thz->trips; count++) {
-               thz->ops->get_trip_temp(thz, count, &trip_temp);
+               trip_state = &data->plat_data.trips[count];
+               trip_temp = trip_state->trip_temp;
+               hysteresis_temp = trip_state->is_enabled ?
+                               trip_temp - trip_state->hysteresis : trip_temp;
 
                if ((trip_temp >= temp) && (trip_temp < high_temp)) {
                        high_temp = trip_temp;
                        type = THERMAL_AUX1;
                }
 
-               if ((trip_temp < temp) && (trip_temp > low_temp)) {
-                       low_temp = trip_temp -
-                                  data->plat_data.trips[count].hysteresis;
+               if ((hysteresis_temp < temp) && (hysteresis_temp > low_temp)) {
+                       low_temp = hysteresis_temp;
                        type = THERMAL_AUX0;
                }
        }
@@ -574,8 +578,18 @@ static int nct1008_ext_get_trip_temp(struct thermal_zone_device *thz,
                                     unsigned long *temp)
 {
        struct nct1008_data *data = thz->devdata;
+       struct nct_trip_temp *trip_state = &data->plat_data.trips[trip];
+
+       *temp = trip_state->trip_temp;
+
+       if (thz->temperature >= trip_state->trip_temp) {
+               trip_state->is_enabled = true;
+       } else if (trip_state->is_enabled) {
+               *temp -= trip_state->hysteresis;
+               if (thz->temperature < *temp)
+                       trip_state->is_enabled = false;
+       }
 
-       *temp = data->plat_data.trips[trip].trip_temp;
        return 0;
 }
 
index c6beb04..d5890cf 100644 (file)
@@ -38,6 +38,7 @@ struct nct_trip_temp {
        enum thermal_trip_type trip_type;
        unsigned long state;
        long hysteresis;
+       bool is_enabled;
 };
 
 #define NCT_MAX_TRIPS (32)