* [PATCH v5 0/4] thermal: loongson2: Add support for Loongson-2K0300 SoC
@ 2026-09-17 11:11 Binbin Zhou
2026-09-17 11:11 ` [PATCH v5 1/4] thermal/drivers/loongson2: Correct thermal sensor registration loop Binbin Zhou
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Binbin Zhou @ 2026-09-17 11:11 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Yinbo Zhu, zhanghongchen, Rafael J . Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba
Cc: Huacai Chen, devicetree, linux-pm, Binbin Zhou
Hi all:
This patch series adds thermal zone support for the Loongson-2K0300 SoC.
The Loongson-2K0300's thermal sensor is generally compatible with the
existing Loongson-2K series, but it features several key differences:
1. It has an independent CPU ID register for reading chip version
information.
2. The raw temperature output field has been extended from 8 bits to 11
bits.
3. The temperature calculation formula has been updated to incorporate a
correction factor based on the version information.
To ensure robustness on older hardware revisions, a fallback mechanism
is included: if the calculated temperature falls outside the valid range
(-55 TO 125), the driver falls back to a simpler calculation and prints
a warning.
The patches have been validated on the Loongson-2K0300 development board.
Thanks.
Binbin
=========
V5:
- Rebase on linux-pm/thermal;
- Drop patch-3 for it was applied.
Link to V4:
https://lore.kernel.org/all/cover.1785829933.git.zhoubinbin@loongson.cn/
V4:
- Rebase on linux-mfd/for-mfd-next;
Patch (3/5):
- Remove the operation that adds `compatible` to the `select` node.
Link to V3:
https://lore.kernel.org/all/cover.1785480242.git.zhoubinbin@loongson.cn/
V3:
Patch (2/5):
- New patch for moving thermal_ops to chip_data;
Patch (3/5):
- Correct spelling errors;
Patch (4/5):
- Add Acked-by from Conor, thanks;
Patch (5/5):
- Keep loongson2_thermal_data->chip_data as const, and use
data->flags as the private data.
- Renmae LOONGSON2_THSENS_OUT_10B_MASK ->
LOONGSON2_THSENS_OUT_11B_MASK;
Link to V2:
https://lore.kernel.org/all/cover.1784619512.git.zhoubinbin@loongson.cn/
V2:
Patch (1/4):
- New patch form Sashiko;
Patch (2/4):
- New patch for adding chipid syscon compatible;
Patch (3/4):
- Use `loongson,chipid` phandle replace reg property;
Patch (3/4):
- Refact `calib_offset` calculate routing;
- Add LS2K0300_OLD_FUSE_FLAG flag.
Link to V1:
https://lore.kernel.org/all/cover.1783670011.git.zhoubinbin@loongson.cn/
Binbin Zhou (4):
thermal/drivers/loongson2: Correct thermal sensor registration loop
thermal/drivers/loongson2: Move thermal_ops to chip_data for SoC
scalability
dt-bindings: thermal: loongson,ls2k-thermal: Add compatible for
Loongson-2K0300
thermal/drivers/loongson2: Add support for Loongson-2K0300
.../thermal/loongson,ls2k-thermal.yaml | 73 +++++++++---
drivers/thermal/loongson2_thermal.c | 110 ++++++++++++++++--
2 files changed, 155 insertions(+), 28 deletions(-)
base-commit: 5ad0af4f4367202b1bc71813052fe39b5116cdb9
--
2.52.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 1/4] thermal/drivers/loongson2: Correct thermal sensor registration loop
2026-09-17 11:11 [PATCH v5 0/4] thermal: loongson2: Add support for Loongson-2K0300 SoC Binbin Zhou
@ 2026-09-17 11:11 ` Binbin Zhou
2026-09-17 11:11 ` [PATCH v5 2/4] thermal/drivers/loongson2: Move thermal_ops to chip_data for SoC scalability Binbin Zhou
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Binbin Zhou @ 2026-09-17 11:11 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Yinbo Zhu, zhanghongchen, Rafael J . Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba
Cc: Huacai Chen, devicetree, linux-pm, Binbin Zhou, stable, Sashiko
The registration loop in loongson2_thermal_probe() incorrectly uses
dev_err_probe() when the sensor is not present (-ENODEV). In that case,
the driver should continue to the next sensor index rather than treating
it as a fatal error.
Fix this by correctly handling -ENODEV and only returning on other
errors. Also add a final check to ensure at least one thermal zone was
registered.
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/cover.1783670011.git.zhoubinbin@loongson.cn?part=2
Fixes: e7e3a7c35791 ("thermal/drivers/loongson-2: Add thermal management support")
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
drivers/thermal/loongson2_thermal.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/loongson2_thermal.c b/drivers/thermal/loongson2_thermal.c
index 4d40fc706a53..99b7392fc68f 100644
--- a/drivers/thermal/loongson2_thermal.c
+++ b/drivers/thermal/loongson2_thermal.c
@@ -160,16 +160,18 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
for (i = 0; i <= LOONGSON2_MAX_SENSOR_SEL_NUM; i++) {
tzd = devm_thermal_of_zone_register(dev, i, data, thermal_ops);
-
if (!IS_ERR(tzd))
break;
- if (PTR_ERR(tzd) != -ENODEV)
+ if (PTR_ERR(tzd) == -ENODEV)
continue;
- return dev_err_probe(dev, PTR_ERR(tzd), "failed to register");
+ return dev_err_probe(dev, PTR_ERR(tzd), "failed to register sensor %d\n", i);
}
+ if (IS_ERR(tzd))
+ return dev_err_probe(dev, -ENODEV, "No thermal sensor registered\n");
+
ret = devm_request_threaded_irq(dev, irq, NULL, loongson2_thermal_irq_thread,
IRQF_ONESHOT, "loongson2_thermal", tzd);
if (ret < 0)
--
2.52.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v5 2/4] thermal/drivers/loongson2: Move thermal_ops to chip_data for SoC scalability
2026-09-17 11:11 [PATCH v5 0/4] thermal: loongson2: Add support for Loongson-2K0300 SoC Binbin Zhou
2026-09-17 11:11 ` [PATCH v5 1/4] thermal/drivers/loongson2: Correct thermal sensor registration loop Binbin Zhou
@ 2026-09-17 11:11 ` Binbin Zhou
2026-09-17 11:11 ` [PATCH v5 3/4] dt-bindings: thermal: loongson,ls2k-thermal: Add compatible for Loongson-2K0300 Binbin Zhou
2026-09-17 11:15 ` [PATCH v5 4/4] thermal/drivers/loongson2: Add support " Binbin Zhou
3 siblings, 0 replies; 7+ messages in thread
From: Binbin Zhou @ 2026-09-17 11:11 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Yinbo Zhu, zhanghongchen, Rafael J . Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba
Cc: Huacai Chen, devicetree, linux-pm, Binbin Zhou
In preparation for supporting additional Loongson SoCs, relocate the
thermal zone device operations pointer (thermal_ops) from the probe
routine to the per-SoC chip_data structure. This eliminates the need
to add conditional branches in probe() when a new SoC is introduced;
instead, the appropriate ops can be statically assigned in the match
data.
No functional change intended.
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
drivers/thermal/loongson2_thermal.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/thermal/loongson2_thermal.c b/drivers/thermal/loongson2_thermal.c
index 99b7392fc68f..fb4793a9bc55 100644
--- a/drivers/thermal/loongson2_thermal.c
+++ b/drivers/thermal/loongson2_thermal.c
@@ -38,6 +38,7 @@
struct loongson2_thermal_chip_data {
unsigned int thermal_sensor_sel;
unsigned int flags;
+ const struct thermal_zone_device_ops *thermal_ops;
};
struct loongson2_thermal_data {
@@ -123,7 +124,6 @@ static const struct thermal_zone_device_ops loongson2_2k2000_of_thermal_ops = {
static int loongson2_thermal_probe(struct platform_device *pdev)
{
- const struct thermal_zone_device_ops *thermal_ops;
struct device *dev = &pdev->dev;
struct loongson2_thermal_data *data;
struct thermal_zone_device *tzd;
@@ -144,10 +144,6 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
data->temp_reg = devm_platform_ioremap_resource(pdev, 1);
if (IS_ERR(data->temp_reg))
return PTR_ERR(data->temp_reg);
-
- thermal_ops = &loongson2_2k2000_of_thermal_ops;
- } else {
- thermal_ops = &loongson2_2k1000_of_thermal_ops;
}
irq = platform_get_irq(pdev, 0);
@@ -159,7 +155,7 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
loongson2_thermal_set(data, 0, 0, false);
for (i = 0; i <= LOONGSON2_MAX_SENSOR_SEL_NUM; i++) {
- tzd = devm_thermal_of_zone_register(dev, i, data, thermal_ops);
+ tzd = devm_thermal_of_zone_register(dev, i, data, data->chip_data->thermal_ops);
if (!IS_ERR(tzd))
break;
@@ -185,11 +181,13 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k1000_data = {
.thermal_sensor_sel = 0,
.flags = 0,
+ .thermal_ops = &loongson2_2k1000_of_thermal_ops,
};
static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k2000_data = {
.thermal_sensor_sel = 0,
.flags = LS2K2000_THSENS_OUT_FLAG,
+ .thermal_ops = &loongson2_2k2000_of_thermal_ops,
};
static const struct of_device_id of_loongson2_thermal_match[] = {
--
2.52.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v5 3/4] dt-bindings: thermal: loongson,ls2k-thermal: Add compatible for Loongson-2K0300
2026-09-17 11:11 [PATCH v5 0/4] thermal: loongson2: Add support for Loongson-2K0300 SoC Binbin Zhou
2026-09-17 11:11 ` [PATCH v5 1/4] thermal/drivers/loongson2: Correct thermal sensor registration loop Binbin Zhou
2026-09-17 11:11 ` [PATCH v5 2/4] thermal/drivers/loongson2: Move thermal_ops to chip_data for SoC scalability Binbin Zhou
@ 2026-09-17 11:11 ` Binbin Zhou
2026-09-17 11:15 ` [PATCH v5 4/4] thermal/drivers/loongson2: Add support " Binbin Zhou
3 siblings, 0 replies; 7+ messages in thread
From: Binbin Zhou @ 2026-09-17 11:11 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Yinbo Zhu, zhanghongchen, Rafael J . Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba
Cc: Huacai Chen, devicetree, linux-pm, Binbin Zhou, Conor Dooley
Add a new compatible string `loongson,ls2k0300-thermal` for the thermal
sensor found on the Loongson-2K0300 SoC.
The hardware differs from existing SoCs in that it requires a phandle to
a syscon node that provides the CHIP ID register, used as a compensation
source in the temperature calculation.
Update the binding to make `loongson,chipid` required for this new
compatible, and clarify the register region requirements for each
variant.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
.../thermal/loongson,ls2k-thermal.yaml | 73 ++++++++++++++-----
1 file changed, 55 insertions(+), 18 deletions(-)
diff --git a/Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml b/Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml
index 79e691b08341..d312e27737a2 100644
--- a/Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml
+++ b/Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml
@@ -10,13 +10,11 @@ maintainers:
- zhanghongchen <zhanghongchen@loongson.cn>
- Yinbo Zhu <zhuyinbo@loongson.cn>
-allOf:
- - $ref: /schemas/thermal/thermal-sensor.yaml#
-
properties:
compatible:
oneOf:
- enum:
+ - loongson,ls2k0300-thermal
- loongson,ls2k1000-thermal
- loongson,ls2k2000-thermal
- items:
@@ -34,28 +32,56 @@ properties:
'#thermal-sensor-cells':
const: 1
+ loongson,chipid:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description:
+ Phandle to the syscon with the Loongson-2K0300 CHIP ID.
+
required:
- compatible
- reg
- interrupts
-if:
- properties:
- compatible:
- contains:
- enum:
- - loongson,ls2k2000-thermal
+allOf:
+ - $ref: /schemas/thermal/thermal-sensor.yaml#
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: loongson,ls2k0300-thermal
+ then:
+ properties:
+ reg:
+ items:
+ - description: Thermal base register region
+ required:
+ - loongson,chipid
-then:
- properties:
- reg:
- minItems: 2
- maxItems: 2
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: loongson,ls2k1000-thermal
+ then:
+ properties:
+ loongson,chipid: false
+ reg:
+ items:
+ - description: Thermal base register region
-else:
- properties:
- reg:
- maxItems: 1
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: loongson,ls2k2000-thermal
+ then:
+ properties:
+ loongson,chipid: false
+ reg:
+ items:
+ - description: Thermal base register region
+ - description: Thermal data output register region
unevaluatedProperties: false
@@ -69,3 +95,14 @@ examples:
interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
#thermal-sensor-cells = <1>;
};
+
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ thermal-sensor@16001500 {
+ compatible = "loongson,ls2k0300-thermal";
+ reg = <0x16001500 0x30>;
+ interrupt-parent = <&liointc1>;
+ interrupts = <20 IRQ_TYPE_LEVEL_HIGH>;
+ loongson,chipid = <&chipid>;
+ #thermal-sensor-cells = <1>;
+ };
--
2.52.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v5 4/4] thermal/drivers/loongson2: Add support for Loongson-2K0300
2026-09-17 11:11 [PATCH v5 0/4] thermal: loongson2: Add support for Loongson-2K0300 SoC Binbin Zhou
` (2 preceding siblings ...)
2026-09-17 11:11 ` [PATCH v5 3/4] dt-bindings: thermal: loongson,ls2k-thermal: Add compatible for Loongson-2K0300 Binbin Zhou
@ 2026-09-17 11:15 ` Binbin Zhou
2026-09-18 17:02 ` Daniel Lezcano
3 siblings, 1 reply; 7+ messages in thread
From: Binbin Zhou @ 2026-09-17 11:15 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Yinbo Zhu, zhanghongchen, Rafael J . Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba
Cc: Huacai Chen, devicetree, linux-pm, Binbin Zhou
The Loongson-2K0300 thermal sensor uses a 10-bit ADC and requires
per-chip calibration. The calibration offset is stored in the CHIP ID
registers, which are accessed via syscon. The driver reads this offset
and applies it when converting the raw ADC value to millicelsius.
To handle old fuse versions that cannot be calibrated correctly, the
driver includes a fallback formula and a validity check. Once invalid
data is detected, the driver falls back to the old formula for future
reads and warns the user.
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
drivers/thermal/loongson2_thermal.c | 94 ++++++++++++++++++++++++++++-
1 file changed, 92 insertions(+), 2 deletions(-)
diff --git a/drivers/thermal/loongson2_thermal.c b/drivers/thermal/loongson2_thermal.c
index fb4793a9bc55..8930a8a75da7 100644
--- a/drivers/thermal/loongson2_thermal.c
+++ b/drivers/thermal/loongson2_thermal.c
@@ -2,9 +2,11 @@
/*
* Author: zhanghongchen <zhanghongchen@loongson.cn>
* Yinbo Zhu <zhuyinbo@loongson.cn>
+ * Binbin Zhou <zhoubinbin@loongson.cn>
* Copyright (C) 2022-2023 Loongson Technology Corporation Limited
*/
+#include <linux/bitfield.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/minmax.h>
@@ -13,6 +15,9 @@
#include <linux/property.h>
#include <linux/thermal.h>
#include <linux/units.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/syscore_ops.h>
#include "thermal_hwmon.h"
@@ -22,18 +27,34 @@
#define LOONGSON2_THSENS_CTRL_LOW_REG 0x8
#define LOONGSON2_THSENS_STATUS_REG 0x10
#define LOONGSON2_THSENS_OUT_REG 0x14
+#define LOONGSON2_THSENS_CFG_REG 0x18
#define LOONGSON2_THSENS_INT_LO BIT(0)
#define LOONGSON2_THSENS_INT_HIGH BIT(1)
#define LOONGSON2_THSENS_INT_EN (LOONGSON2_THSENS_INT_LO | \
LOONGSON2_THSENS_INT_HIGH)
-#define LOONGSON2_THSENS_OUT_MASK 0xFF
+#define LOONGSON2_THSENS_OUT_8B_MASK 0xFF
+#define LOONGSON2_THSENS_OUT_11B_MASK GENMASK(10, 0)
+
+#define LS2K0300_CHIP_ID0 0x10
+#define LS2K0300_CHIP_ID1 0x14
+#define LS2K0300_EXTERN_ID BIT(4)
+#define LS2K0300_ID0_VAL_MASK GENMASK(31, 20)
+#define LS2K0300_ID1_VAL_MASK GENMASK(15, 0)
+
+#define LS2K0300_COMP_VAL_MASK GENMASK(14, 0)
+#define LS2K0300_COMP_SIGN_BIT BIT(15)
+
+#define LS2K0300_LOWEST_VALID_TEMP (-55000)
+#define LS2K0300_HIGHEST_VALID_TEMP (125000)
/*
* This flag is used to indicate the temperature reading
* method of the Loongson-2K2000
*/
#define LS2K2000_THSENS_OUT_FLAG BIT(0)
+#define LS2K0300_CHIP_ID_FLAG BIT(1)
+#define LS2K0300_OLD_FUSE_FLAG BIT(2)
struct loongson2_thermal_chip_data {
unsigned int thermal_sensor_sel;
@@ -42,8 +63,11 @@ struct loongson2_thermal_chip_data {
};
struct loongson2_thermal_data {
+ struct device *dev;
void __iomem *ctrl_reg;
void __iomem *temp_reg;
+ struct regmap *regmap_cfg;
+ u32 flags;
const struct loongson2_thermal_chip_data *chip_data;
};
@@ -71,13 +95,54 @@ static int loongson2_thermal_set(struct loongson2_thermal_data *data,
return 0;
}
+static int loongson2_2k0300_get_temp(struct thermal_zone_device *tz, int *temp)
+{
+ struct loongson2_thermal_data *tdata = thermal_zone_device_priv(tz);
+ int calib_data, calib_offset, temp_mc, raw_adc;
+ u32 chip_id0 = 0, chip_id1 = 0;
+
+ writel(0xff03, tdata->ctrl_reg + LOONGSON2_THSENS_CFG_REG);
+ raw_adc = FIELD_GET(LOONGSON2_THSENS_OUT_11B_MASK,
+ readl(tdata->ctrl_reg + LOONGSON2_THSENS_OUT_REG));
+
+ if (tdata->flags & LS2K0300_OLD_FUSE_FLAG) {
+ *temp = raw_adc * 569 - 394700;
+ return 0;
+ }
+
+ regmap_read(tdata->regmap_cfg, LS2K0300_CHIP_ID0, &chip_id0);
+ regmap_read(tdata->regmap_cfg, LS2K0300_CHIP_ID1, &chip_id1);
+
+ if (chip_id0 & LS2K0300_EXTERN_ID) {
+ calib_data = FIELD_GET(LS2K0300_ID1_VAL_MASK, chip_id1);
+ calib_offset = FIELD_GET(LS2K0300_COMP_VAL_MASK, calib_data);
+ if (calib_data & LS2K0300_COMP_SIGN_BIT)
+ calib_offset = -calib_offset;
+ } else {
+ calib_data = FIELD_GET(LS2K0300_ID0_VAL_MASK, chip_id0);
+ calib_offset = FIELD_GET(LS2K0300_COMP_VAL_MASK, calib_data);
+ }
+
+ temp_mc = (raw_adc + calib_offset) * 570 - 394700;
+
+ /* For old fuse which can not read right thermal data */
+ if (temp_mc < LS2K0300_LOWEST_VALID_TEMP || temp_mc > LS2K0300_HIGHEST_VALID_TEMP) {
+ dev_warn_once(tdata->dev, "It's an old fuse, thermal %d is not right\n", temp_mc);
+ tdata->flags |= LS2K0300_OLD_FUSE_FLAG;
+ temp_mc = raw_adc * 569 - 394700;
+ }
+ *temp = temp_mc;
+
+ return 0;
+}
+
static int loongson2_2k1000_get_temp(struct thermal_zone_device *tz, int *temp)
{
int val;
struct loongson2_thermal_data *data = thermal_zone_device_priv(tz);
val = readl(data->ctrl_reg + LOONGSON2_THSENS_OUT_REG);
- *temp = ((val & LOONGSON2_THSENS_OUT_MASK) - HECTO) * KILO;
+ *temp = ((val & LOONGSON2_THSENS_OUT_8B_MASK) - HECTO) * KILO;
return 0;
}
@@ -112,6 +177,11 @@ static int loongson2_thermal_set_trips(struct thermal_zone_device *tz, int low,
return loongson2_thermal_set(data, low/MILLI, high/MILLI, true);
}
+static const struct thermal_zone_device_ops loongson2_2k0300_of_thermal_ops = {
+ .get_temp = loongson2_2k0300_get_temp,
+ .set_trips = loongson2_thermal_set_trips,
+};
+
static const struct thermal_zone_device_ops loongson2_2k1000_of_thermal_ops = {
.get_temp = loongson2_2k1000_get_temp,
.set_trips = loongson2_thermal_set_trips,
@@ -134,6 +204,8 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
return -ENOMEM;
data->chip_data = device_get_match_data(dev);
+ data->flags = data->chip_data->flags;
+ data->dev = dev;
data->ctrl_reg = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(data->ctrl_reg))
@@ -146,6 +218,14 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
return PTR_ERR(data->temp_reg);
}
+ /* The chip id register is needed for Loongson-2K0300 */
+ if (data->chip_data->flags & LS2K0300_CHIP_ID_FLAG) {
+ data->regmap_cfg =
+ syscon_regmap_lookup_by_phandle(dev->of_node, "loongson,chipid");
+ if (IS_ERR(data->regmap_cfg))
+ return PTR_ERR(data->regmap_cfg);
+ }
+
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
@@ -178,6 +258,12 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
return 0;
}
+static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k0300_data = {
+ .thermal_sensor_sel = 0,
+ .flags = LS2K0300_CHIP_ID_FLAG,
+ .thermal_ops = &loongson2_2k0300_of_thermal_ops,
+};
+
static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k1000_data = {
.thermal_sensor_sel = 0,
.flags = 0,
@@ -191,6 +277,10 @@ static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k2000_data
};
static const struct of_device_id of_loongson2_thermal_match[] = {
+ {
+ .compatible = "loongson,ls2k0300-thermal",
+ .data = &loongson2_thermal_ls2k0300_data,
+ },
{
.compatible = "loongson,ls2k1000-thermal",
.data = &loongson2_thermal_ls2k1000_data,
--
2.52.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v5 4/4] thermal/drivers/loongson2: Add support for Loongson-2K0300
2026-09-17 11:15 ` [PATCH v5 4/4] thermal/drivers/loongson2: Add support " Binbin Zhou
@ 2026-09-18 17:02 ` Daniel Lezcano
2026-09-20 1:48 ` Binbin Zhou
0 siblings, 1 reply; 7+ messages in thread
From: Daniel Lezcano @ 2026-09-18 17:02 UTC (permalink / raw)
To: Binbin Zhou, Binbin Zhou, Huacai Chen, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Yinbo Zhu, zhanghongchen,
Rafael J . Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba
Cc: Huacai Chen, devicetree, linux-pm
Hi Binbin,
On 9/17/26 13:15, Binbin Zhou wrote:
> The Loongson-2K0300 thermal sensor uses a 10-bit ADC and requires
The commit message says this is a 10-bit ADC, while the code uses bits
[10:0]. The 2K0300 user manual also describes Thsens_val[10:0], i.e. an
11-bit value. Should this say 11-bit instead?
> per-chip calibration. The calibration offset is stored in the CHIP ID
> registers, which are accessed via syscon. The driver reads this offset
> and applies it when converting the raw ADC value to millicelsius.
>
> To handle old fuse versions that cannot be calibrated correctly, the
> driver includes a fallback formula and a validity check. Once invalid
> data is detected, the driver falls back to the old formula for future
> reads and warns the user.
>
> Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
> ---
> drivers/thermal/loongson2_thermal.c | 94 ++++++++++++++++++++++++++++-
> 1 file changed, 92 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/thermal/loongson2_thermal.c b/drivers/thermal/loongson2_thermal.c
> index fb4793a9bc55..8930a8a75da7 100644
> --- a/drivers/thermal/loongson2_thermal.c
> +++ b/drivers/thermal/loongson2_thermal.c
> @@ -2,9 +2,11 @@
> /*
> * Author: zhanghongchen <zhanghongchen@loongson.cn>
> * Yinbo Zhu <zhuyinbo@loongson.cn>
> + * Binbin Zhou <zhoubinbin@loongson.cn>
> * Copyright (C) 2022-2023 Loongson Technology Corporation Limited
> */
>
> +#include <linux/bitfield.h>
> #include <linux/interrupt.h>
> #include <linux/io.h>
> #include <linux/minmax.h>
> @@ -13,6 +15,9 @@
> #include <linux/property.h>
> #include <linux/thermal.h>
> #include <linux/units.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
> +#include <linux/syscore_ops.h>
Is it enabled ?
>
> #include "thermal_hwmon.h"
>
> @@ -22,18 +27,34 @@
> #define LOONGSON2_THSENS_CTRL_LOW_REG 0x8
> #define LOONGSON2_THSENS_STATUS_REG 0x10
> #define LOONGSON2_THSENS_OUT_REG 0x14
> +#define LOONGSON2_THSENS_CFG_REG 0x18
>
> #define LOONGSON2_THSENS_INT_LO BIT(0)
> #define LOONGSON2_THSENS_INT_HIGH BIT(1)
> #define LOONGSON2_THSENS_INT_EN (LOONGSON2_THSENS_INT_LO | \
> LOONGSON2_THSENS_INT_HIGH)
> -#define LOONGSON2_THSENS_OUT_MASK 0xFF
> +#define LOONGSON2_THSENS_OUT_8B_MASK 0xFF
> +#define LOONGSON2_THSENS_OUT_11B_MASK GENMASK(10, 0)
> +
> +#define LS2K0300_CHIP_ID0 0x10
> +#define LS2K0300_CHIP_ID1 0x14
> +#define LS2K0300_EXTERN_ID BIT(4)
> +#define LS2K0300_ID0_VAL_MASK GENMASK(31, 20)
> +#define LS2K0300_ID1_VAL_MASK GENMASK(15, 0)
> +
> +#define LS2K0300_COMP_VAL_MASK GENMASK(14, 0)
> +#define LS2K0300_COMP_SIGN_BIT BIT(15)
> +
> +#define LS2K0300_LOWEST_VALID_TEMP (-55000)
> +#define LS2K0300_HIGHEST_VALID_TEMP (125000)
>
> /*
> * This flag is used to indicate the temperature reading
> * method of the Loongson-2K2000
> */
> #define LS2K2000_THSENS_OUT_FLAG BIT(0)
> +#define LS2K0300_CHIP_ID_FLAG BIT(1)
> +#define LS2K0300_OLD_FUSE_FLAG BIT(2)
>
> struct loongson2_thermal_chip_data {
> unsigned int thermal_sensor_sel;
> @@ -42,8 +63,11 @@ struct loongson2_thermal_chip_data {
> };
>
> struct loongson2_thermal_data {
> + struct device *dev;
> void __iomem *ctrl_reg;
> void __iomem *temp_reg;
> + struct regmap *regmap_cfg;
> + u32 flags;
> const struct loongson2_thermal_chip_data *chip_data;
> };
>
> @@ -71,13 +95,54 @@ static int loongson2_thermal_set(struct loongson2_thermal_data *data,
> return 0;
> }
>
> +static int loongson2_2k0300_get_temp(struct thermal_zone_device *tz, int *temp)
> +{
> + struct loongson2_thermal_data *tdata = thermal_zone_device_priv(tz);
> + int calib_data, calib_offset, temp_mc, raw_adc;
> + u32 chip_id0 = 0, chip_id1 = 0;
> +
> + writel(0xff03, tdata->ctrl_reg + LOONGSON2_THSENS_CFG_REG);
Please no litterals or magic values in the code. Add a define with a
self-explanatory names and a comment if it makes sense (there are other
places in the code to be checked).
> + raw_adc = FIELD_GET(LOONGSON2_THSENS_OUT_11B_MASK,
> + readl(tdata->ctrl_reg + LOONGSON2_THSENS_OUT_REG));
Why is it done at every read and not at probe time ?
> +
> + if (tdata->flags & LS2K0300_OLD_FUSE_FLAG) {
> + *temp = raw_adc * 569 - 394700;
no litterals ...
and don't repeat the formula, write a function for it
> + return 0;
> + }
> +
> + regmap_read(tdata->regmap_cfg, LS2K0300_CHIP_ID0, &chip_id0);
> + regmap_read(tdata->regmap_cfg, LS2K0300_CHIP_ID1, &chip_id1);
The return values of regmap_read() are ignored here. If accessing the
CHIP ID registers fails, the driver will silently use zero or partially
initialized calibration data and may report a plausible but incorrect
temperature. Could you propagate the error instead?
> + if (chip_id0 & LS2K0300_EXTERN_ID) {
> + calib_data = FIELD_GET(LS2K0300_ID1_VAL_MASK, chip_id1);
> + calib_offset = FIELD_GET(LS2K0300_COMP_VAL_MASK, calib_data);
> + if (calib_data & LS2K0300_COMP_SIGN_BIT)
> + calib_offset = -calib_offset;
> + } else {
> + calib_data = FIELD_GET(LS2K0300_ID0_VAL_MASK, chip_id0);
> + calib_offset = FIELD_GET(LS2K0300_COMP_VAL_MASK, calib_data);
> + }
> +
> + temp_mc = (raw_adc + calib_offset) * 570 - 394700;
no litterals + formula ...
> +
> + /* For old fuse which can not read right thermal data */
> + if (temp_mc < LS2K0300_LOWEST_VALID_TEMP || temp_mc > LS2K0300_HIGHEST_VALID_TEMP) {
> + dev_warn_once(tdata->dev, "It's an old fuse, thermal %d is not right\n", temp_mc);
Improve the message please
> + tdata->flags |= LS2K0300_OLD_FUSE_FLAG;
> + temp_mc = raw_adc * 569 - 394700;
> + }
> + *temp = temp_mc;
> +
> + return 0;
> +}
> +
> static int loongson2_2k1000_get_temp(struct thermal_zone_device *tz, int *temp)
> {
> int val;
> struct loongson2_thermal_data *data = thermal_zone_device_priv(tz);
>
> val = readl(data->ctrl_reg + LOONGSON2_THSENS_OUT_REG);
> - *temp = ((val & LOONGSON2_THSENS_OUT_MASK) - HECTO) * KILO;
> + *temp = ((val & LOONGSON2_THSENS_OUT_8B_MASK) - HECTO) * KILO;
>
> return 0;
> }
> @@ -112,6 +177,11 @@ static int loongson2_thermal_set_trips(struct thermal_zone_device *tz, int low,
> return loongson2_thermal_set(data, low/MILLI, high/MILLI, true);
> }
>
> +static const struct thermal_zone_device_ops loongson2_2k0300_of_thermal_ops = {
> + .get_temp = loongson2_2k0300_get_temp,
> + .set_trips = loongson2_thermal_set_trips,
> +};
> +
> static const struct thermal_zone_device_ops loongson2_2k1000_of_thermal_ops = {
> .get_temp = loongson2_2k1000_get_temp,
> .set_trips = loongson2_thermal_set_trips,
Can you confirm the set_trips function is the same for 2k1000 and 2k0300 ?
> @@ -134,6 +204,8 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
> return -ENOMEM;
>
> data->chip_data = device_get_match_data(dev);
> + data->flags = data->chip_data->flags;
> + data->dev = dev;
>
> data->ctrl_reg = devm_platform_ioremap_resource(pdev, 0);
> if (IS_ERR(data->ctrl_reg))
> @@ -146,6 +218,14 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
> return PTR_ERR(data->temp_reg);
> }
>
> + /* The chip id register is needed for Loongson-2K0300 */
> + if (data->chip_data->flags & LS2K0300_CHIP_ID_FLAG) {
> + data->regmap_cfg =
> + syscon_regmap_lookup_by_phandle(dev->of_node, "loongson,chipid");
> + if (IS_ERR(data->regmap_cfg))
> + return PTR_ERR(data->regmap_cfg);
> + }
> +
> irq = platform_get_irq(pdev, 0);
> if (irq < 0)
> return irq;
> @@ -178,6 +258,12 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
> return 0;
> }
>
> +static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k0300_data = {
> + .thermal_sensor_sel = 0,
> + .flags = LS2K0300_CHIP_ID_FLAG,
> + .thermal_ops = &loongson2_2k0300_of_thermal_ops,
> +};
> +
> static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k1000_data = {
> .thermal_sensor_sel = 0,
> .flags = 0,
> @@ -191,6 +277,10 @@ static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k2000_data
> };
>
> static const struct of_device_id of_loongson2_thermal_match[] = {
> + {
> + .compatible = "loongson,ls2k0300-thermal",
> + .data = &loongson2_thermal_ls2k0300_data,
> + },
> {
> .compatible = "loongson,ls2k1000-thermal",
> .data = &loongson2_thermal_ls2k1000_data,
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 4/4] thermal/drivers/loongson2: Add support for Loongson-2K0300
2026-09-18 17:02 ` Daniel Lezcano
@ 2026-09-20 1:48 ` Binbin Zhou
0 siblings, 0 replies; 7+ messages in thread
From: Binbin Zhou @ 2026-09-20 1:48 UTC (permalink / raw)
To: Daniel Lezcano
Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Yinbo Zhu, zhanghongchen, Rafael J . Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Huacai Chen, devicetree,
linux-pm
Hi Daniel:
Thanks for your reply.
On Sat, Sep 19, 2026 at 1:02 AM Daniel Lezcano
<daniel.lezcano@oss.qualcomm.com> wrote:
>
>
> Hi Binbin,
>
>
> On 9/17/26 13:15, Binbin Zhou wrote:
> > The Loongson-2K0300 thermal sensor uses a 10-bit ADC and requires
>
> The commit message says this is a 10-bit ADC, while the code uses bits
> [10:0]. The 2K0300 user manual also describes Thsens_val[10:0], i.e. an
> 11-bit value. Should this say 11-bit instead?
>
> > per-chip calibration. The calibration offset is stored in the CHIP ID
> > registers, which are accessed via syscon. The driver reads this offset
> > and applies it when converting the raw ADC value to millicelsius.
> >
> > To handle old fuse versions that cannot be calibrated correctly, the
> > driver includes a fallback formula and a validity check. Once invalid
> > data is detected, the driver falls back to the old formula for future
> > reads and warns the user.
> >
> > Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
> > ---
> > drivers/thermal/loongson2_thermal.c | 94 ++++++++++++++++++++++++++++-
> > 1 file changed, 92 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/thermal/loongson2_thermal.c b/drivers/thermal/loongson2_thermal.c
> > index fb4793a9bc55..8930a8a75da7 100644
> > --- a/drivers/thermal/loongson2_thermal.c
> > +++ b/drivers/thermal/loongson2_thermal.c
> > @@ -2,9 +2,11 @@
> > /*
> > * Author: zhanghongchen <zhanghongchen@loongson.cn>
> > * Yinbo Zhu <zhuyinbo@loongson.cn>
> > + * Binbin Zhou <zhoubinbin@loongson.cn>
> > * Copyright (C) 2022-2023 Loongson Technology Corporation Limited
> > */
> >
> > +#include <linux/bitfield.h>
> > #include <linux/interrupt.h>
> > #include <linux/io.h>
> > #include <linux/minmax.h>
> > @@ -13,6 +15,9 @@
> > #include <linux/property.h>
> > #include <linux/thermal.h>
> > #include <linux/units.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/regmap.h>
> > +#include <linux/syscore_ops.h>
>
> Is it enabled ?
Yes, it's redundant; it must have been left over from my previous testing.
>
> >
> > #include "thermal_hwmon.h"
> >
> > @@ -22,18 +27,34 @@
> > #define LOONGSON2_THSENS_CTRL_LOW_REG 0x8
> > #define LOONGSON2_THSENS_STATUS_REG 0x10
> > #define LOONGSON2_THSENS_OUT_REG 0x14
> > +#define LOONGSON2_THSENS_CFG_REG 0x18
> >
> > #define LOONGSON2_THSENS_INT_LO BIT(0)
> > #define LOONGSON2_THSENS_INT_HIGH BIT(1)
> > #define LOONGSON2_THSENS_INT_EN (LOONGSON2_THSENS_INT_LO | \
> > LOONGSON2_THSENS_INT_HIGH)
> > -#define LOONGSON2_THSENS_OUT_MASK 0xFF
> > +#define LOONGSON2_THSENS_OUT_8B_MASK 0xFF
> > +#define LOONGSON2_THSENS_OUT_11B_MASK GENMASK(10, 0)
> > +
> > +#define LS2K0300_CHIP_ID0 0x10
> > +#define LS2K0300_CHIP_ID1 0x14
> > +#define LS2K0300_EXTERN_ID BIT(4)
> > +#define LS2K0300_ID0_VAL_MASK GENMASK(31, 20)
> > +#define LS2K0300_ID1_VAL_MASK GENMASK(15, 0)
> > +
> > +#define LS2K0300_COMP_VAL_MASK GENMASK(14, 0)
> > +#define LS2K0300_COMP_SIGN_BIT BIT(15)
> > +
> > +#define LS2K0300_LOWEST_VALID_TEMP (-55000)
> > +#define LS2K0300_HIGHEST_VALID_TEMP (125000)
> >
> > /*
> > * This flag is used to indicate the temperature reading
> > * method of the Loongson-2K2000
> > */
> > #define LS2K2000_THSENS_OUT_FLAG BIT(0)
> > +#define LS2K0300_CHIP_ID_FLAG BIT(1)
> > +#define LS2K0300_OLD_FUSE_FLAG BIT(2)
> >
> > struct loongson2_thermal_chip_data {
> > unsigned int thermal_sensor_sel;
> > @@ -42,8 +63,11 @@ struct loongson2_thermal_chip_data {
> > };
> >
> > struct loongson2_thermal_data {
> > + struct device *dev;
> > void __iomem *ctrl_reg;
> > void __iomem *temp_reg;
> > + struct regmap *regmap_cfg;
> > + u32 flags;
> > const struct loongson2_thermal_chip_data *chip_data;
> > };
> >
> > @@ -71,13 +95,54 @@ static int loongson2_thermal_set(struct loongson2_thermal_data *data,
> > return 0;
> > }
> >
> > +static int loongson2_2k0300_get_temp(struct thermal_zone_device *tz, int *temp)
> > +{
> > + struct loongson2_thermal_data *tdata = thermal_zone_device_priv(tz);
> > + int calib_data, calib_offset, temp_mc, raw_adc;
> > + u32 chip_id0 = 0, chip_id1 = 0;
> > +
> > + writel(0xff03, tdata->ctrl_reg + LOONGSON2_THSENS_CFG_REG);
>
> Please no litterals or magic values in the code. Add a define with a
> self-explanatory names and a comment if it makes sense (there are other
> places in the code to be checked).
ok. I will do it.
>
> > + raw_adc = FIELD_GET(LOONGSON2_THSENS_OUT_11B_MASK,
> > + readl(tdata->ctrl_reg + LOONGSON2_THSENS_OUT_REG));
>
> Why is it done at every read and not at probe time ?
`raw_adc` represents the initial temperature value, which, of course,
needs to be read each time.
>
> > +
> > + if (tdata->flags & LS2K0300_OLD_FUSE_FLAG) {
> > + *temp = raw_adc * 569 - 394700;
>
> no litterals ...
>
> and don't repeat the formula, write a function for it
>
> > + return 0;
> > + }
> > +
> > + regmap_read(tdata->regmap_cfg, LS2K0300_CHIP_ID0, &chip_id0);
> > + regmap_read(tdata->regmap_cfg, LS2K0300_CHIP_ID1, &chip_id1);
>
> The return values of regmap_read() are ignored here. If accessing the
> CHIP ID registers fails, the driver will silently use zero or partially
> initialized calibration data and may report a plausible but incorrect
> temperature. Could you propagate the error instead?
Okay, and as for this static calibration data, I'll try to move it to
`probe()` (to be read only once) to avoid repeated polling in the hot
path.
Like:
static int loongson2_2k0300_read_calib(struct loongson2_thermal_data *data)
{
u32 chip_id0, chip_id1;
int calib_data, calib_offset;
int ret;
ret = regmap_read(data->regmap_cfg, LS2K0300_CHIP_ID0, &chip_id0);
if (ret)
return ret;
ret = regmap_read(data->regmap_cfg, LS2K0300_CHIP_ID1, &chip_id1);
if (ret)
return ret;
if (chip_id0 & LS2K0300_EXTERN_ID) {
calib_data = FIELD_GET(LS2K0300_ID1_VAL_MASK, chip_id1);
calib_offset = FIELD_GET(LS2K0300_COMP_VAL_MASK, calib_data);
if (calib_data & LS2K0300_COMP_SIGN_BIT)
calib_offset = -calib_offset;
} else {
calib_data = FIELD_GET(LS2K0300_ID0_VAL_MASK, chip_id0);
calib_offset = FIELD_GET(LS2K0300_COMP_VAL_MASK, calib_data);
}
data->calib_offset = calib_offset;
return 0;
}
static void loongson2_2k0300_detect_old_fuse(struct
loongson2_thermal_data *data)
{
int raw_adc, temp_mc;
writel(0xff03, data->ctrl_reg + LOONGSON2_THSENS_CFG_REG);
raw_adc = FIELD_GET(LOONGSON2_THSENS_OUT_11B_MASK,
readl(data->ctrl_reg + LOONGSON2_THSENS_OUT_REG));
temp_mc = (raw_adc + data->calib_offset) * 570 - 394700;
if (temp_mc < LS2K0300_LOWEST_VALID_TEMP ||
temp_mc > LS2K0300_HIGHEST_VALID_TEMP)
data->flags |= LS2K0300_OLD_FUSE_FLAG;
}
> > + if (chip_id0 & LS2K0300_EXTERN_ID) {
> > + calib_data = FIELD_GET(LS2K0300_ID1_VAL_MASK, chip_id1);
> > + calib_offset = FIELD_GET(LS2K0300_COMP_VAL_MASK, calib_data);
> > + if (calib_data & LS2K0300_COMP_SIGN_BIT)
> > + calib_offset = -calib_offset;
> > + } else {
> > + calib_data = FIELD_GET(LS2K0300_ID0_VAL_MASK, chip_id0);
> > + calib_offset = FIELD_GET(LS2K0300_COMP_VAL_MASK, calib_data);
> > + }
> > +
> > + temp_mc = (raw_adc + calib_offset) * 570 - 394700;
>
> no litterals + formula ...
>
> > +
> > + /* For old fuse which can not read right thermal data */
> > + if (temp_mc < LS2K0300_LOWEST_VALID_TEMP || temp_mc > LS2K0300_HIGHEST_VALID_TEMP) {
> > + dev_warn_once(tdata->dev, "It's an old fuse, thermal %d is not right\n", temp_mc);
>
> Improve the message please
I will remove this prompt and move this section to
`loongson2_2k0300_detect_old_fuse()` (as shown above), calling it
directly from `probe()`.
>
> > + tdata->flags |= LS2K0300_OLD_FUSE_FLAG;
> > + temp_mc = raw_adc * 569 - 394700;
> > + }
> > + *temp = temp_mc;
> > +
> > + return 0;
> > +}
> > +
> > static int loongson2_2k1000_get_temp(struct thermal_zone_device *tz, int *temp)
> > {
> > int val;
> > struct loongson2_thermal_data *data = thermal_zone_device_priv(tz);
> >
> > val = readl(data->ctrl_reg + LOONGSON2_THSENS_OUT_REG);
> > - *temp = ((val & LOONGSON2_THSENS_OUT_MASK) - HECTO) * KILO;
> > + *temp = ((val & LOONGSON2_THSENS_OUT_8B_MASK) - HECTO) * KILO;
> >
> > return 0;
> > }
> > @@ -112,6 +177,11 @@ static int loongson2_thermal_set_trips(struct thermal_zone_device *tz, int low,
> > return loongson2_thermal_set(data, low/MILLI, high/MILLI, true);
> > }
> >
> > +static const struct thermal_zone_device_ops loongson2_2k0300_of_thermal_ops = {
> > + .get_temp = loongson2_2k0300_get_temp,
> > + .set_trips = loongson2_thermal_set_trips,
> > +};
> > +
> > static const struct thermal_zone_device_ops loongson2_2k1000_of_thermal_ops = {
> > .get_temp = loongson2_2k1000_get_temp,
> > .set_trips = loongson2_thermal_set_trips,
>
> Can you confirm the set_trips function is the same for 2k1000 and 2k0300 ?
ok. I will check it.
>
> > @@ -134,6 +204,8 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
> > return -ENOMEM;
> >
> > data->chip_data = device_get_match_data(dev);
> > + data->flags = data->chip_data->flags;
> > + data->dev = dev;
> >
> > data->ctrl_reg = devm_platform_ioremap_resource(pdev, 0);
> > if (IS_ERR(data->ctrl_reg))
> > @@ -146,6 +218,14 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
> > return PTR_ERR(data->temp_reg);
> > }
> >
> > + /* The chip id register is needed for Loongson-2K0300 */
> > + if (data->chip_data->flags & LS2K0300_CHIP_ID_FLAG) {
> > + data->regmap_cfg =
> > + syscon_regmap_lookup_by_phandle(dev->of_node, "loongson,chipid");
> > + if (IS_ERR(data->regmap_cfg))
> > + return PTR_ERR(data->regmap_cfg);
> > + }
> > +
> > irq = platform_get_irq(pdev, 0);
> > if (irq < 0)
> > return irq;
> > @@ -178,6 +258,12 @@ static int loongson2_thermal_probe(struct platform_device *pdev)
> > return 0;
> > }
> >
> > +static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k0300_data = {
> > + .thermal_sensor_sel = 0,
> > + .flags = LS2K0300_CHIP_ID_FLAG,
> > + .thermal_ops = &loongson2_2k0300_of_thermal_ops,
> > +};
> > +
> > static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k1000_data = {
> > .thermal_sensor_sel = 0,
> > .flags = 0,
> > @@ -191,6 +277,10 @@ static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k2000_data
> > };
> >
> > static const struct of_device_id of_loongson2_thermal_match[] = {
> > + {
> > + .compatible = "loongson,ls2k0300-thermal",
> > + .data = &loongson2_thermal_ls2k0300_data,
> > + },
> > {
> > .compatible = "loongson,ls2k1000-thermal",
> > .data = &loongson2_thermal_ls2k1000_data,
>
--
Thanks.
Binbin
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-09-20 1:48 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-17 11:11 [PATCH v5 0/4] thermal: loongson2: Add support for Loongson-2K0300 SoC Binbin Zhou
2026-09-17 11:11 ` [PATCH v5 1/4] thermal/drivers/loongson2: Correct thermal sensor registration loop Binbin Zhou
2026-09-17 11:11 ` [PATCH v5 2/4] thermal/drivers/loongson2: Move thermal_ops to chip_data for SoC scalability Binbin Zhou
2026-09-17 11:11 ` [PATCH v5 3/4] dt-bindings: thermal: loongson,ls2k-thermal: Add compatible for Loongson-2K0300 Binbin Zhou
2026-09-17 11:15 ` [PATCH v5 4/4] thermal/drivers/loongson2: Add support " Binbin Zhou
2026-09-18 17:02 ` Daniel Lezcano
2026-09-20 1:48 ` Binbin Zhou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox