Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] mediatek: Make SVS work on MT8183
@ 2026-10-06  2:54 Nils Büchner
  2026-10-06  2:54 ` [PATCH 1/2] thermal/drivers/mediatek/auxadc: Register per-sensor thermal zones Nils Büchner
  2026-10-06  2:54 ` [PATCH 2/2] soc: mediatek: mtk-svs: Don't fail init01 on a bank whose buck is not at vboot yet Nils Büchner
  0 siblings, 2 replies; 5+ messages in thread
From: Nils Büchner @ 2026-10-06  2:54 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J . Wysocki, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Zhang Rui, Lukasz Luba, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, Nils Büchner

On MT8183 mtk-svs does not probe with mainline, so the SoC never gets
its calibrated voltages and runs at the default OPP voltages. Two
independent problems stand in the way:

1. auxadc_thermal registers only thermal zone 0 (the hottest sensor),
   while mtk-svs looks up the "gpu-thermal" zone that the MT8183
   devicetree describes:

     SVSB_GPU: cannot get "gpu-thermal" thermal zone
     mtk-svs 1100bc00.svs: error -ENODEV: svs bank resource setup fail

   Patch 1 registers every sensor that has a devicetree zone.

2. With that zone available, init01 requires each bank's buck to read
   back vboot immediately after the bank was moved to its vboot OPP.
   The GPU buck follows devfreq, which has not acted yet when the GPU
   is idle, so the whole probe fails with -EPERM:

     SVSB_GPU: buck voltage: 700000uV, expected vboot: 800000uV
     mtk-svs 1100bc00.svs: error -EPERM: svs start fail

   Patch 2 polls for up to 500ms and, failing that, skips only the
   affected bank instead of all of them.

With both applied, all four banks (CPU little, CPU big, CCI, GPU)
calibrate at boot on an Acer Chromebook Spin 311 (juniper), e.g. CPU
little at 1.99 GHz goes from 1050 to 1000 mV and the GPU runs 800 MHz at
775 mV, stable under sustained full load.

Testing: runtime-tested on the device with a 7.0-based kernel (the
hardware is not set up to boot mainline); build-tested on mainline with
W=1. Only MT8183 was available for testing.

The patches touch different subsystems (thermal, MediaTek SoC) and do
not depend on each other to build; patch 2 only matters on MT8183 once
patch 1 provides the zone.

Both patches were developed with an AI coding assistant while debugging
on the hardware (see the Assisted-by tags); I reviewed and tested them.

Nils Büchner (2):
  thermal/drivers/mediatek/auxadc: Register per-sensor thermal zones
  soc: mediatek: mtk-svs: Don't fail init01 on a bank whose buck is not
    at vboot yet

 drivers/soc/mediatek/mtk-svs.c            | 34 ++++++++--
 drivers/thermal/mediatek/auxadc_thermal.c | 80 ++++++++++++++++++++++-
 2 files changed, 106 insertions(+), 8 deletions(-)

-- 
2.53.0



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

* [PATCH 1/2] thermal/drivers/mediatek/auxadc: Register per-sensor thermal zones
  2026-10-06  2:54 [PATCH 0/2] mediatek: Make SVS work on MT8183 Nils Büchner
@ 2026-10-06  2:54 ` Nils Büchner
  2026-10-07 11:51   ` Daniel Lezcano
  2026-10-06  2:54 ` [PATCH 2/2] soc: mediatek: mtk-svs: Don't fail init01 on a bank whose buck is not at vboot yet Nils Büchner
  1 sibling, 1 reply; 5+ messages in thread
From: Nils Büchner @ 2026-10-06  2:54 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J . Wysocki, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Zhang Rui, Lukasz Luba, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, Nils Büchner

The driver registers only thermal zone 0, which reports the hottest of
all sensors. The MT8183 devicetree also describes a zone per sensor
(soc, gpu, md1, cpu-little, cpu-big, abb as sensor ids 1-6), and
mtk-svs looks up the "gpu-thermal" zone for its GPU banks. Without it
SVS fails to probe on MT8183:

  SVSB_GPU: cannot get "gpu-thermal" thermal zone
  mtk-svs 1100bc00.svs: error -ENODEV: svs bank resource setup fail

so the SoC never gets its calibrated, lower voltages.

Additionally register every sensor that has a devicetree zone, using
sensor id = sensor number + 1, read from that sensor's own measurement
register. Sensors without a zone are skipped, so SoCs whose devicetrees
only describe zone 0 are unaffected.

Runtime-tested on an Acer Chromebook Spin 311 (MT8183, juniper) with a
7.0-based kernel (the hardware is not set up to boot mainline);
build-tested on mainline with W=1. On the device: all six
sensor zones register and read plausible values (31-34 C idle, close
to the board sensors), and mtk-svs finds gpu-thermal.

The change and this changelog were drafted with an AI coding assistant
during a debugging session on the hardware; they were reviewed and
tested by the submitter.

Assisted-by: Claude Opus 5.5
Signed-off-by: Nils Büchner <nils@buechner.me>
---
 drivers/thermal/mediatek/auxadc_thermal.c | 80 ++++++++++++++++++++++-
 1 file changed, 79 insertions(+), 1 deletion(-)

diff --git a/drivers/thermal/mediatek/auxadc_thermal.c b/drivers/thermal/mediatek/auxadc_thermal.c
index 9ee2e7283..59c8eaf87 100644
--- a/drivers/thermal/mediatek/auxadc_thermal.c
+++ b/drivers/thermal/mediatek/auxadc_thermal.c
@@ -308,6 +308,13 @@ struct mtk_thermal_bank {
 	int id;
 };
 
+/* A single sensor, exposed as its own thermal zone (DT sensor id = sensor + 1) */
+struct mtk_thermal_sensor {
+	struct mtk_thermal *mt;
+	int bank;
+	int index;
+};
+
 struct mtk_thermal_data {
 	s32 num_banks;
 	s32 num_sensors;
@@ -870,6 +877,77 @@ static const struct thermal_zone_device_ops mtk_thermal_ops = {
 	.get_temp = mtk_read_temp,
 };
 
+static int mtk_read_sensor_temp(struct thermal_zone_device *tz, int *temperature)
+{
+	struct mtk_thermal_sensor *sensor = thermal_zone_device_priv(tz);
+	struct mtk_thermal *mt = sensor->mt;
+	const struct mtk_thermal_data *conf = mt->conf;
+	struct mtk_thermal_bank *bank = &mt->banks[sensor->bank];
+	int temp;
+	u32 raw;
+
+	mtk_thermal_get_bank(bank);
+	raw = readl(mt->thermal_base + conf->msr[sensor->index]);
+	temp = mt->raw_to_mcelsius(mt, conf->bank_data[sensor->bank].sensors[sensor->index],
+				   raw);
+	mtk_thermal_put_bank(bank);
+
+	if (!mtk_thermal_temp_is_valid(temp))
+		return -EAGAIN;
+
+	*temperature = temp;
+
+	return 0;
+}
+
+static const struct thermal_zone_device_ops mtk_thermal_sensor_ops = {
+	.get_temp = mtk_read_sensor_temp,
+};
+
+/*
+ * Zone 0 reports the hottest sensor. Also register every individual sensor
+ * the devicetree describes (sensor id = sensor number + 1): MT8183 SVS looks
+ * up its GPU bank temperature through the "gpu-thermal" zone and cannot
+ * probe without it. Sensors without a devicetree zone are skipped.
+ */
+static int mtk_thermal_register_sensors(struct mtk_thermal *mt)
+{
+	const struct mtk_thermal_data *conf = mt->conf;
+	struct thermal_zone_device *tzdev;
+	struct mtk_thermal_sensor *sensor;
+	int id, b, i;
+
+	for (id = 1; id <= conf->num_sensors; id++) {
+		sensor = NULL;
+		for (b = 0; b < conf->num_banks && !sensor; b++) {
+			for (i = 0; i < conf->bank_data[b].num_sensors; i++) {
+				if (conf->bank_data[b].sensors[i] != id - 1)
+					continue;
+				sensor = devm_kzalloc(mt->dev, sizeof(*sensor), GFP_KERNEL);
+				if (!sensor)
+					return -ENOMEM;
+				sensor->mt = mt;
+				sensor->bank = b;
+				sensor->index = i;
+				break;
+			}
+		}
+		if (!sensor)
+			continue;
+
+		tzdev = devm_thermal_of_zone_register(mt->dev, id, sensor,
+						      &mtk_thermal_sensor_ops);
+		if (IS_ERR(tzdev)) {
+			if (PTR_ERR(tzdev) == -ENODEV)
+				continue;
+			return dev_err_probe(mt->dev, PTR_ERR(tzdev),
+					     "failed to register sensor %d\n", id);
+		}
+	}
+
+	return 0;
+}
+
 static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num,
 				  u32 apmixed_phys_base, u32 auxadc_phys_base,
 				  int ctrl_id)
@@ -1294,7 +1372,7 @@ static int mtk_thermal_probe(struct platform_device *pdev)
 	if (ret)
 		dev_warn(&pdev->dev, "error in thermal_add_hwmon_sysfs");
 
-	return 0;
+	return mtk_thermal_register_sensors(mt);
 }
 
 static struct platform_driver mtk_thermal_driver = {
-- 
2.53.0



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

* [PATCH 2/2] soc: mediatek: mtk-svs: Don't fail init01 on a bank whose buck is not at vboot yet
  2026-10-06  2:54 [PATCH 0/2] mediatek: Make SVS work on MT8183 Nils Büchner
  2026-10-06  2:54 ` [PATCH 1/2] thermal/drivers/mediatek/auxadc: Register per-sensor thermal zones Nils Büchner
