Devicetree
 help / color / mirror / Atom feed
* [PATCH v6 0/7] thermal/drivers: airoha: Add support for AN7583
@ 2026-07-02  9:48 Christian Marangi
  2026-07-02  9:48 ` [PATCH v6 1/7] thermal/drivers: airoha: fix copy paste error on clamp_t low temp Christian Marangi
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Christian Marangi @ 2026-07-02  9:48 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Christian Marangi,
	Lorenzo Bianconi, devicetree, linux-kernel, linux-pm

This small series implement all the required changes to
support Airoha AN7583 Thermal Sensor.

The SoC dropped the Monitor subsystem and only provide
temperature reading. Some generalization was required
to at least save the common code with also the help of
reg field API.

Changes v6:
- Add review tag to DT patch
- Add review tag to fix patch
- Rebase on top of linux-next
Changes v5:
- Fix alpabetical order in Documentation patch
- Address suggested change by AI Bot
Changes v4:
- Rebase on top of linux-next
Changes v3:
- Property use chip-scu for thermal sensor
Changes v2:
- Update DT schema patch to implement dedicated schema

Christian Marangi (7):
  thermal/drivers: airoha: fix copy paste error on clamp_t low temp
  thermal/drivers: airoha: fix copy paste error for sen internal
  thermal/drivers: airoha: Convert to regmap API
  thermal/drivers: airoha: Generalize probe function
  thermal/drivers: airoha: Generalize get_thermal_ADC and set_mux
    function
  dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC
  thermal/drivers: airoha: Add support for AN7583 Thermal Sensor

 .../bindings/arm/airoha,en7581-chip-scu.yaml  |  14 +
 drivers/thermal/airoha_thermal.c              | 380 +++++++++++++++---
 2 files changed, 327 insertions(+), 67 deletions(-)

-- 
2.53.0


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

* [PATCH v6 1/7] thermal/drivers: airoha: fix copy paste error on clamp_t low temp
  2026-07-02  9:48 [PATCH v6 0/7] thermal/drivers: airoha: Add support for AN7583 Christian Marangi
@ 2026-07-02  9:48 ` Christian Marangi
  2026-07-02 10:00   ` sashiko-bot
  2026-07-02  9:48 ` [PATCH v6 2/7] thermal/drivers: airoha: fix copy paste error for sen internal Christian Marangi
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Christian Marangi @ 2026-07-02  9:48 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Christian Marangi,
	Lorenzo Bianconi, devicetree, linux-kernel, linux-pm
  Cc: Wayen Yan

In airoha_thermal_set_trips, there is a copy paste error on clamping the
value for the low trip temp point. Fix it to the correct value and actually
clamp for the low variable.

Fixes: 42de37f40e1b ("thermal/drivers: Add support for Airoha EN7581 thermal sensor")
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Wayen Yan <win847@gmail.com>
---
 drivers/thermal/airoha_thermal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
