Lines Matching +full:thermal +full:- +full:zone

1 // SPDX-License-Identifier: GPL-2.0
7 * Thermal zone tempalates handling for thermal core testing.
10 #define pr_fmt(fmt) "thermal-testing: " fmt
15 #include <linux/thermal.h>
23 * struct tt_thermal_zone - Testing thermal zone template
25 * Represents a template of a thermal zone that can be used for registering
26 * a test thermal zone with the thermal core.
28 * @list_node: Node in the list of all testing thermal zone templates.
29 * @trips: List of trip point templates for this thermal zone template.
31 * @tz: Test thermal zone based on this template, if present.
36 * @tz_temp: Current thermal zone temperature (after registration).
54 DEFINE_GUARD(tt_zone, struct tt_thermal_zone *, mutex_lock(&_T->lock), mutex_unlock(&_T->lock))
57 * struct tt_trip - Testing trip point template
60 * during the registration of a thermal zone based on a given zone template.
62 * @list_node: Node in the list of all trip templates in the zone template.
63 * @trip: Trip point data to use for thernal zone registration.
76 * of zone-related command functions have a part that runs from a workqueue and
102 return -EINVAL; in tt_int_set()
116 if (!tt_zone->tz) in tt_zone_tz_temp_get()
117 return -EBUSY; in tt_zone_tz_temp_get()
119 *val = tt_zone->tz_temp; in tt_zone_tz_temp_get()
129 if (!tt_zone->tz) in tt_zone_tz_temp_set()
130 return -EBUSY; in tt_zone_tz_temp_set()
132 WRITE_ONCE(tt_zone->tz_temp, val); in tt_zone_tz_temp_set()
133 thermal_zone_device_update(tt_zone->tz, THERMAL_EVENT_TEMP_SAMPLE); in tt_zone_tz_temp_set()
144 list_for_each_entry_safe(tt_trip, aux, &tt_zone->trips, list_node) { in tt_zone_free_trips()
145 list_del(&tt_trip->list_node); in tt_zone_free_trips()
146 ida_free(&tt_zone->ida, tt_trip->id); in tt_zone_free_trips()
154 ida_free(&tt_thermal_zones_ida, tt_zone->id); in tt_zone_free()
155 ida_destroy(&tt_zone->ida); in tt_zone_free()
162 struct tt_thermal_zone *tt_zone = tt_work->tt_zone; in tt_add_tz_work_fn()
167 snprintf(f_name, TT_MAX_FILE_NAME_LENGTH, "tz%d", tt_zone->id); in tt_add_tz_work_fn()
168 tt_zone->d_tt_zone = debugfs_create_dir(f_name, d_testing); in tt_add_tz_work_fn()
169 if (IS_ERR(tt_zone->d_tt_zone)) { in tt_add_tz_work_fn()
174 debugfs_create_file_unsafe("temp", 0600, tt_zone->d_tt_zone, tt_zone, in tt_add_tz_work_fn()
177 debugfs_create_file_unsafe("init_temp", 0600, tt_zone->d_tt_zone, in tt_add_tz_work_fn()
178 &tt_zone->temp, &tt_int_attr); in tt_add_tz_work_fn()
182 list_add_tail(&tt_zone->list_node, &tt_thermal_zones); in tt_add_tz_work_fn()
193 return -ENOMEM; in tt_add_tz()
197 return -ENOMEM; in tt_add_tz()
199 INIT_LIST_HEAD(&tt_zone->trips); in tt_add_tz()
200 mutex_init(&tt_zone->lock); in tt_add_tz()
201 ida_init(&tt_zone->ida); in tt_add_tz()
202 tt_zone->temp = THERMAL_TEMP_INVALID; in tt_add_tz()
208 tt_zone->id = ret; in tt_add_tz()
210 INIT_WORK(&tt_work->work, tt_add_tz_work_fn); in tt_add_tz()
211 tt_work->tt_zone = no_free_ptr(tt_zone); in tt_add_tz()
212 schedule_work(&(no_free_ptr(tt_work)->work)); in tt_add_tz()
220 struct tt_thermal_zone *tt_zone = tt_work->tt_zone; in tt_del_tz_work_fn()
224 debugfs_remove(tt_zone->d_tt_zone); in tt_del_tz_work_fn()
232 if (tt_zone->tz) { in tt_zone_unregister_tz()
233 thermal_zone_device_unregister(tt_zone->tz); in tt_zone_unregister_tz()
234 tt_zone->tz = NULL; in tt_zone_unregister_tz()
247 return -EINVAL; in tt_del_tz()
251 return -ENOMEM; in tt_del_tz()
255 ret = -EINVAL; in tt_del_tz()
257 if (tt_zone->id == id) { in tt_del_tz()
258 if (tt_zone->refcount) { in tt_del_tz()
259 ret = -EBUSY; in tt_del_tz()
261 list_del(&tt_zone->list_node); in tt_del_tz()
273 INIT_WORK(&tt_work->work, tt_del_tz_work_fn); in tt_del_tz()
274 tt_work->tt_zone = tt_zone; in tt_del_tz()
275 schedule_work(&(no_free_ptr(tt_work)->work)); in tt_del_tz()
287 return ERR_PTR(-EINVAL); in tt_get_tt_zone()
292 if (tt_zone->id == id) { in tt_get_tt_zone()
293 tt_zone->refcount++; in tt_get_tt_zone()
298 return ERR_PTR(-EINVAL); in tt_get_tt_zone()
305 tt_zone->refcount--; in tt_put_tt_zone()
314 struct tt_thermal_zone *tt_zone = tt_work->tt_zone; in tt_zone_add_trip_work_fn()
315 struct tt_trip *tt_trip = tt_work->tt_trip; in tt_zone_add_trip_work_fn()
320 snprintf(d_name, TT_MAX_FILE_NAME_LENGTH, "trip_%d_temp", tt_trip->id); in tt_zone_add_trip_work_fn()
321 debugfs_create_file_unsafe(d_name, 0600, tt_zone->d_tt_zone, in tt_zone_add_trip_work_fn()
322 &tt_trip->trip.temperature, &tt_int_attr); in tt_zone_add_trip_work_fn()
324 snprintf(d_name, TT_MAX_FILE_NAME_LENGTH, "trip_%d_hyst", tt_trip->id); in tt_zone_add_trip_work_fn()
325 debugfs_create_file_unsafe(d_name, 0600, tt_zone->d_tt_zone, in tt_zone_add_trip_work_fn()
326 &tt_trip->trip.hysteresis, &tt_unsigned_int_attr); in tt_zone_add_trip_work_fn()
340 return -ENOMEM; in tt_zone_add_trip()
344 return -ENOMEM; in tt_zone_add_trip()
350 id = ida_alloc(&tt_zone->ida, GFP_KERNEL); in tt_zone_add_trip()
354 tt_trip->trip.type = THERMAL_TRIP_ACTIVE; in tt_zone_add_trip()
355 tt_trip->trip.temperature = THERMAL_TEMP_INVALID; in tt_zone_add_trip()
356 tt_trip->trip.flags = THERMAL_TRIP_FLAG_RW; in tt_zone_add_trip()
357 tt_trip->id = id; in tt_zone_add_trip()
361 list_add_tail(&tt_trip->list_node, &tt_zone->trips); in tt_zone_add_trip()
362 tt_zone->num_trips++; in tt_zone_add_trip()
364 INIT_WORK(&tt_work->work, tt_zone_add_trip_work_fn); in tt_zone_add_trip()
365 tt_work->tt_zone = no_free_ptr(tt_zone); in tt_zone_add_trip()
366 tt_work->tt_trip = no_free_ptr(tt_trip); in tt_zone_add_trip()
367 schedule_work(&(no_free_ptr(tt_work)->work)); in tt_zone_add_trip()
376 *temp = READ_ONCE(tt_zone->tz_temp); in tt_zone_get_temp()
379 return -ENODATA; in tt_zone_get_temp()
397 if (tt_zone->tz) in tt_zone_register_tz()
398 return -EINVAL; in tt_zone_register_tz()
400 trips = kcalloc(tt_zone->num_trips, sizeof(*trips), GFP_KERNEL); in tt_zone_register_tz()
402 return -ENOMEM; in tt_zone_register_tz()
405 list_for_each_entry(tt_trip, &tt_zone->trips, list_node) in tt_zone_register_tz()
406 trips[i++] = tt_trip->trip; in tt_zone_register_tz()
408 tt_zone->tz_temp = tt_zone->temp; in tt_zone_register_tz()
415 tt_zone->tz = tz; in tt_zone_register_tz()
453 list_del(&tt_zone->list_node); in tt_zone_cleanup()