Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v9 0/9] Exynos Thermal code improvement
@ 2026-09-13 14:58 Anand Moon
  2026-09-13 14:58 ` [PATCH v9 1/9] thermal/drivers/exynos: Optimize clock lifecycle with devm helpers Anand Moon
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Anand Moon @ 2026-09-13 14:58 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, Krzysztof Kozlowski, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Peter Griffin,
	Alim Akhtar, open list:SAMSUNG THERMAL DRIVER, open list:THERMAL,
	open list,
	moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES

Hi All,

This series performs a number of cleanups and refactoring changes to the
Samsung Exynos TMU driver.

The series starts with clock lifecycle and interrupt handling cleanups,
followed by improvements to triminfo clock handling and correction of
the Exynos5420 efuse trimming range.

The later patches simplify the TMU register mapping and refactor the
SoC-specific configuration into static variant data selected through
the device tree match table. Thermal zone operations are also moved
into the variant data, allowing the thermal zone registration to use
the SoC-specific configuration directly.

v8: Refactor SoC-specific configuration to new exynos_tmu_soc_config
    structure which help clean up the callbacks.
    dropped the IRQ clean up patches, with new approach 
    it will be much eaasy for new SoC to be integrated
    and the code will be much better way managed in the future.
v7: Integrated my RFC patch which improves the IRQ framework
    for all the SoC link below.
v6: Add new patch to use devm_clk_get_enabled
    and Fix few typo in subject as suggested by Daniel.
v5: Drop the guard mutex patch
v4: Tried to address Lukasz review comments.

I dont have any Arm64 device the test and verify
Tested on 32 bit Arch Odroid U3 amd XU4 SoC boards.

Please share the feedback on this.

[8] https://lore.kernel.org/all/20260214181930.238981-1-linux.amoon@gmail.com/
[7] https://lore.kernel.org/all/20250813131007.343402-1-linux.amoon@gmail.com/
[6] https://lore.kernel.org/all/20250616163831.8138-1-linux.amoon@gmail.com/
[5] https://lore.kernel.org/all/20250430123306.15072-1-linux.amoon@gmail.com/
[4] https://lore.kernel.org/all/20250410063754.5483-2-linux.amoon@gmail.com/
[3] https://lore.kernel.org/all/20250310143450.8276-2-linux.amoon@gmail.com/
[2] https://lore.kernel.org/all/20250216195850.5352-2-linux.amoon@gmail.com/
[1] https://lore.kernel.org/all/20220515064126.1424-1-linux.amoon@gmail.com/
[0] https://lore.kernel.org/lkml/CANAwSgS=08fVsqn95WHzSF71WTTyD2-=K2C6-BEz0tY0t6A1-g@mail.gmail.com/T/#m77e57120d230d57f34c29e1422d7fc5f5587ac30

Thanks
-Anand

Anand Moon (9):
  thermal/drivers/exynos: Optimize clock lifecycle with devm helpers
  thermal/drivers/exynos: Drop invalid IRQF_SHARED flag from TMU
    interrupts
  thermal/drivers/exynos: Handle optional triminfo clock correctly
  thermal/drivers/exynos: Fixed the efuse min max value for exynos5420
  thermal/drivers/exynos: Remove redundant base_second register resource
  thermal/drivers/exynos: Use SoC-specific variant data to TMU
    configuration
  thermal/drivers/exynos: Move thermal zone ops to variant data
  thermal/drivers/exynos: Add missing drvdata assignment in Exynos TMU
    probe
  thermal/drivers/exynos: Select thermal emulation support

 drivers/thermal/samsung/Kconfig      |   1 +
 drivers/thermal/samsung/exynos_tmu.c | 640 +++++++++++++++------------
 2 files changed, 348 insertions(+), 293 deletions(-)


base-commit: 2f0c1cf72f4682178506f513bbf015e591b1aa4a
-- 
2.55.0



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

* [PATCH v9 1/9] thermal/drivers/exynos: Optimize clock lifecycle with devm helpers
  2026-09-13 14:58 [PATCH v9 0/9] Exynos Thermal code improvement Anand Moon
@ 2026-09-13 14:58 ` Anand Moon
  2026-09-13 14:58 ` [PATCH v9 2/9] thermal/drivers/exynos: Drop invalid IRQF_SHARED flag from TMU interrupts Anand Moon
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anand Moon @ 2026-09-13 14:58 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, Krzysztof Kozlowski, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Peter Griffin,
	Alim Akhtar, open list:SAMSUNG THERMAL DRIVER, open list:THERMAL,
	open list,
	moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES

Use the managed clock APIs to prepare and enable the TMU clocks in
exynos_tmu_probe().

Replace devm_clk_get() followed by manual clock preparation or enabling
with devm_clk_get_prepared(), devm_clk_get_optional_prepared(), and
devm_clk_get_enabled(). This also allows the manual clock cleanup and
error handling paths to be removed.

Preserve the existing requirement for the triminfo clock on
SOC_ARCH_EXYNOS5420_TRIMINFO when using the optional clock API.

This simplifies the probe and remove paths and ensures clock resources
are automatically released when the device is removed or probe fails.

Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
 drivers/thermal/samsung/exynos_tmu.c | 86 ++++++++--------------------
 1 file changed, 25 insertions(+), 61 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 56717bb50d60..e75040222ccf 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -1036,65 +1036,44 @@ static int exynos_tmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	data->clk = devm_clk_get(dev, "tmu_apbif");
+	data->clk = devm_clk_get_prepared(dev, "tmu_apbif");
 	if (IS_ERR(data->clk))
-		return dev_err_probe(dev, PTR_ERR(data->clk), "Failed to get clock\n");
-
-	data->clk_sec = devm_clk_get(dev, "tmu_triminfo_apbif");
-	if (IS_ERR(data->clk_sec)) {
-		if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
-			return dev_err_probe(dev, PTR_ERR(data->clk_sec),
-					     "Failed to get triminfo clock\n");
-	} else {
-		ret = clk_prepare(data->clk_sec);
-		if (ret) {
-			dev_err(dev, "Failed to get clock\n");
-			return ret;
-		}
-	}
-
-	ret = clk_prepare(data->clk);
-	if (ret) {
-		dev_err(dev, "Failed to get clock\n");
-		goto err_clk_sec;
-	}
-
-	switch (data->soc) {
-	case SOC_ARCH_EXYNOS5433:
-	case SOC_ARCH_EXYNOS7:
-		data->sclk = devm_clk_get(dev, "tmu_sclk");
-		if (IS_ERR(data->sclk)) {
-			ret = dev_err_probe(dev, PTR_ERR(data->sclk), "Failed to get sclk\n");
-			goto err_clk;
-		} else {
-			ret = clk_prepare_enable(data->sclk);
-			if (ret) {
-				dev_err(dev, "Failed to enable sclk\n");
-				goto err_clk;
-			}
-		}
-		break;
-	default:
-		break;
+		return dev_err_probe(dev, PTR_ERR(data->clk),
+				     "Failed to get tmu_apbif clock\n");
+
+	data->clk_sec = devm_clk_get_optional_prepared(dev,
+						       "tmu_triminfo_apbif");
+	if (IS_ERR(data->clk_sec))
+		return dev_err_probe(dev, PTR_ERR(data->clk_sec),
+				     "Failed to get tmu_triminfo_apbif clock\n");
+
+	if (!data->clk_sec && data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
+		return dev_err_probe(dev, -ENOENT,
+				     "Failed to get tmu_triminfo_apbif clock\n");
+
+	if (data->soc == SOC_ARCH_EXYNOS5433 ||
+	    data->soc == SOC_ARCH_EXYNOS7) {
+		data->sclk = devm_clk_get_enabled(dev, "tmu_sclk");
+		if (IS_ERR(data->sclk))
+			return dev_err_probe(dev, PTR_ERR(data->sclk),
+					     "Failed to get tmu_sclk clock\n");
 	}
 
 	ret = exynos_tmu_initialize(pdev);
 	if (ret) {
 		dev_err(dev, "Failed to initialize TMU\n");
-		goto err_sclk;
+		return ret;
 	}
 
 	data->tzd = devm_thermal_of_zone_register(dev, 0, data,
 						  &exynos_sensor_ops);
-	if (IS_ERR(data->tzd)) {
+	if (IS_ERR(data->tzd))
 		ret = dev_err_probe(dev, PTR_ERR(data->tzd), "Failed to register sensor\n");
-		goto err_sclk;
-	}
 
 	ret = exynos_thermal_zone_configure(pdev);
 	if (ret) {
 		dev_err(dev, "Failed to configure the thermal zone\n");
-		goto err_sclk;
+		return ret;
 	}
 
 	ret = devm_request_threaded_irq(dev, data->irq, NULL,
@@ -1103,31 +1082,16 @@ static int exynos_tmu_probe(struct platform_device *pdev)
 						| IRQF_SHARED | IRQF_ONESHOT,
 					dev_name(dev), data);
 	if (ret)
-		goto err_sclk;
+		return dev_err_probe(dev, ret, "Failed to request irq\n");
 
 	exynos_tmu_control(pdev, true);
-	return 0;
 
-err_sclk:
-	clk_disable_unprepare(data->sclk);
-err_clk:
-	clk_unprepare(data->clk);
-err_clk_sec:
-	if (!IS_ERR(data->clk_sec))
-		clk_unprepare(data->clk_sec);
-	return ret;
+	return 0;
 }
 
 static void exynos_tmu_remove(struct platform_device *pdev)
 {
-	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
-
 	exynos_tmu_control(pdev, false);
-
-	clk_disable_unprepare(data->sclk);
-	clk_unprepare(data->clk);
-	if (!IS_ERR(data->clk_sec))
-		clk_unprepare(data->clk_sec);
 }
 
 #ifdef CONFIG_PM_SLEEP
-- 
2.55.0



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

* [PATCH v9 2/9] thermal/drivers/exynos: Drop invalid IRQF_SHARED flag from TMU interrupts
  2026-09-13 14:58 [PATCH v9 0/9] Exynos Thermal code improvement Anand Moon
  2026-09-13 14:58 ` [PATCH v9 1/9] thermal/drivers/exynos: Optimize clock lifecycle with devm helpers Anand Moon