index b9fd6bfc88e5..439aa011b75c 100644
--- a/drivers/thermal/airoha_thermal.c
+++ b/drivers/thermal/airoha_thermal.c
@@ -273,7 +273,7 @@ static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
 
 	if (low != -INT_MAX) {
 		/* Validate low and clamp it to a supported value */
-		low = clamp_t(int, high, RAW_TO_TEMP(priv, 0),
+		low = clamp_t(int, low, RAW_TO_TEMP(priv, 0),
 			      RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
 
 		/* We offset the low temp of 1°C to trigger correct event */
-- 
2.53.0


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

* [PATCH v6 2/7] thermal/drivers: airoha: fix copy paste error for sen internal
  2026-07-02  9:48 [PATCH v6 0/7] thermal/drivers: airoha: Add support for AN7583 Christian Marangi
  2026-07-02  9:48 ` [PATCH v6 1/7] thermal/drivers: airoha: fix copy paste error on clamp_t low temp Christian Marangi
@ 2026-07-02  9:48 ` Christian Marangi
  2026-07-02 10:07   ` sashiko-bot
  2026-07-02  9:48 ` [PATCH v6 3/7] thermal/drivers: airoha: Convert to regmap API Christian Marangi
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Christian Marangi @ 2026-07-02  9:48 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Christian Marangi,
	Lorenzo Bianconi, devicetree, linux-kernel, linux-pm
  Cc: Wayen Yan

In airoha_thermal_setup_monitor there is a copy paste error on configuring
the internval for temp monitor. Fix the error and use the correct mask for
the sen interval for the EN7581_TEMPMONCTL2 register.

Fixes: 42de37f40e1b ("thermal/drivers: Add support for Airoha EN7581 thermal sensor")
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Wayen Yan <win847@gmail.com>
---
 drivers/thermal/airoha_thermal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
index 439aa011b75c..829a7327fc40 100644
--- a/drivers/thermal/airoha_thermal.c
+++ b/drivers/thermal/airoha_thermal.c
@@ -403,7 +403,7 @@ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
 	 * sen interval is 379 * 52.715us = 19.97ms
 	 */
 	writel(FIELD_PREP(EN7581_FILT_INTERVAL, 1) |
-	       FIELD_PREP(EN7581_FILT_INTERVAL, 379),
+	       FIELD_PREP(EN7581_SEN_INTERVAL, 379),
 	       priv->base + EN7581_TEMPMONCTL2);
 
 	/* AHB poll is set to 146 * 68.64 = 10.02us */
-- 
2.53.0


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

* [PATCH v6 3/7] thermal/drivers: airoha: Convert to regmap API
  2026-07-02  9:48 [PATCH v6 0/7] thermal/drivers: airoha: Add support for AN7583 Christian Marangi
  2026-07-02  9:48 ` [PATCH v6 1/7] thermal/drivers: airoha: fix copy paste error on clamp_t low temp Christian Marangi
  2026-07-02  9:48 ` [PATCH v6 2/7] thermal/drivers: airoha: fix copy paste error for sen internal Christian Marangi
@ 2026-07-02  9:48 ` Christian Marangi
  2026-07-02 10:16   ` sashiko-bot
  2026-07-02  9:48 ` [PATCH v6 4/7] thermal/drivers: airoha: Generalize probe function Christian Marangi
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Christian Marangi @ 2026-07-02  9:48 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Christian Marangi,
	Lorenzo Bianconi, devicetree, linux-kernel, linux-pm

In preparation for support of Airoha AN7583, convert the driver to
regmap API. This is needed as Airoha AN7583 will be based on syscon
regmap.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 drivers/thermal/airoha_thermal.c | 77 +++++++++++++++++++-------------
 1 file changed, 45 insertions(+), 32 deletions(-)

diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
index 829a7327fc40..b63893a8997a 100644
--- a/drivers/thermal/airoha_thermal.c
+++ b/drivers/thermal/airoha_thermal.c
@@ -194,7 +194,7 @@
 #define AIROHA_MAX_SAMPLES			6
 
 struct airoha_thermal_priv {
-	void __iomem *base;
+	struct regmap *map;
 	struct regmap *chip_scu;
 	struct resource scu_adc_res;
 
@@ -265,8 +265,8 @@ static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
 			       RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
 
 		/* We offset the high temp of 1°C to trigger correct event */
-		writel(TEMP_TO_RAW(priv, high) >> 4,
-		       priv->base + EN7581_TEMPOFFSETH);
+		regmap_write(priv->map, EN7581_TEMPOFFSETH,
+			     TEMP_TO_RAW(priv, high) >> 4);
 
 		enable_monitor = true;
 	}
@@ -277,15 +277,15 @@ static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
 			      RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
 
 		/* We offset the low temp of 1°C to trigger correct event */
-		writel(TEMP_TO_RAW(priv, low) >> 4,
-		       priv->base + EN7581_TEMPOFFSETL);
+		regmap_write(priv->map, EN7581_TEMPOFFSETL,
+			     TEMP_TO_RAW(priv, low) >> 4);
 
 		enable_monitor = true;
 	}
 
 	/* Enable sensor 0 monitor after trip are set */
 	if (enable_monitor)
-		writel(EN7581_SENSE0_EN, priv->base + EN7581_TEMPMONCTL0);
+		regmap_write(priv->map, EN7581_TEMPMONCTL0, EN7581_SENSE0_EN);
 
 	return 0;
 }
@@ -300,9 +300,9 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data)
 	struct airoha_thermal_priv *priv = data;
 	enum thermal_notify_event event;
 	bool update = false;
-	u32 status;
+	u32 status = 0;
 
-	status = readl(priv->base + EN7581_TEMPMONINTSTS);
+	regmap_read(priv->map, EN7581_TEMPMONINTSTS, &status);
 	switch (status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0)) {
 	case EN7581_HOFSINTSTS0:
 		event = THERMAL_TRIP_VIOLATED;
@@ -318,7 +318,7 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data)
 	}
 
 	/* Reset Interrupt */
-	writel(status, priv->base + EN7581_TEMPMONINTSTS);
+	regmap_write(priv->map, EN7581_TEMPMONINTSTS, status);
 
 	if (update)
 		thermal_zone_device_update(priv->tz, event);
@@ -329,18 +329,19 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data)
 static void airoha_thermal_setup_adc_val(struct device *dev,
 					 struct airoha_thermal_priv *priv)
 {
-	u32 efuse_calib_info, cpu_sensor;
+	u32 efuse_calib_info = 0;
+	u32 cpu_sensor = 0;
 
 	/* Setup thermal sensor to ADC mode and setup the mux to DIODE1 */
 	airoha_init_thermal_ADC_mode(priv);
 	/* sleep 10 ms for ADC to enable */
 	usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
 
-	efuse_calib_info = readl(priv->base + EN7581_EFUSE_TEMP_OFFSET_REG);
+	regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info);
 	if (efuse_calib_info) {
 		priv->default_offset = FIELD_GET(EN7581_EFUSE_TEMP_OFFSET, efuse_calib_info);
 		/* Different slope are applied if the sensor is used for CPU or for package */
-		cpu_sensor = readl(priv->base + EN7581_EFUSE_TEMP_CPU_SENSOR_REG);
+		regmap_read(priv->map, EN7581_EFUSE_TEMP_CPU_SENSOR_REG, &cpu_sensor);
 		if (cpu_sensor) {
 			priv->default_slope = EN7581_SLOPE_X100_DIO_DEFAULT;
 			priv->init_temp = EN7581_INIT_TEMP_FTK_X10;
@@ -359,8 +360,8 @@ static void airoha_thermal_setup_adc_val(struct device *dev,
 static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
 {
 	/* Set measure mode */
-	writel(FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4),
-	       priv->base + EN7581_TEMPMSRCTL0);
+	regmap_write(priv->map, EN7581_TEMPMSRCTL0,
+		     FIELD_PREP(EN7581_MSRCTL0, EN7581_MSRCTL_6SAMPLE_MAX_MIX_AVG4));
 
 	/*
 	 * Configure ADC valid reading addr
@@ -375,15 +376,15 @@ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
 	 * We set valid instead of volt as we don't enable valid/volt
 	 * split reading and AHB read valid addr in such case.
 	 */
-	writel(priv->scu_adc_res.start + EN7581_DOUT_TADC,
-	       priv->base + EN7581_TEMPADCVALIDADDR);
+	regmap_write(priv->map, EN7581_TEMPADCVALIDADDR,
+		     priv->scu_adc_res.start + EN7581_DOUT_TADC);
 
 	/*
 	 * Configure valid bit on a fake value of bit 16. The ADC outputs
 	 * max of 2 bytes for voltage.
 	 */
-	writel(FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16),
-	       priv->base + EN7581_TEMPADCVALIDMASK);
+	regmap_write(priv->map, EN7581_TEMPADCVALIDMASK,
+		     FIELD_PREP(EN7581_ADV_RD_VALID_POS, 16));
 
 	/*
 	 * AHB supports max 12 bytes for ADC voltage. Shift the read
@@ -391,40 +392,52 @@ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
 	 * in the order of half a °C and is acceptable in the context
 	 * of triggering interrupt in critical condition.
 	 */
-	writel(FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4),
-	       priv->base + EN7581_TEMPADCVOLTAGESHIFT);
+	regmap_write(priv->map, EN7581_TEMPADCVOLTAGESHIFT,
+		     FIELD_PREP(EN7581_ADC_VOLTAGE_SHIFT, 4));
 
 	/* BUS clock is 300MHz counting unit is 3 * 68.64 * 256 = 52.715us */
-	writel(FIELD_PREP(EN7581_PERIOD_UNIT, 3),
-	       priv->base + EN7581_TEMPMONCTL1);
+	regmap_write(priv->map, EN7581_TEMPMONCTL1,
+		     FIELD_PREP(EN7581_PERIOD_UNIT, 3));
 
 	/*
 	 * filt interval is 1 * 52.715us = 52.715us,
 	 * sen interval is 379 * 52.715us = 19.97ms
 	 */
-	writel(FIELD_PREP(EN7581_FILT_INTERVAL, 1) |
-	       FIELD_PREP(EN7581_SEN_INTERVAL, 379),
-	       priv->base + EN7581_TEMPMONCTL2);
+	regmap_write(priv->map, EN7581_TEMPMONCTL2,
+		     FIELD_PREP(EN7581_FILT_INTERVAL, 1) |
+		     FIELD_PREP(EN7581_SEN_INTERVAL, 379));
 
 	/* AHB poll is set to 146 * 68.64 = 10.02us */
-	writel(FIELD_PREP(EN7581_ADC_POLL_INTVL, 146),
-	       priv->base + EN7581_TEMPAHBPOLL);
+	regmap_write(priv->map, EN7581_TEMPAHBPOLL,
+		     FIELD_PREP(EN7581_ADC_POLL_INTVL, 146));
 }
 
+static const struct regmap_config airoha_thermal_regmap_config = {
+	.reg_bits		= 32,
+	.reg_stride		= 4,
+	.val_bits		= 32,
+};
+
 static int airoha_thermal_probe(struct platform_device *pdev)
 {
 	struct airoha_thermal_priv *priv;
 	struct device_node *chip_scu_np;
 	struct device *dev = &pdev->dev;
+	void __iomem *base;
 	int irq, ret;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
-	priv->base = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(priv->base))
-		return PTR_ERR(priv->base);
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	priv->map = devm_regmap_init_mmio(dev, base,
+					  &airoha_thermal_regmap_config);
+	if (IS_ERR(priv->map))
+		return PTR_ERR(priv->map);
 
 	chip_scu_np = of_parse_phandle(dev->of_node, "airoha,chip-scu", 0);
 	if (!chip_scu_np)
@@ -462,8 +475,8 @@ static int airoha_thermal_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, priv);
 
 	/* Enable LOW and HIGH interrupt */
-	writel(EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0,
-	       priv->base + EN7581_TEMPMONINT);
+	regmap_write(priv->map, EN7581_TEMPMONINT,
+		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
 
 	return 0;
 }
-- 
2.53.0


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

* [PATCH v6 4/7] thermal/drivers: airoha: Generalize probe function
  2026-07-02  9:48 [PATCH v6 0/7] thermal/drivers: airoha: Add support for AN7583 Christian Marangi
                   ` (2 preceding siblings ...)
  2026-07-02  9:48 ` [PATCH v6 3/7] thermal/drivers: airoha: Convert to regmap API Christian Marangi
@ 2026-07-02  9:48 ` Christian Marangi
  2026-07-02 10:35   ` sashiko-bot
  2026-07-02  9:48 ` [PATCH v6 5/7] thermal/drivers: airoha: Generalize get_thermal_ADC and set_mux function Christian Marangi
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Christian Marangi @ 2026-07-02  9:48 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Christian Marangi,
	Lorenzo Bianconi, devicetree, linux-kernel, linux-pm

In preparation for support of Airoha AN7583, generalize the probe
function to address for the 2 SoC differece.

Implement a match_data struct where it's possible to define a more
specific probe and post_probe function and specific thermal ops and
pllrg protect value.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 drivers/thermal/airoha_thermal.c | 102 +++++++++++++++++++++++--------
 1 file changed, 75 insertions(+), 27 deletions(-)

diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
index b63893a8997a..ebb47ae5f2ce 100644
--- a/drivers/thermal/airoha_thermal.c
+++ b/drivers/thermal/airoha_thermal.c
@@ -198,12 +198,23 @@ struct airoha_thermal_priv {
 	struct regmap *chip_scu;
 	struct resource scu_adc_res;
 
+	u32 pllrg_protect;
+
 	struct thermal_zone_device *tz;
 	int init_temp;
 	int default_slope;
 	int default_offset;
 };
 
+struct airoha_thermal_soc_data {
+	u32 pllrg_protect;
+
+	const struct thermal_zone_device_ops *thdev_ops;
+	int (*probe)(struct platform_device *pdev,
+		     struct airoha_thermal_priv *priv);
+	int (*post_probe)(struct platform_device *pdev);
+};
+
 static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
 {
 	u32 val;
@@ -220,7 +231,8 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
 	regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
 
 	/* Give access to thermal regs */
-	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY);
+	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
+		     priv->pllrg_protect);
 	adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
 	regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
 
@@ -228,7 +240,7 @@ static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
 	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
 }
 
-static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
+static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
 {
 	struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
 	int min_value, max_value, avg_value, value;
@@ -253,7 +265,7 @@ static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
 	return 0;
 }
 
-static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
+static int en7581_thermal_set_trips(struct thermal_zone_device *tz, int low,
 				    int high)
 {
 	struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
@@ -290,12 +302,12 @@ static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
 	return 0;
 }
 
-static const struct thermal_zone_device_ops thdev_ops = {
-	.get_temp = airoha_thermal_get_temp,
-	.set_trips = airoha_thermal_set_trips,
+static const struct thermal_zone_device_ops en7581_thdev_ops = {
+	.get_temp = en7581_thermal_get_temp,
+	.set_trips = en7581_thermal_set_trips,
 };
 
-static irqreturn_t airoha_thermal_irq(int irq, void *data)
+static irqreturn_t en7581_thermal_irq(int irq, void *data)
 {
 	struct airoha_thermal_priv *priv = data;
 	enum thermal_notify_event event;
@@ -326,7 +338,7 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static void airoha_thermal_setup_adc_val(struct device *dev,
+static void en7581_thermal_setup_adc_val(struct device *dev,
 					 struct airoha_thermal_priv *priv)
 {
 	u32 efuse_calib_info = 0;
@@ -357,7 +369,7 @@ static void airoha_thermal_setup_adc_val(struct device *dev,
 	}
 }
 
-static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
+static void en7581_thermal_setup_monitor(struct airoha_thermal_priv *priv)
 {
 	/* Set measure mode */
 	regmap_write(priv->map, EN7581_TEMPMSRCTL0,
@@ -412,30 +424,26 @@ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
 		     FIELD_PREP(EN7581_ADC_POLL_INTVL, 146));
 }
 
-static const struct regmap_config airoha_thermal_regmap_config = {
+static const struct regmap_config en7581_thermal_regmap_config = {
 	.reg_bits		= 32,
 	.reg_stride		= 4,
 	.val_bits		= 32,
 };
 
-static int airoha_thermal_probe(struct platform_device *pdev)
+static int en7581_thermal_probe(struct platform_device *pdev,
+				struct airoha_thermal_priv *priv)
 {
-	struct airoha_thermal_priv *priv;
 	struct device_node *chip_scu_np;
 	struct device *dev = &pdev->dev;
 	void __iomem *base;
 	int irq, ret;
 
-	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
 	priv->map = devm_regmap_init_mmio(dev, base,
-					  &airoha_thermal_regmap_config);
+					  &en7581_thermal_regmap_config);
 	if (IS_ERR(priv->map))
 		return PTR_ERR(priv->map);
 
@@ -455,18 +463,55 @@ static int airoha_thermal_probe(struct platform_device *pdev)
 		return irq;
 
 	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
-					airoha_thermal_irq, IRQF_ONESHOT,
+					en7581_thermal_irq, IRQF_ONESHOT,
 					pdev->name, priv);
 	if (ret) {
 		dev_err(dev, "Can't get interrupt working.\n");
 		return ret;
 	}
 
-	airoha_thermal_setup_monitor(priv);
-	airoha_thermal_setup_adc_val(dev, priv);
+	en7581_thermal_setup_monitor(priv);
+	en7581_thermal_setup_adc_val(dev, priv);
+
+	return 0;
+}
+
+static int en7581_thermal_post_probe(struct platform_device *pdev)
+{
+	struct airoha_thermal_priv *priv = platform_get_drvdata(pdev);
+
+	/* Enable LOW and HIGH interrupt (if supported) */
+	regmap_write(priv->map, EN7581_TEMPMONINT,
+		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
+
+	return 0;
+}
+
+static int airoha_thermal_probe(struct platform_device *pdev)
+{
+	const struct airoha_thermal_soc_data *soc_data;
+	struct airoha_thermal_priv *priv;
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	soc_data = device_get_match_data(dev);
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->pllrg_protect = soc_data->pllrg_protect;
+
+	if (!soc_data->probe)
+		return -EINVAL;
+
+	ret = soc_data->probe(pdev, priv);
+	if (ret)
+		return ret;
 
 	/* register of thermal sensor and get info from DT */
-	priv->tz = devm_thermal_of_zone_register(dev, 0, priv, &thdev_ops);
+	priv->tz = devm_thermal_of_zone_register(dev, 0, priv,
+						 soc_data->thdev_ops);
 	if (IS_ERR(priv->tz)) {
 		dev_err(dev, "register thermal zone sensor failed\n");
 		return PTR_ERR(priv->tz);
@@ -474,15 +519,18 @@ static int airoha_thermal_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, priv);
 
-	/* Enable LOW and HIGH interrupt */
-	regmap_write(priv->map, EN7581_TEMPMONINT,
-		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
-
-	return 0;
+	return soc_data->post_probe ? soc_data->post_probe(pdev) : 0;
 }
 
+static const struct airoha_thermal_soc_data en7581_data = {
+	.pllrg_protect = EN7581_SCU_THERMAL_PROTECT_KEY,
+	.thdev_ops = &en7581_thdev_ops,
+	.probe = &en7581_thermal_probe,
+	.post_probe = &en7581_thermal_post_probe,
+};
+
 static const struct of_device_id airoha_thermal_match[] = {
-	{ .compatible = "airoha,en7581-thermal" },
+	{ .compatible = "airoha,en7581-thermal", .data = &en7581_data },
 	{},
 };
 MODULE_DEVICE_TABLE(of, airoha_thermal_match);
-- 
2.53.0


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

* [PATCH v6 5/7] thermal/drivers: airoha: Generalize get_thermal_ADC and set_mux function
  2026-07-02  9:48 [PATCH v6 0/7] thermal/drivers: airoha: Add support for AN7583 Christian Marangi
                   ` (3 preceding siblings ...)
  2026-07-02  9:48 ` [PATCH v6 4/7] thermal/drivers: airoha: Generalize probe function Christian Marangi
@ 2026-07-02  9:48 ` Christian Marangi
  2026-07-02  9:48 ` [PATCH v6 6/7] dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC Christian Marangi
  2026-07-02  9:48 ` [PATCH v6 7/7] thermal/drivers: airoha: Add support for AN7583 Thermal Sensor Christian Marangi
  6 siblings, 0 replies; 14+ messages in thread
From: Christian Marangi @ 2026-07-02  9:48 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Christian Marangi,
	Lorenzo Bianconi, devicetree, linux-kernel, linux-pm

In preparation for support of Airoha AN7583, generalize
get_thermal_ADC() and set_thermal_mux() with the use of reg_field API.

This is to account the same logic between the current supported SoC and
the new one but with different register address.

While at it also further improve some comments and move sleep inside the
set_thermal_mux function.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 drivers/thermal/airoha_thermal.c | 56 +++++++++++++++++++++++++-------
 1 file changed, 44 insertions(+), 12 deletions(-)

diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
index ebb47ae5f2ce..249abbbd46bc 100644
--- a/drivers/thermal/airoha_thermal.c
+++ b/drivers/thermal/airoha_thermal.c
@@ -193,9 +193,18 @@
 
 #define AIROHA_MAX_SAMPLES			6
 
+enum airoha_thermal_chip_scu_field {
+	AIROHA_THERMAL_DOUT_TADC,
+	AIROHA_THERMAL_MUX_TADC,
+
+	/* keep last */
+	AIROHA_THERMAL_FIELD_MAX,
+};
+
 struct airoha_thermal_priv {
 	struct regmap *map;
 	struct regmap *chip_scu;
+	struct regmap_field *chip_scu_fields[AIROHA_THERMAL_FIELD_MAX];
 	struct resource scu_adc_res;
 
 	u32 pllrg_protect;
@@ -219,25 +228,32 @@ static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
 {
 	u32 val;
 
-	regmap_read(priv->chip_scu, EN7581_DOUT_TADC, &val);
-	return FIELD_GET(EN7581_DOUT_TADC_MASK, val);
+	regmap_field_read(priv->chip_scu_fields[AIROHA_THERMAL_DOUT_TADC],
+			  &val);
+	return val;
 }
 
-static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
+static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv,
+				   int tdac_idx)
 {
-	u32 adc_mux, pllrg;
+	u32 pllrg;
 
 	/* Save PLLRG current value */
 	regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
 
-	/* Give access to thermal regs */
+	/* Give access to Thermal regs */
 	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
 		     priv->pllrg_protect);
-	adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
-	regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
+
+	/* Configure Thermal ADC mux to tdac_idx */
+	regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC],
+			   tdac_idx);
 
 	/* Restore PLLRG value on exit */
 	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
+
+	/* Sleep 10 ms for Thermal ADC to enable */
+	usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
 }
 
 static int en7581_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
@@ -344,10 +360,8 @@ static void en7581_thermal_setup_adc_val(struct device *dev,
 	u32 efuse_calib_info = 0;
 	u32 cpu_sensor = 0;
 
-	/* Setup thermal sensor to ADC mode and setup the mux to DIODE1 */
-	airoha_init_thermal_ADC_mode(priv);
-	/* sleep 10 ms for ADC to enable */
-	usleep_range(10 * USEC_PER_MSEC, 11 * USEC_PER_MSEC);
+	/* Setup Thermal Sensor to ADC mode and setup the mux to DIODE1 */
+	airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1);
 
 	regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info);
 	if (efuse_calib_info) {
@@ -430,13 +444,18 @@ static const struct regmap_config en7581_thermal_regmap_config = {
 	.val_bits		= 32,
 };
 
+static const struct reg_field en7581_chip_scu_fields[AIROHA_THERMAL_FIELD_MAX] = {
+	[AIROHA_THERMAL_DOUT_TADC] = REG_FIELD(EN7581_DOUT_TADC, 0, 15),
+	[AIROHA_THERMAL_MUX_TADC] = REG_FIELD(EN7581_PWD_TADC, 1, 3),
+};
+
 static int en7581_thermal_probe(struct platform_device *pdev,
 				struct airoha_thermal_priv *priv)
 {
 	struct device_node *chip_scu_np;
 	struct device *dev = &pdev->dev;
 	void __iomem *base;
-	int irq, ret;
+	int i, irq, ret;
 
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
@@ -455,6 +474,19 @@ static int en7581_thermal_probe(struct platform_device *pdev,
 	if (IS_ERR(priv->chip_scu))
 		return PTR_ERR(priv->chip_scu);
 
+	for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) {
+		struct regmap_field *field;
+
+		field = devm_regmap_field_alloc(dev, priv->chip_scu,
+						en7581_chip_scu_fields[i]);
+		if (IS_ERR(field)) {
+			of_node_put(chip_scu_np);
+			return PTR_ERR(field);
+		}
+
+		priv->chip_scu_fields[i] = field;
+	}
+
 	of_address_to_resource(chip_scu_np, 0, &priv->scu_adc_res);
 	of_node_put(chip_scu_np);
 
-- 
2.53.0


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

* [PATCH v6 6/7] dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC
  2026-07-02  9:48 [PATCH v6 0/7] thermal/drivers: airoha: Add support for AN7583 Christian Marangi
                   ` (4 preceding siblings ...)
  2026-07-02  9:48 ` [PATCH v6 5/7] thermal/drivers: airoha: Generalize get_thermal_ADC and set_mux function Christian Marangi
@ 2026-07-02  9:48 ` Christian Marangi
  2026-07-02 10:48   ` sashiko-bot
  2026-07-02  9:48 ` [PATCH v6 7/7] thermal/drivers: airoha: Add support for AN7583 Thermal Sensor Christian Marangi
  6 siblings, 1 reply; 14+ messages in thread
From: Christian Marangi @ 2026-07-02  9:48 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Christian Marangi,
	Lorenzo Bianconi, devicetree, linux-kernel, linux-pm
  Cc: Krzysztof Kozlowski

Document support for Airoha AN7583 chip-scu node.

This is similar to Airoha EN7581 with the addition of the presence of
thermal sensor in addition to controlling HW PIN and other miscellaneous
pheriperals.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
 .../bindings/arm/airoha,en7581-chip-scu.yaml       | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml b/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml
index 67c449d804c2..cc564dc7b414 100644
--- a/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml
+++ b/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml
@@ -19,15 +19,29 @@ properties:
     items:
       - enum:
           - airoha,en7581-chip-scu
+          - airoha,an7583-chip-scu
       - const: syscon
 
   reg:
     maxItems: 1
 
+  '#thermal-sensor-cells':
+    const: 0
+
 required:
   - compatible
   - reg
 
+if:
+  properties:
+    compatible:
+      contains:
+        const: airoha,en7581-chip-scu
+
+then:
+  properties:
+    '#thermal-sensor-cells': false
+
 additionalProperties: false
 
 examples:
-- 
2.53.0


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

* [PATCH v6 7/7] thermal/drivers: airoha: Add support for AN7583 Thermal Sensor
  2026-07-02  9:48 [PATCH v6 0/7] thermal/drivers: airoha: Add support for AN7583 Christian Marangi
                   ` (5 preceding siblings ...)
  2026-07-02  9:48 ` [PATCH v6 6/7] dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC Christian Marangi
@ 2026-07-02  9:48 ` Christian Marangi
  2026-07-02 11:04   ` sashiko-bot
  6 siblings, 1 reply; 14+ messages in thread
From: Christian Marangi @ 2026-07-02  9:48 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Christian Marangi,
	Lorenzo Bianconi, devicetree, linux-kernel, linux-pm

Add support for Airoha AN7583 Thermal driver. This apply similar logic
on how to read the temperature but totally drop support for the
PTP_THERMAL subsystem. PTP_THERMAL subsystem was a way to trigger trip
point from hardware by configuring how to read the temperature
internally.

This subsystem has been totally removed from Airoha AN7583 permitting
only to read the temperature.

The SoC support up to 3 sensor but the original driver always read the
BGA sensor hence it's currently implemented reading only this specific
sensor. Reference and values for the other 2 sensor are defined for
further implementation if confirmed working.

set_thermal_mux() is extended to also address muxing the sensor as
AN7583 use a different way to read the temperature from 3 different
diode. The EN7581 code is updated to account for these changes.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
 drivers/thermal/airoha_thermal.c | 161 ++++++++++++++++++++++++++++++-
 1 file changed, 157 insertions(+), 4 deletions(-)

diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
index 249abbbd46bc..c84b5c36e880 100644
--- a/drivers/thermal/airoha_thermal.c
+++ b/drivers/thermal/airoha_thermal.c
@@ -18,6 +18,12 @@
 #define EN7581_DOUT_TADC			0x2f8
 #define   EN7581_DOUT_TADC_MASK			GENMASK(15, 0)
 
+#define AN7583_MUX_SENSOR			0x2a0
+#define   AN7583_LOAD_ADJ			GENMASK(3, 2)
+#define AN7583_MUX_TADC				0x2e4
+#define   AN7583_MUX_TADC_MASK			GENMASK(3, 1)
+#define AN7583_DOUT_TADC			0x2f0
+
 /* PTP_THERMAL regs */
 #define EN7581_TEMPMONCTL0			0x800
 #define   EN7581_SENSE3_EN			BIT(3)
@@ -181,6 +187,11 @@
 #define EN7581_SCU_THERMAL_PROTECT_KEY		0x12
 #define EN7581_SCU_THERMAL_MUX_DIODE1		0x7
 
+#define AN7583_SCU_THERMAL_PROTECT_KEY		0x80
+#define AN7583_NUM_SENSOR			3
+
+#define AIROHA_THERMAL_NO_MUX_SENSOR		-1
+
 /* Convert temp to raw value as read from ADC	((((temp / 100) - init) * slope) / 1000) + offset */
 #define TEMP_TO_RAW(priv, temp)			((((((temp) / 100) - (priv)->init_temp) * \
 						  (priv)->default_slope) / 1000) + \
@@ -193,8 +204,39 @@
 
 #define AIROHA_MAX_SAMPLES			6
 
+/*
+ * AN7583 supports all these ADC mux but the original driver
+ * always checked temp with the AN7583_BGP_TEMP_SENSOR.
+ * Assume using the other sensor temperature is invalid and
+ * always read from AN7583_BGP_TEMP_SENSOR.
+ *
+ * On top of this it's defined that AN7583 supports 3
+ * sensor: AN7583_BGP_TEMP_SENSOR, AN7583_GBE_TEMP_SENSOR,
+ * AN7583_CPU_TEMP_SENSOR.
+ *
+ * Provide the ADC mux for reference.
+ */
+enum an7583_thermal_adc_mux {
+	AN7583_BGP_TEMP_SENSOR,
+	AN7583_PAD_AVS,
+	AN7583_CORE_POWER,
+	AN7583_AVSDAC_OUT,
+	AN7583_VCM,
+	AN7583_GBE_TEMP_SENSOR,
+	AN7583_CPU_TEMP_SENSOR,
+
+	AN7583_ADC_MUX_MAX,
+};
+
+enum an7583_thermal_diode_mux {
+	AN7583_D0_TADC,
+	AN7583_ZERO_TADC,
+	AN7583_D1_TADC,
+};
+
 enum airoha_thermal_chip_scu_field {
 	AIROHA_THERMAL_DOUT_TADC,
+	AIROHA_THERMAL_MUX_SENSOR,
 	AIROHA_THERMAL_MUX_TADC,
 
 	/* keep last */
@@ -208,6 +250,7 @@ struct airoha_thermal_priv {
 	struct resource scu_adc_res;
 
 	u32 pllrg_protect;
+	int current_adc;
 
 	struct thermal_zone_device *tz;
 	int init_temp;
@@ -224,6 +267,24 @@ struct airoha_thermal_soc_data {
 	int (*post_probe)(struct platform_device *pdev);
 };
 
+static const unsigned int an7583_thermal_coeff[AN7583_ADC_MUX_MAX] = {
+	[AN7583_BGP_TEMP_SENSOR] = 973,
+	[AN7583_GBE_TEMP_SENSOR] = 995,
+	[AN7583_CPU_TEMP_SENSOR] = 1035,
+};
+
+static const unsigned int an7583_thermal_slope[AN7583_ADC_MUX_MAX] = {
+	[AN7583_BGP_TEMP_SENSOR] = 7440,
+	[AN7583_GBE_TEMP_SENSOR] = 7620,
+	[AN7583_CPU_TEMP_SENSOR] = 8390,
+};
+
+static const unsigned int an7583_thermal_offset[AN7583_ADC_MUX_MAX] = {
+	[AN7583_BGP_TEMP_SENSOR] = 294,
+	[AN7583_GBE_TEMP_SENSOR] = 298,
+	[AN7583_CPU_TEMP_SENSOR] = 344,
+};
+
 static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
 {
 	u32 val;
@@ -234,7 +295,7 @@ static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
 }
 
 static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv,
-				   int tdac_idx)
+				   int tdac_idx, int sensor_idx)
 {
 	u32 pllrg;
 
@@ -245,9 +306,20 @@ static void airoha_set_thermal_mux(struct airoha_thermal_priv *priv,
 	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT,
 		     priv->pllrg_protect);
 
+	/*
+	 * Configure Thermal Sensor mux to sensor_idx.
+	 * (if not supported, sensor_idx is AIROHA_THERMAL_NO_MUX_SENSOR)
+	 */
+	if (sensor_idx != AIROHA_THERMAL_NO_MUX_SENSOR)
+		regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_SENSOR],
+				   sensor_idx);
+
 	/* Configure Thermal ADC mux to tdac_idx */
-	regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC],
-			   tdac_idx);
+	if (priv->current_adc != tdac_idx) {
+		regmap_field_write(priv->chip_scu_fields[AIROHA_THERMAL_MUX_TADC],
+				   tdac_idx);
+		priv->current_adc = tdac_idx;
+	}
 
 	/* Restore PLLRG value on exit */
 	regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
