Lines Matching +full:min +full:- +full:residency

1 // SPDX-License-Identifier: GPL-2.0
40 * struct cdev_debugfs - per cooling device statistics structure
65 * struct cdev_record - Common structure for cooling device entry
74 * @residency: a ktime_t representing a state residency duration
81 ktime_t residency; member
87 * struct trip_stats - Thermal trip statistics
97 * @min: minimum recorded temperature above the trip point
106 int min; member
111 * struct tz_episode - A mitigation episode information
135 * struct tz_debugfs - Store all mitigation episodes for a thermal zone
158 * struct thermal_debugfs - High level structure for a thermal object in debugfs
200 mutex_init(&thermal_dbg->lock); in thermal_debugfs_add_id()
204 thermal_dbg->d_top = debugfs_create_dir(ids, d); in thermal_debugfs_add_id()
205 if (IS_ERR(thermal_dbg->d_top)) { in thermal_debugfs_add_id()
218 debugfs_remove(thermal_dbg->d_top); in thermal_debugfs_remove_id()
233 cdev_record->id = id; in thermal_debugfs_cdev_record_alloc()
234 INIT_LIST_HEAD(&cdev_record->node); in thermal_debugfs_cdev_record_alloc()
235 list_add_tail(&cdev_record->node, in thermal_debugfs_cdev_record_alloc()
236 &lists[cdev_record->id % CDEVSTATS_HASH_SIZE]); in thermal_debugfs_cdev_record_alloc()
248 if (entry->id == id) in thermal_debugfs_cdev_record_find()
275 &cdev_dbg->transitions[i], node) { in thermal_debugfs_cdev_clear()
276 list_del(&entry->node); in thermal_debugfs_cdev_clear()
281 &cdev_dbg->durations[i], node) { in thermal_debugfs_cdev_clear()
282 list_del(&entry->node); in thermal_debugfs_cdev_clear()
287 cdev_dbg->total = 0; in thermal_debugfs_cdev_clear()
292 struct thermal_debugfs *thermal_dbg = s->private; in cdev_seq_start()
294 mutex_lock(&thermal_dbg->lock); in cdev_seq_start()
308 struct thermal_debugfs *thermal_dbg = s->private; in cdev_seq_stop()
310 mutex_unlock(&thermal_dbg->lock); in cdev_seq_stop()
315 struct thermal_debugfs *thermal_dbg = s->private; in cdev_tt_seq_show()
316 struct cdev_debugfs *cdev_dbg = &thermal_dbg->cdev_dbg; in cdev_tt_seq_show()
317 struct list_head *transitions = cdev_dbg->transitions; in cdev_tt_seq_show()
327 * string for a transition would be "1024->1024\0" in cdev_tt_seq_show()
331 snprintf(buffer, ARRAY_SIZE(buffer), "%d->%d", in cdev_tt_seq_show()
332 entry->id >> 16, entry->id & 0xFFFF); in cdev_tt_seq_show()
334 seq_printf(s, "%-10s\t%-10llu\n", buffer, entry->count); in cdev_tt_seq_show()
351 struct thermal_debugfs *thermal_dbg = s->private; in cdev_dt_seq_show()
352 struct cdev_debugfs *cdev_dbg = &thermal_dbg->cdev_dbg; in cdev_dt_seq_show()
353 struct list_head *durations = cdev_dbg->durations; in cdev_dt_seq_show()
361 s64 duration = ktime_to_ms(entry->residency); in cdev_dt_seq_show()
363 if (entry->id == cdev_dbg->current_state) in cdev_dt_seq_show()
365 cdev_dbg->timestamp); in cdev_dt_seq_show()
367 seq_printf(s, "%-5d\t%-10llu\n", entry->id, duration); in cdev_dt_seq_show()
387 return -EINVAL; in cdev_clear_set()
389 mutex_lock(&thermal_dbg->lock); in cdev_clear_set()
391 thermal_debugfs_cdev_clear(&thermal_dbg->cdev_dbg); in cdev_clear_set()
393 mutex_unlock(&thermal_dbg->lock); in cdev_clear_set()
401 * thermal_debug_cdev_state_update - Update a cooling device state change
403 * Computes a transition and the duration of the previous state residency.
411 struct thermal_debugfs *thermal_dbg = cdev->debugfs; in thermal_debug_cdev_state_update()
416 if (!thermal_dbg || (thermal_dbg->cdev_dbg.current_state == new_state)) in thermal_debug_cdev_state_update()
419 mutex_lock(&thermal_dbg->lock); in thermal_debug_cdev_state_update()
421 cdev_dbg = &thermal_dbg->cdev_dbg; in thermal_debug_cdev_state_update()
423 old_state = cdev_dbg->current_state; in thermal_debug_cdev_state_update()
432 cdev_dbg->durations, in thermal_debug_cdev_state_update()
436 ktime_t delta = ktime_sub(now, cdev_dbg->timestamp); in thermal_debug_cdev_state_update()
437 cdev_record->residency = ktime_add(cdev_record->residency, delta); in thermal_debug_cdev_state_update()
438 cdev_dbg->timestamp = now; in thermal_debug_cdev_state_update()
441 cdev_dbg->current_state = new_state; in thermal_debug_cdev_state_update()
448 thermal_debugfs_cdev_record_get(thermal_dbg, cdev_dbg->durations, new_state); in thermal_debug_cdev_state_update()
459 cdev_dbg->transitions, in thermal_debug_cdev_state_update()
462 cdev_record->count++; in thermal_debug_cdev_state_update()
464 cdev_dbg->total++; in thermal_debug_cdev_state_update()
466 mutex_unlock(&thermal_dbg->lock); in thermal_debug_cdev_state_update()
470 * thermal_debug_cdev_add - Add a cooling device debugfs entry
483 thermal_dbg = thermal_debugfs_add_id(d_cdev, cdev->id); in thermal_debug_cdev_add()
487 cdev_dbg = &thermal_dbg->cdev_dbg; in thermal_debug_cdev_add()
490 INIT_LIST_HEAD(&cdev_dbg->transitions[i]); in thermal_debug_cdev_add()
491 INIT_LIST_HEAD(&cdev_dbg->durations[i]); in thermal_debug_cdev_add()
494 cdev_dbg->current_state = state; in thermal_debug_cdev_add()
495 cdev_dbg->timestamp = ktime_get(); in thermal_debug_cdev_add()
502 thermal_debugfs_cdev_record_get(thermal_dbg, cdev_dbg->durations, state); in thermal_debug_cdev_add()
504 debugfs_create_file("trans_table", 0400, thermal_dbg->d_top, in thermal_debug_cdev_add()
507 debugfs_create_file("time_in_state_ms", 0400, thermal_dbg->d_top, in thermal_debug_cdev_add()
510 debugfs_create_file("clear", 0200, thermal_dbg->d_top, in thermal_debug_cdev_add()
513 debugfs_create_u32("total_trans", 0400, thermal_dbg->d_top, in thermal_debug_cdev_add()
514 &cdev_dbg->total); in thermal_debug_cdev_add()
516 cdev->debugfs = thermal_dbg; in thermal_debug_cdev_add()
525 thermal_dbg = cdev->debugfs; in thermal_debug_cdev_clear()
527 cdev->debugfs = NULL; in thermal_debug_cdev_clear()
533 * thermal_debug_cdev_remove - Remove a cooling device debugfs entry
547 mutex_lock(&thermal_dbg->lock); in thermal_debug_cdev_remove()
549 thermal_debugfs_cdev_clear(&thermal_dbg->cdev_dbg); in thermal_debug_cdev_remove()
551 mutex_unlock(&thermal_dbg->lock); in thermal_debug_cdev_remove()
562 tze = kzalloc(struct_size(tze, trip_stats, tz->num_trips), GFP_KERNEL); in thermal_debugfs_tz_event_alloc()
566 INIT_LIST_HEAD(&tze->node); in thermal_debugfs_tz_event_alloc()
567 tze->timestamp = now; in thermal_debugfs_tz_event_alloc()
568 tze->duration = KTIME_MIN; in thermal_debugfs_tz_event_alloc()
569 tze->max_temp = INT_MIN; in thermal_debugfs_tz_event_alloc()
571 for (i = 0; i < tz->num_trips; i++) { in thermal_debugfs_tz_event_alloc()
572 tze->trip_stats[i].trip_temp = THERMAL_TEMP_INVALID; in thermal_debugfs_tz_event_alloc()
573 tze->trip_stats[i].min = INT_MAX; in thermal_debugfs_tz_event_alloc()
582 struct thermal_debugfs *thermal_dbg = tz->debugfs; in thermal_debug_tz_trip_up()
592 tz_dbg = &thermal_dbg->tz_dbg; in thermal_debug_tz_trip_up()
594 mutex_lock(&thermal_dbg->lock); in thermal_debug_tz_trip_up()
610 * | -------- in thermal_debug_tz_trip_up()
611 * trip 2 / \ ------ in thermal_debug_tz_trip_up()
613 * trip 1 / | | `---- | | \ in thermal_debug_tz_trip_up()
617 * | / | | | | | | | | `-- in thermal_debug_tz_trip_up()
619 * |----- | | | | | | | | in thermal_debug_tz_trip_up()
621 * --------|-|-|--------|--------|------|-|-|------------------> time in thermal_debug_tz_trip_up()
622 * | | |<--t2-->| |<-t2'>| | | in thermal_debug_tz_trip_up()
624 * | |<------------t1------------>| | in thermal_debug_tz_trip_up()
626 * |<-------------t0--------------->| in thermal_debug_tz_trip_up()
629 if (!tz_dbg->nr_trips) { in thermal_debug_tz_trip_up()
634 list_add(&tze->node, &tz_dbg->tz_episodes); in thermal_debug_tz_trip_up()
650 tz_dbg->trips_crossed[tz_dbg->nr_trips++] = trip_id; in thermal_debug_tz_trip_up()
652 tze = list_first_entry(&tz_dbg->tz_episodes, struct tz_episode, node); in thermal_debug_tz_trip_up()
653 trip_stats = &tze->trip_stats[trip_id]; in thermal_debug_tz_trip_up()
654 trip_stats->trip_temp = trip->temperature; in thermal_debug_tz_trip_up()
655 trip_stats->trip_hyst = trip->hysteresis; in thermal_debug_tz_trip_up()
656 trip_stats->timestamp = now; in thermal_debug_tz_trip_up()
659 mutex_unlock(&thermal_dbg->lock); in thermal_debug_tz_trip_up()
664 struct trip_stats *trip_stats = &tze->trip_stats[trip_id]; in tz_episode_close_trip()
665 ktime_t delta = ktime_sub(now, trip_stats->timestamp); in tz_episode_close_trip()
667 trip_stats->duration = ktime_add(delta, trip_stats->duration); in tz_episode_close_trip()
669 trip_stats->timestamp = KTIME_MAX; in tz_episode_close_trip()
675 struct thermal_debugfs *thermal_dbg = tz->debugfs; in thermal_debug_tz_trip_down()
685 tz_dbg = &thermal_dbg->tz_dbg; in thermal_debug_tz_trip_down()
687 mutex_lock(&thermal_dbg->lock); in thermal_debug_tz_trip_down()
696 if (!tz_dbg->nr_trips) in thermal_debug_tz_trip_down()
699 for (i = tz_dbg->nr_trips - 1; i >= 0; i--) { in thermal_debug_tz_trip_down()
700 if (tz_dbg->trips_crossed[i] == trip_id) in thermal_debug_tz_trip_down()
707 tz_dbg->nr_trips--; in thermal_debug_tz_trip_down()
709 if (i < tz_dbg->nr_trips) in thermal_debug_tz_trip_down()
710 tz_dbg->trips_crossed[i] = tz_dbg->trips_crossed[tz_dbg->nr_trips]; in thermal_debug_tz_trip_down()
712 tze = list_first_entry(&tz_dbg->tz_episodes, struct tz_episode, node); in thermal_debug_tz_trip_down()
720 if (!tz_dbg->nr_trips) in thermal_debug_tz_trip_down()
721 tze->duration = ktime_sub(now, tze->timestamp); in thermal_debug_tz_trip_down()
724 mutex_unlock(&thermal_dbg->lock); in thermal_debug_tz_trip_down()
729 struct thermal_debugfs *thermal_dbg = tz->debugfs; in thermal_debug_update_trip_stats()
737 tz_dbg = &thermal_dbg->tz_dbg; in thermal_debug_update_trip_stats()
739 mutex_lock(&thermal_dbg->lock); in thermal_debug_update_trip_stats()
741 if (!tz_dbg->nr_trips) in thermal_debug_update_trip_stats()
744 tze = list_first_entry(&tz_dbg->tz_episodes, struct tz_episode, node); in thermal_debug_update_trip_stats()
746 if (tz->temperature > tze->max_temp) in thermal_debug_update_trip_stats()
747 tze->max_temp = tz->temperature; in thermal_debug_update_trip_stats()
749 for (i = 0; i < tz_dbg->nr_trips; i++) { in thermal_debug_update_trip_stats()
750 int trip_id = tz_dbg->trips_crossed[i]; in thermal_debug_update_trip_stats()
751 struct trip_stats *trip_stats = &tze->trip_stats[trip_id]; in thermal_debug_update_trip_stats()
753 trip_stats->min = min(trip_stats->min, tz->temperature); in thermal_debug_update_trip_stats()
754 trip_stats->avg += (tz->temperature - trip_stats->avg) / in thermal_debug_update_trip_stats()
755 ++trip_stats->count; in thermal_debug_update_trip_stats()
758 mutex_unlock(&thermal_dbg->lock); in thermal_debug_update_trip_stats()
763 struct thermal_debugfs *thermal_dbg = s->private; in tze_seq_start()
764 struct tz_debugfs *tz_dbg = &thermal_dbg->tz_dbg; in tze_seq_start()
766 mutex_lock(&thermal_dbg->lock); in tze_seq_start()
768 return seq_list_start(&tz_dbg->tz_episodes, *pos); in tze_seq_start()
773 struct thermal_debugfs *thermal_dbg = s->private; in tze_seq_next()
774 struct tz_debugfs *tz_dbg = &thermal_dbg->tz_dbg; in tze_seq_next()
776 return seq_list_next(v, &tz_dbg->tz_episodes, pos); in tze_seq_next()
781 struct thermal_debugfs *thermal_dbg = s->private; in tze_seq_stop()
783 mutex_unlock(&thermal_dbg->lock); in tze_seq_stop()
788 struct thermal_debugfs *thermal_dbg = s->private; in tze_seq_show()
789 struct thermal_zone_device *tz = thermal_dbg->tz_dbg.tz; in tze_seq_show()
798 if (tze->duration == KTIME_MIN) { in tze_seq_show()
800 duration_ms = ktime_to_ms(ktime_sub(ktime_get(), tze->timestamp)); in tze_seq_show()
803 duration_ms = ktime_to_ms(tze->duration); in tze_seq_show()
807 seq_printf(s, ",-Mitigation at %llums, duration%c%llums, max. temp=%dm°C\n", in tze_seq_show()
808 ktime_to_ms(tze->timestamp), c, duration_ms, tze->max_temp); in tze_seq_show()
810 …seq_printf(s, "| trip | type | temp(m°C) | hyst(m°C) | duration(ms) | avg(m°C) | min(m°C) |\… in tze_seq_show()
813 const struct thermal_trip *trip = &td->trip; in tze_seq_show()
821 if (trip->type == THERMAL_TRIP_CRITICAL) in tze_seq_show()
825 trip_stats = &tze->trip_stats[trip_id]; in tze_seq_show()
828 if (trip_stats->trip_temp == THERMAL_TEMP_INVALID) in tze_seq_show()
831 if (trip_stats->timestamp != KTIME_MAX) { in tze_seq_show()
834 trip_stats->timestamp); in tze_seq_show()
836 delta = ktime_add(delta, trip_stats->duration); in tze_seq_show()
840 duration_ms = ktime_to_ms(trip_stats->duration); in tze_seq_show()
846 8, thermal_trip_type_name(trip->type), in tze_seq_show()
847 9, trip_stats->trip_temp, in tze_seq_show()
848 9, trip_stats->trip_hyst, in tze_seq_show()
850 9, trip_stats->avg, in tze_seq_show()
851 9, trip_stats->min); in tze_seq_show()
871 thermal_dbg = thermal_debugfs_add_id(d_tz, tz->id); in thermal_debug_tz_add()
875 tz_dbg = &thermal_dbg->tz_dbg; in thermal_debug_tz_add()
877 tz_dbg->tz = tz; in thermal_debug_tz_add()
879 tz_dbg->trips_crossed = kzalloc(sizeof(int) * tz->num_trips, GFP_KERNEL); in thermal_debug_tz_add()
880 if (!tz_dbg->trips_crossed) { in thermal_debug_tz_add()
885 INIT_LIST_HEAD(&tz_dbg->tz_episodes); in thermal_debug_tz_add()
887 debugfs_create_file("mitigations", 0400, thermal_dbg->d_top, in thermal_debug_tz_add()
890 tz->debugfs = thermal_dbg; in thermal_debug_tz_add()
899 thermal_dbg = tz->debugfs; in thermal_debug_tz_clear()
901 tz->debugfs = NULL; in thermal_debug_tz_clear()
917 tz_dbg = &thermal_dbg->tz_dbg; in thermal_debug_tz_remove()
919 mutex_lock(&thermal_dbg->lock); in thermal_debug_tz_remove()
921 trips_crossed = tz_dbg->trips_crossed; in thermal_debug_tz_remove()
923 list_for_each_entry_safe(tze, tmp, &tz_dbg->tz_episodes, node) { in thermal_debug_tz_remove()
924 list_del(&tze->node); in thermal_debug_tz_remove()
928 mutex_unlock(&thermal_dbg->lock); in thermal_debug_tz_remove()
936 struct thermal_debugfs *thermal_dbg = tz->debugfs; in thermal_debug_tz_resume()
945 mutex_lock(&thermal_dbg->lock); in thermal_debug_tz_resume()
947 tz_dbg = &thermal_dbg->tz_dbg; in thermal_debug_tz_resume()
949 if (!tz_dbg->nr_trips) in thermal_debug_tz_resume()
957 tze = list_first_entry(&tz_dbg->tz_episodes, struct tz_episode, node); in thermal_debug_tz_resume()
959 for (i = 0; i < tz_dbg->nr_trips; i++) in thermal_debug_tz_resume()
960 tz_episode_close_trip(tze, tz_dbg->trips_crossed[i], now); in thermal_debug_tz_resume()
962 tze->duration = ktime_sub(now, tze->timestamp); in thermal_debug_tz_resume()
964 tz_dbg->nr_trips = 0; in thermal_debug_tz_resume()
967 mutex_unlock(&thermal_dbg->lock); in thermal_debug_tz_resume()