@ 2026-09-13 14:58 ` Anand Moon
  2026-09-13 14:58 ` [PATCH v9 3/9] thermal/drivers/exynos: Handle optional triminfo clock correctly Anand Moon
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anand Moon @ 2026-09-13 14:58 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, Krzysztof Kozlowski, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Peter Griffin,
	Alim Akhtar, open list:SAMSUNG THERMAL DRIVER, open list:THERMAL,
	open list,
	moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES

Remove the IRQF_SHARED flag from devm_request_threaded_irq().

The driver requests a threaded interrupt with a NULL primary handler,
which requires IRQF_ONESHOT to keep the interrupt line masked until
the threaded handler completes.

The TMU interrupts are dedicated GIC SPIs in the Exynos device tree
configurations, so there is no need to request them as shared
interrupts.

Requesting the interrupt without IRQF_SHARED avoids unnecessary
interrupt sharing and matches the dedicated nature of the TMU
interrupt lines.

Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
 drivers/thermal/samsung/exynos_tmu.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index e75040222ccf..825dbdef0b9a 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -1078,8 +1078,7 @@ static int exynos_tmu_probe(struct platform_device *pdev)
 
 	ret = devm_request_threaded_irq(dev, data->irq, NULL,
 					exynos_tmu_threaded_irq,
-					IRQF_TRIGGER_RISING
-						| IRQF_SHARED | IRQF_ONESHOT,
+					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
 					dev_name(dev), data);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to request irq\n");
-- 
2.55.0



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

* [PATCH v9 3/9] thermal/drivers/exynos: Handle optional triminfo clock correctly
  2026-09-13 14:58 [PATCH v9 0/9] Exynos Thermal code improvement Anand Moon
  2026-09-13 14:58 ` [PATCH v9 1/9] thermal/drivers/exynos: Optimize clock lifecycle with devm helpers Anand Moon
  2026-09-13 14:58 ` [PATCH v9 2/9] thermal/drivers/exynos: Drop invalid IRQF_SHARED flag from TMU interrupts Anand Moon
@ 2026-09-13 14:58 ` Anand Moon
  2026-09-13 14:58 ` [PATCH v9 4/9] thermal/drivers/exynos: Fixed the efuse min max value for exynos5420 Anand Moon
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anand Moon @ 2026-09-13 14:58 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, Krzysztof Kozlowski, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Peter Griffin,
	Alim Akhtar, open list:SAMSUNG THERMAL DRIVER, open list:THERMAL,
	open list,
	moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES

The triminfo clock is obtained using devm_clk_get_optional_prepared(),
which returns NULL when the optional clock is not present.

Update the clock checks in exynos_tmu_initialize() to test for NULL
instead of using IS_ERR(), allowing TMU instances without a triminfo
clock to initialize correctly.

Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
 drivers/thermal/samsung/exynos_tmu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 825dbdef0b9a..a64b11e6acdc 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -258,7 +258,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
 
 	mutex_lock(&data->lock);
 	clk_enable(data->clk);
-	if (!IS_ERR(data->clk_sec))
+	if (data->clk_sec)
 		clk_enable(data->clk_sec);
 
 	status = readb(data->base + EXYNOS_TMU_REG_STATUS);
@@ -269,7 +269,7 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
 		data->tmu_clear_irqs(data);
 	}
 
-	if (!IS_ERR(data->clk_sec))
+	if (data->clk_sec)
 		clk_disable(data->clk_sec);
 	clk_disable(data->clk);
 	mutex_unlock(&data->lock);
-- 
2.55.0



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

* [PATCH v9 4/9] thermal/drivers/exynos: Fixed the efuse min max value for exynos5420
  2026-09-13 14:58 [PATCH v9 0/9] Exynos Thermal code improvement Anand Moon
                   ` (2 preceding siblings ...)
  2026-09-13 14:58 ` [PATCH v9 3/9] thermal/drivers/exynos: Handle optional triminfo clock correctly Anand Moon
@ 2026-09-13 14:58 ` Anand Moon
  2026-09-13 14:58 ` [PATCH v9 5/9] thermal/drivers/exynos: Remove redundant base_second register resource Anand Moon
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anand Moon @ 2026-09-13 14:58 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, Krzysztof Kozlowski, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Peter Griffin,
	Alim Akhtar, open list:SAMSUNG THERMAL DRIVER, open list:THERMAL,
	open list,
	moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES

The Exynos5420 TMU uses a valid efuse range of 16 to 76 according to
the Exynos5422 user manual. The current driver incorrectly allows
values from 0 to 100 for Exynos5420 and Exynos5420_TRIMINFO.

Separate the Exynos5420 variants from Exynos4412, Exynos5250 and
Exynos5260 and use the correct 16 to 76 efuse range for them.

Keep the existing 40 to 100 range for Exynos4412, Exynos5250 and
Exynos5260.

Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
 drivers/thermal/samsung/exynos_tmu.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index a64b11e6acdc..a38b48e2236a 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -886,6 +886,22 @@ static int exynos_map_dt_data(struct platform_device *pdev)
 	case SOC_ARCH_EXYNOS4412:
 	case SOC_ARCH_EXYNOS5250:
 	case SOC_ARCH_EXYNOS5260:
+		data->tmu_set_low_temp = exynos4412_tmu_set_low_temp;
+		data->tmu_set_high_temp = exynos4412_tmu_set_high_temp;
+		data->tmu_disable_low = exynos4412_tmu_disable_low;
+		data->tmu_disable_high = exynos4210_tmu_disable_high;
+		data->tmu_set_crit_temp = exynos4412_tmu_set_crit_temp;
+		data->tmu_initialize = exynos4412_tmu_initialize;
+		data->tmu_control = exynos4210_tmu_control;
+		data->tmu_read = exynos4412_tmu_read;
+		data->tmu_set_emulation = exynos4412_tmu_set_emulation;
+		data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
+		data->gain = 8;
+		data->reference_voltage = 16;
+		data->efuse_value = 55;
+		data->min_efuse_value = 40;
+		data->max_efuse_value = 100;
+		break;
 	case SOC_ARCH_EXYNOS5420:
 	case SOC_ARCH_EXYNOS5420_TRIMINFO:
 		data->tmu_set_low_temp = exynos4412_tmu_set_low_temp;
@@ -901,12 +917,9 @@ static int exynos_map_dt_data(struct platform_device *pdev)
 		data->gain = 8;
 		data->reference_voltage = 16;
 		data->efuse_value = 55;
-		if (data->soc != SOC_ARCH_EXYNOS5420 &&
-		    data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO)
-			data->min_efuse_value = 40;
-		else
-			data->min_efuse_value = 0;
-		data->max_efuse_value = 100;
+		/* Valid efuse range according to the Exynos5422 user manual. */
+		data->min_efuse_value = 16;
+		data->max_efuse_value = 76;
 		break;
 	case SOC_ARCH_EXYNOS5433:
 		data->tmu_set_low_temp = exynos5433_tmu_set_low_temp;
-- 
2.55.0



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

* [PATCH v9 5/9] thermal/drivers/exynos: Remove redundant base_second register resource
  2026-09-13 14:58 [PATCH v9 0/9] Exynos Thermal code improvement Anand Moon
                   ` (3 preceding siblings ...)
  2026-09-13 14:58 ` [PATCH v9 4/9] thermal/drivers/exynos: Fixed the efuse min max value for exynos5420 Anand Moon