@ 2026-10-06  2:54 ` Nils Büchner
  2026-10-06  8:32   ` Chen-Yu Tsai
  1 sibling, 1 reply; 5+ messages in thread
From: Nils Büchner @ 2026-10-06  2:54 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J . Wysocki, Matthias Brugger,
	AngeloGioacchino Del Regno
  Cc: Zhang Rui, Lukasz Luba, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek, Nils Büchner

svs_init01() moves every bank to its vboot OPP and then immediately
requires the bank's buck to read back exactly vboot. For the MT8183 GPU
banks the buck follows panfrost devfreq, which has not necessarily acted
on the OPP change yet (an idle GPU stays at its lowest OPP), so the
check fails and the whole SVS probe aborts with -EPERM, leaving the CPU
and CCI banks uncalibrated as well:

  SVSB_GPU: buck voltage: 700000uV, expected vboot: 800000uV
  mtk-svs 1100bc00.svs: error -EPERM: svs start fail

Poll the buck for up to 500ms before giving up. If it still is not at
vboot, skip only that bank: restore its default OPP voltages, disable it,
and calibrate the others.

On Acer Chromebook Spin 311 (MT8183) the GPU buck reaches vboot within
the poll window and all four banks complete init01/init02.

Runtime-tested on an Acer Chromebook Spin 311 (MT8183, juniper) with a
7.0-based kernel (the hardware is not set up to boot mainline);
build-tested on mainline with W=1. On the device together with
the auxadc_thermal per-sensor zone change: all four banks complete
init01/init02 at boot (CPU little 1.99 GHz 1050 -> 1000 mV), stable
under 60 s of full load on all cores at maximum frequency.

The change and this changelog were drafted with an AI coding assistant
during a debugging session on the hardware; they were reviewed and
tested by the submitter.

Fixes: 681a02e95000 ("soc: mediatek: SVS: introduce MTK SVS engine")
Assisted-by: Claude Opus 5.5
Signed-off-by: Nils Büchner <nils@buechner.me>
---
 drivers/soc/mediatek/mtk-svs.c | 34 +++++++++++++++++++++++++++-------
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 99edecb20..2598a1ccb 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -16,6 +16,7 @@
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/kthread.h>
 #include <linux/module.h>
@@ -1439,6 +1440,7 @@ static int svs_init01(struct svs_platform *svsp)
 	bool search_done;
 	int ret = 0, r;
 	u32 opp_freq, opp_vboot, buck_volt, idx, i;
