thermal 代码分析
生活随笔
收集整理的這篇文章主要介紹了
thermal 代码分析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
thermal 代碼分析
基礎知識
1.thermal 的框架
使用場景:
當cpu 溫度過高時,適當的進行降頻,從而控制穩定cpu 溫度。
代碼分析:
從Makefile 開始
# SPDX-License-Identifier: GPL-2.0 # # Makefile for sensor chip drivers. #obj-$(CONFIG_THERMAL) += thermal_sys.o thermal_sys-y += thermal_core.o thermal_sysfs.o \thermal_helpers.o # 核心代碼# interface to/from other layers providing sensors thermal_sys-$(CONFIG_THERMAL_HWMON) += thermal_hwmon.o thermal_sys-$(CONFIG_THERMAL_OF) += of-thermal.o # dts 解析# governors thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE) += fair_share.o # governors 也是五種 thermal_sys-$(CONFIG_THERMAL_GOV_BANG_BANG) += gov_bang_bang.o thermal_sys-$(CONFIG_THERMAL_GOV_STEP_WISE) += step_wise.o thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += user_space.o thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR) += power_allocator.o# cpufreq cooling thermal_sys-$(CONFIG_CPU_THERMAL) += cpu_cooling.o # cooling device# clock cooling thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o # devfreq cooling thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o# platform thermal drivers obj-$(CONFIG_SUN8I_THS) += sun8i_ths.o # 平臺相關代碼,提供讀取溫度的接口1.thermal 的初始化
static int __init thermal_init(void) {int result;mutex_init(&poweroff_lock);result = thermal_register_governors(); // 1.注冊五種governorsresult = class_register(&thermal_class); // 2.注冊 /sys/class/thermal result = of_parse_thermal_zones(); // 3.解析dts 的"thermal-zones"節點,并注冊// thermal_zone_deviceresult = register_pm_notifier(&thermal_pm_nb); // 4.notifier} fs_initcall(thermal_init);其中最重要的是 of_parse_thermal_zones
先看看 相關dts:
thermal-zones {cpu_thermal: cpu_thermal {polling-delay-passive = <330>;polling-delay = <1000>;thermal-sensors = <&ths 0>;trips {cpu_warm: cpu_warm {temperature = <65000>;hysteresis = <2000>;type = "passive";};cpu_hot: cpu_hot {temperature = <75000>;hysteresis = <2000>;type = "passive";};cpu_very_hot: cpu_very_hot {temperature = <90000>;hysteresis = <2000>;type = "passive";};cpu_crit: cpu_crit {temperature = <105000>;hysteresis = <2000>;type = "critical";};};cooling-maps {cpu_warm_limit_cpu {trip = <&cpu_warm>;cooling-device = <&cpu0 THERMAL_NO_LIMIT 1>;};cpu_hot_limit_cpu {trip = <&cpu_hot>;cooling-device = <&cpu0 2 3>;};cpu_very_hot_limit_cpu {trip = <&cpu_very_hot>;cooling-device = <&cpu0 5 THERMAL_NO_LIMIT>;};};};}; int __init of_parse_thermal_zones(void) { np = of_find_node_by_name(NULL, "thermal-zones"); // 查找 "thermal-zones" for_each_available_child_of_node(np, child) { // 遍歷子節點tz = thermal_of_build_thermal_zone(child); // 解析關鍵詞,填充tz 數據結構ops = kmemdup(&of_thermal_ops, sizeof(*ops), GFP_KERNEL);if (!ops)goto exit_free;tzp = kzalloc(sizeof(*tzp), GFP_KERNEL); zone = thermal_zone_device_register(child->name, tz->ntrips,mask, tz,ops, tzp,tz->passive_delay,tz->polling_delay); // 注冊一個 thermal_zone_device} } struct thermal_zone_device * thermal_zone_device_register(const char *type, int trips, int mask,void *devdata, struct thermal_zone_device_ops *ops,struct thermal_zone_params *tzp, int passive_delay,int polling_delay) { dev_set_name(&tz->device, "thermal_zone%d", tz->id);result = device_register(&tz->device); // 注冊設備result = thermal_set_governor(tz, governor); // set governorlist_add_tail(&tz->node, &thermal_tz_list); /* Bind cooling devices for this zone */bind_tz(tz); // 將thermal_cdev_list 中的所有cooling devices 與之綁定INIT_DELAYED_WORK(&tz->poll_queue, thermal_zone_device_check); // 初始化工作隊列if (atomic_cmpxchg(&tz->need_update, 1, 0))thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); }cpufreq cooling device 的注冊,位于 cpufreq_driver -> reay 階段,
static void cpufreq_ready(struct cpufreq_policy *policy) { if (of_find_property(np, "#cooling-cells", NULL)) { // 包含#cooling-cells 屬性的priv->cdev = of_cpufreq_power_cooling_register(np,policy, power_coefficient, NULL); // register} } else {cooling_ops = &cpufreq_cooling_ops; }cdev = thermal_of_cooling_device_register(np, dev_name, cpufreq_cdev,cooling_ops); list_add(&cdev->node, &thermal_cdev_list); // 就是添加到 thermal_cdev_list 中需要關心的是 cpufreq_cooling_ops
static struct thermal_cooling_device_ops cpufreq_cooling_ops = {.get_max_state = cpufreq_get_max_state,.get_cur_state = cpufreq_get_cur_state,.set_cur_state = cpufreq_set_cur_state, };.set_cur_state 被 thermal governor 調用
static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev,unsigned long state) {clip_freq = cpufreq_cdev->freq_table[state].frequency; //根據state 設置新的頻率cpufreq_cdev->cpufreq_state = state;cpufreq_cdev->clipped_freq = clip_freq; // cpufreq_update_policy(cpufreq_cdev->policy->cpu);return 0; }時序圖:
總結
以上是生活随笔為你收集整理的thermal 代码分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TrustedInstaller
- 下一篇: java选择,智力,数量,推理