@ 2026-09-13 14:58 ` Anand Moon
  2026-09-13 14:58 ` [PATCH v9 6/9] thermal/drivers/exynos: Use SoC-specific variant data to TMU configuration Anand Moon
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anand Moon @ 2026-09-13 14:58 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, Krzysztof Kozlowski, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Peter Griffin,
	Alim Akhtar, open list:SAMSUNG THERMAL DRIVER, open list:THERMAL,
	open list,
	moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES

The Exynos5420 TRIMINFO register can be accessed through the main TMU
register space, so a separate register mapping is not required.

Remove the base_second member and the corresponding second resource
mapping from the driver. Access EXYNOS_TMU_REG_TRIMINFO through the
main TMU base address for all supported SoCs.

Also simplify the triminfo reload handling by directly using the
appropriate reload register for Exynos3250, Exynos4412 and Exynos5250.

Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
 drivers/thermal/samsung/exynos_tmu.c | 39 +++++-----------------------
 1 file changed, 6 insertions(+), 33 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index a38b48e2236a..82cb4140646a 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -139,12 +139,11 @@ enum soc_type {
  * struct exynos_tmu_data : A structure to hold the private data of the TMU
  *			    driver
  * @base: base address of the single instance of the TMU controller.
- * @base_second: base address of the common registers of the TMU controller.
  * @irq: irq number of the TMU controller.
  * @soc: id of the SOC type.
  * @lock: lock to implement synchronization.
  * @clk: pointer to the clock structure.
- * @clk_sec: pointer to the clock structure for accessing the base_second.
+ * @clk_sec: pointer to the clock structure for accessing triminfo registers.
  * @sclk: pointer to the clock structure for accessing the tmu special clk.
  * @cal_type: calibration type for temperature
  * @efuse_value: SoC defined fuse value
@@ -172,7 +171,6 @@ enum soc_type {
  */
 struct exynos_tmu_data {
 	void __iomem *base;
-	void __iomem *base_second;
 	int irq;
 	enum soc_type soc;
 	struct mutex lock;
@@ -447,23 +445,17 @@ static void exynos4412_tmu_initialize(struct platform_device *pdev)
 	unsigned int trim_info, ctrl;
 
 	if (data->soc == SOC_ARCH_EXYNOS3250 ||
-	    data->soc == SOC_ARCH_EXYNOS4412 ||
 	    data->soc == SOC_ARCH_EXYNOS5250) {
-		if (data->soc == SOC_ARCH_EXYNOS3250) {
-			ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1);
-			ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
-			writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1);
-		}
+		ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1);
+		ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
+		writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1);
+	} else if (data->soc == SOC_ARCH_EXYNOS4412) {
 		ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2);
 		ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
 		writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2);
 	}
 
-	/* On exynos5420 the triminfo register is in the shared space */
-	if (data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
-		trim_info = readl(data->base_second + EXYNOS_TMU_REG_TRIMINFO);
-	else
-		trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
+	trim_info = readl(data->base + EXYNOS_TMU_REG_TRIMINFO);
 
 	sanitize_temp_error(data, trim_info);
 }
@@ -965,25 +957,6 @@ static int exynos_map_dt_data(struct platform_device *pdev)
 
 	data->cal_type = TYPE_ONE_POINT_TRIMMING;
 
-	/*
-	 * Check if the TMU shares some registers and then try to map the
-	 * memory of common registers.
-	 */
-	if (data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO)
-		return 0;
-
-	if (of_address_to_resource(pdev->dev.of_node, 1, &res)) {
-		dev_err(&pdev->dev, "failed to get Resource 1\n");
-		return -ENODEV;
-	}
-
-	data->base_second = devm_ioremap(&pdev->dev, res.start,
-					resource_size(&res));
-	if (!data->base_second) {
-		dev_err(&pdev->dev, "Failed to ioremap memory\n");
-		return -ENOMEM;
-	}
-
 	return 0;
 }
 
-- 
2.55.0



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

* [PATCH v9 6/9] thermal/drivers/exynos: Use SoC-specific variant data to TMU configuration
  2026-09-13 14:58 [PATCH v9 0/9] Exynos Thermal code improvement Anand Moon
                   ` (4 preceding siblings ...)
  2026-09-13 14:58 ` [PATCH v9 5/9] thermal/drivers/exynos: Remove redundant base_second register resource Anand Moon
@ 2026-09-13 14:58 ` Anand Moon
  2026-09-13 14:58 ` [PATCH v9 7/9] thermal/drivers/exynos: Move thermal zone ops to variant data Anand Moon
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Anand Moon @ 2026-09-13 14:58 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, Krzysztof Kozlowski, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Peter Griffin,
	Alim Akhtar, open list:SAMSUNG THERMAL DRIVER, open list:THERMAL,
	open list,
	moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES

Replace the SoC-specific switch statement in exynos_map_dt_data() with
static variant data selected through the device tree match table.

Move SoC-specific TMU configuration, including calibration values and
operation callbacks, from struct exynos_tmu_data into
struct exynos_tmu_variant. The variant is selected using
of_device_get_match_data() and is used throughout the driver for
SoC-specific operations.

Keep the effective reference voltage in struct exynos_tmu_data to
preserve the Exynos5433 G3D-specific reference voltage override.

