4.3.14. Thermal System
4.3.14.1. Overview of the Thermal System
The Thermal system is a mechanism designed to monitor and manage device temperature, aiming to prevent hardware damage or performance degradation caused by overheating. It reads data from temperature sensors and takes various response actions based on predefined thresholds, such as adjusting device performance or triggering thermal throttling. This system provides temperature control and protection functions, ensuring that hardware operates within a safe temperature range.
4.3.14.2. Functional Description of the Thermal System
Typical Applications of the Thermal System
There are three temperature sensors on the board-level system, used to display the temperatures of DDR, BPU, and CPU respectively. Typical application examples related to the thermal system are as follows:
Throttling: Reducing CPU or GPU frequency to lower power consumption and thus reduce heat generation.
Fan acceleration: If the device has a fan, the system can enhance heat dissipation by adjusting the fan speed.
System shutdown or reboot: When the temperature becomes excessively high and cannot be controlled through throttling or other measures, the system may automatically shut down or reboot.
Principle of Thermal System Functionality
The core principle of the Thermal system is to read temperature sensor values from the hardware system and compare them with predefined temperature thresholds. When the temperature reaches a certain critical value, the system initiates response mechanisms to prevent hardware overheating.
The functional principle of the Thermal system is illustrated in the figure below:

Operation of the Thermal System
The operation of the Thermal system typically consists of the following steps:
Temperature Acquisition: Real-time temperature data is obtained via hardware temperature sensors. These sensors can be built-in sensors within the processor or external thermocouples or thermistors.
Threshold Setting: The kernel or user-space applications define safe temperature ranges and corresponding response measures. These usually include high-temperature thresholds (Critical) and moderate-temperature thresholds (Warning).
Response Strategy: When the temperature exceeds the preset threshold, the system activates the corresponding strategy. Responses may include:
Reducing frequency
Increasing fan speed
Shutting down unnecessary hardware or services
Triggering thermal protection (e.g., system shutdown)
Temperature Adjustment: After adjustments based on the strategy, the system continues monitoring temperature changes and repeats the above process.
4.3.14.3. Thermal Driver Code
Thermal Device Tree Configuration
The device tree definition for the Thermal system is located in the arch/arm64/boot/dts/hobot/x5.dtsi file under the kernel folder of the BSP package:
thermal-zones {
thermal_cpu: thermal-cpu {
polling-delay-passive = <1000>;
polling-delay = <1000>;
thermal-sensors = <&pvt 2>;
trips {
cpu_alert0: cpu-alert0 {
temperature = <110000>;
hysteresis = <500>;
type = "passive";
};
cpu_alert1: cpu-alert1 {
temperature = <95000>;
hysteresis = <1000>;
type = "passive";
};
cpu_crit: cpu-crit {
temperature = <110000>;
hysteresis = <0>;
type = "critical";
};
};
cooling-maps {
cpu_map0: cpu-map0 {
trip = <&cpu_alert1>;
cooling-device =
<&cpu_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu_4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu_5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu_6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&cpu_7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
cpu_map1: cpu-map1 {
trip = <&cpu_alert1>;
cooling-device = <&bpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
cpu_map2: cpu-map2 {
trip = <&cpu_alert1>;
cooling-device = <&gc8000 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
};
thermal_ddr: thermal-ddr {
polling-delay-passive = <1000>;
polling-delay = <1000>;
thermal-sensors = <&pvt 0>;
trips {
ddr_alert0: ddr-alert0 {
temperature = <95000>;
hysteresis = <1000>;
type = "passive";
};
};
cooling-maps {
ddr_map0: ddr-map0 {
trip = <&ddr_alert0>;
cooling-device = <&ddrc_freq THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
};
};
This device tree describes temperature management configurations for CPU and DDR thermal zones, primarily including the following components:
Temperature Sensors: Specifies the associated temperature sensor instances for each thermal zone.
Temperature Thresholds (trips): Defines different temperature thresholds (
cpu_alert0,cpu_alert1,cpu_crit, etc.), each triggering different behaviors (e.g., passive cooling or critical protection) when reached.Cooling Maps: Defines how different cooling devices (e.g., CPU cores, BPU, GC8000, DDR) are activated when temperature thresholds are triggered.
Below is a detailed analysis:
thermal-zones The
thermal-zonesnode lists all thermal zone configurations. In this file, there are two thermal zones:thermal_cpu(for CPU temperature management) andthermal_ddr(for DDR memory temperature management).thermal_cpu: thermal-cpu This section defines the thermal zone related to the CPU, including the following key configurations:
polling-delay-passive and polling-delay: These properties set the polling delay for the thermal zone in milliseconds.
polling-delay-passivespecifies the delay in passive mode, whilepolling-delayspecifies the delay in normal mode. Both are set to 1000 milliseconds (i.e., 1 second) here.thermal-sensors: This property defines the temperature sensor associated with this thermal zone. Here,
< &pvt 2 >indicates the sensor related to CPU temperature monitoring, pointing to the second instance of a sensor namedpvt.
trips (CPU) The
tripssection describes different temperature thresholds and behaviors (trigger conditions), i.e., how the system reacts when the temperature reaches a certain level. There are three thresholds in this file:cpu_alert0: Trigger temperature is 110,000 millidegrees (110°C), of type
passive. This means that when the CPU temperature exceeds 110°C, passive cooling measures (e.g., reducing power consumption) are taken.cpu_alert1: Trigger temperature is 95,000 millidegrees (95°C), also of type
passive. Although lower thancpu_alert0, similar passive cooling measures are still applied.cpu_crit: Critical temperature is 110,000 millidegrees (110°C), of type
critical. Typically, a critical temperature triggers stronger thermal protection measures, such as shutting down the CPU or other hardware.
cooling-maps The
cooling-mapssection describes how cooling devices are regulated under specific temperature trigger conditions. There are three cooling maps:cpu_map0: When the
cpu_alert1temperature threshold is triggered, the following cooling devices are activated:Cooling devices for 8 CPU cores (CPU 0 to CPU 7).
THERMAL_NO_LIMIThere means no specific temperature limit.
cpu_map1: When the
cpu_alert1temperature threshold is triggered, the cooling device namedbpuis activated.THERMAL_NO_LIMITsimilarly indicates no temperature limit.cpu_map2: When the
cpu_alert1temperature threshold is triggered, the cooling device namedgc8000is activated.
thermal_ddr: thermal-ddr This section defines the thermal zone related to DDR memory. Similar to
thermal_cpu, it includes settings for temperature polling and sensors, but only defines one temperature threshold.thermal-sensors: The temperature sensor related to DDR is
< &pvt 0 >, pointing to the first instance of a sensor namedpvt.
trips (DDR) The DDR thermal zone also defines one temperature threshold:
ddr_alert0: Trigger temperature is 95,000 millidegrees (95°C), of type
passive. When DDR temperature exceeds this threshold, passive cooling measures are taken.
cooling-maps
ddr_map0: When
ddr_alert0is triggered, the cooling device namedddrc_freqis activated. Again,THERMAL_NO_LIMITindicates no specific temperature limit.
This device tree code can be parsed by the kernel to guide the system in effectively managing hardware temperatures under different temperature conditions, avoiding overheating issues, and ensuring hardware operates within a safe temperature range.
Thermal Kernel Configuration
The kernel configuration for the Thermal system can be viewed in menuconfig. The current system configuration is as follows:
--- Thermal drivers
[ ] Thermal netlink management
[ ] Thermal state transition statistics
(0) Emergency poweroff delay in milli-seconds
[*] Expose thermal sensors as hwmon device
[*] APIs to parse thermal data out of device tree
[*] Enable writable trip points
Default Thermal governor (step_wise) --->
[ ] Fair-share thermal governor
-*- Step_wise thermal governor
[ ] Bang Bang thermal governor
[*] User_space thermal governor
[*] Generic cpu cooling support
[*] CPU frequency cooling device
[*] Generic device cooling support
[ ] Thermal emulation mode support
< > Generic Thermal MMIO driver
< > Generic ADC based thermal sensor
Below are the currently enabled options and their explanations:
Expose thermal sensors as hwmon device
When enabled, the system’s thermal sensors are exposed as hardware monitoring (hwmon) devices to user space. Through this feature, users can access temperature sensor data via the
/sys/class/hwmon/directory. Tools such aslm_sensorscan use this data to monitor system temperature, facilitating debugging and optimization of thermal management.
APIs to parse thermal data out of device tree
When enabled, the kernel gains the ability to parse thermal management-related data from the device tree. The device tree is a configuration file describing hardware, commonly used in ARM architecture systems. By enabling this option, the kernel can read information about temperature sensors, thermal thresholds, cooling devices, etc., from the device tree and make corresponding thermal management decisions.
Enable writable trip points
When enabled, the system allows users to modify trip points (temperature thresholds) at runtime. Trip points are preset temperature thresholds; when exceeded, the system takes actions (e.g., lowering frequency or starting fans). With this option enabled, users can dynamically modify these thresholds via the sysfs interface to better adapt to different workloads and environmental conditions.
Step_wise thermal governor
This is the default thermal management governor. The
step_wisegovernor gradually adjusts cooling strategies based on temperature changes. For example, as temperature rises gradually, the system incrementally increases cooling measures. Compared to simpler strategies likebang-bang,step_wiseprovides finer and smoother temperature control.
User_space thermal governor
When enabled, the system allows user-space applications to control thermal management policies. This means users can write their own applications to dynamically adjust temperature control measures, such as starting/stopping cooling devices or modifying cooling strategies. This feature is suitable for systems requiring customized thermal management, especially in embedded or high-performance applications where cooling methods can be adjusted according to specific needs.
Generic cpu cooling support
When enabled, the system supports generic CPU cooling mechanisms, typically by adjusting CPU frequency, power consumption, or activating/deactivating cooling devices to lower temperature. This feature is crucial for systems requiring efficient CPU temperature management, particularly under high load, to avoid overheating by reducing power consumption.
CPU frequency cooling device
When enabled, the system supports cooling devices based on CPU frequency adjustment. This means that when temperature increases, the system can dynamically reduce CPU frequency to decrease power consumption and heat, thereby helping lower system temperature. This function is usually associated with CPU dynamic frequency scaling (DVFS), automatically reducing CPU performance under high temperatures to protect hardware.
Generic device cooling support
When enabled, the system supports generic device cooling mechanisms. This includes cooling measures for devices beyond the CPU (e.g., GPU, memory controller, hard drives, etc.). The system adjusts the power consumption of related devices or activates cooling devices based on temperature changes, improving overall thermal management capability.
4.3.14.4. Functions and Usage of the Thermal System
Linux Thermal is a module related to temperature control in Linux systems, primarily used to control heat generated by chips during system operation, keeping chip and device casing temperatures within a safe and comfortable range.
The entire Thermal framework can be divided into four parts:
Thermal Driver: Responsible for acquiring temperature devices and registering them as
struct thermal_zone_device. A Thermal Zone Device is essentially an abstraction of the temperature-measuring device. There are two thermal zones in this board-level system:thermal_zone0andthermal_zone1.Thermal Governor: Responsible for determining how to control temperature, registered as
struct thermal_governor, such as Step Wise, User space, etc. The Thermal Governor is essentially a temperature control policy.Thermal Cooling: Responsible for managing temperature-controlling devices, registered as
struct thermal_cooling_device. These are the actual devices requiring cooling. There are four cooling devices on the board-level system:cooling_device0: cpu
cooling_device1: bpu
cooling_device2: gpu
cooling_device3: ddr Among them, the DDR cooling device is associated with
thermal_zone0, while CPU/BPU/GPU cooling devices are associated withthermal_zone1.
Thermal Core: Responsible for integrating governor, cooling device, zone device, and other components, while providing common functionalities such as sysfs nodes in user space. Thermal Core is the core of the thermal system.
Information and control states of the above modules can be accessed under the /sys/class/thermal directory.
The workflow of Thermal involves acquiring temperature via the Thermal Driver, making decisions via the Thermal Governor, and finally executing temperature control via the Thermal Cooling. The relationship between these modules can be described in the figure below:

After incorporating device components, the relationship between the Thermal framework and device components, along with the data processing flow during temperature changes, is shown below:

Explanation of Key Structures in Thermal Driver
thermal_zone_device
struct thermal_zone_device {
int id;
char type[THERMAL_NAME_LENGTH];
struct device device;
struct attribute_group trips_attribute_group;
struct thermal_attr *trip_temp_attrs;
struct thermal_attr *trip_type_attrs;
struct thermal_attr *trip_hyst_attrs;
enum thermal_device_mode mode;
void *devdata;
struct thermal_trip *trips;
int num_trips;
unsigned long trips_disabled; /* bitmap for disabled trips */
unsigned long passive_delay_jiffies;
unsigned long polling_delay_jiffies;
int temperature;
int last_temperature;
int emul_temperature;
int passive;
int prev_low_trip;
int prev_high_trip;
atomic_t need_update;
struct thermal_zone_device_ops *ops;
struct thermal_zone_params *tzp;
struct thermal_governor *governor;
void *governor_data;
struct list_head thermal_instances;
struct ida ida;
struct mutex lock;
struct list_head node;
struct delayed_work poll_queue;
enum thermal_notify_event notify_event;
};
struct thermal_zone_device is a structure used to describe a thermal zone device, containing various fields for managing and monitoring thermal management information. A thermal zone device is an abstraction in the operating system representing a hardware region with thermal management capabilities. This structure involves temperature sensors, thermal management policies, temperature thresholds, and various system parameters.
Below is a detailed analysis of each member variable:
id:Type:
intThis field assigns a unique identifier to each thermal zone to distinguish different thermal zones.
type:Type:
char[THERMAL_NAME_LENGTH]This field represents the type name of the thermal zone device, usually a string indicating the type of the thermal zone (e.g., CPU thermal zone, GPU thermal zone, etc.).
device:Type:
struct deviceThis field represents the thermal zone device itself, a
devicestructure that allows interaction with the device model, facilitating management of hardware related to the thermal zone.
trips_attribute_group:Type:
struct attribute_groupUsed to manage attribute groups of the thermal zone (e.g., accessible via sysfs).
trips_attribute_groupcontains attributes related to temperature thresholds (trip points).
trip_temp_attrs,trip_type_attrs,trip_hyst_attrs:Type:
struct thermal_attr *These fields point to attributes related to thermal zone temperature thresholds:
trip_temp_attrs: attributes of threshold temperatures;trip_type_attrs: attributes of threshold types (e.g., high temperature, low temperature, etc.);trip_hyst_attrs: attributes of threshold hysteresis, used to control the interval between upper and lower temperature limits.
mode:Type:
enum thermal_device_modeRepresents the current operating mode of the thermal zone. The mode determines how the thermal zone responds to temperature changes (e.g., active, sleep, shutdown modes).
devdata:Type:
void *Points to private data associated with the thermal zone device. Drivers can use this field to store device-specific private data.
trips:Type:
struct thermal_trip *This field is a pointer array to
struct thermal_trip, used to store various temperature thresholds (trip points) of the thermal zone. Each threshold defines a temperature point at which specific actions are triggered when the system temperature reaches it (e.g., enabling fans, reducing frequency, etc.).
num_trips:Type:
intIndicates the number of temperature thresholds supported by the current thermal zone device. Each threshold may trigger different cooling measures.
trips_disabled:Type:
unsigned longA bitmap indicating which temperature thresholds have been disabled. If a threshold is disabled, no events related to it will be triggered.
passive_delay_jiffies:Type:
unsigned longThe delay time required when the system performs passive cooling, measured in jiffies. Passive cooling typically refers to lowering temperature by reducing CPU or other device frequencies.
polling_delay_jiffies:Type:
unsigned longThe delay time used to check whether the temperature exceeds certain thresholds, measured in jiffies. If the system is interrupt-driven, this value may be 0.
temperature:Type:
intCurrent temperature. This field is primarily used by core code; drivers should use the
thermal_zone_get_temp()function to obtain the current temperature.
last_temperature:Type:
intThe last recorded temperature value.
emul_temperature:Type:
intIf
CONFIG_THERMAL_EMULATION(thermal management emulation) is enabled, this field represents the simulated temperature value. It is very useful during development or testing, especially when real hardware is unavailable.
passive:Type:
intSet to 1 if the device has passed a passive threshold; otherwise 0. Passive cooling usually involves adjusting device frequency to lower temperature.
prev_low_trip,prev_high_trip:Type:
intThese fields store the temperature range when a passive cooling threshold is triggered.
prev_low_tripis the previous low-temperature threshold, andprev_high_tripis the previous high-temperature threshold.
need_update:Type:
atomic_tUsed to mark whether the thermal zone device needs updating. This field is typically set to 1 by core code if the device’s temperature or state requires updating, triggering an update.
ops:Type:
struct thermal_zone_device_ops *Pointer to a set of operation functions for the thermal zone device. These operation functions define the behavior of the thermal zone device, including how to obtain temperature, set mode, trigger thresholds, etc.
tzp:Type:
struct thermal_zone_params *Pointer to the thermal zone parameters structure. This structure contains other configuration parameters related to the thermal zone.
governor:Type:
struct thermal_governor *Pointer to the thermal zone governor. The governor is responsible for deciding how to adjust temperature based on current temperature and thermal zone policies (e.g., by changing CPU or other hardware frequencies for cooling).
governor_data:Type:
void *Used to store private data associated with the thermal zone governor.
thermal_instances:Type:
struct list_headA linked list of all instances of the thermal zone. Each instance represents a specific hardware or function within the thermal zone device.
ida:Type:
struct idaAn
IDA(ID allocator) structure used to generate unique IDs, typically for assigning unique IDs to cooling devices of each thermal zone.
lock:Type:
struct mutexA lock used to protect the
thermal_instanceslist, preventing race conditions from multiple threads or interrupts.
node:Type:
struct list_headA node used to add the
thermal_zone_deviceto the global thermal zone list.thermal_tz_listis a linked list containing all thermal zone devices.
poll_queue:Type:
struct delayed_workA queue for delayed work tasks, used for periodic temperature checks or threshold triggering.
notify_event:Type:
enum thermal_notify_eventThe type of the last notification event, indicating what kind of notification event was triggered by temperature (e.g., high temperature).
Among the above members, ops is the abstraction of operations for this Thermal Zone, governor is the temperature regulation policy used by this Thermal Zone, and thermal_instances is the list of Cooling Devices under this Thermal Zone.
thermal_governor
struct thermal_governor {
char name[THERMAL_NAME_LENGTH];
int (*bind_to_tz)(struct thermal_zone_device *tz);
void (*unbind_from_tz)(struct thermal_zone_device *tz);
int (*throttle)(struct thermal_zone_device *tz, int trip);
struct list_head governor_list;
};
The thermal_governor structure is used to represent a “thermal governor” and its relationship with thermal zone devices. A thermal governor is a mechanism used to control temperature and regulate thermal management in the system. It interacts with thermal zone devices (thermal_zone_device) and corresponding temperature thresholds (trip points) to help avoid system overheating or ensure temperature remains within a certain range. This structure includes the following members:
name(char name[THERMAL_NAME_LENGTH])
char name[THERMAL_NAME_LENGTH];
Function: Stores the name of the thermal governor.
THERMAL_NAME_LENGTHis the maximum length of the name. This name is used to identify different thermal governors (e.g., “user mode” or “hardware control”).
bind_to_tz(int (*bind_to_tz)(struct thermal_zone_device *tz))
int (*bind_to_tz)(struct thermal_zone_device *tz);
Function: A callback function invoked when binding the thermal governor to a thermal zone device (
thermal_zone_device).Parameter:
tz: Pointer to the thermal zone device being bound.
Return value: Returns 0 if binding succeeds; non-zero indicates failure.
Description: This callback function establishes the association between the thermal governor and the thermal zone device. After successful binding, the governor can control the temperature of that thermal zone device.
unbind_from_tz(void (*unbind_from_tz)(struct thermal_zone_device *tz))
void (*unbind_from_tz)(struct thermal_zone_device *tz);
Function: A callback function invoked when unbinding the thermal governor from a thermal zone device.
Parameter:
tz: Pointer to the thermal zone device being unbound.
Return value: This function has no return value.
Description: When the thermal governor no longer needs to control a thermal zone device, this function is called to unbind them.
throttle(int (*throttle)(struct thermal_zone_device *tz, int trip))
int (*throttle)(struct thermal_zone_device *tz, int trip);
Function: A callback function used to perform thermal regulation when a temperature threshold is triggered (regardless of whether the temperature has reached the threshold). Typically, this is used to adjust system power or performance when temperature approaches or exceeds a threshold.
Parameters:
tz: Pointer to the thermal zone device.trip: Index of the temperature threshold in the thermal zone device, indicating whether the current temperature is approaching or has exceeded a certain threshold.
Return value: Returns an integer, usually a success or error code; 0 indicates success, other values indicate failure.
Description: This callback function adjusts system behavior based on the given threshold (
trip), such as reducing CPU frequency or adjusting fan speed.
governor_list(struct list_head governor_list)
struct list_head governor_list;
Function: A linked list node used to add different thermal governors to a global thermal governor list.
Description: This structure member is of type
list_head, a data structure in the Linux kernel for implementing linked lists, allowing thermal governors to be managed and scheduled as list elements within the system.
In summary, struct thermal_governor is a structure used to manage and control temperature, typically working closely with thermal zone devices and temperature thresholds in the thermal management system. It implements thermal regulation through the following mechanisms:
Binding/Unbinding: Using
bind_to_tzandunbind_from_tzcallback functions, the thermal governor can bind or unbind with thermal zone devices.Temperature Regulation: Using the
throttlecallback function, the thermal governor adjusts device behavior based on temperature thresholds (trip) to ensure temperature remains within a safe range.
thermal_bind_params (Cooling Device)
The thermal_bind_params structure is used to describe binding parameters between a thermal zone and a cooling device. In the system’s thermal management framework, thermal zones and cooling devices may need to be bound according to different temperature thresholds (trip points) to effectively control device temperature. This structure serves as an abstraction of cooling devices—different fan speeds for fan devices, different voltages or frequencies for CPU, DDR, GPU, etc.
struct thermal_bind_params {
struct thermal_cooling_device *cdev;
int weight;
int trip_mask;
unsigned long *binding_limits;
int (*match)(struct thermal_zone_device *tz, struct thermal_cooling_device *cdev);
};
```1) `cdev` (`struct thermal_cooling_device *cdev`)
```c
struct thermal_cooling_device *cdev;
Type: Pointer to
thermal_cooling_device.Function: Points to a cooling device. A cooling device is a hardware component or software control mechanism used to regulate the temperature of a thermal zone. Through this pointer, the system can operate the cooling device—starting, stopping, or adjusting its cooling capacity.
weight(int weight)
int weight;
Type: Integer type.
Function: Represents the weight of the cooling effect of the cooling device on the thermal zone. The weight is determined by system characteristics and reflects the cooling capability of the device. A higher weight indicates better cooling performance. For example, a device with twice the weight of another will be more effective at reducing temperature.
Note: The
weightof a cooling device is relative. When multiple cooling devices exist, their weights help the system determine which device should be prioritized at certain temperature thresholds.
trip_mask(int trip_mask)
int trip_mask;
Type: Integer type.
Function: A bitmask that specifies the binding relationship between the cooling device and the thermal zone, particularly for specific temperature thresholds (trip points). It indicates which cooling devices should be enabled or activated at certain temperature thresholds.
Note: Each bit in the
trip_maskcorresponds to the state of a cooling device at a given temperature threshold. By setting the bitmask, it can be determined how the cooling device should operate under different temperature ranges.
binding_limits(unsigned long *binding_limits)
unsigned long *binding_limits;
Type: Pointer to
unsigned long.Function: An array indicating the cooling state limits when the cooling device is bound to a thermal zone. The size of this array is
2 * thermal_zone.number_of_trip_points, meaning each trip point has a corresponding limit range. Each trip point is associated with a pair of state limits (lower and upper). For instance, at a certain trip point, the operating state of the cooling device may be restricted within a specific range.Note: If
binding_limitsisNULL, it means there are no restrictions on the cooling device’s state, and the device has no limits across all temperature thresholds.
match(int (*match)(struct thermal_zone_device *tz, struct thermal_cooling_device *cdev))
int (*match)(struct thermal_zone_device *tz, struct thermal_cooling_device *cdev);
Type: A function pointer pointing to a matching function.
Function: A callback function used to determine whether a cooling device is compatible with a thermal zone device. Specifically, the
matchfunction returns an integer value based on the characteristics of the current thermal zone (tz) and cooling device (cdev), typically returning0for a successful match and non-zero for failure.Note: This function enables the system to decide whether to bind a cooling device to a thermal zone based on their specific characteristics.
thermal_instance
struct thermal_instance {
int id;
char name[THERMAL_NAME_LENGTH];
struct thermal_zone_device *tz;
struct thermal_cooling_device *cdev;
int trip;
bool initialized;
unsigned long upper; /* Highest cooling state for this trip point */
unsigned long lower; /* Lowest cooling state for this trip point */
unsigned long target; /* expected cooling state */
char attr_name[THERMAL_NAME_LENGTH];
struct device_attribute attr;
char weight_attr_name[THERMAL_NAME_LENGTH];
struct device_attribute weight_attr;
struct list_head tz_node; /* node in tz->thermal_instances */
struct list_head cdev_node; /* node in cdev->thermal_instances */
unsigned int weight; /* The weight of the cooling device */
};
The thermal_instance structure describes the behavior of a cooling device at a specific temperature threshold (trip point). It is primarily used in the system’s thermal management mechanism to represent the state and configuration of a cooling device within a specific thermal zone and at a given trip point.
id(int id)int id;
Type: Integer type.
Function: Uniquely identifies a
thermal_instance. It can be used to distinguish between different cooling device instances, even if they are in the same thermal zone and at the same trip point.
name(char name[THERMAL_NAME_LENGTH])char name[THERMAL_NAME_LENGTH];
Type: Character array used to store the instance name.
Function: This name identifies the current cooling device instance.
THERMAL_NAME_LENGTHis a macro defining the maximum length of the name. The name is typically used in debugging or logging to help developers understand the current cooling device instance.
tz(struct thermal_zone_device *tz)struct thermal_zone_device *tz;
Type: Pointer to
thermal_zone_devicestructure.Function: Points to the thermal zone to which the cooling device is bound. A thermal zone represents a monitored and controlled temperature region, possibly a physical area or a hardware component in the system. This member indicates the cooling device’s behavior within a specific thermal zone.
cdev(struct thermal_cooling_device *cdev)struct thermal_cooling_device *cdev;
Type: Pointer to
thermal_cooling_devicestructure.Function: Points to the cooling device. Cooling devices are typically hardware components (e.g., fans, heatsinks) or software control mechanisms used to reduce the temperature of a thermal zone.
trip(int trip)int trip;
Type: Integer type.
Function: Indicates the index of the temperature threshold (trip point) associated with this cooling device instance. Thermal zones usually have multiple trip points, each corresponding to a different cooling strategy.
tripspecifies which threshold’s cooling behavior this instance targets.
initialized(bool initialized)bool initialized;
Type: Boolean type.
Function: Indicates whether this cooling device instance has been initialized. If
true, the instance has been initialized and is ready for use. Iffalse, the instance has not yet been initialized.
upper(unsigned long upper)unsigned long upper;
Type: Unsigned long integer.
Function: Represents the highest cooling state of the cooling device at the specified trip point. Cooling states usually represent the intensity of device operation (e.g., fan speed).
upperindicates the maximum state the cooling device can reach.
lower(unsigned long lower)unsigned long lower;
Type: Unsigned long integer.
Function: Represents the lowest cooling state of the cooling device at the specified trip point. In contrast to
upper,lowerindicates the minimum operating intensity of the cooling device at this trip point.
target(unsigned long target)unsigned long target;
Type: Unsigned long integer.
Function: Represents the expected cooling state. This state is dynamically calculated based on the trip point and the thermal zone’s requirements. The system attempts to bring the cooling device to this target state.
attr_name(char attr_name[THERMAL_NAME_LENGTH])char attr_name[THERMAL_NAME_LENGTH];
Type: Character array.
Function: Stores the attribute name associated with this cooling device instance. The attribute name is used to create files in the system’s device tree or file system, allowing users to access and control the cooling device’s state.
attr(struct device_attribute attr)struct device_attribute attr;
Type:
device_attributestructure.Function: Represents the device attribute associated with the cooling device instance. It is typically used in the sysfs interface to allow information exchange between user space and kernel space. For example, users can control the cooling device’s operating state via
attr.
weight_attr_name(char weight_attr_name[THERMAL_NAME_LENGTH])char weight_attr_name[THERMAL_NAME_LENGTH];
Type: Character array.
Function: Stores the name of the cooling device’s weight attribute. The weight is typically used to determine the device’s priority and cooling effectiveness in thermal management.
weight_attr(struct device_attribute weight_attr)struct device_attribute weight_attr;
Type:
device_attributestructure.Function: Represents the device attribute related to the cooling device’s weight. It is usually exposed in sysfs as an interface to user space, allowing users to adjust the cooling device’s weight and thus influence the system’s thermal management strategy.
tz_node(struct list_head tz_node)struct list_head tz_node;
Type:
list_headstructure.Function: This node is used to add the current
thermal_instanceto the instance list of the thermal zone device (tz). Each thermal zone can contain multiple cooling device instances, and this node helps organize the linked list of all cooling device instances under the thermal zone.
cdev_node(struct list_head cdev_node)struct list_head cdev_node;
Type:
list_headstructure.Function: This node is used to add the current
thermal_instanceto the instance list of the cooling device (cdev). Each cooling device can be used in multiple thermal zones, and this node helps organize the linked list of all instances under the cooling device.
weight(unsigned int weight)unsigned int weight;
Type: Unsigned integer.
Function: Represents the weight of the cooling device. The weight value is typically used in decision-making for thermal management strategies; a higher weight indicates stronger cooling effectiveness. It affects the scheduling and priority of the cooling device within the thermal zone.
Key Function Interfaces of Thermal Subsystem
The Thermal core acts as a coordinator among Thermal Zones, Thermal Cooling devices, and Thermal Governors, providing unified APIs to interconnect them and achieve temperature control.
Specifically, the Thermal core operates as follows:
Obtain temperature from Thermal Zone: First, retrieve the current temperature value from the Thermal Zone device.
Select the appropriate Thermal Governor: Based on the temperature, select a suitable Thermal Governor to manage the thermal control policy.
Control Thermal Cooling devices: Adjust the states of Thermal Cooling devices according to the settings of the Thermal Governor to regulate temperature.
Device Registration and Unregistration:
Register Thermal Zone Device: Call
thermal_zone_device_register()to register a thermal zone device, create a series of sysfs nodes, and bind it with the corresponding governor and cooling devices.Unregister Thermal Zone Device:
thermal_zone_device_unregister()performs the reverse operation—removing the thermal zone device, unbinding it from cooling devices, and deleting the corresponding sysfs nodes.
Cooling Device Management:
Register Cooling Device: Use
thermal_cooling_device_register()to create a cooling device, add it to thethermal_cdev_list, and create relevant sysfs nodes. At this point, the cooling device is bound to thermal zone devices.Unregister Cooling Device:
thermal_cooling_device_unregister()performs the reverse operation—unbinding the cooling device from thermal zones and removing associated sysfs nodes.
Governor Management:
Register Thermal Governor:
thermal_register_governor()first checks whether a governor with the same name already exists inthermal_governor_list. If not, it adds the new governor to the list and updates thethermal_tz_listfor any thermal zones that have no assigned governor.Unregister Thermal Governor:
thermal_unregister_governor()unbinds the specified governor from its associated thermal zones, callsunbind_from_tz()to clear related data, and finally removes the governor from thethermal_governor_list.
Binding and Unbinding Devices:
Bind Cooling Device to Thermal Zone:
thermal_zone_bind_cooling_device()creates athermal_instancedevice to bind a Thermal Zone with a Thermal Cooling device, enabling temperature-based control of the cooling device.Unbind Cooling Device:
thermal_zone_unbind_cooling_device()removes the boundthermal_instancefrom both linked lists, thereby breaking the binding relationship.
Temperature Update and Handling:
Update Thermal Zone Temperature:
thermal_zone_device_update()is typically triggered by a thermal driver, either via polling or interrupt, to update the current temperature. Based on temperature changes, it invokeshandle_thermal_trip()for appropriate handling.
Monitoring and Delayed Processing:
Monitor Thermal Zone:
monitor_thermal_zone()determines whether to start thethermal_zone_device->poll_queuedelayed work item based on passive or polling settings.Polling Process: The entire polling process is triggered by
thermal_zone_device_update(), with the following steps:In
handle_thermal_trip(), callmonitor_thermal_zone().In
monitor_thermal_zone(), callmod_delayed_work()to update the delay value ofpoll_queue. If the thermal zone has multiple trip points, the delay may be updated multiple times.Once
poll_queueis queued intosystem_freezable_wq, after the specified delay,thermal_zone_device_check()is called, which in turn callsthermal_zone_device_update()to complete periodic updates and processing.
The above process can be illustrated in the following diagram:

Below is a detailed analysis of some key functions.
thermal_set_governor Function
Function:
Switch the thermal policy (governor) of a thermal zone.
Function Prototype:
static int thermal_set_governor(struct thermal_zone_device *tz,
struct thermal_governor *new_gov)
Parameters:
tz: Pointer to the thermal zone device.new_gov: The new thermal governor.
Logic:
If the thermal zone already has a bound governor, first call its
unbind_from_tzmethod to unbind.If the new governor exists and has a
bind_to_tzmethod, attempt to bind it to the thermal zone.If binding fails, try to revert to the previous governor.
Finally, update the thermal zone’s governor pointer.
Return Value:
Returns 0 on success; returns an error code if binding the new governor fails.
thermal_register_governor Function
Function:
Register a new thermal governor.
Function Prototype:
int thermal_register_governor(struct thermal_governor *governor)
Parameters:
governor: The thermal governor to register.
Logic:
Check whether the governor already exists.
If not, add it to the governor list and set it as the default governor if applicable.
Traverse all thermal zones and attempt to apply the new governor to each.
Return Value:
Returns 0 on success; returns an error code on failure.
thermal_unregister_governor Function
Function:
Unregister a thermal governor.
Function Prototype:
void thermal_unregister_governor(struct thermal_governor *governor)
Parameters:
governor: The thermal governor to unregister.
Logic:
Remove the specified governor from the governor list.
Traverse all thermal zones and revert any zones using this governor back to the default governor.
update_temperature Function
Function:
Update the temperature of the thermal zone device.
Function Prototype:
static void update_temperature(struct thermal_zone_device *tz)
Parameters:
tz: Pointer to the thermal zone device.
Logic:
Call
thermal_zone_get_tempto read the temperature.Update the temperature value of the thermal zone device.
If the temperature is valid, trigger corresponding notifications.
thermal_zone_device_update Function
Function:
Update the state of the thermal zone device.
Function Prototype:
void thermal_zone_device_update(struct thermal_zone_device *tz,
enum thermal_notify_event event)
Parameters:
tz: Pointer to the thermal zone device.event: Type of event triggering the update.
Logic:
Check if the system is suspended; if so, return immediately.
Update the temperature.
Handle all trip points.
Adjust polling frequency as needed.
thermal_zone_device_check Function
Function:
Callback function for the work queue, used to check and update the state of the thermal zone device.
Function Prototype:
static void thermal_zone_device_check(struct work_struct *work)
Parameters:
work: Pointer to the work structure.
Logic:
Call
thermal_zone_device_updateto update the state of the thermal zone device.
thermal_zone_bind_cooling_device Function
Function:
Bind a cooling device to a specific trip point of a thermal zone device.
Function Prototype:
int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
int trip,
struct thermal_cooling_device *cdev,
unsigned long upper, unsigned long lower,
unsigned int weight)
Parameters:
tz: Thermal zone device.trip: Index of the trip point.cdev: Cooling device.upper: Maximum cooling state.lower: Minimum cooling state.weight: Weight of the cooling device.
Logic:
Validate input parameters.
Create a new
thermal_instancestructure to represent the binding between the cooling device and the thermal zone.Update the sysfs interface to reflect the new binding.
Return Value:
Returns 0 on success; returns an error code on failure.
thermal_zone_unbind_cooling_device Function
Function:
Unbind a cooling device from a thermal zone device.
Function Prototype:
int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
int trip,
struct thermal_cooling_device *cdev)
Parameters:
tz: Thermal zone device.trip: Index of the trip point.cdev: Cooling device.
Logic:
Locate the corresponding
thermal_instancestructure and remove it from the list.Update the sysfs interface to reflect the unbinding.
Return Value:
Returns 0 on success; returns an error code on failure.
thermal_cooling_device_unregister Function
Function:
Unregister a cooling device.
Function Prototype:
void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
Parameters:
cdev: The cooling device to unregister.
Logic:
Remove the specified cooling device from the cooling device list.
Unbind it from all associated thermal zones.
bind_tz Function
Function:
Bind a cooling device to a thermal zone.
Function Prototype:
static void bind_tz(struct thermal_zone_device *tz)
Parameters:
tz: Thermal zone device.
Logic:
Iterate through all cooling devices and attempt to bind each to the thermal zone.
thermal_zone_device_register_with_trips Function
Function:
Create and register a new thermal zone device with specified trip point information.
Function Prototype:
struct thermal_zone_device *
thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *trips, int num_trips, int mask,
void *devdata, struct thermal_zone_device_ops *ops,
struct thermal_zone_params *tzp, int passive_delay,
int polling_delay)
Parameters:
type: Name of the thermal zone.trips: Array of trip points.num_trips: Number of trip points.mask: Bitmask of trip points.devdata: Private data.ops: Operations for the thermal zone device.tzp: Parameters for the thermal zone.passive_delay: Delay for passive cooling.polling_delay: Polling interval.-ops: Thermal zone operation interface.tzp: Thermal zone parameters.passive_delay: Passive cooling delay.polling_delay: Polling delay.
Logic:
Initialize the thermal zone device.
Register the device to sysfs.
Bind cooling devices.
Set polling and delays.
Return value:
Returns a pointer to the thermal zone device on success, or an error pointer on failure.
thermal_zone_device_unregister function
Function:
Unregister a thermal zone device.
Function prototype:
void thermal_zone_device_unregister(struct thermal_zone_device *tz)
Parameters:
tz: Thermal zone device.
Logic:
Remove the thermal zone from the thermal zone list.
Unbind all cooling devices.
Unregister the device.
thermal_init function
Function:
Initialize the thermal management framework.
Function prototype:
static int __init thermal_init(void)
Logic:
Register thermal governor.
Register thermal class.
Register PM notifier.
Return value:
Returns 0 on success, or an error code on failure.
4.3.14.5. Thermal system debugging guide for driver platform
Under the board’s system directory /sys/class/hwmon/hwmon0, temperature sensor parameters are available: temp1_input represents DDR temperature, temp2_input represents BPU temperature, and temp3_input represents CPU temperature, as shown below:
root@buildroot:~# ls /sys/class/hwmon/hwmon0/ | grep temp
temp1_input
temp2_input
temp3_input
The temperature precision is 0.001°C. To check DDR temperature, use the following command:
cat /sys/class/hwmon/hwmon0/temp1_input
46643
The above log indicates that the current DDR temperature is 46.643°C.
Note: The BPU temperature sensor is located in the BPU subsystem, which is only powered when the BPU is running. Therefore, BPU temperature can only be read when the BPU is active.
Currently, the default policy can be checked via the following command and is set to step_wise:
cat /sys/class/thermal/thermal_zone0/policy
step_wise
Available policies can be viewed with the following command, which shows two options: user_space and step_wise:
cat /sys/class/thermal/thermal_zone0/available_policies
user_space step_wise
user_space: Reports current temperature, trip points, and other thermal information to user space via uevent, allowing user-space software to determine the thermal control strategy.step_wise: Gradually increases cooling states in each polling cycle, representing a relatively gentle thermal control strategy.
The choice of policy should be based on product requirements. It can be specified at compile time or dynamically switched via sysfs.
For example, to dynamically switch thermal_zone0’s policy to user_space mode:
echo user_space > /sys/class/thermal/thermal_zone0/policy
In thermal_zone0, there is one trip_point used to control the frequency throttling temperature of the DDR cooling device.
The DDR frequency throttling temperature can be viewed via sysfs. The current configuration is 95°C:
cat /sys/devices/virtual/thermal/thermal_zone0/trip_point_0_temp
To adjust the DDR throttling temperature to 85°C, use the following command:
echo 85000 > /sys/devices/virtual/thermal/thermal_zone0/trip_point_0_temp
In thermal_zone1, there are three trip_points:
trip_point_0_temp: Reserved for future use.trip_point_1_temp: Frequency throttling temperature for this thermal zone, controlling CPU/BPU/GPU frequencies. Currently set to 95°C.trip_point_2_temp: Shutdown temperature, currently set to 105°C.
For example, to make CPU/BPU/GPU start throttling at a junction temperature of 85°C:
echo 85000 > /sys/devices/virtual/thermal/thermal_zone1/trip_point_1_temp
To change the shutdown temperature to 105°C:
echo 105000 > /sys/devices/virtual/thermal/thermal_zone1/trip_point_2_temp
Note: All the above settings must be reconfigured after power cycle or reboot.
4.3.14.6. Thermal reference documentation
The following paths are relative to the kernel source root directory:
./Documentation/devicetree/bindings/thermal
./Documentation/driver-api/thermal