summaryrefslogtreecommitdiffstats
path: root/drivers/thermal/thermal_debugfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thermal/thermal_debugfs.c')
-rw-r--r--drivers/thermal/thermal_debugfs.c116
1 files changed, 75 insertions, 41 deletions
diff --git a/drivers/thermal/thermal_debugfs.c b/drivers/thermal/thermal_debugfs.c
index 942447229157..939d3e5f1817 100644
--- a/drivers/thermal/thermal_debugfs.c
+++ b/drivers/thermal/thermal_debugfs.c
@@ -94,7 +94,6 @@ struct cdev_record {
* @trip_temp: trip temperature at mitigation start
* @trip_hyst: trip hysteresis at mitigation start
* @count: the number of times the zone temperature was above the trip point
- * @max: maximum recorded temperature above the trip point
* @min: minimum recorded temperature above the trip point
* @avg: average temperature above the trip point
*/
@@ -104,7 +103,6 @@ struct trip_stats {
int trip_temp;
int trip_hyst;
int count;
- int max;
int min;
int avg;
};
@@ -122,12 +120,14 @@ struct trip_stats {
* @timestamp: first trip point crossed the way up
* @duration: total duration of the mitigation episode
* @node: a list element to be added to the list of tz events
+ * @max_temp: maximum zone temperature during this episode
* @trip_stats: per trip point statistics, flexible array
*/
struct tz_episode {
ktime_t timestamp;
ktime_t duration;
struct list_head node;
+ int max_temp;
struct trip_stats trip_stats[];
};
@@ -178,11 +178,11 @@ struct thermal_debugfs {
void thermal_debug_init(void)
{
d_root = debugfs_create_dir("thermal", NULL);
- if (!d_root)
+ if (IS_ERR(d_root))
return;
d_cdev = debugfs_create_dir("cooling_devices", d_root);
- if (!d_cdev)
+ if (IS_ERR(d_cdev))
return;
d_tz = debugfs_create_dir("thermal_zones", d_root);
@@ -202,7 +202,7 @@ static struct thermal_debugfs *thermal_debugfs_add_id(struct dentry *d, int id)
snprintf(ids, IDSLENGTH, "%d", id);
thermal_dbg->d_top = debugfs_create_dir(ids, d);
- if (!thermal_dbg->d_top) {
+ if (IS_ERR(thermal_dbg->d_top)) {
kfree(thermal_dbg);
return NULL;
}
@@ -561,10 +561,11 @@ static struct tz_episode *thermal_debugfs_tz_event_alloc(struct thermal_zone_dev
INIT_LIST_HEAD(&tze->node);
tze->timestamp = now;
tze->duration = KTIME_MIN;
+ tze->max_temp = INT_MIN;
for (i = 0; i < tz->num_trips; i++) {
+ tze->trip_stats[i].trip_temp = THERMAL_TEMP_INVALID;
tze->trip_stats[i].min = INT_MAX;
- tze->trip_stats[i].max = INT_MIN;
}
return tze;
@@ -573,20 +574,20 @@ static struct tz_episode *thermal_debugfs_tz_event_alloc(struct thermal_zone_dev
void thermal_debug_tz_trip_up(struct thermal_zone_device *tz,
const struct thermal_trip *trip)
{
- struct tz_episode *tze;
- struct tz_debugfs *tz_dbg;
struct thermal_debugfs *thermal_dbg = tz->debugfs;
int trip_id = thermal_zone_trip_id(tz, trip);
ktime_t now = ktime_get();
struct trip_stats *trip_stats;
+ struct tz_debugfs *tz_dbg;
+ struct tz_episode *tze;
if (!thermal_dbg)
return;
- mutex_lock(&thermal_dbg->lock);
-
tz_dbg = &thermal_dbg->tz_dbg;
+ mutex_lock(&thermal_dbg->lock);
+
/*
* The mitigation is starting. A mitigation can contain
* several episodes where each of them is related to a
@@ -653,23 +654,33 @@ unlock:
mutex_unlock(&thermal_dbg->lock);
}
+static void tz_episode_close_trip(struct tz_episode *tze, int trip_id, ktime_t now)
+{
+ struct trip_stats *trip_stats = &tze->trip_stats[trip_id];
+ ktime_t delta = ktime_sub(now, trip_stats->timestamp);
+
+ trip_stats->duration = ktime_add(delta, trip_stats->duration);
+ /* Mark the end of mitigation for this trip point. */
+ trip_stats->timestamp = KTIME_MAX;
+}
+
void thermal_debug_tz_trip_down(struct thermal_zone_device *tz,
const struct thermal_trip *trip)
{
struct thermal_debugfs *thermal_dbg = tz->debugfs;
+ int trip_id = thermal_zone_trip_id(tz, trip);
+ ktime_t now = ktime_get();
struct tz_episode *tze;
struct tz_debugfs *tz_dbg;
- ktime_t delta, now = ktime_get();
- int trip_id = thermal_zone_trip_id(tz, trip);
int i;
if (!thermal_dbg)
return;
- mutex_lock(&thermal_dbg->lock);
-
tz_dbg = &thermal_dbg->tz_dbg;
+ mutex_lock(&thermal_dbg->lock);
+
/*
* The temperature crosses the way down but there was not
* mitigation detected before. That may happen when the
@@ -695,13 +706,7 @@ void thermal_debug_tz_trip_down(struct thermal_zone_device *tz,
tze = list_first_entry(&tz_dbg->tz_episodes, struct tz_episode, node);
- delta = ktime_sub(now, tze->trip_stats[trip_id].timestamp);
-
- tze->trip_stats[trip_id].duration =
- ktime_add(delta, tze->trip_stats[trip_id].duration);
-
- /* Mark the end of mitigation for this trip point. */
- tze->trip_stats[trip_id].timestamp = KTIME_MAX;
+ tz_episode_close_trip(tze, trip_id, now);
/*
* This event closes the mitigation as we are crossing the
@@ -724,20 +729,22 @@ void thermal_debug_update_trip_stats(struct thermal_zone_device *tz)
if (!thermal_dbg)
return;
- mutex_lock(&thermal_dbg->lock);
-
tz_dbg = &thermal_dbg->tz_dbg;
+ mutex_lock(&thermal_dbg->lock);
+
if (!tz_dbg->nr_trips)
goto out;
tze = list_first_entry(&tz_dbg->tz_episodes, struct tz_episode, node);
+ if (tz->temperature > tze->max_temp)
+ tze->max_temp = tz->temperature;
+
for (i = 0; i < tz_dbg->nr_trips; i++) {
int trip_id = tz_dbg->trips_crossed[i];
struct trip_stats *trip_stats = &tze->trip_stats[trip_id];
- trip_stats->max = max(trip_stats->max, tz->temperature);
trip_stats->min = min(trip_stats->min, tz->temperature);
trip_stats->avg += (tz->temperature - trip_stats->avg) /
++trip_stats->count;
@@ -777,7 +784,6 @@ static int tze_seq_show(struct seq_file *s, void *v)
struct thermal_zone_device *tz = thermal_dbg->tz_dbg.tz;
struct thermal_trip_desc *td;
struct tz_episode *tze;
- const char *type;
u64 duration_ms;
int trip_id;
char c;
@@ -793,10 +799,10 @@ static int tze_seq_show(struct seq_file *s, void *v)
c = '=';
}
- seq_printf(s, ",-Mitigation at %lluus, duration%c%llums\n",
- ktime_to_us(tze->timestamp), c, duration_ms);
+ seq_printf(s, ",-Mitigation at %llums, duration%c%llums, max. temp=%dm°C\n",
+ ktime_to_ms(tze->timestamp), c, duration_ms, tze->max_temp);
- seq_printf(s, "| trip | type | temp(°mC) | hyst(°mC) | duration | avg(°mC) | min(°mC) | max(°mC) |\n");
+ seq_printf(s, "| trip | type | temp(m°C) | hyst(m°C) | duration(ms) | avg(m°C) | min(m°C) |\n");
for_each_trip_desc(tz, td) {
const struct thermal_trip *trip = &td->trip;
@@ -814,16 +820,9 @@ static int tze_seq_show(struct seq_file *s, void *v)
trip_stats = &tze->trip_stats[trip_id];
/* Skip trips without any stats. */
- if (trip_stats->min > trip_stats->max)
+ if (trip_stats->trip_temp == THERMAL_TEMP_INVALID)
continue;
- if (trip->type == THERMAL_TRIP_PASSIVE)
- type = "passive";
- else if (trip->type == THERMAL_TRIP_ACTIVE)
- type = "active";
- else
- type = "hot";
-
if (trip_stats->timestamp != KTIME_MAX) {
/* Mitigation in progress. */
ktime_t delta = ktime_sub(ktime_get(),
@@ -837,15 +836,14 @@ static int tze_seq_show(struct seq_file *s, void *v)
c = ' ';
}
- seq_printf(s, "| %*d | %*s | %*d | %*d | %c%*lld | %*d | %*d | %*d |\n",
+ seq_printf(s, "| %*d | %*s | %*d | %*d | %c%*lld | %*d | %*d |\n",
4 , trip_id,
- 8, type,
+ 8, thermal_trip_type_name(trip->type),
9, trip_stats->trip_temp,
9, trip_stats->trip_hyst,
- c, 10, duration_ms,
+ c, 11, duration_ms,
9, trip_stats->avg,
- 9, trip_stats->min,
- 9, trip_stats->max);
+ 9, trip_stats->min);
}
return 0;
@@ -922,3 +920,39 @@ void thermal_debug_tz_remove(struct thermal_zone_device *tz)
thermal_debugfs_remove_id(thermal_dbg);
kfree(trips_crossed);
}
+
+void thermal_debug_tz_resume(struct thermal_zone_device *tz)
+{
+ struct thermal_debugfs *thermal_dbg = tz->debugfs;
+ ktime_t now = ktime_get();
+ struct tz_debugfs *tz_dbg;
+ struct tz_episode *tze;
+ int i;
+
+ if (!thermal_dbg)
+ return;
+
+ mutex_lock(&thermal_dbg->lock);
+
+ tz_dbg = &thermal_dbg->tz_dbg;
+
+ if (!tz_dbg->nr_trips)
+ goto out;
+
+ /*
+ * A mitigation episode was in progress before the preceding system
+ * suspend transition, so close it because the zone handling is starting
+ * over from scratch.
+ */
+ tze = list_first_entry(&tz_dbg->tz_episodes, struct tz_episode, node);
+
+ for (i = 0; i < tz_dbg->nr_trips; i++)
+ tz_episode_close_trip(tze, tz_dbg->trips_crossed[i], now);
+
+ tze->duration = ktime_sub(now, tze->timestamp);
+
+ tz_dbg->nr_trips = 0;
+
+out:
+ mutex_unlock(&thermal_dbg->lock);
+}