This removes duplicated per-SoC initialization from the probe path and
makes the SoC-specific configuration easier to maintain and extend.

Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
 drivers/thermal/samsung/exynos_tmu.c | 472 ++++++++++++++++-----------
 1 file changed, 282 insertions(+), 190 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 82cb4140646a..a689c6a40b67 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -136,60 +136,70 @@ enum soc_type {
 };
 
 /**
- * struct exynos_tmu_data : A structure to hold the private data of the TMU
- *			    driver
- * @base: base address of the single instance of the TMU controller.
- * @irq: irq number of the TMU controller.
- * @soc: id of the SOC type.
- * @lock: lock to implement synchronization.
- * @clk: pointer to the clock structure.
- * @clk_sec: pointer to the clock structure for accessing triminfo registers.
- * @sclk: pointer to the clock structure for accessing the tmu special clk.
- * @cal_type: calibration type for temperature
- * @efuse_value: SoC defined fuse value
- * @min_efuse_value: minimum valid trimming data
- * @max_efuse_value: maximum valid trimming data
- * @temp_error1: fused value of the first point trim.
- * @temp_error2: fused value of the second point trim.
- * @gain: gain of amplifier in the positive-TC generator block
- *	0 < gain <= 15
- * @reference_voltage: reference voltage of amplifier
- *	in the positive-TC generator block
- *	0 < reference_voltage <= 31
- * @tzd: pointer to thermal_zone_device structure
- * @enabled: current status of TMU device
- * @tmu_set_low_temp: SoC specific method to set trip (falling threshold)
- * @tmu_set_high_temp: SoC specific method to set trip (rising threshold)
- * @tmu_set_crit_temp: SoC specific method to set critical temperature
- * @tmu_disable_low: SoC specific method to disable an interrupt (falling threshold)
- * @tmu_disable_high: SoC specific method to disable an interrupt (rising threshold)
- * @tmu_initialize: SoC specific TMU initialization method
- * @tmu_control: SoC specific TMU control method
- * @tmu_read: SoC specific TMU temperature read method
- * @tmu_set_emulation: SoC specific TMU emulation setting method
- * @tmu_clear_irqs: SoC specific TMU interrupts clearing method
+ * struct exynos_tmu_data - private data for the Exynos TMU driver
+ * @base: base address of the TMU controller.
+ * @variant: pointer to SoC-specific TMU configuration data.
+ * @irq: IRQ number of the TMU controller.
+ * @lock: protects access to TMU registers and shared state.
+ * @clk: pointer to the TMU APB clock.
+ * @clk_sec: pointer to the optional triminfo clock.
+ * @sclk: pointer to the TMU special clock.
+ * @cal_type: calibration type for temperature.
+ * @reference_voltage: effective reference voltage for the TMU.
+ * @temp_error1: fused value of the first calibration point.
+ * @temp_error2: fused value of the second calibration point.
+ * @tzd: thermal zone device associated with the TMU.
+ * @enabled: current status of the TMU device.
  */
 struct exynos_tmu_data {
 	void __iomem *base;
+	const struct exynos_tmu_variant *variant;
 	int irq;
-	enum soc_type soc;
 	struct mutex lock;
-	struct clk *clk, *clk_sec, *sclk;
+	struct clk *clk;
+	struct clk *clk_sec;
+	struct clk *sclk;
 	u32 cal_type;
-	u32 efuse_value;
-	u32 min_efuse_value;
-	u32 max_efuse_value;
-	u16 temp_error1, temp_error2;
-	u8 gain;
 	u8 reference_voltage;
+	u16 temp_error1;
+	u16 temp_error2;
 	struct thermal_zone_device *tzd;
 	bool enabled;
+};
+
+/**
+ * struct exynos_tmu_variant - SoC-specific TMU configuration
+ * @soc: SoC type.
+ * @gain: gain of the amplifier in the positive-TC generator block.
+ * @reference_voltage: default reference voltage of the amplifier in the
+ *                     positive-TC generator block.
+ * @efuse_value: SoC-specific fuse value.
+ * @min_efuse_value: minimum valid trimming value.
+ * @max_efuse_value: maximum valid trimming value.
+ * @tmu_set_low_temp: SoC-specific method to set the low temperature trip.
+ * @tmu_set_high_temp: SoC-specific method to set the high temperature trip.
+ * @tmu_disable_low: SoC-specific method to disable the low temperature trip.
+ * @tmu_disable_high: SoC-specific method to disable the high temperature trip.
+ * @tmu_set_crit_temp: SoC-specific method to set the critical temperature trip.
+ * @tmu_initialize: SoC-specific TMU initialization method.
+ * @tmu_control: SoC-specific TMU enable/disable method.
+ * @tmu_read: SoC-specific TMU temperature read method.
+ * @tmu_set_emulation: SoC-specific TMU emulation setting method.
+ * @tmu_clear_irqs: SoC-specific TMU interrupt clearing method.
+ */
+struct exynos_tmu_variant {
+	enum soc_type soc;
+	u8 gain;
+	u8 reference_voltage;
+	u32 efuse_value;
+	u32 min_efuse_value;
+	u32 max_efuse_value;
 
 	void (*tmu_set_low_temp)(struct exynos_tmu_data *data, u8 temp);
 	void (*tmu_set_high_temp)(struct exynos_tmu_data *data, u8 temp);
-	void (*tmu_set_crit_temp)(struct exynos_tmu_data *data, u8 temp);
 	void (*tmu_disable_low)(struct exynos_tmu_data *data);
 	void (*tmu_disable_high)(struct exynos_tmu_data *data);
+	void (*tmu_set_crit_temp)(struct exynos_tmu_data *data, u8 temp);
 	void (*tmu_initialize)(struct platform_device *pdev);
 	void (*tmu_control)(struct platform_device *pdev, bool on);
 	int (*tmu_read)(struct exynos_tmu_data *data);
@@ -229,22 +239,25 @@ static int code_to_temp(struct exynos_tmu_data *data, u16 temp_code)
 
 static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info)
 {
-	u16 tmu_temp_mask =
-		(data->soc == SOC_ARCH_EXYNOS7) ? EXYNOS7_TMU_TEMP_MASK
-						: EXYNOS_TMU_TEMP_MASK;
+	u16 tmu_temp_mask = EXYNOS_TMU_TEMP_MASK;
+
+	if (data->variant->soc == SOC_ARCH_EXYNOS7)
+		tmu_temp_mask = EXYNOS7_TMU_TEMP_MASK;
 
 	data->temp_error1 = trim_info & tmu_temp_mask;
-	data->temp_error2 = ((trim_info >> EXYNOS_TRIMINFO_85_SHIFT) &
-				EXYNOS_TMU_TEMP_MASK);
+	data->temp_error2 = (trim_info >> EXYNOS_TRIMINFO_85_SHIFT) &
+		EXYNOS_TMU_TEMP_MASK;
 
 	if (!data->temp_error1 ||
-	    (data->min_efuse_value > data->temp_error1) ||
-	    (data->temp_error1 > data->max_efuse_value))
-		data->temp_error1 = data->efuse_value & EXYNOS_TMU_TEMP_MASK;
+	    data->variant->min_efuse_value > data->temp_error1 ||
+	    data->temp_error1 > data->variant->max_efuse_value)
+		data->temp_error1 = data->variant->efuse_value &
+			EXYNOS_TMU_TEMP_MASK;
 
 	if (!data->temp_error2)
 		data->temp_error2 =
-			(data->efuse_value >> EXYNOS_TRIMINFO_85_SHIFT) &
+			(data->variant->efuse_value >>
+			 EXYNOS_TRIMINFO_85_SHIFT) &
 			EXYNOS_TMU_TEMP_MASK;
 }
 
@@ -263,8 +276,8 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
 	if (!status) {
 		ret = -EBUSY;
 	} else {
-		data->tmu_initialize(pdev);
-		data->tmu_clear_irqs(data);
+		data->variant->tmu_initialize(pdev);
+		data->variant->tmu_clear_irqs(data);
 	}
 
 	if (data->clk_sec)
