根据TMU,将CPU的温升分为四种情况来处理,分别是下述情况:
THERMAL_TRIP_HOT
THERMAL_TRIP_ACTIVE
THERMAL_TRIP_PASSIVE
THERMAL_TRIP_CRITICAL
THERMAL_TRIP_HOT只是简单的调用该平台实现的notify函数即可。
THERMAL_TRIP_ACTIVE是主动降频,
THERMAL_TRIP_PASSIVE是被动降频。
主动降频和被动降频都是降低CPU主频来达到减少CPU发热的目的,但是两者还是有区别的,假如当前设定的CP最高主频是1.6G,主动降频就是调节CPU的频率低于1.6G,不限制CPU最高频率,被动降频就会把1.6G的上限向下设,比如1.2G,这样不论负载如何CPU的主频就不会超过1.2G。
THERMAL_TRIP_CRITICAL是要关闭系统,温度太高了,通常物理临界CPU的结温是120°C,三星的5410的最高结温是119°C。
drivers/thermal/thermal_sys.c
case THERMAL_TRIP_CRITICAL:
if (temp >= trip_temp) {
pr_info("[TMU] CRITICAL: Need tripping\n");
if (tz->ops->notify)
ret = tz->ops->notify(tz, count,
trip_type);
if (ret) {
pr_emerg("Critical temperature reached (%ld C), shutting down\n",
temp/1000);
orderly_poweroff(true);
}
}
break;
即调用orderly_poweroff来关闭系统电源。
1. 工作温度
Ta 最高85度,只是表明在散热条件很好的情况下允许的环境温度,并不能表现为 CPU 在额定最高频率下的允许工作温度。
所以 5410 的 TMU 管理分为两步:
- 在温度上升到trip门限的时候,通过限制DVFS最高level限制频率上升的方法来限制 CPU 性能
- 如果降频调节温度的方法失败, CPU 温度持续上升,在上升到critical温度门限的时候,强制CPU关机。
在手机设计中通常的设计是将热量通过金属中框和LCD传导出去,其他的对体积没有要求的行业类应用中大部分是使用外加散热片的方法。
因为热阻的原因,可能环境温度60度时导流散热效果已经很弱。建议在加强散热导流的同时,引入主动散热机制。也就是加入散热风扇强制散热。
2. Power off
machine power off 过程最终会调用板子的 pm_power_off。在 TF4 环境中,调用的是 tf4_power_off (./arch/arm/mach-exynos/mach-tf4.c)。
tf4_power_off 的实现方法是通过释放 PS_HOLD 来通知 PMIC 掉电。在machine_init函数里会将pm_power_off指向该函数pm_power_off = tf4_power_off;
char poweroff_cmd[POWEROFF_CMD_PATH_LEN] = "/sbin/poweroff";
/**
* orderly_poweroff - Trigger an orderly system poweroff
* @force: force poweroff if command execution fails
*
* This may be called from any context to trigger a system shutdown.
* If the orderly shutdown fails, it will force an immediate shutdown.
*/
int orderly_poweroff(bool force)
{
int argc;
char **argv = argv_split(GFP_ATOMIC, poweroff_cmd, &argc);
static char *envp[] = {
"HOME=/",
"PATH=/sbin:/bin:/usr/sbin:/usr/bin",
NULL
};
int ret = -ENOMEM;
struct subprocess_info *info;
if (argv == NULL) {
printk(KERN_WARNING "%s failed to allocate memory for \"%s\"\n",
__func__, poweroff_cmd);
goto out;
}
info = call_usermodehelper_setup(argv[0], argv, envp, GFP_ATOMIC);
if (info == NULL) {
argv_free(argv);
goto out;
}
call_usermodehelper_setfns(info, NULL, argv_cleanup, NULL);
ret = call_usermodehelper_exec(info, UMH_NO_WAIT);
out:
if (ret && force) {
printk(KERN_WARNING "Failed to start orderly shutdown: "
"forcing the issue\n");
/* I guess this should try to kick off some daemon to
sync and poweroff asap. Or not even bother syncing
if we're doing an emergency shutdown? */
emergency_sync();
kernel_power_off();
}
return ret;
}
EXPORT_SYMBOL_GPL(orderly_poweroff);
char poweroff_cmd[POWEROFF_CMD_PATH_LEN] = "/sbin/poweroff";
执行这个poweroff命令就可以使系统整机掉电。