+	unsigned long skipped = 0;
 
 	if (!svs_mode_available(svsp, SVSB_MODE_INIT01))
 		return 0;
@@ -1542,13 +1544,20 @@ static int svs_init01(struct svs_platform *svsp)
 						      bdata->volt_step,
 						      bdata->volt_base);
 
-		buck_volt = regulator_get_voltage(svsb->buck);
-		if (buck_volt != opp_vboot) {
-			dev_err(svsb->dev,
-				"buck voltage: %uuV, expected vboot: %uuV\n",
-				buck_volt, opp_vboot);
-			ret = -EPERM;
-			goto svs_init01_finish;
+		/*
+		 * The consumer's DVFS (e.g. GPU devfreq while the GPU is idle)
+		 * may not have moved to the vboot OPP yet. Give it a moment,
+		 * then calibrate the remaining banks without this one instead
+		 * of failing the whole SVS probe.
+		 */
+		if (read_poll_timeout(regulator_get_voltage, buck_volt,
+				      buck_volt == opp_vboot, 10000, 500000,
+				      false, svsb->buck)) {
+			dev_warn(svsb->dev,
+				 "buck voltage: %uuV, expected vboot: %uuV, skipping bank\n",
+				 buck_volt, opp_vboot);
+			__set_bit(idx, &skipped);
+			continue;
 		}
 
 		spin_lock_irqsave(&svs_lock, flags);
@@ -1578,6 +1587,14 @@ static int svs_init01(struct svs_platform *svsp)
 			if (r)
 				dev_err(svsb->dev, "opp %uHz enable fail: %d\n",
 					svsb->opp_dfreq[i], r);
+
+			/* A skipped bank keeps its default OPP voltages */
+			if (test_bit(idx, &skipped))
+				dev_pm_opp_adjust_voltage(svsb->opp_dev,
+							  svsb->opp_dfreq[i],
+							  svsb->opp_dvolt[i],
+							  svsb->opp_dvolt[i],
+							  svsb->opp_dvolt[i]);
 		}
 
 		if (svsb->volt_flags & SVSB_INIT01_PD_REQ) {
@@ -1599,6 +1616,9 @@ static int svs_init01(struct svs_platform *svsp)
 		if (r)
 			dev_err(svsb->dev, "%s disable fail: %d\n",
 				bdata->buck_name, r);
+
+		if (test_bit(idx, &skipped))
+			svsb->mode_support = SVSB_MODE_ALL_DISABLE;
 	}
 
 svs_init01_resume_cpuidle:
-- 
2.53.0



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

* Re: [PATCH 2/2] soc: mediatek: mtk-svs: Don't fail init01 on a bank whose buck is not at vboot yet
  2026-10-06  2:54 ` [PATCH 2/2] soc: mediatek: mtk-svs: Don't fail init01 on a bank whose buck is not at vboot yet Nils Büchner
@ 2026-10-06  8:32   ` Chen-Yu Tsai
  0 siblings, 0 replies; 5+ messages in thread
From: Chen-Yu Tsai @ 2026-10-06  8:32 UTC (permalink / raw)
  To: Nils Büchner
  Cc: Daniel Lezcano, Rafael J . Wysocki, Matthias Brugger,
	AngeloGioacchino Del Regno, Zhang Rui, Lukasz Luba, linux-pm,
	linux-kernel, linux-arm-kernel, linux-mediatek

On Tue, Oct 6, 2026 at 4:54 AM Nils Büchner <nils@buechner.me> wrote:
>
> svs_init01() moves every bank to its vboot OPP and then immediately
> requires the bank's buck to read back exactly vboot. For the MT8183 GPU
> banks the buck follows panfrost devfreq, which has not necessarily acted
> on the OPP change yet (an idle GPU stays at its lowest OPP), so the
> check fails and the whole SVS probe aborts with -EPERM, leaving the CPU
> and CCI banks uncalibrated as well:
>
>   SVSB_GPU: buck voltage: 700000uV, expected vboot: 800000uV
>   mtk-svs 1100bc00.svs: error -EPERM: svs start fail
>
> Poll the buck for up to 500ms before giving up. If it still is not at
> vboot, skip only that bank: restore its default OPP voltages, disable it,
> and calibrate the others.
>
> On Acer Chromebook Spin 311 (MT8183) the GPU buck reaches vboot within
> the poll window and all four banks complete init01/init02.

Were both drivers (mtk-svs and panfrost) built-in, or as modules?
This would affect the timing.

> Runtime-tested on an Acer Chromebook Spin 311 (MT8183, juniper) with a
> 7.0-based kernel (the hardware is not set up to boot mainline);
> build-tested on mainline with W=1. On the device together with
> the auxadc_thermal per-sensor zone change: all four banks complete
> init01/init02 at boot (CPU little 1.99 GHz 1050 -> 1000 mV), stable
> under 60 s of full load on all cores at maximum frequency.
>
> The change and this changelog were drafted with an AI coding assistant
> during a debugging session on the hardware; they were reviewed and
> tested by the submitter.

This section could be moved after the "---".

> Fixes: 681a02e95000 ("soc: mediatek: SVS: introduce MTK SVS engine")
> Assisted-by: Claude Opus 5.5
> Signed-off-by: Nils Büchner <nils@buechner.me>
> ---
>  drivers/soc/mediatek/mtk-svs.c | 34 +++++++++++++++++++++++++++-------
>  1 file changed, 27 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
> index 99edecb20..2598a1ccb 100644
> --- a/drivers/soc/mediatek/mtk-svs.c
> +++ b/drivers/soc/mediatek/mtk-svs.c
> @@ -16,6 +16,7 @@
>  #include <linux/device.h>
>  #include <linux/init.h>
>  #include <linux/interrupt.h>
> +#include <linux/iopoll.h>
>  #include <linux/kernel.h>
>  #include <linux/kthread.h>
>  #include <linux/module.h>
> @@ -1439,6 +1440,7 @@ static int svs_init01(struct svs_platform *svsp)
>         bool search_done;
>         int ret = 0, r;
>         u32 opp_freq, opp_vboot, buck_volt, idx, i;
> +       unsigned long skipped = 0;
>
>         if (!svs_mode_available(svsp, SVSB_MODE_INIT01))
>                 return 0;
> @@ -1542,13 +1544,20 @@ static int svs_init01(struct svs_platform *svsp)
>                                                       bdata->volt_step,
>                                                       bdata->volt_base);
>
> -               buck_volt = regulator_get_voltage(svsb->buck);
> -               if (buck_volt != opp_vboot) {
> -                       dev_err(svsb->dev,
> -                               "buck voltage: %uuV, expected vboot: %uuV\n",
> -                               buck_volt, opp_vboot);
> -                       ret = -EPERM;
> -                       goto svs_init01_finish;
> +               /*
> +                * The consumer's DVFS (e.g. GPU devfreq while the GPU is idle)
> +                * may not have moved to the vboot OPP yet. Give it a moment,
> +                * then calibrate the remaining banks without this one instead
> +                * of failing the whole SVS probe.
> +                */
> +               if (read_poll_timeout(regulator_get_voltage, buck_volt,
> +                                     buck_volt == opp_vboot, 10000, 500000,
> +                                     false, svsb->buck)) {
> +                       dev_warn(svsb->dev,
> +                                "buck voltage: %uuV, expected vboot: %uuV, skipping bank\n",
> +                                buck_volt, opp_vboot);
> +                       __set_bit(idx, &skipped);
> +                       continue;
>                 }
>
>                 spin_lock_irqsave(&svs_lock, flags);
> @@ -1578,6 +1587,14 @@ static int svs_init01(struct svs_platform *svsp)
>                         if (r)
>                                 dev_err(svsb->dev, "opp %uHz enable fail: %d\n",
>                                         svsb->opp_dfreq[i], r);
> +
> +                       /* A skipped bank keeps its default OPP voltages */
> +                       if (test_bit(idx, &skipped))
> +                               dev_pm_opp_adjust_voltage(svsb->opp_dev,
> +                                                         svsb->opp_dfreq[i],
> +                                                         svsb->opp_dvolt[i],
> +                                                         svsb->opp_dvolt[i],
> +                                                         svsb->opp_dvolt[i]);
>                 }
>
>                 if (svsb->volt_flags & SVSB_INIT01_PD_REQ) {
> @@ -1599,6 +1616,9 @@ static int svs_init01(struct svs_platform *svsp)
>                 if (r)
>                         dev_err(svsb->dev, "%s disable fail: %d\n",
>                                 bdata->buck_name, r);
> +
> +               if (test_bit(idx, &skipped))
> +                       svsb->mode_support = SVSB_MODE_ALL_DISABLE;
>         }
>
>  svs_init01_resume_cpuidle:
> --
> 2.53.0
>
>


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

