Devicetree
 help / color / mirror / Atom feed
* [PATCH 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor
@ 2026-07-22 20:33 Sören Hantel
  2026-07-22 20:33 ` [PATCH 1/3] dt-bindings: thermal: sun8i: Add binding for the A80 THS controller Sören Hantel
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Sören Hantel @ 2026-07-22 20:33 UTC (permalink / raw)
  To: linux-pm
  Cc: Vasily Khoruzhick, Yangtao Li, Rafael J . Wysocki, Daniel Lezcano,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Rossak, devicetree,
	linux-arm-kernel, linux-sunxi, linux-kernel, FuginInsanE

From: FuginInsanE <FuginInsanE@googlemail.com>

This series adds support for the thermal sensor of the Allwinner A80
(sun9i), the last SoC of the family with an in-tree DT but no THS
support.

The A80 THS is an early relative of the A83T/H3-era sensor generation:
same register semantics, but the block, bus gate, module clock and
reset line are shared with the GPADC, the THS registers start at
offset 0x40, and there are four sensors (big cluster, DRAM, GPU,
little cluster).

Philipp Rossak posted a driver for this hardware back in 2018 as part
of a larger THS rework which never landed for the A80; Armbian has
been carrying his DT patches ever since. This series takes the
mainline sun8i_thermal driver as the base instead: patch 2 adds a
chip description derived from the vendor BSP (register init values,
protection thresholds and the temperature formula), and patch 3
revives Philipp's DT patch with a fixed interrupt number (SPI 115 as
in the vendor BSP - verified on hardware, the original SPI 31 never
fires) and critical trip points.

Two A80 particularities are worth calling out: the data-ready
interrupt fires at the conversion rate on this SoC, so it stays
disabled and the sensors are polled, with the interrupt line serving
the alarm/shutdown events only (as in the vendor BSP). And the A80
SID is not yet supported by the sunxi nvmem driver, so calibration
data is unavailable for now and the driver falls back to defaults,
which produce plausible values on real hardware.

Tested on a Cubietech Cubieboard4: all four zones report
load-reactive temperatures (idle ~40 degC, ~54 degC under sustained
full load) tracking the BSP formula across the range we could
provoke.

Philipp Rossak (1):
  ARM: dts: sun9i-a80: Add thermal sensor and thermal zones

Sören Hantel (2):
  dt-bindings: thermal: sun8i: Add binding for the A80 THS controller
  thermal/drivers/sun8i: Add support for the A80 THS

 .../thermal/allwinner,sun8i-a83t-ths.yaml     |  1 +
 arch/arm/boot/dts/allwinner/sun9i-a80.dtsi    | 68 ++++++++++++++
 drivers/thermal/sun8i_thermal.c               | 93 ++++++++++++++++++-
 3 files changed, 161 insertions(+), 1 deletion(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/3] dt-bindings: thermal: sun8i: Add binding for the A80 THS controller
  2026-07-22 20:33 [PATCH 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Sören Hantel
@ 2026-07-22 20:33 ` Sören Hantel
  2026-07-22 20:33 ` [PATCH 2/3] thermal/drivers/sun8i: Add support for the A80 THS Sören Hantel
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 11+ messages in thread
From: Sören Hantel @ 2026-07-22 20:33 UTC (permalink / raw)
  To: linux-pm
  Cc: Vasily Khoruzhick, Yangtao Li, Rafael J . Wysocki, Daniel Lezcano,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Rossak, devicetree,
	linux-arm-kernel, linux-sunxi, linux-kernel, Sören Hantel,
	Claude Fable 5

The Allwinner A80 has a thermal sensor with four channels which shares
its MMIO block, bus gate, module clock and reset line with the GPADC.
Register-wise it is an early version of the THS found in the A83T and
later SoCs, with the THS registers starting at offset 0x40 of the
shared block.

Add the compatible to the sun8i THS binding. The A80 takes a bus and a
module clock plus a reset line, so the existing conditionals already
describe it correctly.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Sören Hantel <fugininsane@googlemail.com>
---
 .../devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml    | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml b/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
index 3e61689..718c44d 100644
--- a/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
+++ b/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
@@ -18,6 +18,7 @@ properties:
       - allwinner,sun8i-a83t-ths
       - allwinner,sun8i-h3-ths
       - allwinner,sun8i-r40-ths
+      - allwinner,sun9i-a80-ths
       - allwinner,sun20i-d1-ths
       - allwinner,sun50i-a64-ths
       - allwinner,sun50i-a100-ths
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/3] thermal/drivers/sun8i: Add support for the A80 THS
  2026-07-22 20:33 [PATCH 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Sören Hantel
  2026-07-22 20:33 ` [PATCH 1/3] dt-bindings: thermal: sun8i: Add binding for the A80 THS controller Sören Hantel
@ 2026-07-22 20:33 ` Sören Hantel
  2026-07-22 20:45   ` sashiko-bot
  2026-07-22 20:33 ` [PATCH 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones Sören Hantel
  2026-07-22 21:00 ` [PATCH v2 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Sören Hantel
  3 siblings, 1 reply; 11+ messages in thread
From: Sören Hantel @ 2026-07-22 20:33 UTC (permalink / raw)
  To: linux-pm
  Cc: Vasily Khoruzhick, Yangtao Li, Rafael J . Wysocki, Daniel Lezcano,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Rossak, devicetree,
	linux-arm-kernel, linux-sunxi, linux-kernel, Sören Hantel,
	Claude Fable 5

The Allwinner A80 thermal sensor is an early relative of the THS found
in the A83T and later SoCs. It shares its register block, bus gate,
4 MHz module clock and reset line with the GPADC; the THS registers
live at offset 0x40 of the shared block, with four data registers for
the four sensors (0: big cluster, 1: DRAM, 2: GPU, 3: little cluster).

Register layout, initialization values and the temperature formula
(T = 190 - raw * 1000 / 14543, i.e. offset 190000 / scale 688 in this
driver's convention) are taken from the vendor BSP kernel. The init
sequence also programs the hardware alarm (~90 degC) and emergency
shutdown (~105 degC) thresholds the BSP uses, since their reset
defaults are undefined.

Unlike on later SoCs the data-ready interrupt fires at the conversion
rate (tens of kHz), so it is left disabled and the thermal core polls
the sensors; the interrupt line only serves the alarm and shutdown
events, matching the vendor BSP behaviour.

The A80 SID is not yet supported by the sunxi nvmem driver, so
calibration data is currently unavailable and the driver falls back to
the defaults, which yield plausible results (idle temperatures around
40 degC, full-load peaks in the mid 50s on a Cubieboard4).

Tested on a Cubietech Cubieboard4: all four zones report load-reactive
temperatures via polling.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Sören Hantel <fugininsane@googlemail.com>
---
 drivers/thermal/sun8i_thermal.c | 93 ++++++++++++++++++++++++++++++++-
 1 file changed, 92 insertions(+), 1 deletion(-)

diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
index 2267479..3e7bfda 100644
--- a/drivers/thermal/sun8i_thermal.c
+++ b/drivers/thermal/sun8i_thermal.c
@@ -65,8 +65,27 @@ struct tsensor {
 	int				id;
 };
 
+/*
+ * The A80 thermal sensor shares its register block with the GPADC.
+ * The THS registers start at offset 0x40 within that block.
+ */
+#define SUN9I_THS_CTRL				0x40
+#define SUN9I_THS_IC				0x44
+#define SUN9I_THS_IS				0x48
+#define SUN9I_THS_ALARM_TH(x)			(0x50 + (x) * 0x4)
+#define SUN9I_THS_SHUT_TH(x)			(0x60 + (x) * 0x4)
+#define SUN9I_THS_MFC				0x70
+#define SUN9I_THS_TEMP_DATA			0x80
+#define SUN9I_THS_CTRL_ACQ(x)			((x) << 16)
+#define SUN9I_THS_CTRL_SENSOR_EN		GENMASK(3, 0)
+#define SUN9I_THS_ALARM_IRQ_EN			GENMASK(3, 0)
+#define SUN9I_THS_SHUT_IRQ_EN			GENMASK(7, 4)
+#define SUN9I_THS_ALARM_IRQ_STS(x)		BIT(x)
+#define SUN9I_THS_SHUT_IRQ_STS(x)		BIT(4 + (x))
+
 struct ths_thermal_chip {
 	bool            has_mod_clk;
+	unsigned long	mod_clk_rate;
 	bool            has_bus_clk_reset;
 	bool		needs_sram;
 	int		sensor_num;
@@ -413,7 +432,8 @@ static int sun8i_ths_resource_init(struct ths_device *tmdev)
 			return PTR_ERR(tmdev->mod_clk);
 	}
 
-	ret = clk_set_rate(tmdev->mod_clk, 24000000);
+	ret = clk_set_rate(tmdev->mod_clk, tmdev->chip->mod_clk_rate ?:
+			   24000000);
 	if (ret)
 		return ret;
 
@@ -596,6 +616,76 @@ static int sun8i_ths_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int sun9i_a80_thermal_init(struct ths_device *tmdev)
+{
+	int i;
+
+	/* clear any pending interrupt status */
+	regmap_write(tmdev->regmap, SUN9I_THS_IS, 0xfff);
+	/* set up the median filter, average over 8 samples */
+	regmap_write(tmdev->regmap, SUN9I_THS_MFC, 0x5);
+
+	/*
+	 * Program the protection thresholds with the values the vendor
+	 * BSP uses (thresholds are in raw sensor units, which decrease
+	 * with rising temperature): an alarm interrupt at ~90 degC and
+	 * an emergency hardware shutdown at ~105 degC.
+	 */
+	for (i = 0; i < tmdev->chip->sensor_num; i++) {
+		regmap_write(tmdev->regmap, SUN9I_THS_ALARM_TH(i),
+			     (1454 << 16) | 0xfff);
+		regmap_write(tmdev->regmap, SUN9I_THS_SHUT_TH(i),
+			     (1231 << 16) | 0xfff);
+	}
+
+	/*
+	 * Unlike on later SoCs, the data-ready interrupt fires at the
+	 * conversion rate (tens of kHz), so leave it disabled and let the
+	 * thermal core poll the data registers; the interrupt line only
+	 * serves the alarm and shutdown events, like in the vendor BSP.
+	 */
+	regmap_write(tmdev->regmap, SUN9I_THS_IC,
+		     SUN9I_THS_ALARM_IRQ_EN | SUN9I_THS_SHUT_IRQ_EN);
+	/* acquire time 0x2f, enable all four sensors */
+	regmap_write(tmdev->regmap, SUN9I_THS_CTRL,
+		     SUN9I_THS_CTRL_ACQ(0x2f) | SUN9I_THS_CTRL_SENSOR_EN);
+
+	return 0;
+}
+
+static unsigned long sun9i_a80_irq_ack(struct ths_device *tmdev)
+{
+	unsigned long irq_bitmap = 0;
+	int i, state;
+
+	regmap_read(tmdev->regmap, SUN9I_THS_IS, &state);
+
+	for (i = 0; i < MAX_SENSOR_NUM; i++) {
+		if (state & (SUN9I_THS_ALARM_IRQ_STS(i) |
+			     SUN9I_THS_SHUT_IRQ_STS(i))) {
+			regmap_write(tmdev->regmap, SUN9I_THS_IS,
+				     state & (SUN9I_THS_ALARM_IRQ_STS(i) |
+					      SUN9I_THS_SHUT_IRQ_STS(i)));
+			set_bit(i, &irq_bitmap);
+		}
+	}
+
+	return irq_bitmap;
+}
+
+static const struct ths_thermal_chip sun9i_a80_ths = {
+	.sensor_num = 4,
+	.has_mod_clk = true,
+	.mod_clk_rate = 4000000,
+	.has_bus_clk_reset = true,
+	.scale = 688,
+	.offset = 190000,
+	.temp_data_base = SUN9I_THS_TEMP_DATA,
+	.init = sun9i_a80_thermal_init,
+	.irq_ack = sun9i_a80_irq_ack,
+	.calc_temp = sun8i_ths_calc_temp,
+};
+
 static const struct ths_thermal_chip sun8i_a83t_ths = {
 	.sensor_num = 3,
 	.scale = 705,
@@ -711,6 +801,7 @@ static const struct ths_thermal_chip sun50i_h616_ths = {
 
 static const struct of_device_id of_ths_match[] = {
 	{ .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths },
+	{ .compatible = "allwinner,sun9i-a80-ths", .data = &sun9i_a80_ths },
 	{ .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths },
 	{ .compatible = "allwinner,sun8i-r40-ths", .data = &sun8i_r40_ths },
 	{ .compatible = "allwinner,sun50i-a64-ths", .data = &sun50i_a64_ths },
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones
  2026-07-22 20:33 [PATCH 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Sören Hantel
  2026-07-22 20:33 ` [PATCH 1/3] dt-bindings: thermal: sun8i: Add binding for the A80 THS controller Sören Hantel
  2026-07-22 20:33 ` [PATCH 2/3] thermal/drivers/sun8i: Add support for the A80 THS Sören Hantel
@ 2026-07-22 20:33 ` Sören Hantel
  2026-07-22 20:46   ` sashiko-bot
  2026-07-22 21:00 ` [PATCH v2 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Sören Hantel
  3 siblings, 1 reply; 11+ messages in thread
From: Sören Hantel @ 2026-07-22 20:33 UTC (permalink / raw)
  To: linux-pm
  Cc: Vasily Khoruzhick, Yangtao Li, Rafael J . Wysocki, Daniel Lezcano,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Rossak, devicetree,
	linux-arm-kernel, linux-sunxi, linux-kernel, Claude Fable 5,
	Sören Hantel

From: Philipp Rossak <embed3d@gmail.com>

Now that the A80 thermal sensor is supported, add its device node and
the thermal zones to the device tree.

The clocks and the resets are shared between the GPADC and the THS
sensor. Sensor 0 is located beside the big CPU cluster, sensor 1
beside the DRAM controller, sensor 2 beside the GPU and sensor 3
beside the little CPU cluster.

Signed-off-by: Philipp Rossak <embed3d@gmail.com>
[soeren: rebased from the 2018 series, fixed the interrupt number
(SPI 115 as in the vendor BSP; verified on hardware - SPI 31 stays
silent), added critical trip points matching the driver's emergency
shutdown threshold]
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Sören Hantel <fugininsane@googlemail.com>
---
 arch/arm/boot/dts/allwinner/sun9i-a80.dtsi | 68 ++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi b/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
index a1ae092..8e7f8cd 100644
--- a/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
@@ -941,6 +941,16 @@
 			#reset-cells = <1>;
 		};
 
+		ths: thermal-sensor@6004c00 {
+			compatible = "allwinner,sun9i-a80-ths";
+			reg = <0x06004c00 0x100>;
+			interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_GPADC>, <&ccu CLK_GPADC>;
+			clock-names = "bus", "mod";
+			resets = <&ccu RST_BUS_GPADC>;
+			#thermal-sensor-cells = <1>;
+		};
+
 		timer@6000c00 {
 			compatible = "allwinner,sun4i-a10-timer";
 			reg = <0x06000c00 0xa0>;
@@ -1250,4 +1260,62 @@
 			#size-cells = <0>;
 		};
 	};
+
+	thermal-zones {
+		cpu0_thermal: cpu0-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <5000>;
+			thermal-sensors = <&ths 0>;
+
+			trips {
+				cpu0_crit: cpu0-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		dram_thermal: dram-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <5000>;
+			thermal-sensors = <&ths 1>;
+
+			trips {
+				dram_crit: dram-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		gpu_thermal: gpu-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <5000>;
+			thermal-sensors = <&ths 2>;
+
+			trips {
+				gpu_crit: gpu-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu2_thermal: cpu2-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <5000>;
+			thermal-sensors = <&ths 3>;
+
+			trips {
+				cpu2_crit: cpu2-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+	};
 };
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/3] thermal/drivers/sun8i: Add support for the A80 THS
  2026-07-22 20:33 ` [PATCH 2/3] thermal/drivers/sun8i: Add support for the A80 THS Sören Hantel
@ 2026-07-22 20:45   ` sashiko-bot
  0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-07-22 20:45 UTC (permalink / raw)
  To: Sören Hantel; +Cc: devicetree, linux-sunxi, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] Unconditional NULL pointer dereference if calibration nvmem cell is present.
- [High] Statically enabled ALARM interrupt will cause a severe interrupt storm when triggered.

Pre-existing issues:
- [High] Interrupt handler defeats spurious interrupt detection by unconditionally returning IRQ_HANDLED.
--

--- Patch [2]: [PATCH 2/3] thermal/drivers/sun8i: Add support for the A80 THS ---
commit 95ccac1aebf565b0761d7e8e612500acbb05beba
Author: Sören Hantel <fugininsane@gmail.com>

thermal/drivers/sun8i: Add support for the A80 THS

The Allwinner A80 thermal sensor is an early relative of the THS found
in the A83T and later SoCs. It shares its register block, bus gate,
4 MHz module clock and reset line with the GPADC; the THS registers
live at offset 0x40 of the shared block, with four data registers for
the four sensors (0: big cluster, 1: DRAM, 2: GPU, 3: little cluster).

> diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
> index 22674790629a7..3e7bfda621267 100644
> --- a/drivers/thermal/sun8i_thermal.c
> +++ b/drivers/thermal/sun8i_thermal.c

[ ... ]

> @@ -596,6 +616,76 @@ static int sun8i_ths_probe(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +static int sun9i_a80_thermal_init(struct ths_device *tmdev)
> +{
> +	int i;
> +
> +	/* clear any pending interrupt status */
> +	regmap_write(tmdev->regmap, SUN9I_THS_IS, 0xfff);
> +	/* set up the median filter, average over 8 samples */
> +	regmap_write(tmdev->regmap, SUN9I_THS_MFC, 0x5);
> +
> +	/*
> +	 * Program the protection thresholds with the values the vendor
> +	 * BSP uses (thresholds are in raw sensor units, which decrease
> +	 * with rising temperature): an alarm interrupt at ~90 degC and
> +	 * an emergency hardware shutdown at ~105 degC.
> +	 */
> +	for (i = 0; i < tmdev->chip->sensor_num; i++) {
> +		regmap_write(tmdev->regmap, SUN9I_THS_ALARM_TH(i),
> +			     (1454 << 16) | 0xfff);
> +		regmap_write(tmdev->regmap, SUN9I_THS_SHUT_TH(i),
> +			     (1231 << 16) | 0xfff);
> +	}
> +
> +	/*
> +	 * Unlike on later SoCs, the data-ready interrupt fires at the
> +	 * conversion rate (tens of kHz), so leave it disabled and let the
> +	 * thermal core poll the data registers; the interrupt line only
> +	 * serves the alarm and shutdown events, like in the vendor BSP.
> +	 */
> +	regmap_write(tmdev->regmap, SUN9I_THS_IC,
> +		     SUN9I_THS_ALARM_IRQ_EN | SUN9I_THS_SHUT_IRQ_EN);

[Severity: High]
Will this statically enabled ALARM interrupt cause an interrupt storm when
triggered?

Since the ALARM threshold is static (~90 degC) and sun8i_irq_thread() clears
the status bit but does not mask the interrupt or adjust the threshold (as
there is no set_trips callback in this driver), won't the hardware immediately
re-assert the interrupt once the IRQF_ONESHOT thread unmasks the line while
the temperature remains above the threshold?

> +	/* acquire time 0x2f, enable all four sensors */
> +	regmap_write(tmdev->regmap, SUN9I_THS_CTRL,
> +		     SUN9I_THS_CTRL_ACQ(0x2f) | SUN9I_THS_CTRL_SENSOR_EN);
> +
> +	return 0;
> +}

[ ... ]

> +static const struct ths_thermal_chip sun9i_a80_ths = {
> +	.sensor_num = 4,
> +	.has_mod_clk = true,
> +	.mod_clk_rate = 4000000,
> +	.has_bus_clk_reset = true,
> +	.scale = 688,
> +	.offset = 190000,
> +	.temp_data_base = SUN9I_THS_TEMP_DATA,
> +	.init = sun9i_a80_thermal_init,

[Severity: High]
Is it possible for the calibration nvmem cell to be present for this chip?

The sun8i_ths_calibrate() function unconditionally dereferences the .calibrate
callback if calibration data is successfully read:

drivers/thermal/sun8i_thermal.c:sun8i_ths_calibrate() {
    ...
	caldata = nvmem_cell_read(calcell, &callen);
	if (IS_ERR(caldata)) {
		ret = PTR_ERR(caldata);
		goto out;
	}

	tmdev->chip->calibrate(tmdev, caldata, callen);
    ...
}

Since the sun9i_a80_ths struct omits the .calibrate callback, if a calibration
nvmem cell is provided (e.g. via a device tree overlay), would this cause a
NULL pointer dereference during probe?

> +	.irq_ack = sun9i_a80_irq_ack,

[Severity: High]
This is a pre-existing issue, but does sun8i_irq_thread() defeat spurious
interrupt detection by unconditionally returning IRQ_HANDLED?

If the hardware triggers an interrupt but irq_ack() finds no relevant status
bits (returning an irq_bitmap of 0), the loop is skipped:

drivers/thermal/sun8i_thermal.c:sun8i_irq_thread() {
	struct ths_device *tmdev = data;
	unsigned long irq_bitmap = tmdev->chip->irq_ack(tmdev);
	int i;

	for_each_set_bit(i, &irq_bitmap, tmdev->chip->sensor_num) {
        ...
	}

	return IRQ_HANDLED;
}

Returning IRQ_HANDLED instead of IRQ_NONE when no status bits are set prevents
the core IRQ subsystem from detecting and disabling a stuck or spurious
interrupt line.

> +	.calc_temp = sun8i_ths_calc_temp,
> +};
> +
>  static const struct ths_thermal_chip sun8i_a83t_ths = {
>  	.sensor_num = 3,
>  	.scale = 705,

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260722203341.2917852-1-fugininsane@googlemail.com?part=2

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones
  2026-07-22 20:33 ` [PATCH 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones Sören Hantel
@ 2026-07-22 20:46   ` sashiko-bot
  0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-07-22 20:46 UTC (permalink / raw)
  To: Sören Hantel; +Cc: robh, devicetree, linux-sunxi, conor+dt

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] The thermal zones for the CPU clusters are incorrectly named relative to their mapped hardware sensors, risking incorrect cooling mitigations.
- [High] The A80 thermal sensor driver lacks a `.calibrate` callback, resulting in a NULL pointer dereference if `nvmem` calibration data is ever provided.
- [Medium] The critical trip point temperature does not match the driver's emergency shutdown threshold as explicitly claimed in the commit message.
- [Low] The 'ths' node is not sorted properly by unit address.
--

--- Patch [3]: [PATCH 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones ---
commit cb2cbf274b6f042626c2998af64fc2030a9af3ea
Author: Philipp Rossak <embed3d@gmail.com>

ARM: dts: sun9i-a80: Add thermal sensor and thermal zones

This commit adds the device node for the A80 thermal sensor and the thermal
zones to the device tree. It maps the sensors to the big CPU cluster, DRAM,
GPU, and little CPU cluster.

> [soeren: rebased from the 2018 series, fixed the interrupt number
> (SPI 115 as in the vendor BSP; verified on hardware - SPI 31 stays
> silent), added critical trip points matching the driver's emergency
> shutdown threshold]

[Severity: Medium]
Does the trip point temperature match the driver's emergency shutdown
threshold as claimed in the commit message?

The commit message states that the patch adds trip points matching the
driver's emergency shutdown threshold, which is around 105C. However, the
device tree source sets the temperature to 100C (100000). Could the commit
message be more precise about this difference?

> diff --git a/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi b/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
> index a1ae0929cec9d..8e7f8cd943d2e 100644
> --- a/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
> +++ b/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
> @@ -941,6 +941,16 @@ ccu: clock@6000000 {
>  			#reset-cells = <1>;
>  		};
>  
> +		ths: thermal-sensor@6004c00 {

[Severity: Low]
Is this node sorted properly by unit address?

This thermal-sensor@6004c00 node is inserted between clock@6000000 and
timer@6000c00. Since 0x06004c00 is numerically greater than 0x06000c00, it
appears to break the standard ascending order sorting of unit addresses.

> +			compatible = "allwinner,sun9i-a80-ths";

[Severity: High]
Does the sun9i-a80-ths driver lack a calibrate callback?

If an nvmem calibration cell is provided in the device tree, the driver
unconditionally calls the calibrate callback:

drivers/thermal/sun8i_thermal.c:sun8i_ths_calibrate() {
    ...
    tmdev->chip->calibrate(tmdev, caldata, callen);
    ...
}

Will this cause a NULL pointer dereference during driver probe if calibration
data is ever provided, since sun9i-a80-ths omits this function pointer?

> +			reg = <0x06004c00 0x100>;
> +			interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&ccu CLK_BUS_GPADC>, <&ccu CLK_GPADC>;
> +			clock-names = "bus", "mod";
> +			resets = <&ccu RST_BUS_GPADC>;
> +			#thermal-sensor-cells = <1>;
> +		};
> +
>  		timer@6000c00 {

[ ... ]

> @@ -1250,4 +1260,62 @@ r_rsb: rsb@8003400 {
>  			#size-cells = <0>;
>  		};
>  	};
> +
> +	thermal-zones {
> +		cpu0_thermal: cpu0-thermal {
> +			polling-delay-passive = <1000>;
> +			polling-delay = <5000>;
> +			thermal-sensors = <&ths 0>;

[Severity: High]
Are the thermal zones for the CPU clusters incorrectly named relative to their
mapped hardware sensors?

The commit message notes that sensor 0 is located beside the big CPU cluster
(cpu4-7), and sensor 3 is beside the little CPU cluster (cpu0-3).

Here cpu0-thermal is mapped to sensor 0 (the big cluster). Will this cause
userspace daemons or future device tree cooling maps to incorrectly throttle
the little cluster when the big cluster overheats?

[ ... ]

> +		cpu2_thermal: cpu2-thermal {
> +			polling-delay-passive = <1000>;
> +			polling-delay = <5000>;
> +			thermal-sensors = <&ths 3>;

[Severity: High]
Similar to the question above, cpu2-thermal targets sensor 3, which monitors
the little cluster. Is this misleadingly named, risking incorrect cooling
mitigations?

> +
> +			trips {
> +				cpu2_crit: cpu2-crit {
> +					temperature = <100000>;
> +					hysteresis = <2000>;
> +					type = "critical";
> +				};
> +			};
> +		};
> +	};
>  };

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260722203341.2917852-1-fugininsane@googlemail.com?part=3

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor
  2026-07-22 20:33 [PATCH 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Sören Hantel
                   ` (2 preceding siblings ...)
  2026-07-22 20:33 ` [PATCH 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones Sören Hantel
@ 2026-07-22 21:00 ` Sören Hantel
  2026-07-22 21:00   ` [PATCH v2 1/3] dt-bindings: thermal: sun8i: Add binding for the A80 THS controller Sören Hantel
                     ` (2 more replies)
  3 siblings, 3 replies; 11+ messages in thread
From: Sören Hantel @ 2026-07-22 21:00 UTC (permalink / raw)
  To: linux-pm
  Cc: Vasily Khoruzhick, Yangtao Li, Rafael J . Wysocki, Daniel Lezcano,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Rossak, devicetree,
	linux-arm-kernel, linux-sunxi, linux-kernel, FuginInsanE

From: FuginInsanE <FuginInsanE@googlemail.com>

This series adds support for the thermal sensor of the Allwinner A80
(sun9i), the last SoC of the family with an in-tree DT but no THS
support.

The A80 THS is an early relative of the A83T/H3-era sensor generation:
same register semantics, but the block, bus gate, module clock and
reset line are shared with the GPADC, the THS registers start at
offset 0x40, and there are four sensors (big cluster, DRAM, GPU,
little cluster).

Philipp Rossak posted a driver for this hardware back in 2018 as part
of a larger THS rework which never landed for the A80; Armbian has
been carrying his DT patches ever since. This series takes the
mainline sun8i_thermal driver as the base instead: patch 2 adds a
chip description derived from the vendor BSP (register init values,
protection thresholds and the temperature formula), and patch 3
revives Philipp's DT patch with a fixed interrupt number (SPI 115 as
in the vendor BSP - verified on hardware, the original SPI 31 never
fires) and critical trip points.

The A80 SID is not yet supported by the sunxi nvmem driver, so
calibration data is unavailable for now and the driver falls back to
defaults, which produce plausible values on real hardware.

Tested on a Cubietech Cubieboard4: all four zones report
load-reactive temperatures (idle ~40 degC, ~54 degC under sustained
full load) tracking the BSP formula across the range we could
provoke.

Changes in v2:
- Guard the calibrate callback invocation in sun8i_ths_calibrate()
  against chips without a calibrate op (would have oopsed if a
  calibration nvmem cell were ever added for the A80)
- Do not enable the alarm interrupt: being level triggered it would
  retrigger at conversion rate for as long as an over-temperature
  condition persists; only the emergency shutdown interrupt remains
  enabled
- Note: the unconditional IRQ_HANDLED in the existing interrupt
  handler predates this series and is left untouched here

Philipp Rossak (1):
  ARM: dts: sun9i-a80: Add thermal sensor and thermal zones

Sören Hantel (2):
  dt-bindings: thermal: sun8i: Add binding for the A80 THS controller
  thermal/drivers/sun8i: Add support for the A80 THS

 .../thermal/allwinner,sun8i-a83t-ths.yaml     |  1 +
 arch/arm/boot/dts/allwinner/sun9i-a80.dtsi    | 68 +++++++++++++
 drivers/thermal/sun8i_thermal.c               | 98 ++++++++++++++++++-
 3 files changed, 166 insertions(+), 1 deletion(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/3] dt-bindings: thermal: sun8i: Add binding for the A80 THS controller
  2026-07-22 21:00 ` [PATCH v2 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Sören Hantel
@ 2026-07-22 21:00   ` Sören Hantel
  2026-07-22 21:00   ` [PATCH v2 2/3] thermal/drivers/sun8i: Add support for the A80 THS Sören Hantel
  2026-07-22 21:00   ` [PATCH v2 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones Sören Hantel
  2 siblings, 0 replies; 11+ messages in thread
From: Sören Hantel @ 2026-07-22 21:00 UTC (permalink / raw)
  To: linux-pm
  Cc: Vasily Khoruzhick, Yangtao Li, Rafael J . Wysocki, Daniel Lezcano,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Rossak, devicetree,
	linux-arm-kernel, linux-sunxi, linux-kernel, Sören Hantel,
	Claude Fable 5

The Allwinner A80 has a thermal sensor with four channels which shares
its MMIO block, bus gate, module clock and reset line with the GPADC.
Register-wise it is an early version of the THS found in the A83T and
later SoCs, with the THS registers starting at offset 0x40 of the
shared block.

Add the compatible to the sun8i THS binding. The A80 takes a bus and a
module clock plus a reset line, so the existing conditionals already
describe it correctly.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Sören Hantel <fugininsane@googlemail.com>
---
 .../devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml    | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml b/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
index 3e61689..718c44d 100644
--- a/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
+++ b/Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml
@@ -18,6 +18,7 @@ properties:
       - allwinner,sun8i-a83t-ths
       - allwinner,sun8i-h3-ths
       - allwinner,sun8i-r40-ths
+      - allwinner,sun9i-a80-ths
       - allwinner,sun20i-d1-ths
       - allwinner,sun50i-a64-ths
       - allwinner,sun50i-a100-ths
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 2/3] thermal/drivers/sun8i: Add support for the A80 THS
  2026-07-22 21:00 ` [PATCH v2 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Sören Hantel
  2026-07-22 21:00   ` [PATCH v2 1/3] dt-bindings: thermal: sun8i: Add binding for the A80 THS controller Sören Hantel
@ 2026-07-22 21:00   ` Sören Hantel
  2026-07-22 21:00   ` [PATCH v2 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones Sören Hantel
  2 siblings, 0 replies; 11+ messages in thread
From: Sören Hantel @ 2026-07-22 21:00 UTC (permalink / raw)
  To: linux-pm
  Cc: Vasily Khoruzhick, Yangtao Li, Rafael J . Wysocki, Daniel Lezcano,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Rossak, devicetree,
	linux-arm-kernel, linux-sunxi, linux-kernel, Sören Hantel,
	Claude Fable 5

The Allwinner A80 thermal sensor is an early relative of the THS found
in the A83T and later SoCs. It shares its register block, bus gate,
4 MHz module clock and reset line with the GPADC; the THS registers
live at offset 0x40 of the shared block, with four data registers for
the four sensors (0: big cluster, 1: DRAM, 2: GPU, 3: little cluster).

Register layout, initialization values and the temperature formula
(T = 190 - raw * 1000 / 14543, i.e. offset 190000 / scale 688 in this
driver's convention) are taken from the vendor BSP kernel. The init
sequence also programs the hardware alarm (~90 degC) and emergency
shutdown (~105 degC) thresholds the BSP uses, since their reset
defaults are undefined.

Unlike on later SoCs the data-ready interrupt fires at the conversion
rate (tens of kHz), and the level triggered alarm interrupt would
retrigger for as long as an over-temperature condition persists, so
both stay disabled and the thermal core polls the sensors; only the
emergency shutdown event keeps its interrupt enabled.

Since the A80 chip description has no calibrate callback, guard the
callback invocation in sun8i_ths_calibrate(); the A80 SID is not yet
supported by the sunxi nvmem driver anyway, so calibration data is
currently unavailable and the driver falls back to the defaults,
which yield plausible results (idle temperatures around 40 degC,
full-load peaks in the mid 50s on a Cubieboard4).

Tested on a Cubietech Cubieboard4: all four zones report load-reactive
temperatures via polling.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Sören Hantel <fugininsane@googlemail.com>
---
 drivers/thermal/sun8i_thermal.c | 98 ++++++++++++++++++++++++++++++++-
 1 file changed, 97 insertions(+), 1 deletion(-)

diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c
index 2267479..c906dea 100644
--- a/drivers/thermal/sun8i_thermal.c
+++ b/drivers/thermal/sun8i_thermal.c
@@ -65,8 +65,27 @@ struct tsensor {
 	int				id;
 };
 
+/*
+ * The A80 thermal sensor shares its register block with the GPADC.
+ * The THS registers start at offset 0x40 within that block.
+ */
+#define SUN9I_THS_CTRL				0x40
+#define SUN9I_THS_IC				0x44
+#define SUN9I_THS_IS				0x48
+#define SUN9I_THS_ALARM_TH(x)			(0x50 + (x) * 0x4)
+#define SUN9I_THS_SHUT_TH(x)			(0x60 + (x) * 0x4)
+#define SUN9I_THS_MFC				0x70
+#define SUN9I_THS_TEMP_DATA			0x80
+#define SUN9I_THS_CTRL_ACQ(x)			((x) << 16)
+#define SUN9I_THS_CTRL_SENSOR_EN		GENMASK(3, 0)
+#define SUN9I_THS_ALARM_IRQ_EN			GENMASK(3, 0)
+#define SUN9I_THS_SHUT_IRQ_EN			GENMASK(7, 4)
+#define SUN9I_THS_ALARM_IRQ_STS(x)		BIT(x)
+#define SUN9I_THS_SHUT_IRQ_STS(x)		BIT(4 + (x))
+
 struct ths_thermal_chip {
 	bool            has_mod_clk;
+	unsigned long	mod_clk_rate;
 	bool            has_bus_clk_reset;
 	bool		needs_sram;
 	int		sensor_num;
@@ -307,6 +326,9 @@ static int sun8i_ths_calibrate(struct ths_device *tmdev)
 	size_t callen;
 	int ret = 0;
 
+	if (!tmdev->chip->calibrate)
+		return 0;
+
 	calcell = nvmem_cell_get(dev, "calibration");
 	if (IS_ERR(calcell)) {
 		if (PTR_ERR(calcell) == -EPROBE_DEFER)
@@ -413,7 +435,8 @@ static int sun8i_ths_resource_init(struct ths_device *tmdev)
 			return PTR_ERR(tmdev->mod_clk);
 	}
 
-	ret = clk_set_rate(tmdev->mod_clk, 24000000);
+	ret = clk_set_rate(tmdev->mod_clk, tmdev->chip->mod_clk_rate ?:
+			   24000000);
 	if (ret)
 		return ret;
 
@@ -596,6 +619,78 @@ static int sun8i_ths_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int sun9i_a80_thermal_init(struct ths_device *tmdev)
+{
+	int i;
+
+	/* clear any pending interrupt status */
+	regmap_write(tmdev->regmap, SUN9I_THS_IS, 0xfff);
+	/* set up the median filter, average over 8 samples */
+	regmap_write(tmdev->regmap, SUN9I_THS_MFC, 0x5);
+
+	/*
+	 * Program the protection thresholds with the values the vendor
+	 * BSP uses (thresholds are in raw sensor units, which decrease
+	 * with rising temperature): an alarm interrupt at ~90 degC and
+	 * an emergency hardware shutdown at ~105 degC.
+	 */
+	for (i = 0; i < tmdev->chip->sensor_num; i++) {
+		regmap_write(tmdev->regmap, SUN9I_THS_ALARM_TH(i),
+			     (1454 << 16) | 0xfff);
+		regmap_write(tmdev->regmap, SUN9I_THS_SHUT_TH(i),
+			     (1231 << 16) | 0xfff);
+	}
+
+	/*
+	 * Unlike on later SoCs, the data-ready interrupt fires at the
+	 * conversion rate (tens of kHz), and the level triggered alarm
+	 * interrupt would retrigger for as long as the over-temperature
+	 * condition persists. Leave both disabled and let the thermal
+	 * core poll the data registers; only the emergency shutdown
+	 * interrupt stays enabled, as by the time it fires the hardware
+	 * is powering off anyway.
+	 */
+	regmap_write(tmdev->regmap, SUN9I_THS_IC, SUN9I_THS_SHUT_IRQ_EN);
+	/* acquire time 0x2f, enable all four sensors */
+	regmap_write(tmdev->regmap, SUN9I_THS_CTRL,
+		     SUN9I_THS_CTRL_ACQ(0x2f) | SUN9I_THS_CTRL_SENSOR_EN);
+
+	return 0;
+}
+
+static unsigned long sun9i_a80_irq_ack(struct ths_device *tmdev)
+{
+	unsigned long irq_bitmap = 0;
+	int i, state;
+
+	regmap_read(tmdev->regmap, SUN9I_THS_IS, &state);
+
+	for (i = 0; i < MAX_SENSOR_NUM; i++) {
+		if (state & (SUN9I_THS_ALARM_IRQ_STS(i) |
+			     SUN9I_THS_SHUT_IRQ_STS(i))) {
+			regmap_write(tmdev->regmap, SUN9I_THS_IS,
+				     state & (SUN9I_THS_ALARM_IRQ_STS(i) |
+					      SUN9I_THS_SHUT_IRQ_STS(i)));
+			set_bit(i, &irq_bitmap);
+		}
+	}
+
+	return irq_bitmap;
+}
+
+static const struct ths_thermal_chip sun9i_a80_ths = {
+	.sensor_num = 4,
+	.has_mod_clk = true,
+	.mod_clk_rate = 4000000,
+	.has_bus_clk_reset = true,
+	.scale = 688,
+	.offset = 190000,
+	.temp_data_base = SUN9I_THS_TEMP_DATA,
+	.init = sun9i_a80_thermal_init,
+	.irq_ack = sun9i_a80_irq_ack,
+	.calc_temp = sun8i_ths_calc_temp,
+};
+
 static const struct ths_thermal_chip sun8i_a83t_ths = {
 	.sensor_num = 3,
 	.scale = 705,
@@ -711,6 +806,7 @@ static const struct ths_thermal_chip sun50i_h616_ths = {
 
 static const struct of_device_id of_ths_match[] = {
 	{ .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths },
+	{ .compatible = "allwinner,sun9i-a80-ths", .data = &sun9i_a80_ths },
 	{ .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths },
 	{ .compatible = "allwinner,sun8i-r40-ths", .data = &sun8i_r40_ths },
 	{ .compatible = "allwinner,sun50i-a64-ths", .data = &sun50i_a64_ths },
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones
  2026-07-22 21:00 ` [PATCH v2 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Sören Hantel
  2026-07-22 21:00   ` [PATCH v2 1/3] dt-bindings: thermal: sun8i: Add binding for the A80 THS controller Sören Hantel
  2026-07-22 21:00   ` [PATCH v2 2/3] thermal/drivers/sun8i: Add support for the A80 THS Sören Hantel
@ 2026-07-22 21:00   ` Sören Hantel
  2026-07-22 21:10     ` sashiko-bot
  2 siblings, 1 reply; 11+ messages in thread
From: Sören Hantel @ 2026-07-22 21:00 UTC (permalink / raw)
  To: linux-pm
  Cc: Vasily Khoruzhick, Yangtao Li, Rafael J . Wysocki, Daniel Lezcano,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Rossak, devicetree,
	linux-arm-kernel, linux-sunxi, linux-kernel, Claude Fable 5,
	Sören Hantel

From: Philipp Rossak <embed3d@gmail.com>

Now that the A80 thermal sensor is supported, add its device node and
the thermal zones to the device tree.

The clocks and the resets are shared between the GPADC and the THS
sensor. Sensor 0 is located beside the big CPU cluster, sensor 1
beside the DRAM controller, sensor 2 beside the GPU and sensor 3
beside the little CPU cluster.

Signed-off-by: Philipp Rossak <embed3d@gmail.com>
[soeren: rebased from the 2018 series, fixed the interrupt number
(SPI 115 as in the vendor BSP; verified on hardware - SPI 31 stays
silent), added critical trip points matching the driver's emergency
shutdown threshold]
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Sören Hantel <fugininsane@googlemail.com>
---
 arch/arm/boot/dts/allwinner/sun9i-a80.dtsi | 68 ++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi b/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
index a1ae092..8e7f8cd 100644
--- a/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
@@ -941,6 +941,16 @@
 			#reset-cells = <1>;
 		};
 
+		ths: thermal-sensor@6004c00 {
+			compatible = "allwinner,sun9i-a80-ths";
+			reg = <0x06004c00 0x100>;
+			interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_GPADC>, <&ccu CLK_GPADC>;
+			clock-names = "bus", "mod";
+			resets = <&ccu RST_BUS_GPADC>;
+			#thermal-sensor-cells = <1>;
+		};
+
 		timer@6000c00 {
 			compatible = "allwinner,sun4i-a10-timer";
 			reg = <0x06000c00 0xa0>;
@@ -1250,4 +1260,62 @@
 			#size-cells = <0>;
 		};
 	};
+
+	thermal-zones {
+		cpu0_thermal: cpu0-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <5000>;
+			thermal-sensors = <&ths 0>;
+
+			trips {
+				cpu0_crit: cpu0-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		dram_thermal: dram-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <5000>;
+			thermal-sensors = <&ths 1>;
+
+			trips {
+				dram_crit: dram-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		gpu_thermal: gpu-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <5000>;
+			thermal-sensors = <&ths 2>;
+
+			trips {
+				gpu_crit: gpu-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+
+		cpu2_thermal: cpu2-thermal {
+			polling-delay-passive = <1000>;
+			polling-delay = <5000>;
+			thermal-sensors = <&ths 3>;
+
+			trips {
+				cpu2_crit: cpu2-crit {
+					temperature = <100000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+	};
 };
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v2 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones
  2026-07-22 21:00   ` [PATCH v2 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones Sören Hantel
@ 2026-07-22 21:10     ` sashiko-bot
  0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-07-22 21:10 UTC (permalink / raw)
  To: Sören Hantel; +Cc: devicetree, conor+dt, linux-sunxi, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Thermal zones for CPU clusters are misnamed and cross-mapped relative to the actual CPU cores.
--

--- Patch [3]: [PATCH v2 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones ---
commit 073b6503b11cee70b348c673193855cbda7082e3
Author: Philipp Rossak <embed3d@gmail.com>

ARM: dts: sun9i-a80: Add thermal sensor and thermal zones

This commit adds the device node for the A80 thermal sensor and defines
the thermal zones in the device tree. It maps the sensors to the big CPU
cluster, DRAM, GPU, and little CPU cluster.

> diff --git a/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi b/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
> index a1ae0929cec9d..8e7f8cd943d2e 100644
> --- a/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
> +++ b/arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
[ ... ]
> @@ -1250,4 +1260,62 @@ r_rsb: rsb@8003400 {
>  			#size-cells = <0>;
>  		};
>  	};
> +
> +	thermal-zones {
> +		cpu0_thermal: cpu0-thermal {
> +			polling-delay-passive = <1000>;
> +			polling-delay = <5000>;
> +			thermal-sensors = <&ths 0>;

[Severity: Medium]
Since cpu0 on the sun9i-a80 is part of the little CPU cluster, does this
map the cpu0 thermal zone to the wrong sensor? The commit message notes
that sensor 0 is beside the big CPU cluster. This could lead to mislabeled
temperatures in userspace and potentially throttle the wrong cluster if
cooling maps are added later.

> +
> +			trips {
> +				cpu0_crit: cpu0-crit {
> +					temperature = <100000>;
> +					hysteresis = <2000>;
> +					type = "critical";
> +				};
> +			};
> +		};
[ ... ]
> +		cpu2_thermal: cpu2-thermal {
> +			polling-delay-passive = <1000>;
> +			polling-delay = <5000>;
> +			thermal-sensors = <&ths 3>;

[Severity: Medium]
Are these names cross-mapped? This maps cpu2-thermal to sensor 3, which the
commit message states is beside the little CPU cluster. Since cpu2 is also
typically a little core, should the node names better reflect the actual
big/little clusters to avoid confusion?

> +
> +			trips {
> +				cpu2_crit: cpu2-crit {
> +					temperature = <100000>;
> +					hysteresis = <2000>;
> +					type = "critical";
> +				};
> +			};
> +		};
> +	};
>  };

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260722210046.2932498-1-fugininsane@googlemail.com?part=3

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-07-22 21:10 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-22 20:33 [PATCH 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Sören Hantel
2026-07-22 20:33 ` [PATCH 1/3] dt-bindings: thermal: sun8i: Add binding for the A80 THS controller Sören Hantel
2026-07-22 20:33 ` [PATCH 2/3] thermal/drivers/sun8i: Add support for the A80 THS Sören Hantel
2026-07-22 20:45   ` sashiko-bot
2026-07-22 20:33 ` [PATCH 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones Sören Hantel
2026-07-22 20:46   ` sashiko-bot
2026-07-22 21:00 ` [PATCH v2 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Sören Hantel
2026-07-22 21:00   ` [PATCH v2 1/3] dt-bindings: thermal: sun8i: Add binding for the A80 THS controller Sören Hantel
2026-07-22 21:00   ` [PATCH v2 2/3] thermal/drivers/sun8i: Add support for the A80 THS Sören Hantel
2026-07-22 21:00   ` [PATCH v2 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones Sören Hantel
2026-07-22 21:10     ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox