diff options
Diffstat (limited to 'drivers/thermal/thermal_trip.c')
-rw-r--r-- | drivers/thermal/thermal_trip.c | 55 |
1 files changed, 45 insertions, 10 deletions
diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c index 024e2e365a26..e42456442c68 100644 --- a/drivers/thermal/thermal_trip.c +++ b/drivers/thermal/thermal_trip.c @@ -13,15 +13,11 @@ int for_each_thermal_trip(struct thermal_zone_device *tz, int (*cb)(struct thermal_trip *, void *), void *data) { - int i, ret; - - lockdep_assert_held(&tz->lock); - - if (!tz->trips) - return -ENODATA; + struct thermal_trip *trip; + int ret; - for (i = 0; i < tz->num_trips; i++) { - ret = cb(&tz->trips[i], data); + for_each_trip(tz, trip) { + ret = cb(trip, data); if (ret) return ret; } @@ -30,6 +26,20 @@ int for_each_thermal_trip(struct thermal_zone_device *tz, } EXPORT_SYMBOL_GPL(for_each_thermal_trip); +int thermal_zone_for_each_trip(struct thermal_zone_device *tz, + int (*cb)(struct thermal_trip *, void *), + void *data) +{ + int ret; + + mutex_lock(&tz->lock); + ret = for_each_thermal_trip(tz, cb, data); + mutex_unlock(&tz->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(thermal_zone_for_each_trip); + int thermal_zone_get_num_trips(struct thermal_zone_device *tz) { return tz->num_trips; @@ -55,6 +65,7 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz) { struct thermal_trip trip; int low = -INT_MAX, high = INT_MAX; + bool same_trip = false; int i, ret; lockdep_assert_held(&tz->lock); @@ -63,6 +74,7 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz) return; for (i = 0; i < tz->num_trips; i++) { + bool low_set = false; int trip_low; ret = __thermal_zone_get_trip(tz, i , &trip); @@ -71,18 +83,31 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz) trip_low = trip.temperature - trip.hysteresis; - if (trip_low < tz->temperature && trip_low > low) + if (trip_low < tz->temperature && trip_low > low) { low = trip_low; + low_set = true; + same_trip = false; + } if (trip.temperature > tz->temperature && - trip.temperature < high) + trip.temperature < high) { high = trip.temperature; + same_trip = low_set; + } } /* No need to change trip points */ if (tz->prev_low_trip == low && tz->prev_high_trip == high) return; + /* + * If "high" and "low" are the same, skip the change unless this is the + * first time. + */ + if (same_trip && (tz->prev_low_trip != -INT_MAX || + tz->prev_high_trip != INT_MAX)) + return; + tz->prev_low_trip = low; tz->prev_high_trip = high; @@ -160,3 +185,13 @@ int thermal_zone_set_trip(struct thermal_zone_device *tz, int trip_id, return 0; } + +int thermal_zone_trip_id(struct thermal_zone_device *tz, + const struct thermal_trip *trip) +{ + /* + * Assume the trip to be located within the bounds of the thermal + * zone's trips[] table. + */ + return trip - tz->trips; +} |