* [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: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, 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 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 21:00 ` [PATCH v2 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Sören Hantel
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, 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
* [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
` (3 more replies)
3 siblings, 4 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-24 7:09 ` Krzysztof Kozlowski
2026-07-22 21:00 ` [PATCH v2 2/3] thermal/drivers/sun8i: Add support for the A80 THS Sören Hantel
` (2 subsequent siblings)
3 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, 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-24 7:10 ` Krzysztof Kozlowski
2026-07-22 21:00 ` [PATCH v2 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones Sören Hantel
2026-07-24 7:10 ` [PATCH v2 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Krzysztof Kozlowski
3 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, 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-24 7:10 ` [PATCH v2 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Krzysztof Kozlowski
3 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, 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 1/3] dt-bindings: thermal: sun8i: Add binding for the A80 THS controller
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-24 7:09 ` Krzysztof Kozlowski
0 siblings, 0 replies; 11+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-24 7:09 UTC (permalink / raw)
To: Sören Hantel
Cc: linux-pm, 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
On Wed, Jul 22, 2026 at 11:00:44PM +0200, Sören Hantel wrote:
> 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>
NAK. Tools cannot certify DCO, cannot be authors.
> Signed-off-by: Sören Hantel <fugininsane@googlemail.com>
Messed DCO even more.
> ---
> .../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
Really, single compatible was co-authored by the tool? Folks cannot
write a single line of code nowadays or how does it work exactly?
And the tool did not even read the rules about sending patches, DCO,
proper subject for DT bindings? What is the use of the tool if it
produces obviously incorrect patch?
subject: drop second/last, redundant "binding for". The "dt-bindings"
prefix is already stating that these are bindings. See also:
https://elixir.bootlin.com/linux/v7.1-rc7/source/Documentation/devicetree/bindings/submitting-patches.rst#L23
Ask your tool to read the docs before using it, please.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor
2026-07-22 21:00 ` [PATCH v2 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Sören Hantel
` (2 preceding siblings ...)
2026-07-22 21:00 ` [PATCH v2 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones Sören Hantel
@ 2026-07-24 7:10 ` Krzysztof Kozlowski
3 siblings, 0 replies; 11+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-24 7:10 UTC (permalink / raw)
To: Sören Hantel
Cc: linux-pm, 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
On Wed, Jul 22, 2026 at 11:00:43PM +0200, Sören Hantel wrote:
> 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.
Do not attach (thread) your patchsets to some other threads (unrelated
or older versions). This buries them deep in the mailbox and might
interfere with applying entire sets. See also:
https://elixir.bootlin.com/linux/v6.16-rc2/source/Documentation/process/submitting-patches.rst#L830
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/3] thermal/drivers/sun8i: Add support for the A80 THS
2026-07-22 21:00 ` [PATCH v2 2/3] thermal/drivers/sun8i: Add support for the A80 THS Sören Hantel
@ 2026-07-24 7:10 ` Krzysztof Kozlowski
0 siblings, 0 replies; 11+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-24 7:10 UTC (permalink / raw)
To: Sören Hantel
Cc: linux-pm, 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
On Wed, Jul 22, 2026 at 11:00:45PM +0200, Sören Hantel wrote:
> 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>
Same as for binding: nope. Claude is not a person.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-07-24 7: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: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
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-24 7:09 ` Krzysztof Kozlowski
2026-07-22 21:00 ` [PATCH v2 2/3] thermal/drivers/sun8i: Add support for the A80 THS Sören Hantel
2026-07-24 7:10 ` Krzysztof Kozlowski
2026-07-22 21:00 ` [PATCH v2 3/3] ARM: dts: sun9i-a80: Add thermal sensor and thermal zones Sören Hantel
2026-07-24 7:10 ` [PATCH v2 0/3] thermal/drivers/sun8i: Add support for the Allwinner A80 thermal sensor Krzysztof Kozlowski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox