- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Our hardware team asked that I reduce the trip points for the thermal monitoring on our imx8mq board based on the EVK design. I've updated the trip points with the following in an attempt to set the requested temperatures:
&cpu_thermal {
trips {
cpu_alert: cpu-alert {
temperature = <75000>;
hysteresis = <2000>;
type = "passive";
};
cpu-crit {
temperature = <85000>;
hysteresis = <2000>;
type = "critical";
};
};
However, the board still shows 9500 for alert, and 105000 for critical in /sys/class/thermal/thermal_zone0/trip_point_*.
What's odd is that the devicetree node under /sys/firmware (or /proc/device-tree) also has 95000/105000. (Seen in /sys/firmware/devicetree/base/thermal-zones/cpu-thermal/trips/cpu-*/temperature)
# xxd /sys/firmware/devicetree/base/thermal-zones/cpu-thermal/trips/cpu-alert/temperature
00000000: 0001 7318
But when I decompile the devicetree, it has the values I set in the devicetree source.
dtc -I dtb -O dts imx8mq-custom.dtb -o test.dts
cpu-alert {
temperature = <0xfde8>;
hysteresis = <0x7d0>;
type = "passive";
phandle = <0x0a>;
};
cpu-crit {
temperature = <0x14c08>;
For some reason, the kernel is ignoring my devicetree. This is further evident by the fact that it doesn't even report the values from imx8mq.dtsi - 80000/90000.
I've tried adding logging to qoriq_thermal.c and thermal_of.c to try to figure out where this is coming from, but all logs report 95000/105000.
I'm using the 6.6 kernel from the scarthgap BSP. I also changed the u-boot device tree and verified that u-boot does see those changes.
What is the correct process for modifying the thermal trip points?
This is similar to the issue below, but there wasn't a solution to draw from:
Solved! Go to Solution.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I find that the possible answer is in uboot: arch/arm/mach-imx/imx8m/soc.c
static int fixup_thermal_trips(void *blob, const char *name)
{
int minc, maxc;
int node, trip;
node = fdt_path_offset(blob, "/thermal-zones");
if (node < 0)
return node;
node = fdt_subnode_offset(blob, node, name);
if (node < 0)
return node;
node = fdt_subnode_offset(blob, node, "trips");
if (node < 0)
return node;
get_cpu_temp_grade(&minc, &maxc);
fdt_for_each_subnode(trip, blob, node) {
const char *type;
int temp, ret;
type = fdt_getprop(blob, trip, "type", NULL);
if (!type)
continue;
temp = 0;
if (!strcmp(type, "critical"))
temp = 1000 * maxc;
else if (!strcmp(type, "passive"))
temp = 1000 * (maxc - 10);
if (temp) {
ret = fdt_setprop_u32(blob, trip, "temperature", temp);
if (ret)
return ret;
}
}
return 0;
}
Best Regards,
Zhiming

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
Did you try to add logs in tmu_set_trip_temp?
Please try to add dump_stack() in tmu_set_trip_temp
Best Regards,
Zhiming
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Zhiming,
Yea, I started there first actually. It looks like that function only gets called when I set the trip point from userspace.
# echo 75000 >/sys/class/thermal/thermal_zone0/trip_point_0_temp
[ 80.216814] qoriq set trip: 0 75000
From there, I added lines to qoriq_tmu_register_tmu_zone().
I then went into the dt parsing in thermal_of.c. The part I'm most confused by is that when the dt properties are read in thermal_of_populate_trip(), it logs as 95000/105000 even though the imx8mq.dtsi entries are set for 80000/90000.
Another odd thing is that changes to hysteresis and other properties are seen by the kernel. The temperature property is the only one that doesn't follow the dt.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I find that the possible answer is in uboot: arch/arm/mach-imx/imx8m/soc.c
static int fixup_thermal_trips(void *blob, const char *name)
{
int minc, maxc;
int node, trip;
node = fdt_path_offset(blob, "/thermal-zones");
if (node < 0)
return node;
node = fdt_subnode_offset(blob, node, name);
if (node < 0)
return node;
node = fdt_subnode_offset(blob, node, "trips");
if (node < 0)
return node;
get_cpu_temp_grade(&minc, &maxc);
fdt_for_each_subnode(trip, blob, node) {
const char *type;
int temp, ret;
type = fdt_getprop(blob, trip, "type", NULL);
if (!type)
continue;
temp = 0;
if (!strcmp(type, "critical"))
temp = 1000 * maxc;
else if (!strcmp(type, "passive"))
temp = 1000 * (maxc - 10);
if (temp) {
ret = fdt_setprop_u32(blob, trip, "temperature", temp);
if (ret)
return ret;
}
}
return 0;
}
Best Regards,
Zhiming
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Zhiming,
That was it. Thank you very much.
A quick test letting the preexisting dt values remain gives me the correct trips in /sys:
temp = fdt_getprop_u32_default_node(blob, trip, 0, "temperature", 0);
if (!strcmp(type, "critical") && (!temp || temp > (maxc * 1000)))
temp = 1000 * maxc;
else if (!strcmp(type, "passive") && (!temp || temp > ((maxc - 10) * 1000)))
temp = 1000 * (maxc - 10);
# cat /sys/class/thermal/thermal_zone0/trip_point_*temp
75000
85000
