通用热Sysfs驱动程序操作指南¶
作者:Sujith Thomas <sujith.thomas@intel.com>,Zhang Rui <rui.zhang@intel.com>
版权所有 (c) 2008 Intel Corporation
0. 介绍¶
通用热sysfs提供了一组接口,用于热区设备(传感器)和散热设备(风扇、处理器等)注册到热管理解决方案并成为其一部分。
本操作指南重点介绍如何使新的热区和散热设备参与热管理。该解决方案与平台无关,任何类型的热区设备和散热设备都应能够利用此基础设施。
热sysfs驱动程序的主要任务是将热区属性和散热设备属性暴露给用户空间。智能热管理应用程序可以根据热区属性(当前温度和跳变点温度)的输入做出决策,并对相应的设备进行节流。
[0-*] 表示从0开始的任何正数
[1-*] 表示从1开始的任何正数
1. 热sysfs驱动程序接口函数¶
1.1 热区设备接口¶
struct thermal_zone_device * thermal_zone_device_register_with_trips(const char *type, const struct thermal_trip *trips, int num_trips, void *devdata, const struct thermal_zone_device_ops *ops, const struct thermal_zone_params *tzp, unsigned int passive_delay, unsigned int polling_delay)此接口函数将一个新的热区设备(传感器)添加到 /sys/class/thermal 文件夹,命名为 thermal_zone[0-*]。它会同时尝试绑定所有已注册的散热设备。
- 类型
热区类型。
- 跳变点
此热区的跳变点表。
- 设备数据
设备私有数据
- 操作
热区设备回调。
- .should_bind
检查给定的散热设备是否应绑定到此热区中的给定跳变点。
- .get_temp
获取热区的当前温度。
- .set_trips
设置跳变点窗口。每当当前温度更新时,都会找到紧邻当前温度之下和之上的跳变点。
- .change_mode
更改热区的模式(启用/禁用)。
- .set_trip_temp
设置给定跳变点的温度。
- .get_crit_temp
获取此热区的临界温度。
- .set_emul_temp
设置仿真温度,这有助于调试不同的阈值温度点。
- .get_trend
获取最近区域温度变化的趋势。
- .hot
热跳变点越界处理程序。
- .critical
临界跳变点越界处理程序。
- tzp
热区平台参数。
- passive_delay
执行被动冷却时,两次轮询之间等待的毫秒数。
- polling_delay
检查跳变点是否已被越过时,两次轮询之间等待的毫秒数(中断驱动系统为0)。
void thermal_zone_device_unregister(struct thermal_zone_device *tz)此接口函数移除热区设备。它会从 /sys/class/thermal 文件夹中删除相应的条目,并解绑所有使用它的散热设备。
struct thermal_zone_device *thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data, const struct thermal_zone_of_device_ops *ops)此接口将一个新传感器添加到DT热区。此函数将搜索设备树中描述的热区列表,并查找引用 dev->of_node 指向的传感器设备作为温度提供者的区域。对于指向传感器节点的区域,该传感器将被添加到DT热区设备中。
此接口的参数有
- dev
传感器设备节点,其中dev->of_node包含有效的节点指针。
- sensor_id
传感器标识符,以防传感器IP有多个传感器
- 数据
一个私有指针(由调用者拥有),当需要温度读数时将回传。
- 操作
结构体 thermal_zone_of_device_ops *.
get_temp
指向读取传感器温度的函数的指针。这是传感器驱动程序提供的强制回调。
set_trips
指向设置温度窗口的函数的指针。当离开此窗口时,驱动程序必须通过 thermal_zone_device_update 通知热核心。
get_trend
指向读取传感器温度趋势的函数的指针。
set_emul_temp
指向设置传感器仿真温度的函数的指针。
热区温度由 thermal_zone_of_device_ops 的 get_temp() 函数指针提供。当调用时,它将返回私有指针 @data。
如果失败,它将返回错误指针,否则返回有效的热区设备句柄。调用者应使用
IS_ERR()
检查返回句柄以判断是否成功。void thermal_zone_of_sensor_unregister(struct device *dev, struct thermal_zone_device *tzd)此接口从DT热区注销一个传感器,该传感器曾通过 thermal_zone_of_sensor_register() 接口成功添加。此函数从通过 thermal_zone_of_sensor_register() 接口注册的热区设备中移除传感器回调和私有数据。它还会通过移除 .get_temp() 和 get_trend() 热区设备回调来使该区域静默。
struct thermal_zone_device *devm_thermal_zone_of_sensor_register(struct device *dev, int sensor_id, void *data, const struct thermal_zone_of_device_ops *ops)此接口是 thermal_zone_of_sensor_register() 的资源管理版本。
第1.1.3节中描述的 thermal_zone_of_sensor_register() 的所有细节都适用于此处。
使用此接口注册传感器的好处是,不需要在错误路径或驱动程序解绑期间显式调用 thermal_zone_of_sensor_unregister(),因为这由驱动程序资源管理器完成。
void devm_thermal_zone_of_sensor_unregister(struct device *dev, struct thermal_zone_device *tzd)此接口是 thermal_zone_of_sensor_unregister() 的资源管理版本。第1.1.4节中描述的 thermal_zone_of_sensor_unregister() 的所有细节都适用于此处。通常不需要调用此函数,资源管理代码将确保资源被释放。
int thermal_zone_get_slope(struct thermal_zone_device *tz)此接口用于读取热区设备的斜率属性值,这可能对平台驱动程序的温度计算有用。
int thermal_zone_get_offset(struct thermal_zone_device *tz)此接口用于读取热区设备的偏移属性值,这可能对平台驱动程序的温度计算有用。
1.2 散热设备接口¶
struct thermal_cooling_device *thermal_cooling_device_register(char *name, void *devdata, struct thermal_cooling_device_ops *)此接口函数将一个新的散热设备(风扇/处理器/...)添加到 /sys/class/thermal/ 文件夹,命名为 cooling_device[0-*]。它会尝试同时将自己绑定到所有已注册的热区设备。
- 名称
散热设备名称。
- 设备数据
设备私有数据。
- 操作
散热设备回调。
- .get_max_state
获取散热设备的最大节流状态。
- .get_cur_state
获取散热设备当前请求的节流状态。
- .set_cur_state
设置散热设备的当前节流状态。
void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)此接口函数移除散热设备。它会从 /sys/class/thermal 文件夹中删除相应的条目,并解绑所有使用它的热区设备。
1.4 热区参数¶
struct thermal_zone_params此结构定义了热区的平台级参数。这些数据,对于每个热区,应来自平台层。这是一个可选功能,某些平台可以选择不提供此数据。
- .governor_name
此区域使用的热控制器名称
- .no_hwmon
一个布尔值,指示是否需要热到hwmon sysfs接口。当no_hwmon == false时,将创建一个hwmon sysfs接口。当no_hwmon == true时,将不进行任何操作。如果 thermal_zone_params 为NULL,则将创建hwmon接口(为了向后兼容)。
2. sysfs属性结构¶
RO |
只读值 |
WO |
只写值 |
RW |
读/写值 |
热sysfs属性将表示在 /sys/class/thermal 下。如果hwmon已编译或作为模块构建,hwmon sysfs I/F扩展也可在 /sys/class/hwmon 下使用。
热区设备sys I/F,注册后创建
/sys/class/thermal/thermal_zone[0-*]:
|---type: Type of the thermal zone
|---temp: Current temperature
|---mode: Working mode of the thermal zone
|---policy: Thermal governor used for this zone
|---available_policies: Available thermal governors for this zone
|---trip_point_[0-*]_temp: Trip point temperature
|---trip_point_[0-*]_type: Trip point type
|---trip_point_[0-*]_hyst: Hysteresis value for this trip point
|---emul_temp: Emulated temperature set node
|---sustainable_power: Sustainable dissipatable power
|---k_po: Proportional term during temperature overshoot
|---k_pu: Proportional term during temperature undershoot
|---k_i: PID's integral term in the power allocator gov
|---k_d: PID's derivative term in the power allocator
|---integral_cutoff: Offset above which errors are accumulated
|---slope: Slope constant applied as linear extrapolation
|---offset: Offset constant applied as linear extrapolation
散热设备sys I/F,注册后创建
/sys/class/thermal/cooling_device[0-*]:
|---type: Type of the cooling device(processor/fan/...)
|---max_state: Maximum cooling state of the cooling device
|---cur_state: Current cooling state of the cooling device
|---stats: Directory containing cooling device's statistics
|---stats/reset: Writing any value resets the statistics
|---stats/time_in_state_ms: Time (msec) spent in various cooling states
|---stats/total_trans: Total number of times cooling state is changed
|---stats/trans_table: Cooling state transition table
接下来两个动态属性成对创建/移除。它们表示热区及其关联散热设备之间的关系。
/sys/class/thermal/thermal_zone[0-*]:
|---cdev[0-*]: [0-*]th cooling device in current thermal zone
|---cdev[0-*]_trip_point: Trip point that cdev[0-*] is associated with
|---cdev[0-*]_weight: Influence of the cooling device in
this thermal zone
除了热区设备sysfs I/F和散热设备sysfs I/F之外,通用热驱动程序还为每种热区设备类型创建一个hwmon sysfs I/F。例如,通用热驱动程序注册一个hwmon类设备,并为所有已注册的ACPI热区构建相关的hwmon sysfs I/F。
请阅读 ABI文件测试/sysfs-class-thermal 以获取热区和散热设备属性的详细信息。
/sys/class/hwmon/hwmon[0-*]:
|---name: The type of the thermal zone devices
|---temp[1-*]_input: The current temperature of thermal zone [1-*]
|---temp[1-*]_critical: The critical trip point of thermal zone [1-*]
请阅读 sysfs文件命名和数据格式标准 以获取更多信息。
3. 一个简单的实现¶
ACPI热区可能支持多个跳变点,例如临界、热、被动、主动。如果一个ACPI热区同时支持临界、被动、主动[0]和主动[1],它可能会将自己注册为 thermal_zone_device (thermal_zone1),共包含4个跳变点。它有一个处理器和一个风扇,两者都注册为 thermal_cooling_device。两者都被认为在冷却热区方面具有相同的效率。
如果处理器列在 _PSL 方法中,风扇列在 _AL0 方法中,则sys I/F结构将如下构建
/sys/class/thermal:
|thermal_zone1:
|---type: acpitz
|---temp: 37000
|---mode: enabled
|---policy: step_wise
|---available_policies: step_wise fair_share
|---trip_point_0_temp: 100000
|---trip_point_0_type: critical
|---trip_point_1_temp: 80000
|---trip_point_1_type: passive
|---trip_point_2_temp: 70000
|---trip_point_2_type: active0
|---trip_point_3_temp: 60000
|---trip_point_3_type: active1
|---cdev0: --->/sys/class/thermal/cooling_device0
|---cdev0_trip_point: 1 /* cdev0 can be used for passive */
|---cdev0_weight: 1024
|---cdev1: --->/sys/class/thermal/cooling_device3
|---cdev1_trip_point: 2 /* cdev1 can be used for active[0]*/
|---cdev1_weight: 1024
|cooling_device0:
|---type: Processor
|---max_state: 8
|---cur_state: 0
|cooling_device3:
|---type: Fan
|---max_state: 2
|---cur_state: 0
/sys/class/hwmon:
|hwmon0:
|---name: acpitz
|---temp1_input: 37000
|---temp1_crit: 100000
4. 导出符号API¶
4.1. get_tz_trend¶
此函数返回热区的趋势,即热区温度的变化率。理想情况下,热传感器驱动程序应该实现回调。如果它们没有实现,热框架会通过比较先前和当前的温度值来计算趋势。
4.2. thermal_cdev_update¶
此函数用作设置散热设备状态的仲裁器。如果可能,它会将散热设备设置为最深的冷却状态。
5. 临界事件¶
当发生临界跳变温度越界事件时,热框架将根据配置触发硬件保护性关机(shutdown)或重启。
首先,内核将尝试有序关机或重启,但会接受一个延迟,在此延迟之后它将分别进行强制关机或重启。如果这失败,将调用 emergency_restart()
作为最后的手段。
应仔细分析延迟时间,以确保有足够的时间进行有序关机或重启。
如果延迟设置为0,则不支持紧急操作。因此,为了触发紧急操作,必须设置一个经过仔细分析的非零正值。