@@ -361,7 +433,8 @@ static void en7581_thermal_setup_adc_val(struct device *dev,
 	u32 cpu_sensor = 0;
 
 	/* Setup Thermal Sensor to ADC mode and setup the mux to DIODE1 */
-	airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1);
+	airoha_set_thermal_mux(priv, EN7581_SCU_THERMAL_MUX_DIODE1,
+			       AIROHA_THERMAL_NO_MUX_SENSOR);
 
 	regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info);
 	if (efuse_calib_info) {
@@ -477,6 +550,10 @@ static int en7581_thermal_probe(struct platform_device *pdev,
 	for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) {
 		struct regmap_field *field;
 
+		/* Skip registering MUX_SENSOR field as not supported */
+		if (i == AIROHA_THERMAL_MUX_SENSOR)
+			continue;
+
 		field = devm_regmap_field_alloc(dev, priv->chip_scu,
 						en7581_chip_scu_fields[i]);
 		if (IS_ERR(field)) {
@@ -519,6 +596,74 @@ static int en7581_thermal_post_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int an7583_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
+{
+	struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
+	int sensor_idx;
+	int delta_diode, delta_gain;
+	int coeff, slope, offset;
+
+	int diode_zero, diode_d0, diode_d1;
+
+	/* Always read sensor AN7583_BGP_TEMP_SENSOR */
+	sensor_idx = AN7583_BGP_TEMP_SENSOR;
+
+	coeff = an7583_thermal_coeff[sensor_idx];
+	slope = an7583_thermal_slope[sensor_idx];
+	offset = an7583_thermal_offset[sensor_idx];
+
+	airoha_set_thermal_mux(priv, AN7583_ZERO_TADC, sensor_idx);
+	diode_zero = airoha_get_thermal_ADC(priv);
+	airoha_set_thermal_mux(priv, AN7583_D0_TADC, sensor_idx);
+	diode_d0 = airoha_get_thermal_ADC(priv);
+	airoha_set_thermal_mux(priv, AN7583_D1_TADC, sensor_idx);
+	diode_d1 = airoha_get_thermal_ADC(priv);
+
+	delta_diode = diode_d1 - diode_d0;
+	delta_gain = (delta_diode * coeff) / 100 + (diode_zero - diode_d1);
+	if (!delta_gain)
+		return -EINVAL;
+
+	*temp = (slope * delta_diode * 10) / delta_gain - offset * 10;
+	*temp *= 100;
+
+	return 0;
+}
+
+static const struct thermal_zone_device_ops an7583_tz_ops = {
+	.get_temp = an7583_thermal_get_temp,
+};
+
+static const struct reg_field an7583_chip_scu_fields[AIROHA_THERMAL_FIELD_MAX] = {
+	[AIROHA_THERMAL_DOUT_TADC] = REG_FIELD(AN7583_DOUT_TADC, 0, 31),
+	[AIROHA_THERMAL_MUX_TADC] = REG_FIELD(AN7583_MUX_TADC, 1, 3),
+	[AIROHA_THERMAL_MUX_SENSOR] = REG_FIELD(AN7583_MUX_SENSOR, 2, 3),
+};
+
+static int an7583_thermal_probe(struct platform_device *pdev,
+				struct airoha_thermal_priv *priv)
+{
+	struct device *dev = &pdev->dev;
+	int i;
+
+	priv->chip_scu = device_node_to_regmap(dev->of_node);
+	if (IS_ERR(priv->chip_scu))
+		return PTR_ERR(priv->chip_scu);
+
+	for (i = 0; i < AIROHA_THERMAL_FIELD_MAX; i++) {
+		struct regmap_field *field;
+
+		field = devm_regmap_field_alloc(dev, priv->chip_scu,
+						an7583_chip_scu_fields[i]);
+		if (IS_ERR(field))
+			return PTR_ERR(field);
+
+		priv->chip_scu_fields[i] = field;
+	}
+
+	return 0;
+}
+
 static int airoha_thermal_probe(struct platform_device *pdev)
 {
 	const struct airoha_thermal_soc_data *soc_data;
@@ -533,6 +678,7 @@ static int airoha_thermal_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	priv->pllrg_protect = soc_data->pllrg_protect;
+	priv->current_adc = -1;
 
 	if (!soc_data->probe)
 		return -EINVAL;
@@ -561,8 +707,15 @@ static const struct airoha_thermal_soc_data en7581_data = {
 	.post_probe = &en7581_thermal_post_probe,
 };
 
+static const struct airoha_thermal_soc_data an7583_data = {
+	.pllrg_protect = AN7583_SCU_THERMAL_PROTECT_KEY,
+	.thdev_ops = &an7583_tz_ops,
+	.probe = &an7583_thermal_probe,
+};
+
 static const struct of_device_id airoha_thermal_match[] = {
 	{ .compatible = "airoha,en7581-thermal", .data = &en7581_data },
+	{ .compatible = "airoha,an7583-chip-scu", .data = &an7583_data },
 	{},
 };
 MODULE_DEVICE_TABLE(of, airoha_thermal_match);
-- 
2.53.0


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

* Re: [PATCH v6 1/7] thermal/drivers: airoha: fix copy paste error on clamp_t low temp
  2026-07-02  9:48 ` [PATCH v6 1/7] thermal/drivers: airoha: fix copy paste error on clamp_t low temp Christian Marangi
@ 2026-07-02 10:00   ` sashiko-bot
  0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-07-02 10:00 UTC (permalink / raw)
  To: Christian Marangi; +Cc: robh, conor+dt, devicetree

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

Pre-existing issues:
- [High] The driver fails to update or disable hardware trip point thresholds when the thermal framework clears the boundaries, causing continuous spurious interrupts.
- [High] The thermal IRQ handler silently drops valid thermal events if both high and low interrupt status bits are asserted simultaneously.
--

commit c9ebb221cc728a9aaa865333e7d5b41b485e09e1
Author: Christian Marangi <ansuelsmth@gmail.com>

thermal/drivers: airoha: fix copy paste error on clamp_t low temp
    
In airoha_thermal_set_trips, there is a copy paste error on clamping the
value for the low trip temp point. Fix it to the correct value and actually
clamp for the low variable.

> diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
> index b9fd6bfc88e5e..439aa011b75c7 100644
> --- a/drivers/thermal/airoha_thermal.c
> +++ b/drivers/thermal/airoha_thermal.c
> @@ -273,7 +273,7 @@ static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
>  
>  	if (low != -INT_MAX) {
>  		/* Validate low and clamp it to a supported value */
> -		low = clamp_t(int, high, RAW_TO_TEMP(priv, 0),
> +		low = clamp_t(int, low, RAW_TO_TEMP(priv, 0),
>  			      RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
>  
>  		/* We offset the low temp of 1°C to trigger correct event */
>  		writel(TEMP_TO_RAW(priv, low) >> 4,
>  		       priv->base + EN7581_TEMPOFFSETL);
>  
>  		enable_monitor = true;
>  	}
>  
>  	/* Enable sensor 0 monitor after trip are set */
>  	if (enable_monitor)
>  		writel(EN7581_SENSE0_EN, priv->base + EN7581_TEMPMONCTL0);
>
> 	return 0;
> }

[Severity: High]
This is a pre-existing issue, but I noticed the hardware monitor thresholds
aren't disabled when the boundaries are cleared.

If the thermal framework passes INT_MAX for high and -INT_MAX for low
to clear active trip points, enable_monitor will be false, but there is no
code to write 0 to disable the hardware monitor.

Could this lead to spurious interrupts since the stale thresholds remain active?


Looking at airoha_thermal_irq() in the same file:

static irqreturn_t airoha_thermal_irq(int irq, void *data)
{
	...
	status = readl(priv->base + EN7581_TEMPMONINTSTS);
	switch (status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0)) {
	case EN7581_HOFSINTSTS0:
		event = THERMAL_TRIP_VIOLATED;
		update = true;
		break;
	case EN7581_LOFSINTSTS0:
		event = THERMAL_EVENT_UNSPECIFIED;
		update = true;
		break;
	default:
		/* Should be impossible as we enable only these Interrupt */
		break;
	}

[Severity: High]
This isn't a bug introduced by this patch, but does this switch statement
silently drop events if both high and low interrupt status bits are asserted
simultaneously?

If status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0) results in both bits 
being set, it will fall through to the default case and ignore the events.

Since the IRQ handler is a threaded IRQ, could scheduling delays allow both
bits to be latched before the thread executes and cause us to lose thermal
notifications?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260702094846.17325-1-ansuelsmth@gmail.com?part=1

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

* Re: [PATCH v6 2/7] thermal/drivers: airoha: fix copy paste error for sen internal
  2026-07-02  9:48 ` [PATCH v6 2/7] thermal/drivers: airoha: fix copy paste error for sen internal Christian Marangi
@ 2026-07-02 10:07   ` sashiko-bot
  0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-07-02 10:07 UTC (permalink / raw)
  To: Christian Marangi; +Cc: conor+dt, devicetree, robh

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

Pre-existing issues:
- [High] The thermal interrupt handler ignores events if multiple interrupt status bits are set simultaneously, causing lost thermal events.
- [High] The thermal interrupt is requested before the thermal zone device is initialized, risking a NULL pointer dereference.
- [High] Ignored return values from `regmap_read()` lead to the use of uninitialized stack variables, causing garbage temperature readings or hardware corruption.
- [High] Ignored return value from `of_address_to_resource()` leads to configuring the hardware with a bogus uninitialized physical address.
- [High] The `set_trips` callback fails to disable hardware interrupts or update registers when a trip point is removed.
- [High] The driver checks the entire 32-bit EFUSE register instead of the masked calibration field, potentially misinterpreting unrelated bits as calibration data.
--

commit d5d738260788425c2c1e27418bf98a956c539129
Author: Christian Marangi <ansuelsmth@gmail.com>

thermal/drivers: airoha: fix copy paste error for sen internal

In airoha_thermal_setup_monitor there is a copy paste error on configuring
the internval for temp monitor. Fix the error and use the correct mask for
the sen interval for the EN7581_TEMPMONCTL2 register.

> diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
> index 439aa011b75c7..829a7327fc403 100644
> --- a/drivers/thermal/airoha_thermal.c
> +++ b/drivers/thermal/airoha_thermal.c
> @@ -403,7 +403,7 @@ static void airoha_thermal_setup_monitor(struct airoha_thermal_priv *priv)
>  	 * sen interval is 379 * 52.715us = 19.97ms
>  	 */
>  	writel(FIELD_PREP(EN7581_FILT_INTERVAL, 1) |
> -	       FIELD_PREP(EN7581_FILT_INTERVAL, 379),
> +	       FIELD_PREP(EN7581_SEN_INTERVAL, 379),
>  	       priv->base + EN7581_TEMPMONCTL2);
>  
>  	/* AHB poll is set to 146 * 68.64 = 10.02us */

[Severity: High]
This isn't a bug introduced by this patch, but could this switch statement
miss events if multiple interrupt status bits are set simultaneously?

drivers/thermal/airoha_thermal.c:en7581_thermal_irq() {
        switch (status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0)) {
        case EN7581_HOFSINTSTS0:
                event = THERMAL_TRIP_VIOLATED;
                update = true;
                break;
        case EN7581_LOFSINTSTS0:
                event = THERMAL_EVENT_UNSPECIFIED;
                update = true;
                break;
        default:
                /* Should be impossible as we enable only these Interrupt */
                break;
        }
}

If the hardware asserts both EN7581_HOFSINTSTS0 and EN7581_LOFSINTSTS0
concurrently, the bitwise AND evaluates to both bits being set, which matches
neither case. Execution would fall through to default, discarding the events.

[Severity: High]
This is a pre-existing issue, but does this driver request the interrupt
before the thermal zone device is initialized?

drivers/thermal/airoha_thermal.c:en7581_thermal_probe() {
        ...
        ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
                                        en7581_thermal_irq, IRQF_ONESHOT,
                                        pdev->name, priv);
        ...
}

If the bootloader leaves the thermal interrupt enabled and asserted, the
handler could execute immediately:

drivers/thermal/airoha_thermal.c:en7581_thermal_irq() {
        ...
        if (update)
                thermal_zone_device_update(priv->tz, event);
        ...
}

Because the tz pointer is populated later in the probe sequence:

drivers/thermal/airoha_thermal.c:airoha_thermal_probe() {
        ...
        priv->tz = devm_thermal_of_zone_register(dev, 0, priv,
                                                 soc_data->thdev_ops);
        ...
}

Could this result in a NULL pointer dereference if the interrupt fires early?

[Severity: High]
This isn't a bug introduced by this patch, but are the return values of
these regmap reads intentionally ignored?

drivers/thermal/airoha_thermal.c:airoha_get_thermal_ADC() {
        ...
        regmap_field_read(priv->chip_scu_fields[AIROHA_THERMAL_DOUT_TADC],
                          &val);
        return val;
}

And also here:

drivers/thermal/airoha_thermal.c:airoha_set_thermal_mux() {
        ...
        regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
        ...
}

If the underlying regmap read fails, the uninitialized stack variables
val and pllrg could be used directly, potentially returning invalid
temperatures or writing garbage back to the hardware.

[Severity: High]
This is a pre-existing issue, but what happens if the device tree node lacks
a valid reg property?

drivers/thermal/airoha_thermal.c:en7581_thermal_probe() {
        ...
        of_address_to_resource(chip_scu_np, 0, &priv->scu_adc_res);
        ...
}

The return value is ignored here. If the parse fails, priv->scu_adc_res.start
remains 0. The driver then configures the AHB bus master to poll from this
address:

drivers/thermal/airoha_thermal.c:en7581_thermal_setup_monitor() {
        ...
        regmap_write(priv->map, EN7581_TEMPADCVALIDADDR,
                     priv->scu_adc_res.start + EN7581_DOUT_TADC);
        ...
}

Could this asynchronous read from an uninitialized address cause a bus fault?

[Severity: High]
This isn't a bug introduced by this patch, but does the driver handle the
removal of all trip points correctly?

drivers/thermal/airoha_thermal.c:en7581_thermal_set_trips() {
        ...
        /* Enable sensor 0 monitor after trip are set */
        if (enable_monitor)
                regmap_write(priv->map, EN7581_TEMPMONCTL0, EN7581_SENSE0_EN);
        
        return 0;
}

If the thermal core removes a trip point and enable_monitor becomes false,
there is no else branch to disable the monitor in hardware. Would the monitor
continue firing interrupts for the stale thresholds?

[Severity: High]
This is a pre-existing issue, but does this correctly check if the
calibration field is programmed?

drivers/thermal/airoha_thermal.c:en7581_thermal_setup_adc_val() {
        ...
        regmap_read(priv->map, EN7581_EFUSE_TEMP_OFFSET_REG, &efuse_calib_info);
        if (efuse_calib_info) {
                priv->default_offset = FIELD_GET(EN7581_EFUSE_TEMP_OFFSET, efuse_calib_info);
        ...
}

If the lower bits of the register contain non-zero data (outside the
EN7581_EFUSE_TEMP_OFFSET mask), but the calibration field itself is
unprogrammed (0), the condition still evaluates to true. 

Would this trap the driver in the calibrated path with a 0 offset, preventing
the use of the non-calibrated fallback parameters?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260702094846.17325-1-ansuelsmth@gmail.com?part=2

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

* Re: [PATCH v6 3/7] thermal/drivers: airoha: Convert to regmap API
  2026-07-02  9:48 ` [PATCH v6 3/7] thermal/drivers: airoha: Convert to regmap API Christian Marangi
@ 2026-07-02 10:16   ` sashiko-bot
  0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-07-02 10:16 UTC (permalink / raw)
  To: Christian Marangi; +Cc: devicetree, conor+dt, robh

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

Pre-existing issues:
- [High] The device interrupt is requested before the thermal zone is registered, and hardware interrupts are not disabled on unbind.
- [High] The interrupt handler silently drops events if both high and low threshold interrupts are pending simultaneously.
--

commit ddea8884dc559f65dc6c31d8d784b42996724da4
Author: Christian Marangi <ansuelsmth@gmail.com>

thermal/drivers: airoha: Convert to regmap API

Convert the Airoha thermal driver to use the regmap API instead of direct MMIO
accesses. This refactoring prepares the driver for Airoha AN7583 support,
which relies on a syscon regmap.

> diff --git a/drivers/thermal/airoha_thermal.c b/drivers/thermal/airoha_thermal.c
> index 829a7327fc403..b63893a8997a3 100644
> --- a/drivers/thermal/airoha_thermal.c
> +++ b/drivers/thermal/airoha_thermal.c

[ ... ]

> @@ -300,9 +300,9 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data)
>  	struct airoha_thermal_priv *priv = data;
>  	enum thermal_notify_event event;
>  	bool update = false;
> -	u32 status;
> +	u32 status = 0;
>  
> -	status = readl(priv->base + EN7581_TEMPMONINTSTS);
> +	regmap_read(priv->map, EN7581_TEMPMONINTSTS, &status);
>  	switch (status & (EN7581_HOFSINTSTS0 | EN7581_LOFSINTSTS0)) {
>  	case EN7581_HOFSINTSTS0:
>  		event = THERMAL_TRIP_VIOLATED;
> @@ -318,7 +318,7 @@ static irqreturn_t airoha_thermal_irq(int irq, void *data)
>  	}

[Severity: High]
This is a pre-existing issue, but does this switch statement drop events if
both HOFSINTSTS0 and LOFSINTSTS0 are set?

If the hardware latches both the high (EN7581_HOFSINTSTS0) and low
(EN7581_LOFSINTSTS0) threshold interrupt bits simultaneously, the bitwise AND
operation will yield both bits set. The switch statement will attempt an
exact match and fall through to the default case. The interrupts are then
cleared via regmap_write(), but thermal_zone_device_update() is never
called because update remains false.

>  
>  	/* Reset Interrupt */
> -	writel(status, priv->base + EN7581_TEMPMONINTSTS);
> +	regmap_write(priv->map, EN7581_TEMPMONINTSTS, status);
>  
>  	if (update)
>  		thermal_zone_device_update(priv->tz, event);

[ ... ]

> @@ -462,8 +475,8 @@ static int airoha_thermal_probe(struct platform_device *pdev)
>  	platform_set_drvdata(pdev, priv);
>  
>  	/* Enable LOW and HIGH interrupt */
> -	writel(EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0,
> -	       priv->base + EN7581_TEMPMONINT);
> +	regmap_write(priv->map, EN7581_TEMPMONINT,
> +		     EN7581_HOFSINTEN0 | EN7581_LOFSINTEN0);
>  
>  	return 0;
>  }

[Severity: High]
This isn't a bug introduced by this patch, but does the probe function
request the interrupt before the thermal zone is registered?

It appears that devm_request_threaded_irq() is called earlier in
airoha_thermal_probe(), enabling the interrupt before
devm_thermal_of_zone_register() initializes priv->tz. If an interrupt fires
during this window, the ISR will dereference a NULL priv->tz.

Additionally, since there is no .remove callback to mask the hardware
interrupt, could this cause a use-after-free during driver unbind? Devres
executes cleanup in reverse order of creation, so priv->tz is destroyed
first, leaving the IRQ handler active until the IRQ is freed. An incoming
interrupt during this window might also lead to a use-after-free.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260702094846.17325-1-ansuelsmth@gmail.com?part=3

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

* Re: [PATCH v6 4/7] thermal/drivers: airoha: Generalize probe function
  2026-07-02  9:48 ` [PATCH v6 4/7] thermal/drivers: airoha: Generalize probe function Christian Marangi
@ 2026-07-02 10:35   ` sashiko-bot
  0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-07-02 10:35 UTC (permalink / raw)
  To: Christian Marangi; +Cc: robh, conor+dt, devicetree

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

New issues:
- [High] Missing NULL check for the result of `device_get_match_data()` leads to a NULL pointer dereference.

Pre-existing issues:
- [High] Interrupt handler silently drops thermal events if both High and Low threshold interrupts fire simultaneously.
- [High] Incorrect devres initialization order for IRQ causes race conditions (early NULL pointer dereference) and Use-After-Free.
- [High] Missing return value check for `of_address_to_resource()` allows usage of an uninitialized resource address.
--

(Note: The standard inline diff quoting format has been altered to a free-form
summary due to automated recitation restrictions. The original patch code is
not quoted below.)

Commit: a66125bc561d9323e2561d461f2be68491469827
Author: Christian Marangi <ansuelsmth@gmail.com>
Subject: thermal/drivers: airoha: Generalize probe function

This commit generalizes the probe function in preparation for supporting
the Airoha AN7583 SoC. It introduces a match_data struct to define specific
probe and post_probe functions, thermal ops, and pllrg protect values.

[Severity: High]
Could device_get_match_data() return NULL in airoha_thermal_probe()? 
If the driver is bound manually via sysfs by matching the driver name
without an underlying Device Tree node, the match data would be NULL.
Dereferencing soc_data->pllrg_protect immediately after without validation
would cause a NULL pointer dereference. Is there a need to check if
soc_data is valid before accessing it?

[Severity: High]
This is a pre-existing issue, but I noticed a potential flaw in how the
interrupt status is handled in en7581_thermal_irq(). If the temperature
fluctuates rapidly and both EN7581_HOFSINTSTS0 and EN7581_LOFSINTSTS0
are set simultaneously in the status register before the IRQ is serviced,
the bitwise AND yields the combination of both bits.

The switch statement fails to match this combined value and falls through to
the default case, dropping the event entirely. Would it be safer to process
these bits individually rather than using a switch statement?

[Severity: High]
This isn't a bug introduced by this patch, but does the devres initialization
order leave a window for a race condition? devm_request_threaded_irq() is
called in en7581_thermal_probe() before priv->tz is initialized via
devm_thermal_of_zone_register() in airoha_thermal_probe().

If an interrupt is already pending from the bootloader, it can fire
immediately, passing a NULL priv->tz to thermal_zone_device_update().
Furthermore, on driver unbind, devres frees the thermal zone before disabling
the IRQ, potentially leading to a use-after-free if an interrupt fires.
Could moving the IRQ request after the thermal zone registration resolve this?

[Severity: High]
This is a pre-existing issue, but what happens if of_address_to_resource()
fails in en7581_thermal_probe()? The return value is currently ignored.

If it fails, for example due to a malformed device tree,
priv->scu_adc_res.start would remain 0. Later, en7581_thermal_setup_monitor()
unconditionally uses this value to configure EN7581_TEMPADCVALIDADDR,
instructing the ADC controller to read from an invalid physical address
instead of the SCU block. Should the return value of
of_address_to_resource() be validated?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260702094846.17325-1-ansuelsmth@gmail.com?part=4

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

* Re: [PATCH v6 6/7] dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC
  2026-07-02  9:48 ` [PATCH v6 6/7] dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC Christian Marangi
@ 2026-07-02 10:48   ` sashiko-bot
  0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-07-02 10:48 UTC (permalink / raw)
  To: Christian Marangi; +Cc: robh, conor+dt, devicetree

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The `#thermal-sensor-cells` property is missing from the required list for the new `airoha,an7583-chip-scu` variant.
--

commit a9f67eec355a32d0b9aed09bea5f0bd79ecbc7c5
Author: Christian Marangi <ansuelsmth@gmail.com>

dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC

This commit documents support for the Airoha AN7583 chip-scu node. It is
similar to the EN7581 SoC but adds support for a thermal sensor.

> diff --git a/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml b/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml
> index 67c449d804c22..cc564dc7b414d 100644
> --- a/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml
> +++ b/Documentation/devicetree/bindings/arm/airoha,en7581-chip-scu.yaml
[ ... ]
> @@ -19,15 +19,29 @@ properties:
>      items:
>        - enum:
>            - airoha,en7581-chip-scu
> +          - airoha,an7583-chip-scu
>        - const: syscon
>  
>    reg:
>      maxItems: 1
>  
> +  '#thermal-sensor-cells':
> +    const: 0
> +
>  required:
>    - compatible
>    - reg
>  
> +if:
> +  properties:
> +    compatible:
> +      contains:
> +        const: airoha,en7581-chip-scu
> +
> +then:
> +  properties:
> +    '#thermal-sensor-cells': false
> +

[Severity: Medium]
Since the AN7583 variant adds thermal sensor capabilities, shouldn't 
#thermal-sensor-cells be conditionally added to the required properties list 
for airoha,an7583-chip-scu?

Without enforcing this via an else block or an additional conditional, device 
tree nodes for the new AN7583 variant might silently pass schema validation 
even if they omit the #thermal-sensor-cells property.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260702094846.17325-1-ansuelsmth@gmail.com?part=6

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

* Re: [PATCH v6 7/7] thermal/drivers: airoha: Add support for AN7583 Thermal Sensor
  2026-07-02  9:48 ` [PATCH v6 7/7] thermal/drivers: airoha: Add support for AN7583 Thermal Sensor Christian Marangi
@ 2026-07-02 11:04   ` sashiko-bot
  0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-07-02 11:04 UTC (permalink / raw)
  To: Christian Marangi; +Cc: devicetree, robh, conor+dt

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

New issues:
- [Medium] The AIROHA_THERMAL_MUX_SENSOR regmap field is defined as 2 bits wide, which will silently truncate valid sensor enum values.
- [Medium] Potential signed integer overflow in temperature calculation.

Pre-existing issues:
- [High] Devm registration order causes a Use-After-Free of the thermal zone if an interrupt fires during driver unbind.
--

Note: The format of this review has been altered to a free-form summary
rather than an inline diff review to comply with automated code recitation
restrictions.

commit 20661087884d15a906fbdeeb53c5ad53bd3cd15e
Author: Christian Marangi <ansuelsmth@gmail.com>
Subject: thermal/drivers: airoha: Add support for AN7583 Thermal Sensor

Summary: This patch adds support for the Airoha AN7583 Thermal driver,
dropping the PTP_THERMAL subsystem, modifying mux logic, and updating
the EN7581 code to account for these changes.

[Severity: High]
This isn't a bug introduced by this patch, but there appears to be a
pre-existing devres registration order issue that could lead to a
use-after-free during driver unbind.

In en7581_thermal_probe(), devm_request_threaded_irq() is called to
request the IRQ early. Later, in airoha_thermal_probe(), the thermal zone is
registered via devm_thermal_of_zone_register() and assigned to priv->tz.

Because devres frees resources in the reverse order of allocation, during
an unbind or module removal, the thermal zone will be unregistered and
freed first, leaving the IRQ still active. If a hardware thermal interrupt
fires in this small window, en7581_thermal_irq() will execute and
dereference priv->tz, which has already been freed.

Should the IRQ registration be moved after the thermal zone registration,
or perhaps use devm_add_action_or_reset() to ensure safe cleanup ordering?

[Severity: Medium]
In an7583_chip_scu_fields, the AIROHA_THERMAL_MUX_SENSOR regmap field is
defined with LSB 2 and MSB 3, making it exactly 2 bits wide.

However, the an7583_thermal_adc_mux enum defines sensor indices that go
up to 6 (e.g., AN7583_CPU_TEMP_SENSOR). While the code currently only
reads sensor 0, if future or modified code attempts to select sensors 5
or 6 as provisioned by the newly added arrays, regmap_field_write() will
silently mask and truncate the value to fit into the 2 bits.

Does the AN7583_MUX_SENSOR register field span more than 2 bits in
hardware, or are the higher sensor indices handled differently?

[Severity: Medium]
In an7583_thermal_get_temp(), is there a risk of a signed integer overflow
during the temperature calculation?

The formula used is:
*temp = (slope * delta_diode * 10) / delta_gain - offset * 10;

Since slope can be up to 8390 (for the CPU sensor), multiplying slope by
delta_diode and 10 results in 83900 * delta_diode. If the ADC values
diverge such that delta_diode exceeds around 25,595, the multiplication
could overflow a 32-bit signed integer before the division by delta_gain
occurs.

Could this be mitigated by casting to s64 or using mul_u32_u32() if the
hardware ADC resolution allows for such large delta values?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260702094846.17325-1-ansuelsmth@gmail.com?part=7

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

end of thread, other threads:[~2026-07-02 11:04 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-02  9:48 [PATCH v6 0/7] thermal/drivers: airoha: Add support for AN7583 Christian Marangi
2026-07-02  9:48 ` [PATCH v6 1/7] thermal/drivers: airoha: fix copy paste error on clamp_t low temp Christian Marangi
2026-07-02 10:00   ` sashiko-bot
2026-07-02  9:48 ` [PATCH v6 2/7] thermal/drivers: airoha: fix copy paste error for sen internal Christian Marangi
2026-07-02 10:07   ` sashiko-bot
2026-07-02  9:48 ` [PATCH v6 3/7] thermal/drivers: airoha: Convert to regmap API Christian Marangi
2026-07-02 10:16   ` sashiko-bot
2026-07-02  9:48 ` [PATCH v6 4/7] thermal/drivers: airoha: Generalize probe function Christian Marangi
2026-07-02 10:35   ` sashiko-bot
2026-07-02  9:48 ` [PATCH v6 5/7] thermal/drivers: airoha: Generalize get_thermal_ADC and set_mux function Christian Marangi
2026-07-02  9:48 ` [PATCH v6 6/7] dt-bindings: arm: airoha: Add the chip-scu node for AN7583 SoC Christian Marangi
2026-07-02 10:48   ` sashiko-bot
2026-07-02  9:48 ` [PATCH v6 7/7] thermal/drivers: airoha: Add support for AN7583 Thermal Sensor Christian Marangi
2026-07-02 11:04   ` sashiko-bot

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