* Re: [PATCH 1/2] thermal/drivers/mediatek/auxadc: Register per-sensor thermal zones
  2026-10-06  2:54 ` [PATCH 1/2] thermal/drivers/mediatek/auxadc: Register per-sensor thermal zones Nils Büchner
@ 2026-10-07 11:51   ` Daniel Lezcano
  0 siblings, 0 replies; 5+ messages in thread
From: Daniel Lezcano @ 2026-10-07 11:51 UTC (permalink / raw)
  To: Nils Büchner, Daniel Lezcano, Rafael J . Wysocki,
	Matthias Brugger, AngeloGioacchino Del Regno
  Cc: Zhang Rui, Lukasz Luba, linux-pm, linux-kernel, linux-arm-kernel,
	linux-mediatek

On 10/6/26 04:54, Nils Büchner wrote:
> The driver registers only thermal zone 0, which reports the hottest of
> all sensors. The MT8183 devicetree also describes a zone per sensor
> (soc, gpu, md1, cpu-little, cpu-big, abb as sensor ids 1-6), and
> mtk-svs looks up the "gpu-thermal" zone for its GPU banks. Without it
> SVS fails to probe on MT8183:
> 
>    SVSB_GPU: cannot get "gpu-thermal" thermal zone
>    mtk-svs 1100bc00.svs: error -ENODEV: svs bank resource setup fail
> 
> so the SoC never gets its calibrated, lower voltages.
> 
> Additionally register every sensor that has a devicetree zone, using
> sensor id = sensor number + 1, read from that sensor's own measurement
> register. Sensors without a zone are skipped, so SoCs whose devicetrees
> only describe zone 0 are unaffected.
> 
> Runtime-tested on an Acer Chromebook Spin 311 (MT8183, juniper) with a
> 7.0-based kernel (the hardware is not set up to boot mainline);
> build-tested on mainline with W=1. On the device: all six
> sensor zones register and read plausible values (31-34 C idle, close
> to the board sensors), and mtk-svs finds gpu-thermal.
> 
> The change and this changelog were drafted with an AI coding assistant
> during a debugging session on the hardware; they were reviewed and
> tested by the submitter.
> 
> Assisted-by: Claude Opus 5.5
> Signed-off-by: Nils Büchner <nils@buechner.me>
> ---
>   drivers/thermal/mediatek/auxadc_thermal.c | 80 ++++++++++++++++++++++-
>   1 file changed, 79 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/thermal/mediatek/auxadc_thermal.c b/drivers/thermal/mediatek/auxadc_thermal.c
> index 9ee2e7283..59c8eaf87 100644
> --- a/drivers/thermal/mediatek/auxadc_thermal.c
> +++ b/drivers/thermal/mediatek/auxadc_thermal.c
> @@ -308,6 +308,13 @@ struct mtk_thermal_bank {
>   	int id;
>   };
>   
> +/* A single sensor, exposed as its own thermal zone (DT sensor id = sensor + 1) */
> +struct mtk_thermal_sensor {
> +	struct mtk_thermal *mt;
> +	int bank;
> +	int index;
> +};
> +
>   struct mtk_thermal_data {
>   	s32 num_banks;
>   	s32 num_sensors;
> @@ -870,6 +877,77 @@ static const struct thermal_zone_device_ops mtk_thermal_ops = {
>   	.get_temp = mtk_read_temp,
>   };
>   
> +static int mtk_read_sensor_temp(struct thermal_zone_device *tz, int *temperature)
> +{
> +	struct mtk_thermal_sensor *sensor = thermal_zone_device_priv(tz);
> +	struct mtk_thermal *mt = sensor->mt;
> +	const struct mtk_thermal_data *conf = mt->conf;
> +	struct mtk_thermal_bank *bank = &mt->banks[sensor->bank];
> +	int temp;
> +	u32 raw;
> +
> +	mtk_thermal_get_bank(bank);
> +	raw = readl(mt->thermal_base + conf->msr[sensor->index]);
> +	temp = mt->raw_to_mcelsius(mt, conf->bank_data[sensor->bank].sensors[sensor->index],
> +				   raw);
> +	mtk_thermal_put_bank(bank);
> +
> +	if (!mtk_thermal_temp_is_valid(temp))
> +		return -EAGAIN;
> +
> +	*temperature = temp;
> +
> +	return 0;
> +}
> +
> +static const struct thermal_zone_device_ops mtk_thermal_sensor_ops = {
> +	.get_temp = mtk_read_sensor_temp,
> +};
> +
> +/*
> + * Zone 0 reports the hottest sensor. Also register every individual sensor
> + * the devicetree describes (sensor id = sensor number + 1): MT8183 SVS looks
> + * up its GPU bank temperature through the "gpu-thermal" zone and cannot
> + * probe without it. Sensors without a devicetree zone are skipped.
> + */
> +static int mtk_thermal_register_sensors(struct mtk_thermal *mt)
> +{
> +	const struct mtk_thermal_data *conf = mt->conf;
> +	struct thermal_zone_device *tzdev;
> +	struct mtk_thermal_sensor *sensor;
> +	int id, b, i;
> +
> +	for (id = 1; id <= conf->num_sensors; id++) {
> +		sensor = NULL;
> +		for (b = 0; b < conf->num_banks && !sensor; b++) {
> +			for (i = 0; i < conf->bank_data[b].num_sensors; i++) {
> +				if (conf->bank_data[b].sensors[i] != id - 1)
> +					continue;
> +				sensor = devm_kzalloc(mt->dev, sizeof(*sensor), GFP_KERNEL);
> +				if (!sensor)
> +					return -ENOMEM;
> +				sensor->mt = mt;
> +				sensor->bank = b;
> +				sensor->index = i;
> +				break;
> +			}
> +		}
> +		if (!sensor)
> +			continue;

Please move routines into self-explanatory functions and make this 
initialization function simpler to understand

> +
> +		tzdev = devm_thermal_of_zone_register(mt->dev, id, sensor,
> +						      &mtk_thermal_sensor_ops);
> +		if (IS_ERR(tzdev)) {
> +			if (PTR_ERR(tzdev) == -ENODEV)
> +				continue;
> +			return dev_err_probe(mt->dev, PTR_ERR(tzdev),
> +					     "failed to register sensor %d\n", id);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>   static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num,
>   				  u32 apmixed_phys_base, u32 auxadc_phys_base,
>   				  int ctrl_id)
> @@ -1294,7 +1372,7 @@ static int mtk_thermal_probe(struct platform_device *pdev)
>   	if (ret)
>   		dev_warn(&pdev->dev, "error in thermal_add_hwmon_sysfs");
>   
> -	return 0;
> +	return mtk_thermal_register_sensors(mt);
>   }
>   
>   static struct platform_driver mtk_thermal_driver = {



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

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

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-06  2:54 [PATCH 0/2] mediatek: Make SVS work on MT8183 Nils Büchner
2026-10-06  2:54 ` [PATCH 1/2] thermal/drivers/mediatek/auxadc: Register per-sensor thermal zones Nils Büchner
2026-10-07 11:51   ` Daniel Lezcano
2026-10-06  2:54 ` [PATCH 2/2] soc: mediatek: mtk-svs: Don't fail init01 on a bank whose buck is not at vboot yet Nils Büchner
2026-10-06  8:32   ` Chen-Yu Tsai

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