// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2024 , Intel Corporation
*
* Author : Rafael J . Wysocki < rafael . j . wysocki @ intel . com >
*
* Thermal subsystem testing facility .
*
* This facility allows the thermal core functionality to be exercised in a
* controlled way in order to verify its behavior .
*
* It resides in the " thermal - testing " directory under the debugfs root and
* starts with a single file called " command " which can be written a string
* representing a thermal testing facility command .
*
* The currently supported commands are listed in the tt_commands enum below .
*
* The " addtz " command causes a new test thermal zone template to be created ,
* for example :
*
* # echo addtz > / sys / kernel / debug / thermal - testing / command
*
* That template will be represented as a subdirectory in the " thermal - testing "
* directory , for example
*
* # ls / sys / kernel / debug / thermal - testing /
* command tz0
*
* The thermal zone template can be populated with trip points with the help of
* the " tzaddtrip " command , for example :
*
* # echo tzaddtrip : 0 > / sys / kernel / debug / thermal - testing / command
*
* which causes a trip point template to be added to the test thermal zone
* template 0 ( represented by the tz0 subdirectory in " thermal - testing " ) .
*
* # ls / sys / kernel / debug / thermal - testing / tz0
* init_temp temp trip_0_temp trip_0_hyst
*
* The temperature of a trip point template is initially THERMAL_TEMP_INVALID
* and its hysteresis is initially 0 . They can be adjusted by writing to the
* " trip_x_temp " and " trip_x_hyst " files correspoinding to that trip point
* template , respectively .
*
* The initial temperature of a thermal zone based on a template can be set by
* writing to the " init_temp " file in its directory under " thermal - testing " , for
* example :
*
* echo 50000 > / sys / kernel / debug / thermal - testing / tz0 / init_temp
*
* When ready , " tzreg " command can be used for registering and enabling a
* thermal zone based on a given template with the thermal core , for example
*
* # echo tzreg : 0 > / sys / kernel / debug / thermal - testing / command
*
* In this case , test thermal zone template 0 is used for registering a new
* thermal zone and the set of trip point templates associated with it is used
* for populating the new thermal zone ' s trip points table . The type of the new
* thermal zone is " test_tz " .
*
* The temperature and hysteresis of all of the trip points in that new thermal
* zone are adjustable via sysfs , so they can be updated at any time .
*
* The current temperature of the new thermal zone can be set by writing to the
* " temp " file in the corresponding thermal zone template ' s directory under
* " thermal - testing " , for example
*
* echo 10000 > / sys / kernel / debug / thermal - testing / tz0 / temp
*
* which will also trigger a temperature update for this zone in the thermal
* core , including checking its trip points , sending notifications to user space
* if any of them have been crossed and so on .
*
* When it is not needed any more , a test thermal zone template can be deleted
* with the help of the " deltz " command , for example
*
* # echo deltz : 0 > / sys / kernel / debug / thermal - testing / command
*
* which will also unregister the thermal zone based on it , if present .
*/
#define pr_fmt(fmt) "thermal-testing: " fmt
#include <linux/debugfs.h>
#include <linux/module.h>
#include "thermal_testing.h"
struct dentry *d_testing;
#define TT_COMMAND_SIZE 16
enum tt_commands {
TT_CMD_ADDTZ,
TT_CMD_DELTZ,
TT_CMD_TZADDTRIP,
TT_CMD_TZREG,
TT_CMD_TZUNREG,
};
static const char *tt_command_strings[] = {
[TT_CMD_ADDTZ] = "addtz" ,
[TT_CMD_DELTZ] = "deltz" ,
[TT_CMD_TZADDTRIP] = "tzaddtrip" ,
[TT_CMD_TZREG] = "tzreg" ,
[TT_CMD_TZUNREG] = "tzunreg" ,
};
static int tt_command_exec(int index, const char *arg)
{
int ret;
switch (index) {
case TT_CMD_ADDTZ:
ret = tt_add_tz();
break ;
case TT_CMD_DELTZ:
ret = tt_del_tz(arg);
break ;
case TT_CMD_TZADDTRIP:
ret = tt_zone_add_trip(arg);
break ;
case TT_CMD_TZREG:
ret = tt_zone_reg(arg);
break ;
case TT_CMD_TZUNREG:
ret = tt_zone_unreg(arg);
break ;
default :
ret = -EINVAL;
break ;
}
return ret;
}
static ssize_t tt_command_process(char *s)
{
char *arg;
int i;
strim(s);
arg = strchr(s, ':' );
if (arg) {
*arg = '\0' ;
arg++;
}
for (i = 0 ; i < ARRAY_SIZE(tt_command_strings); i++) {
if (!strcmp(s, tt_command_strings[i]))
return tt_command_exec(i, arg);
}
return -EINVAL;
}
static ssize_t tt_command_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
char buf[TT_COMMAND_SIZE];
ssize_t ret;
if (*ppos)
return -EINVAL;
if (count > TT_COMMAND_SIZE - 1 )
return -E2BIG;
if (copy_from_user(buf, user_buf, count))
return -EFAULT;
buf[count] = '\0' ;
ret = tt_command_process(buf);
if (ret)
return ret;
return count;
}
static const struct file_operations tt_command_fops = {
.write = tt_command_write,
.open = simple_open,
.llseek = default_llseek,
};
static int __init thermal_testing_init(void )
{
d_testing = debugfs_create_dir("thermal-testing" , NULL);
if (!IS_ERR(d_testing))
debugfs_create_file("command" , 0200 , d_testing, NULL,
&tt_command_fops);
return 0 ;
}
module_init(thermal_testing_init);
static void __exit thermal_testing_exit(void )
{
debugfs_remove(d_testing);
tt_zone_cleanup();
}
module_exit(thermal_testing_exit);
MODULE_DESCRIPTION("Thermal core testing facility" );
MODULE_LICENSE("GPL v2" );
Messung V0.5 in Prozent C=100 H=97 G=98
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland