dts里的配置如下:
thermal-zones{
cpu_thermal_zone{
polling-delay-passive = <1000>; //超过阀值轮询时间
polling-delay = <2000>; //未超阀值轮询时间
thermal-sensors = <&ths_combine00>;
trips{
cpu_trip0:t0{
temperature = <70>;
type = "passive";
hysteresis = <0>;
};
cpu_trip1:t1{
temperature = <90>;
type = "passive";
hysteresis = <0>;
};
cpu_trip2:t2{
temperature = <100>;
type = "passive";
hysteresis = <0>;
};
cpu_trip3:t3{
temperature = <105>;
type = "passive";
hysteresis = <0>;
};
cpu_trip4:t4{
temperature = <110>;
type = "passive";
hysteresis = <0>;
};
crt_trip0:t5{
temperature = <115>;
type = "critical";
hysteresis = <0>;
};
};
cooling-maps{
bind0{
contribution = <0>;
trip = <&cpu_trip0>;
cooling-device = <&cpu_budget_cooling11>;
};
bind1{
contribution = <0>;
trip = <&cpu_trip1>;
cooling-device = <&cpu_budget_cooling22>;
};
bind2{
contribution = <0>;
trip = <&cpu_trip2>;
cooling-device = <&cpu_budget_cooling33>;
};
bind3{
contribution = <0>;
trip = <&cpu_trip3>;
cooling-device = <&cpu_budget_cooling45>;
};
bind4{
contribution = <0>;
trip = <&cpu_trip4>;
cooling-device = <&cpu_budget_cooling66>;
};
};
};
内核使用thermal_zone_device 抽象获取温度的device.
struct thermal_zone_device {
intid;
char type[THERMAL_NAME_LENGTH];
struct device device;
struct thermal_attr *trip_temp_attrs;
struct thermal_attr *trip_type_attrs;
struct thermal_attr *trip_hyst_attrs;
void *devdata;
int trips;
int passive_delay;
int polling_delay;
int temperature;
int last_temperature;
int emul_temperature;
int passive;
unsignedint forced_passive;
struct thermal_zone_device_ops *ops;
conststruct thermal_zone_params *tzp;
struct thermal_governor *governor;
struct list_head thermal_instances;
struct idr idr;
struct mutex lock; /* protect thermal_instances list */struct list_head node;
struct delayed_work poll_queue;
}
struct thermal_zone_device_ops {
int (*bind) (struct thermal_zone_device *,
struct thermal_cooling_device *);
int (*unbind) (struct thermal_zone_device *,
struct thermal_cooling_device *);
int (*get_temp) (struct thermal_zone_device *, int *);
int (*get_mode) (struct thermal_zone_device *,
enum thermal_device_mode *);
int (*set_mode) (struct thermal_zone_device *,
enum thermal_device_mode);
int (*get_trip_type) (struct thermal_zone_device *, int,
enum thermal_trip_type *);
int (*get_trip_temp) (struct thermal_zone_device *, int,
int *);
int (*set_trip_temp) (struct thermal_zone_device *, int,
int);
int (*get_trip_hyst) (struct thermal_zone_device *, int,
int *);
int (*set_trip_hyst) (struct thermal_zone_device *, int,
int);
int (*get_crit_temp) (struct thermal_zone_device *, int *);
int (*set_emul_temp) (struct thermal_zone_device *, int);
int (*get_trend) (struct thermal_zone_device *, int,
enum thermal_trend *);
int (*notify) (struct thermal_zone_device *, int,
enum thermal_trip_type);
}
thermal governal
降温策略一个抽象,与cpufreq的governal概念类似。
内核已经实现了一些策略,step_wise, user_space, power_allocator, bang_bang 。我们常用step_wise。
/**
* struct thermal_governor - structure that holds thermal governor information
* @name: name of the governor
* @throttle: callback called for every trip point even if temperature is
* below the trip point temperature
* @governor_list: node in thermal_governor_list (in thermal_core.c)
*/
struct thermal_governor {
char name[THERMAL_NAME_LENGTH];
/* 策略函数 */int (*throttle)(struct thermal_zone_device *tz, int trip);
struct list_head governor_list;
};