当cpu温度传感器大于指定温度时,会出现一直在检测温度的情况
有需要时可以修改此温度。
涉及到的修改包括u-boot和内核
drivers/thermal/nxp_tmu.c
int nxp_tmu_get_temp(struct udevice *dev, int *temp) { struct nxp_tmu_plat *pdata = dev_get_platdata(dev); int cpu_tmp = 0; int ret; ret = read_temperature(dev, &cpu_tmp); if (ret) { printf("invalid data\n"); return ret; } //判断读取到的温度是否超过限制 while (cpu_tmp >= pdata->alert) { printf("CPU Temperature (%dC) has beyond alert (%dC), close to critical (%dC)", cpu_tmp, pdata->alert, pdata->critical); puts(" waiting...\n"); mdelay(pdata->polling_delay); ret = read_temperature(dev, &cpu_tmp); if (ret) { printf("invalid data\n"); return ret; } } *temp = cpu_tmp / 1000; return 0; }
pdata->alert的设置在下面这个函数中,主要功能是解析设备树参数
static int nxp_tmu_ofdata_to_platdata(struct udevice *dev) { int ret; int trips_np; struct nxp_tmu_plat *pdata = dev_get_platdata(dev); struct fdtdec_phandle_args args; debug("%s dev name %s\n", __func__, dev->name); if (pdata->zone_node) { pdata->regs = (union tmu_regs *)fdtdec_get_addr(gd->fdt_blob, dev_of_offset(dev), "reg"); if ((fdt_addr_t)pdata->regs == FDT_ADDR_T_NONE) return -EINVAL; return 0; } else { struct nxp_tmu_plat *p_parent_data = dev_get_platdata(dev->parent); if (p_parent_data->zone_node) pdata->regs = p_parent_data->regs; } ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev), "thermal-sensors", "#thermal-sensor-cells", 0, 0, &args); if (ret) return ret; if (args.node != dev_of_offset(dev->parent)) return -EFAULT; if (args.args_count >= 1) pdata->id = args.args[0]; else pdata->id = 0; debug("args.args_count %d, id %d\n", args.args_count, pdata->id); pdata->polling_delay = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "polling-delay", 1000); trips_np = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(dev), "trips"); fdt_for_each_subnode(trips_np, gd->fdt_blob, trips_np) { const char *type; type = fdt_getprop(gd->fdt_blob, trips_np, "type", NULL); if (type) { if (strcmp(type, "critical") == 0) pdata->critical = fdtdec_get_int(gd->fdt_blob, trips_np, "temperature", 85); //读取设备树中的温度临界值 如果读取不到设置默认值85 else if (strcmp(type, "passive") == 0) pdata->alert = fdtdec_get_int(gd->fdt_blob, trips_np, "temperature", 80);//读取设备树中的温度报警值 如果读取不到设置默认值80 } } debug("id %d polling_delay %d, critical %d, alert %d\n", pdata->id, pdata->polling_delay, pdata->critical, pdata->alert); return 0; }
对应的设备树 arch/arm/dts/fsl-imx8mq.dtsi的thermal-zones节点
thermal-zones { /* cpu thermal */ cpu-thermal { polling-delay-passive = <250>; polling-delay = <2000>; thermal-sensors = <&tmu>; trips { cpu_alert0: trip0 { temperature = <85000>; //此处是passive温度 hysteresis = <2000>; type = "passive"; }; cpu_crit0: trip1 { temperature = <95000>;//此处是critical温度 hysteresis = <2000>; type = "critical"; }; }; cooling-maps { map0 { trip = <&cpu_alert0>; cooling-device = <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; }; }; }; };实际调用过程
board_init_f()//uboot板级初始化 initcall_run_list(init_sequence_f) //调用数组内的函数 print_cpuinfo() //调用各平台自定义的温度显示 针对imx8 调用的函数在arch/arm/mach-imx/imx8/cpu.c uclass_get_device_by_name(UCLASS_THERMAL, "cpu-thermal1", &thermal_dev);// 通过设备名从uclass中获取udevice thermal_get_temp(thermal_dev, &cpu_tmp); ops->get_temp(dev, temp) //会调用到.id= UCLASS_THERMAL 且of_match = fsl,imx8mq-tmu的 ubootdriver ... nxp_tmu_get_temp() //drivers/thermal/nxp_tmu.c 检测温度
arch/arm64/boot/dts/freescale/myb-fsl-imx8mq.dtsi
thermal-zones { /* cpu thermal */ cpu-thermal { polling-delay-passive = <250>; polling-delay = <2000>; thermal-sensors = <&tmu>; trips { cpu_alert0: trip0 { temperature = <85000>;//此处是passive温度 hysteresis = <2000>; type = "passive"; }; cpu_crit0: trip1 { temperature = <105000>;//此处是critical温度 hysteresis = <2000>; type = "critical"; }; }; cooling-maps { map0 { trip = <&cpu_alert0>; cooling-device = <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; }; }; }; };对应驱动drivers/thermal/qoriq_thermal.c