* [PATCH v10 1/3] dt-bindings: thermal: imx: Document calibration offset property
2026-07-20 2:19 [PATCH v10 0/3] thermal: imx: Add calibration offset support Haoning CHENG via B4 Relay
@ 2026-07-20 2:19 ` Haoning CHENG via B4 Relay
2026-07-20 2:19 ` [PATCH v10 2/3] thermal/drivers/imx: Fix rounding and clamp for i.MX7D alarm Haoning CHENG via B4 Relay
2026-07-20 2:19 ` [PATCH v10 3/3] thermal/drivers/imx: Add calibration offset support Haoning CHENG via B4 Relay
2 siblings, 0 replies; 5+ messages in thread
From: Haoning CHENG via B4 Relay @ 2026-07-20 2:19 UTC (permalink / raw)
To: Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: linux-pm, devicetree, imx, linux-arm-kernel, linux-kernel,
Haoning CHENG, Krzysztof Kozlowski
From: Haoning CHENG <Haoning.CHENG@cn.bosch.com>
The TEMPMON sensor reading may deviate from the theoretical SoC
junction temperature. Document the optional
fsl,temp-calibration-offset-millicelsius property, a signed offset
in millicelsius applied to correct the sensor reading toward the
theoretical junction temperature.
The offset is determined through thermal characterization by
comparing the sensor output against the calculated junction
temperature. When absent, the offset is zero.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
Signed-off-by: Haoning CHENG <Haoning.CHENG@cn.bosch.com>
---
Documentation/devicetree/bindings/thermal/imx-thermal.yaml | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/Documentation/devicetree/bindings/thermal/imx-thermal.yaml b/Documentation/devicetree/bindings/thermal/imx-thermal.yaml
index 949b154856c5..503a6e7a2c68 100644
--- a/Documentation/devicetree/bindings/thermal/imx-thermal.yaml
+++ b/Documentation/devicetree/bindings/thermal/imx-thermal.yaml
@@ -59,6 +59,17 @@ properties:
clocks:
maxItems: 1
+ fsl,temp-calibration-offset-millicelsius:
+ minimum: -20000
+ maximum: 20000
+ description:
+ A signed offset, in millicelsius, applied to the TEMPMON
+ sensor reading to correct it toward the theoretical SoC
+ junction temperature. The offset is determined through
+ thermal characterization by comparing the sensor output
+ against the calculated junction temperature. The range is
+ limited to ±20 °C. When absent, no offset is applied.
+
"#thermal-sensor-cells":
const: 0
@@ -109,6 +120,7 @@ examples:
nvmem-cells = <&tempmon_calib>, <&tempmon_temp_grade>;
nvmem-cell-names = "calib", "temp_grade";
clocks = <&clks IMX6SX_CLK_PLL3_USB_OTG>;
+ fsl,temp-calibration-offset-millicelsius = <(-6400)>;
#thermal-sensor-cells = <0>;
};
};
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v10 2/3] thermal/drivers/imx: Fix rounding and clamp for i.MX7D alarm
2026-07-20 2:19 [PATCH v10 0/3] thermal: imx: Add calibration offset support Haoning CHENG via B4 Relay
2026-07-20 2:19 ` [PATCH v10 1/3] dt-bindings: thermal: imx: Document calibration offset property Haoning CHENG via B4 Relay
@ 2026-07-20 2:19 ` Haoning CHENG via B4 Relay
2026-07-20 2:19 ` [PATCH v10 3/3] thermal/drivers/imx: Add calibration offset support Haoning CHENG via B4 Relay
2 siblings, 0 replies; 5+ messages in thread
From: Haoning CHENG via B4 Relay @ 2026-07-20 2:19 UTC (permalink / raw)
To: Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: linux-pm, devicetree, imx, linux-arm-kernel, linux-kernel,
Haoning CHENG, Frank Li
From: Haoning CHENG <Haoning.CHENG@cn.bosch.com>
Convert the alarm temperature from millicelsius to degrees for i.MX7D
using ceiling division instead of integer division, ensuring rounding
errors do not cause the alarm to trigger below the intended threshold.
Use DIV_ROUND_UP() for non-negative values and plain integer division
for negative values, since C rounds toward zero which is equivalent to
ceiling when the divisor is positive.
Add clamp() to ensure the hardware register value stays within the 9-bit
range (0..0x1ff) of the i.MX7D alarm field, preventing silent truncation
if an out-of-range value is written.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
Signed-off-by: Haoning Cheng <Haoning.CHENG@cn.bosch.com>
---
drivers/thermal/imx_thermal.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 38c993d1bcb3..7f7d1116b9d6 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -240,10 +240,16 @@ static void imx_set_alarm_temp(struct imx_thermal_data *data,
data->alarm_temp = alarm_temp;
- if (data->socdata->version == TEMPMON_IMX7D)
- alarm_value = alarm_temp / 1000 + data->c1 - 25;
- else
+ if (data->socdata->version == TEMPMON_IMX7D) {
+ if (alarm_temp >= 0)
+ alarm_temp = DIV_ROUND_UP(alarm_temp, 1000);
+ else
+ alarm_temp /= 1000;
+ alarm_value = alarm_temp + data->c1 - 25;
+ alarm_value = clamp(alarm_value, 0, 0x1ff);
+ } else {
alarm_value = (data->c2 - alarm_temp) / data->c1;
+ }
regmap_write(map, soc_data->high_alarm_ctrl + REG_CLR,
soc_data->high_alarm_mask);
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v10 3/3] thermal/drivers/imx: Add calibration offset support
2026-07-20 2:19 [PATCH v10 0/3] thermal: imx: Add calibration offset support Haoning CHENG via B4 Relay
2026-07-20 2:19 ` [PATCH v10 1/3] dt-bindings: thermal: imx: Document calibration offset property Haoning CHENG via B4 Relay
2026-07-20 2:19 ` [PATCH v10 2/3] thermal/drivers/imx: Fix rounding and clamp for i.MX7D alarm Haoning CHENG via B4 Relay
@ 2026-07-20 2:19 ` Haoning CHENG via B4 Relay
2026-07-20 2:30 ` sashiko-bot
2 siblings, 1 reply; 5+ messages in thread
From: Haoning CHENG via B4 Relay @ 2026-07-20 2:19 UTC (permalink / raw)
To: Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: linux-pm, devicetree, imx, linux-arm-kernel, linux-kernel,
Haoning CHENG, Frank Li
From: Haoning CHENG <Haoning.CHENG@cn.bosch.com>
The TEMPMON sensor reading may deviate from the theoretical SoC
junction temperature. Hardware characterization shows a measurable
offset between the sensor output and the calculated junction
temperature, which exists even at the die level without board
influence.
Read the optional fsl,temp-calibration-offset-millicelsius property
from DT and apply it uniformly to the i.MX6/6SX/7D formulas.
The offset is applied symmetrically at two points to keep trip point
semantics consistent:
1. In imx_set_alarm_temp() and imx_set_panic_temp(): the temperature
threshold is *subtracted* by the offset before being converted to a
hardware register value. This keeps the hardware IRQ trigger aligned
with the physical sensor reading that corresponds to the intended
temperature threshold.
2. In imx_get_temp(): after computing the temperature from the hardware
register, the offset is *added* to produce the calibrated value.
The thermal framework always sees the corrected temperature.
For example, if DT sets offset = +3000 m°C and the passive trip is 95°C:
imx_set_alarm_temp(95000):
alarm_temp = 95000 - 3000 = 92000
→ hardware register programmed for 92°C sensor reading
Hardware IRQ fires when sensor reads 92°C
imx_get_temp():
reads hardware, computes 92°C
*temp = 92000 + 3000 = 95000
→ thermal framework sees 95°C → correct trip
When the property is not present, the offset defaults to 0, preserving
the current behavior.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
Signed-off-by: Haoning Cheng <Haoning.CHENG@cn.bosch.com>
---
drivers/thermal/imx_thermal.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index 7f7d1116b9d6..d471acc16bce 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -85,6 +85,10 @@ enum imx_thermal_trip {
#define TEMPMON_IMX6SX 2
#define TEMPMON_IMX7D 3
+/* Calibration offset limits (±20 °C in millicelsius) */
+#define IMX_TEMP_CALIB_OFFSET_MIN (-20000)
+#define IMX_TEMP_CALIB_OFFSET_MAX 20000
+
struct thermal_soc_data {
u32 version;
@@ -207,6 +211,7 @@ struct imx_thermal_data {
struct regmap *tempmon;
u32 c1, c2; /* See formula in imx_init_calib() */
int temp_max;
+ s32 calibration_offset;
int alarm_temp;
int last_temp;
bool irq_enabled;
@@ -223,6 +228,7 @@ static void imx_set_panic_temp(struct imx_thermal_data *data,
struct regmap *map = data->tempmon;
int critical_value;
+ panic_temp -= data->calibration_offset;
critical_value = (data->c2 - panic_temp) / data->c1;
regmap_write(map, soc_data->panic_alarm_ctrl + REG_CLR,
@@ -239,6 +245,7 @@ static void imx_set_alarm_temp(struct imx_thermal_data *data,
int alarm_value;
data->alarm_temp = alarm_temp;
+ alarm_temp -= data->calibration_offset;
if (data->socdata->version == TEMPMON_IMX7D) {
if (alarm_temp >= 0)
@@ -283,6 +290,7 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp)
*temp = (n_meas - data->c1 + 25) * 1000;
else
*temp = data->c2 - n_meas * data->c1;
+ *temp += data->calibration_offset;
/* Update alarm value to next higher trip point for TEMPMON_IMX6Q */
if (data->socdata->version == TEMPMON_IMX6Q) {
@@ -635,6 +643,25 @@ static int imx_thermal_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, data);
+ if (of_property_present(dev->of_node,
+ "fsl,temp-calibration-offset-millicelsius")) {
+ ret = of_property_read_s32(dev->of_node,
+ "fsl,temp-calibration-offset-millicelsius",
+ &data->calibration_offset);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "failed to read calibration offset\n");
+
+ if (data->calibration_offset < IMX_TEMP_CALIB_OFFSET_MIN ||
+ data->calibration_offset > IMX_TEMP_CALIB_OFFSET_MAX)
+ return dev_err_probe(dev, -EINVAL,
+ "calibration offset %d millicelsius out of range\n",
+ data->calibration_offset);
+
+ dev_dbg(dev, "calibration offset: %d millicelsius\n",
+ data->calibration_offset);
+ }
+
if (of_property_present(dev->of_node, "nvmem-cells")) {
ret = imx_init_from_nvmem_cells(pdev);
if (ret)
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v10 3/3] thermal/drivers/imx: Add calibration offset support
2026-07-20 2:19 ` [PATCH v10 3/3] thermal/drivers/imx: Add calibration offset support Haoning CHENG via B4 Relay
@ 2026-07-20 2:30 ` sashiko-bot
0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-07-20 2:30 UTC (permalink / raw)
To: Haoning CHENG; +Cc: imx, devicetree, conor+dt, robh, Frank.Li
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [Critical] Alarm IRQ can fire after thermal zone is unregistered, causing a Use-After-Free.
--
--- Patch [3]: [PATCH v10 3/3] thermal/drivers/imx: Add calibration offset support ---
commit bb0e3bef4010d2e2be1d5402d29e194aaf49548f
Author: Haoning CHENG <Haoning.CHENG@cn.bosch.com>
thermal/drivers/imx: Add calibration offset support
The TEMPMON sensor reading may deviate from the theoretical SoC junction
temperature. This commit adds support for an optional DT property to apply a
calibration offset to the temperature readings. The offset is used when setting
alarm/panic thresholds and reading the current temperature.
> diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
> index 168069a16e930..87ae2e40cc6fe 100644
> --- a/drivers/thermal/imx_thermal.c
> +++ b/drivers/thermal/imx_thermal.c
[ ... ]
> @@ -635,6 +643,25 @@ static int imx_thermal_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, data);
>
> + if (of_property_present(dev->of_node,
> + "fsl,temp-calibration-offset-millicelsius")) {
> + ret = of_property_read_s32(dev->of_node,
> + "fsl,temp-calibration-offset-millicelsius",
> + &data->calibration_offset);
> + if (ret)
> + return dev_err_probe(dev, ret,
> + "failed to read calibration offset\n");
> +
> + if (data->calibration_offset < IMX_TEMP_CALIB_OFFSET_MIN ||
> + data->calibration_offset > IMX_TEMP_CALIB_OFFSET_MAX)
> + return dev_err_probe(dev, -EINVAL,
> + "calibration offset %d millicelsius out of range\n",
> + data->calibration_offset);
> +
> + dev_dbg(dev, "calibration offset: %d millicelsius\n",
> + data->calibration_offset);
> + }
> +
> if (of_property_present(dev->of_node, "nvmem-cells")) {
> ret = imx_init_from_nvmem_cells(pdev);
> if (ret)
[Severity: Critical]
This isn't a bug introduced by this patch, but while reviewing the probe
routine, I noticed a use-after-free issue related to how the alarm IRQ is
managed.
Can an interrupt fire after the thermal zone has been unregistered?
The alarm IRQ is requested with devres in probe:
drivers/thermal/imx_thermal.c:imx_thermal_probe() {
...
ret = devm_request_threaded_irq(dev, data->irq,
imx_thermal_alarm_irq, imx_thermal_alarm_irq_thread,
0, "imx_thermal", data);
...
}
Because it is a devm-managed resource, it is not freed until after
imx_thermal_remove() completes. However, the remove path manually unregisters
and frees the thermal zone:
drivers/thermal/imx_thermal.c:imx_thermal_remove() {
...
thermal_zone_device_unregister(data->tz);
...
}
If an administrative module unload or device unbind is triggered while the
SoC is hot, could an interrupt fire during or immediately after the unregister
call? If so, would the still-active IRQ thread dereference the freed data->tz
pointer?
drivers/thermal/imx_thermal.c:imx_thermal_alarm_irq_thread() {
...
thermal_zone_device_update(data->tz, THERMAL_EVENT_UNSPECIFIED);
...
}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260720-b4-symana21-11221-imx-thermal-support-upstream-6-18-v10-0-f8c3dcd9a57e@cn.bosch.com?part=3
^ permalink raw reply [flat|nested] 5+ messages in thread