@@ -284,7 +297,7 @@ static int exynos_thermal_zone_configure(struct platform_device *pdev)
 	ret = thermal_zone_get_crit_temp(tzd, &temp);
 	if (ret) {
 		/* FIXME: Remove this special case */
-		if (data->soc == SOC_ARCH_EXYNOS5433)
+		if (data->variant->soc == SOC_ARCH_EXYNOS5433)
 			return 0;
 
 		dev_err(&pdev->dev,
@@ -295,7 +308,7 @@ static int exynos_thermal_zone_configure(struct platform_device *pdev)
 	mutex_lock(&data->lock);
 	clk_enable(data->clk);
 
-	data->tmu_set_crit_temp(data, temp / MCELSIUS);
+	data->variant->tmu_set_crit_temp(data, temp / MCELSIUS);
 
 	clk_disable(data->clk);
 	mutex_unlock(&data->lock);
@@ -305,18 +318,18 @@ static int exynos_thermal_zone_configure(struct platform_device *pdev)
 
 static u32 get_con_reg(struct exynos_tmu_data *data, u32 con)
 {
-	if (data->soc == SOC_ARCH_EXYNOS4412 ||
-	    data->soc == SOC_ARCH_EXYNOS3250)
+	if (data->variant->soc == SOC_ARCH_EXYNOS4412 ||
+	    data->variant->soc == SOC_ARCH_EXYNOS3250)
 		con |= (EXYNOS4412_MUX_ADDR_VALUE << EXYNOS4412_MUX_ADDR_SHIFT);
 
 	con &= ~(EXYNOS_TMU_REF_VOLTAGE_MASK << EXYNOS_TMU_REF_VOLTAGE_SHIFT);
 	con |= data->reference_voltage << EXYNOS_TMU_REF_VOLTAGE_SHIFT;
 
 	con &= ~(EXYNOS_TMU_BUF_SLOPE_SEL_MASK << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT);
-	con |= (data->gain << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT);
+	con |= data->variant->gain << EXYNOS_TMU_BUF_SLOPE_SEL_SHIFT;
 
 	con &= ~(EXYNOS_TMU_TRIP_MODE_MASK << EXYNOS_TMU_TRIP_MODE_SHIFT);
-	con |= (EXYNOS_NOISE_CANCEL_MODE << EXYNOS_TMU_TRIP_MODE_SHIFT);
+	con |= EXYNOS_NOISE_CANCEL_MODE << EXYNOS_TMU_TRIP_MODE_SHIFT;
 
 	return con;
 }
@@ -327,7 +340,7 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
 
 	mutex_lock(&data->lock);
 	clk_enable(data->clk);
-	data->tmu_control(pdev, on);
+	data->variant->tmu_control(pdev, on);
 	data->enabled = on;
 	clk_disable(data->clk);
 	mutex_unlock(&data->lock);
@@ -352,9 +365,8 @@ static void exynos_tmu_update_temp(struct exynos_tmu_data *data, int reg_off,
 	u16 tmu_temp_mask;
 	u32 th;
 
-	tmu_temp_mask =
-		(data->soc == SOC_ARCH_EXYNOS7) ? EXYNOS7_TMU_TEMP_MASK
-						: EXYNOS_TMU_TEMP_MASK;
+	tmu_temp_mask = (data->variant->soc == SOC_ARCH_EXYNOS7) ?
+		EXYNOS7_TMU_TEMP_MASK : EXYNOS_TMU_TEMP_MASK;
 
 	th = readl(data->base + reg_off);
 	th &= ~(tmu_temp_mask << bit_off);
@@ -444,12 +456,12 @@ static void exynos4412_tmu_initialize(struct platform_device *pdev)
 	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 	unsigned int trim_info, ctrl;
 
-	if (data->soc == SOC_ARCH_EXYNOS3250 ||
-	    data->soc == SOC_ARCH_EXYNOS5250) {
+	if (data->variant->soc == SOC_ARCH_EXYNOS3250 ||
+	    data->variant->soc == SOC_ARCH_EXYNOS5250) {
 		ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON1);
 		ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
 		writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON1);
-	} else if (data->soc == SOC_ARCH_EXYNOS4412) {
+	} else if (data->variant->soc == SOC_ARCH_EXYNOS4412) {
 		ctrl = readl(data->base + EXYNOS_TMU_TRIMINFO_CON2);
 		ctrl |= EXYNOS_TRIMINFO_RELOAD_ENABLE;
 		writel(ctrl, data->base + EXYNOS_TMU_TRIMINFO_CON2);
@@ -630,7 +642,7 @@ static int exynos_get_temp(struct thermal_zone_device *tz, int *temp)
 	struct exynos_tmu_data *data = thermal_zone_device_priv(tz);
 	int value, ret = 0;
 
-	if (!data || !data->tmu_read)
+	if (!data || !data->variant || !data->variant->tmu_read)
 		return -EINVAL;
 	else if (!data->enabled)
 		/*
@@ -642,7 +654,7 @@ static int exynos_get_temp(struct thermal_zone_device *tz, int *temp)
 	mutex_lock(&data->lock);
 	clk_enable(data->clk);
 
-	value = data->tmu_read(data);
+	value = data->variant->tmu_read(data);
 	if (value < 0)
 		ret = value;
 	else
@@ -663,7 +675,7 @@ static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val,
 
 		val &= ~(EXYNOS_EMUL_TIME_MASK << EXYNOS_EMUL_TIME_SHIFT);
 		val |= (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT);
-		if (data->soc == SOC_ARCH_EXYNOS7) {
+		if (data->variant->soc == SOC_ARCH_EXYNOS7) {
 			val &= ~(EXYNOS7_EMUL_DATA_MASK <<
 				EXYNOS7_EMUL_DATA_SHIFT);
 			val |= (temp_to_code(data, temp) <<
@@ -689,11 +701,11 @@ static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data,
 	unsigned int val;
 	u32 emul_con;
 
-	if (data->soc == SOC_ARCH_EXYNOS5260)
+	if (data->variant->soc == SOC_ARCH_EXYNOS5260)
 		emul_con = EXYNOS5260_EMUL_CON;
-	else if (data->soc == SOC_ARCH_EXYNOS5433)
+	else if (data->variant->soc == SOC_ARCH_EXYNOS5433)
 		emul_con = EXYNOS5433_TMU_EMUL_CON;
-	else if (data->soc == SOC_ARCH_EXYNOS7)
+	else if (data->variant->soc == SOC_ARCH_EXYNOS7)
 		emul_con = EXYNOS7_TMU_REG_EMUL_CON;
 	else
 		emul_con = EXYNOS_EMUL_CON;
@@ -708,7 +720,7 @@ static int exynos_tmu_set_emulation(struct thermal_zone_device *tz, int temp)
 	struct exynos_tmu_data *data = thermal_zone_device_priv(tz);
 	int ret = -EINVAL;
 
-	if (data->soc == SOC_ARCH_EXYNOS4210)
+	if (data->variant->soc == SOC_ARCH_EXYNOS4210)
 		goto out;
 
 	if (temp && temp < MCELSIUS)
@@ -716,7 +728,7 @@ static int exynos_tmu_set_emulation(struct thermal_zone_device *tz, int temp)
 
 	mutex_lock(&data->lock);
 	clk_enable(data->clk);
-	data->tmu_set_emulation(data, temp);
+	data->variant->tmu_set_emulation(data, temp);
 	clk_disable(data->clk);
 	mutex_unlock(&data->lock);
 	return 0;
@@ -758,7 +770,7 @@ static irqreturn_t exynos_tmu_threaded_irq(int irq, void *id)
 	clk_enable(data->clk);
 
 	/* TODO: take action based on particular interrupt */
-	data->tmu_clear_irqs(data);
+	data->variant->tmu_clear_irqs(data);
 
 	clk_disable(data->clk);
 	mutex_unlock(&data->lock);
@@ -771,13 +783,13 @@ static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
 	unsigned int val_irq;
 	u32 tmu_intstat, tmu_intclear;
 
-	if (data->soc == SOC_ARCH_EXYNOS5260) {
+	if (data->variant->soc == SOC_ARCH_EXYNOS5260) {
 		tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
 		tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
-	} else if (data->soc == SOC_ARCH_EXYNOS7) {
+	} else if (data->variant->soc == SOC_ARCH_EXYNOS7) {
 		tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
 		tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
-	} else if (data->soc == SOC_ARCH_EXYNOS5433) {
+	} else if (data->variant->soc == SOC_ARCH_EXYNOS5433) {
 		tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
 		tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
 	} else {
@@ -797,34 +809,204 @@ static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
 	writel(val_irq, data->base + tmu_intclear);
 }
 
+static const struct exynos_tmu_variant exynos3250_data = {
+	.soc = SOC_ARCH_EXYNOS3250,
+	.gain = 8,
+	.reference_voltage = 16,
+	.efuse_value = 55,
+	.min_efuse_value = 40,
+	.max_efuse_value = 100,
+	.tmu_set_low_temp = exynos4412_tmu_set_low_temp,
+	.tmu_set_high_temp = exynos4412_tmu_set_high_temp,
+	.tmu_disable_low = exynos4412_tmu_disable_low,
+	.tmu_disable_high = exynos4210_tmu_disable_high,
+	.tmu_set_crit_temp = exynos4412_tmu_set_crit_temp,
+	.tmu_initialize = exynos4412_tmu_initialize,
+	.tmu_control = exynos4210_tmu_control,
+	.tmu_read = exynos4412_tmu_read,
+	.tmu_set_emulation = exynos4412_tmu_set_emulation,
+	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+};
+
+static const struct exynos_tmu_variant exynos4210_data = {
+	.soc = SOC_ARCH_EXYNOS4210,
+	.gain = 15,
+	.reference_voltage = 7,
+	.efuse_value = 55,
+	.min_efuse_value = 40,
+	.max_efuse_value = 100,
+	.tmu_set_low_temp = exynos4210_tmu_set_low_temp,
+	.tmu_set_high_temp = exynos4210_tmu_set_high_temp,
+	.tmu_disable_low = exynos4210_tmu_disable_low,
+	.tmu_disable_high = exynos4210_tmu_disable_high,
+	.tmu_set_crit_temp = exynos4210_tmu_set_crit_temp,
+	.tmu_initialize = exynos4210_tmu_initialize,
+	.tmu_control = exynos4210_tmu_control,
+	.tmu_read = exynos4210_tmu_read,
+	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+};
+
+static const struct exynos_tmu_variant exynos4412_data = {
+	.soc = SOC_ARCH_EXYNOS4412,
+	.gain = 8,
+	.reference_voltage = 16,
+	.efuse_value = 55,
+	.min_efuse_value = 40,
+	.max_efuse_value = 100,
+	.tmu_set_low_temp = exynos4412_tmu_set_low_temp,
+	.tmu_set_high_temp = exynos4412_tmu_set_high_temp,
+	.tmu_disable_low = exynos4412_tmu_disable_low,
+	.tmu_disable_high = exynos4210_tmu_disable_high,
+	.tmu_set_crit_temp = exynos4412_tmu_set_crit_temp,
+	.tmu_initialize = exynos4412_tmu_initialize,
+	.tmu_control = exynos4210_tmu_control,
+	.tmu_read = exynos4412_tmu_read,
+	.tmu_set_emulation = exynos4412_tmu_set_emulation,
+	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+};
+
+static const struct exynos_tmu_variant exynos5250_data = {
+	.soc = SOC_ARCH_EXYNOS5250,
+	.gain = 8,
+	.reference_voltage = 16,
+	.efuse_value = 55,
+	.min_efuse_value = 40,
+	.max_efuse_value = 100,
+	.tmu_set_low_temp = exynos4412_tmu_set_low_temp,
+	.tmu_set_high_temp = exynos4412_tmu_set_high_temp,
+	.tmu_disable_low = exynos4412_tmu_disable_low,
+	.tmu_disable_high = exynos4210_tmu_disable_high,
+	.tmu_set_crit_temp = exynos4412_tmu_set_crit_temp,
+	.tmu_initialize = exynos4412_tmu_initialize,
+	.tmu_control = exynos4210_tmu_control,
+	.tmu_read = exynos4412_tmu_read,
+	.tmu_set_emulation = exynos4412_tmu_set_emulation,
+	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+};
+
+static const struct exynos_tmu_variant exynos5260_data = {
+	.soc = SOC_ARCH_EXYNOS5260,
+	.gain = 8,
+	.reference_voltage = 16,
+	.efuse_value = 55,
+	.min_efuse_value = 40,
+	.max_efuse_value = 100,
+	.tmu_set_low_temp = exynos4412_tmu_set_low_temp,
+	.tmu_set_high_temp = exynos4412_tmu_set_high_temp,
+	.tmu_disable_low = exynos4412_tmu_disable_low,
+	.tmu_disable_high = exynos4210_tmu_disable_high,
+	.tmu_set_crit_temp = exynos4412_tmu_set_crit_temp,
+	.tmu_initialize = exynos4412_tmu_initialize,
+	.tmu_control = exynos4210_tmu_control,
+	.tmu_read = exynos4412_tmu_read,
+	.tmu_set_emulation = exynos4412_tmu_set_emulation,
+	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+};
+
+static const struct exynos_tmu_variant exynos5420_data = {
+	.soc = SOC_ARCH_EXYNOS5420,
+	.gain = 8,
+	.reference_voltage = 16,
+	.efuse_value = 55,
+	.min_efuse_value = 16,
+	.max_efuse_value = 76,
+	.tmu_set_low_temp = exynos4412_tmu_set_low_temp,
+	.tmu_set_high_temp = exynos4412_tmu_set_high_temp,
+	.tmu_disable_low = exynos4412_tmu_disable_low,
+	.tmu_disable_high = exynos4210_tmu_disable_high,
+	.tmu_set_crit_temp = exynos4412_tmu_set_crit_temp,
+	.tmu_initialize = exynos4412_tmu_initialize,
+	.tmu_control = exynos4210_tmu_control,
+	.tmu_read = exynos4412_tmu_read,
+	.tmu_set_emulation = exynos4412_tmu_set_emulation,
+	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+};
+
+static const struct exynos_tmu_variant exynos5420_triminfo_data = {
+	.soc = SOC_ARCH_EXYNOS5420_TRIMINFO,
+	.gain = 8,
+	.reference_voltage = 16,
+	.efuse_value = 55,
+	.min_efuse_value = 16,
+	.max_efuse_value = 76,
+	.tmu_set_low_temp = exynos4412_tmu_set_low_temp,
+	.tmu_set_high_temp = exynos4412_tmu_set_high_temp,
+	.tmu_disable_low = exynos4412_tmu_disable_low,
+	.tmu_disable_high = exynos4210_tmu_disable_high,
+	.tmu_set_crit_temp = exynos4412_tmu_set_crit_temp,
+	.tmu_initialize = exynos4412_tmu_initialize,
+	.tmu_control = exynos4210_tmu_control,
+	.tmu_read = exynos4412_tmu_read,
+	.tmu_set_emulation = exynos4412_tmu_set_emulation,
+	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+};
+
+static const struct exynos_tmu_variant exynos5433_data = {
+	.soc = SOC_ARCH_EXYNOS5433,
+	.gain = 8,
+	.reference_voltage = 16,
+	.efuse_value = 75,
+	.min_efuse_value = 40,
+	.max_efuse_value = 150,
+	.tmu_set_low_temp = exynos5433_tmu_set_low_temp,
+	.tmu_set_high_temp = exynos5433_tmu_set_high_temp,
+	.tmu_disable_low = exynos5433_tmu_disable_low,
+	.tmu_disable_high = exynos5433_tmu_disable_high,
+	.tmu_set_crit_temp = exynos5433_tmu_set_crit_temp,
+	.tmu_initialize = exynos5433_tmu_initialize,
+	.tmu_control = exynos5433_tmu_control,
+	.tmu_read = exynos4412_tmu_read,
+	.tmu_set_emulation = exynos4412_tmu_set_emulation,
+	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+};
+
+static const struct exynos_tmu_variant exynos7_data = {
+	.soc = SOC_ARCH_EXYNOS7,
+	.gain = 9,
+	.reference_voltage = 17,
+	.efuse_value = 75,
+	.min_efuse_value = 15,
+	.max_efuse_value = 100,
+	.tmu_set_low_temp = exynos7_tmu_set_low_temp,
+	.tmu_set_high_temp = exynos7_tmu_set_high_temp,
+	.tmu_disable_low = exynos7_tmu_disable_low,
+	.tmu_disable_high = exynos7_tmu_disable_high,
+	.tmu_set_crit_temp = exynos7_tmu_set_crit_temp,
+	.tmu_initialize = exynos7_tmu_initialize,
+	.tmu_control = exynos7_tmu_control,
+	.tmu_read = exynos7_tmu_read,
+	.tmu_set_emulation = exynos4412_tmu_set_emulation,
+	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+};
+
 static const struct of_device_id exynos_tmu_match[] = {
 	{
 		.compatible = "samsung,exynos3250-tmu",
-		.data = (const void *)SOC_ARCH_EXYNOS3250,
+		.data = &exynos3250_data,
 	}, {
 		.compatible = "samsung,exynos4210-tmu",
-		.data = (const void *)SOC_ARCH_EXYNOS4210,
+		.data = &exynos4210_data,
 	}, {
 		.compatible = "samsung,exynos4412-tmu",
-		.data = (const void *)SOC_ARCH_EXYNOS4412,
+		.data = &exynos4412_data,
 	}, {
 		.compatible = "samsung,exynos5250-tmu",
-		.data = (const void *)SOC_ARCH_EXYNOS5250,
+		.data = &exynos5250_data,
 	}, {
 		.compatible = "samsung,exynos5260-tmu",
-		.data = (const void *)SOC_ARCH_EXYNOS5260,
+		.data = &exynos5260_data,
 	}, {
 		.compatible = "samsung,exynos5420-tmu",
-		.data = (const void *)SOC_ARCH_EXYNOS5420,
+		.data = &exynos5420_data,
 	}, {
 		.compatible = "samsung,exynos5420-tmu-ext-triminfo",
-		.data = (const void *)SOC_ARCH_EXYNOS5420_TRIMINFO,
+		.data = &exynos5420_triminfo_data,
 	}, {
 		.compatible = "samsung,exynos5433-tmu",
-		.data = (const void *)SOC_ARCH_EXYNOS5433,
+		.data = &exynos5433_data,
 	}, {
 		.compatible = "samsung,exynos7-tmu",
-		.data = (const void *)SOC_ARCH_EXYNOS7,
+		.data = &exynos7_data,
 	},
 	{ },
 };
@@ -855,108 +1037,18 @@ static int exynos_map_dt_data(struct platform_device *pdev)
 		return -EADDRNOTAVAIL;
 	}
 
-	data->soc = (uintptr_t)of_device_get_match_data(&pdev->dev);
-
-	switch (data->soc) {
-	case SOC_ARCH_EXYNOS4210:
-		data->tmu_set_low_temp = exynos4210_tmu_set_low_temp;
-		data->tmu_set_high_temp = exynos4210_tmu_set_high_temp;
-		data->tmu_disable_low = exynos4210_tmu_disable_low;
-		data->tmu_disable_high = exynos4210_tmu_disable_high;
-		data->tmu_set_crit_temp = exynos4210_tmu_set_crit_temp;
-		data->tmu_initialize = exynos4210_tmu_initialize;
-		data->tmu_control = exynos4210_tmu_control;
-		data->tmu_read = exynos4210_tmu_read;
-		data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
-		data->gain = 15;
-		data->reference_voltage = 7;
-		data->efuse_value = 55;
-		data->min_efuse_value = 40;
-		data->max_efuse_value = 100;
-		break;
-	case SOC_ARCH_EXYNOS3250:
-	case SOC_ARCH_EXYNOS4412:
-	case SOC_ARCH_EXYNOS5250:
-	case SOC_ARCH_EXYNOS5260:
-		data->tmu_set_low_temp = exynos4412_tmu_set_low_temp;
-		data->tmu_set_high_temp = exynos4412_tmu_set_high_temp;
-		data->tmu_disable_low = exynos4412_tmu_disable_low;
-		data->tmu_disable_high = exynos4210_tmu_disable_high;
-		data->tmu_set_crit_temp = exynos4412_tmu_set_crit_temp;
-		data->tmu_initialize = exynos4412_tmu_initialize;
-		data->tmu_control = exynos4210_tmu_control;
-		data->tmu_read = exynos4412_tmu_read;
-		data->tmu_set_emulation = exynos4412_tmu_set_emulation;
-		data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
-		data->gain = 8;
-		data->reference_voltage = 16;
-		data->efuse_value = 55;
-		data->min_efuse_value = 40;
-		data->max_efuse_value = 100;
-		break;
-	case SOC_ARCH_EXYNOS5420:
-	case SOC_ARCH_EXYNOS5420_TRIMINFO:
-		data->tmu_set_low_temp = exynos4412_tmu_set_low_temp;
-		data->tmu_set_high_temp = exynos4412_tmu_set_high_temp;
-		data->tmu_disable_low = exynos4412_tmu_disable_low;
-		data->tmu_disable_high = exynos4210_tmu_disable_high;
-		data->tmu_set_crit_temp = exynos4412_tmu_set_crit_temp;
-		data->tmu_initialize = exynos4412_tmu_initialize;
-		data->tmu_control = exynos4210_tmu_control;
-		data->tmu_read = exynos4412_tmu_read;
-		data->tmu_set_emulation = exynos4412_tmu_set_emulation;
-		data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
-		data->gain = 8;
-		data->reference_voltage = 16;
-		data->efuse_value = 55;
-		/* Valid efuse range according to the Exynos5422 user manual. */
-		data->min_efuse_value = 16;
-		data->max_efuse_value = 76;
-		break;
-	case SOC_ARCH_EXYNOS5433:
-		data->tmu_set_low_temp = exynos5433_tmu_set_low_temp;
-		data->tmu_set_high_temp = exynos5433_tmu_set_high_temp;
-		data->tmu_disable_low = exynos5433_tmu_disable_low;
-		data->tmu_disable_high = exynos5433_tmu_disable_high;
-		data->tmu_set_crit_temp = exynos5433_tmu_set_crit_temp;
-		data->tmu_initialize = exynos5433_tmu_initialize;
-		data->tmu_control = exynos5433_tmu_control;
-		data->tmu_read = exynos4412_tmu_read;
-		data->tmu_set_emulation = exynos4412_tmu_set_emulation;
-		data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
-		data->gain = 8;
-		if (res.start == EXYNOS5433_G3D_BASE)
-			data->reference_voltage = 23;
-		else
-			data->reference_voltage = 16;
-		data->efuse_value = 75;
-		data->min_efuse_value = 40;
-		data->max_efuse_value = 150;
-		break;
-	case SOC_ARCH_EXYNOS7:
-		data->tmu_set_low_temp = exynos7_tmu_set_low_temp;
-		data->tmu_set_high_temp = exynos7_tmu_set_high_temp;
-		data->tmu_disable_low = exynos7_tmu_disable_low;
-		data->tmu_disable_high = exynos7_tmu_disable_high;
-		data->tmu_set_crit_temp = exynos7_tmu_set_crit_temp;
-		data->tmu_initialize = exynos7_tmu_initialize;
-		data->tmu_control = exynos7_tmu_control;
-		data->tmu_read = exynos7_tmu_read;
-		data->tmu_set_emulation = exynos4412_tmu_set_emulation;
-		data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
-		data->gain = 9;
-		data->reference_voltage = 17;
-		data->efuse_value = 75;
-		data->min_efuse_value = 15;
-		data->max_efuse_value = 100;
-		break;
-	default:
-		dev_err(&pdev->dev, "Platform not supported\n");
+	data->variant = of_device_get_match_data(&pdev->dev);
+	if (!data->variant)
 		return -EINVAL;
-	}
 
 	data->cal_type = TYPE_ONE_POINT_TRIMMING;
 
+	data->reference_voltage = data->variant->reference_voltage;
+
+	if (data->variant->soc == SOC_ARCH_EXYNOS5433 &&
+	    res.start == EXYNOS5433_G3D_BASE)
+		data->reference_voltage = 23;
+
 	return 0;
 }
 
@@ -968,13 +1060,13 @@ static int exynos_set_trips(struct thermal_zone_device *tz, int low, int high)
 	clk_enable(data->clk);
 
 	if (low > INT_MIN)
-		data->tmu_set_low_temp(data, low / MCELSIUS);
+		data->variant->tmu_set_low_temp(data, low / MCELSIUS);
 	else
-		data->tmu_disable_low(data);
+		data->variant->tmu_disable_low(data);
 	if (high < INT_MAX)
-		data->tmu_set_high_temp(data, high / MCELSIUS);
+		data->variant->tmu_set_high_temp(data, high / MCELSIUS);
 	else
-		data->tmu_disable_high(data);
+		data->variant->tmu_disable_high(data);
 
 	clk_disable(data->clk);
 	mutex_unlock(&data->lock);
@@ -1033,12 +1125,12 @@ static int exynos_tmu_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(data->clk_sec),
 				     "Failed to get tmu_triminfo_apbif clock\n");
 
-	if (!data->clk_sec && data->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
+	if (!data->clk_sec && data->variant->soc == SOC_ARCH_EXYNOS5420_TRIMINFO)
 		return dev_err_probe(dev, -ENOENT,
 				     "Failed to get tmu_triminfo_apbif clock\n");
 
-	if (data->soc == SOC_ARCH_EXYNOS5433 ||
-	    data->soc == SOC_ARCH_EXYNOS7) {
+	if (data->variant->soc == SOC_ARCH_EXYNOS5433 ||
+	    data->variant->soc == SOC_ARCH_EXYNOS7) {
 		data->sclk = devm_clk_get_enabled(dev, "tmu_sclk");
 		if (IS_ERR(data->sclk))
 			return dev_err_probe(dev, PTR_ERR(data->sclk),
-- 
2.55.0



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

* [PATCH v9 7/9] thermal/drivers/exynos: Move thermal zone ops to variant data
  2026-09-13 14:58 [PATCH v9 0/9] Exynos Thermal code improvement Anand Moon
                   ` (5 preceding siblings ...)
  2026-09-13 14:58 ` [PATCH v9 6/9] thermal/drivers/exynos: Use SoC-specific variant data to TMU configuration Anand Moon
@ 2026-09-13 14:58 ` Anand Moon
  2026-09-13 14:58 ` [PATCH v9 8/9] thermal/drivers/exynos: Add missing drvdata assignment in Exynos TMU probe Anand Moon
  2026-09-13 14:58 ` [PATCH v9 9/9] thermal/drivers/exynos: Select thermal emulation support Anand Moon
  8 siblings, 0 replies; 10+ messages in thread
From: Anand Moon @ 2026-09-13 14:58 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, Krzysztof Kozlowski, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Peter Griffin,
	Alim Akhtar, open list:SAMSUNG THERMAL DRIVER, open list:THERMAL,
	open list,
	moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES

Move the thermal zone device operations into the SoC-specific variant
data and use the variant when registering the thermal zone.

Store a thermal_zone_device_ops pointer in struct exynos_tmu_variant
so that each supported SoC can provide its own thermal zone operations.

This allows thermal zone registration to be selected together with the
other SoC-specific TMU configuration through the device tree match data.

Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
 drivers/thermal/samsung/exynos_tmu.c | 69 ++++++++++++++++------------
 1 file changed, 40 insertions(+), 29 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index a689c6a40b67..0e7b92035850 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -186,6 +186,7 @@ struct exynos_tmu_data {
  * @tmu_read: SoC-specific TMU temperature read method.
  * @tmu_set_emulation: SoC-specific TMU emulation setting method.
  * @tmu_clear_irqs: SoC-specific TMU interrupt clearing method.
+ * @tmu_ops: SoC-specific thermal zone device operations.
  */
 struct exynos_tmu_variant {
 	enum soc_type soc;
@@ -205,6 +206,7 @@ struct exynos_tmu_variant {
 	int (*tmu_read)(struct exynos_tmu_data *data);
 	void (*tmu_set_emulation)(struct exynos_tmu_data *data, int temp);
 	void (*tmu_clear_irqs)(struct exynos_tmu_data *data);
+	const struct thermal_zone_device_ops *tmu_ops;
 };
 
 /*
@@ -809,6 +811,34 @@ static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
 	writel(val_irq, data->base + tmu_intclear);
 }
 
+static int exynos_set_trips(struct thermal_zone_device *tz, int low, int high)
+{
+	struct exynos_tmu_data *data = thermal_zone_device_priv(tz);
+
+	mutex_lock(&data->lock);
+	clk_enable(data->clk);
+
+	if (low > INT_MIN)
+		data->variant->tmu_set_low_temp(data, low / MCELSIUS);
+	else
+		data->variant->tmu_disable_low(data);
+	if (high < INT_MAX)
+		data->variant->tmu_set_high_temp(data, high / MCELSIUS);
+	else
+		data->variant->tmu_disable_high(data);
+
+	clk_disable(data->clk);
+	mutex_unlock(&data->lock);
+
+	return 0;
+}
+
+static const struct thermal_zone_device_ops exynos_sensor_ops = {
+	.get_temp = exynos_get_temp,
+	.set_emul_temp = exynos_tmu_set_emulation,
+	.set_trips = exynos_set_trips,
+};
+
 static const struct exynos_tmu_variant exynos3250_data = {
 	.soc = SOC_ARCH_EXYNOS3250,
 	.gain = 8,
@@ -826,6 +856,7 @@ static const struct exynos_tmu_variant exynos3250_data = {
 	.tmu_read = exynos4412_tmu_read,
 	.tmu_set_emulation = exynos4412_tmu_set_emulation,
 	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+	.tmu_ops = &exynos_sensor_ops,
 };
 
 static const struct exynos_tmu_variant exynos4210_data = {
@@ -844,6 +875,7 @@ static const struct exynos_tmu_variant exynos4210_data = {
 	.tmu_control = exynos4210_tmu_control,
 	.tmu_read = exynos4210_tmu_read,
 	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+	.tmu_ops = &exynos_sensor_ops,
 };
 
 static const struct exynos_tmu_variant exynos4412_data = {
@@ -863,6 +895,7 @@ static const struct exynos_tmu_variant exynos4412_data = {
 	.tmu_read = exynos4412_tmu_read,
 	.tmu_set_emulation = exynos4412_tmu_set_emulation,
 	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+	.tmu_ops = &exynos_sensor_ops,
 };
 
 static const struct exynos_tmu_variant exynos5250_data = {
@@ -882,6 +915,7 @@ static const struct exynos_tmu_variant exynos5250_data = {
 	.tmu_read = exynos4412_tmu_read,
 	.tmu_set_emulation = exynos4412_tmu_set_emulation,
 	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+	.tmu_ops = &exynos_sensor_ops,
 };
 
 static const struct exynos_tmu_variant exynos5260_data = {
@@ -901,6 +935,7 @@ static const struct exynos_tmu_variant exynos5260_data = {
 	.tmu_read = exynos4412_tmu_read,
 	.tmu_set_emulation = exynos4412_tmu_set_emulation,
 	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+	.tmu_ops = &exynos_sensor_ops,
 };
 
 static const struct exynos_tmu_variant exynos5420_data = {
@@ -920,6 +955,7 @@ static const struct exynos_tmu_variant exynos5420_data = {
 	.tmu_read = exynos4412_tmu_read,
 	.tmu_set_emulation = exynos4412_tmu_set_emulation,
 	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+	.tmu_ops = &exynos_sensor_ops,
 };
 
 static const struct exynos_tmu_variant exynos5420_triminfo_data = {
@@ -939,6 +975,7 @@ static const struct exynos_tmu_variant exynos5420_triminfo_data = {
 	.tmu_read = exynos4412_tmu_read,
 	.tmu_set_emulation = exynos4412_tmu_set_emulation,
 	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+	.tmu_ops = &exynos_sensor_ops,
 };
 
 static const struct exynos_tmu_variant exynos5433_data = {
@@ -958,6 +995,7 @@ static const struct exynos_tmu_variant exynos5433_data = {
 	.tmu_read = exynos4412_tmu_read,
 	.tmu_set_emulation = exynos4412_tmu_set_emulation,
 	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+	.tmu_ops = &exynos_sensor_ops,
 };
 
 static const struct exynos_tmu_variant exynos7_data = {
@@ -977,6 +1015,7 @@ static const struct exynos_tmu_variant exynos7_data = {
 	.tmu_read = exynos7_tmu_read,
 	.tmu_set_emulation = exynos4412_tmu_set_emulation,
 	.tmu_clear_irqs = exynos4210_tmu_clear_irqs,
+	.tmu_ops = &exynos_sensor_ops,
 };
 
 static const struct of_device_id exynos_tmu_match[] = {
@@ -1052,34 +1091,6 @@ static int exynos_map_dt_data(struct platform_device *pdev)
 	return 0;
 }
 
-static int exynos_set_trips(struct thermal_zone_device *tz, int low, int high)
-{
-	struct exynos_tmu_data *data = thermal_zone_device_priv(tz);
-
-	mutex_lock(&data->lock);
-	clk_enable(data->clk);
-
-	if (low > INT_MIN)
-		data->variant->tmu_set_low_temp(data, low / MCELSIUS);
-	else
-		data->variant->tmu_disable_low(data);
-	if (high < INT_MAX)
-		data->variant->tmu_set_high_temp(data, high / MCELSIUS);
-	else
-		data->variant->tmu_disable_high(data);
-
-	clk_disable(data->clk);
-	mutex_unlock(&data->lock);
-
-	return 0;
-}
-
-static const struct thermal_zone_device_ops exynos_sensor_ops = {
-	.get_temp = exynos_get_temp,
-	.set_emul_temp = exynos_tmu_set_emulation,
-	.set_trips = exynos_set_trips,
-};
-
 static int exynos_tmu_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1144,7 +1155,7 @@ static int exynos_tmu_probe(struct platform_device *pdev)
 	}
 
 	data->tzd = devm_thermal_of_zone_register(dev, 0, data,
-						  &exynos_sensor_ops);
+						  data->variant->tmu_ops);
 	if (IS_ERR(data->tzd))
 		ret = dev_err_probe(dev, PTR_ERR(data->tzd), "Failed to register sensor\n");
 
-- 
2.55.0



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

* [PATCH v9 8/9] thermal/drivers/exynos: Add missing drvdata assignment in Exynos TMU probe
  2026-09-13 14:58 [PATCH v9 0/9] Exynos Thermal code improvement Anand Moon
                   ` (6 preceding siblings ...)
  2026-09-13 14:58 ` [PATCH v9 7/9] thermal/drivers/exynos: Move thermal zone ops to variant data Anand Moon
@ 2026-09-13 14:58 ` Anand Moon
  2026-09-13 14:58 ` [PATCH v9 9/9] thermal/drivers/exynos: Select thermal emulation support Anand Moon
  8 siblings, 0 replies; 10+ messages in thread
From: Anand Moon @ 2026-09-13 14:58 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, Krzysztof Kozlowski, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Peter Griffin,
	Alim Akhtar, open list:SAMSUNG THERMAL DRIVER, open list:THERMAL,
	open list,
	moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES

Add dev_set_drvdata(&pdev->dev, data) early in the probe function,
ensuring that the driver data is properly registered and accessible
throughout the lifecycle of the device.

Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
 drivers/thermal/samsung/exynos_tmu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 0e7b92035850..fe56a48be5fe 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -1125,6 +1125,8 @@ static int exynos_tmu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	dev_set_drvdata(&pdev->dev, data);
+
 	data->clk = devm_clk_get_prepared(dev, "tmu_apbif");
 	if (IS_ERR(data->clk))
 		return dev_err_probe(dev, PTR_ERR(data->clk),
-- 
2.55.0



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

* [PATCH v9 9/9] thermal/drivers/exynos: Select thermal emulation support
  2026-09-13 14:58 [PATCH v9 0/9] Exynos Thermal code improvement Anand Moon
                   ` (7 preceding siblings ...)
  2026-09-13 14:58 ` [PATCH v9 8/9] thermal/drivers/exynos: Add missing drvdata assignment in Exynos TMU probe Anand Moon
@ 2026-09-13 14:58 ` Anand Moon
  8 siblings, 0 replies; 10+ messages in thread
From: Anand Moon @ 2026-09-13 14:58 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, Krzysztof Kozlowski, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Peter Griffin,
	Alim Akhtar, open list:SAMSUNG THERMAL DRIVER, open list:THERMAL,
	open list,
	moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES

Select THERMAL_EMULATION when EXYNOS_THERMAL is enabled, as the Exynos
TMU driver provides thermal emulation support.

This ensures the thermal emulation framework is enabled whenever the
Exynos TMU driver is built.

Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
 drivers/thermal/samsung/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig
index e1e8035d24fb..7d5590f78185 100644
--- a/drivers/thermal/samsung/Kconfig
+++ b/drivers/thermal/samsung/Kconfig
@@ -4,6 +4,7 @@ config EXYNOS_THERMAL
 	depends on THERMAL_OF
 	depends on HAS_IOMEM
 	default ARCH_EXYNOS
+	select THERMAL_EMULATION
 	help
 	  If you say yes here you get support for the TMU (Thermal Management
 	  Unit) driver for Samsung Exynos series of SoCs. This driver initialises
-- 
2.55.0



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

end of thread, other threads:[~2026-09-13 15:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-13 14:58 [PATCH v9 0/9] Exynos Thermal code improvement Anand Moon
2026-09-13 14:58 ` [PATCH v9 1/9] thermal/drivers/exynos: Optimize clock lifecycle with devm helpers Anand Moon
2026-09-13 14:58 ` [PATCH v9 2/9] thermal/drivers/exynos: Drop invalid IRQF_SHARED flag from TMU interrupts Anand Moon
2026-09-13 14:58 ` [PATCH v9 3/9] thermal/drivers/exynos: Handle optional triminfo clock correctly Anand Moon
2026-09-13 14:58 ` [PATCH v9 4/9] thermal/drivers/exynos: Fixed the efuse min max value for exynos5420 Anand Moon
2026-09-13 14:58 ` [PATCH v9 5/9] thermal/drivers/exynos: Remove redundant base_second register resource Anand Moon
2026-09-13 14:58 ` [PATCH v9 6/9] thermal/drivers/exynos: Use SoC-specific variant data to TMU configuration Anand Moon
2026-09-13 14:58 ` [PATCH v9 7/9] thermal/drivers/exynos: Move thermal zone ops to variant data Anand Moon
2026-09-13 14:58 ` [PATCH v9 8/9] thermal/drivers/exynos: Add missing drvdata assignment in Exynos TMU probe Anand Moon
2026-09-13 14:58 ` [PATCH v9 9/9] thermal/drivers/exynos: Select thermal emulation support Anand Moon

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