llvm.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: Anand Moon <linux.amoon@gmail.com>
To: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>,
	Krzysztof Kozlowski <krzk@kernel.org>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	Daniel Lezcano <daniel.lezcano@linaro.org>,
	Zhang Rui <rui.zhang@intel.com>,
	Lukasz Luba <lukasz.luba@arm.com>,
	Alim Akhtar <alim.akhtar@samsung.com>,
	Nathan Chancellor <nathan@kernel.org>,
	Nick Desaulniers <nick.desaulniers+lkml@gmail.com>,
	Bill Wendling <morbo@google.com>,
	Justin Stitt <justinstitt@google.com>,
	linux-pm@vger.kernel.org (open list:SAMSUNG THERMAL DRIVER),
	linux-samsung-soc@vger.kernel.org (open list:SAMSUNG THERMAL
	DRIVER),
	linux-arm-kernel@lists.infradead.org (moderated list:ARM/SAMSUNG
	S3C, S5P AND EXYNOS ARM ARCHITECTURES),
	linux-kernel@vger.kernel.org (open list),
	llvm@lists.linux.dev (open list:CLANG/LLVM BUILD
	SUPPORT:Keyword:\b(?i:clang|llvm)\b)
Cc: Anand Moon <linux.amoon@gmail.com>,
	Mateusz Majewski <m.majewski2@samsung.com>
Subject: [PATCH v7 7/7] thermal/drivers/exynos: Refactor IRQ clear logic using SoC-specific config
Date: Wed, 13 Aug 2025 18:39:51 +0530	[thread overview]
Message-ID: <20250813131007.343402-8-linux.amoon@gmail.com> (raw)
In-Reply-To: <20250813131007.343402-1-linux.amoon@gmail.com>

The Exynos TMU driver's IRQ clear logic has been refactored for improved
maintainability and reduced code duplication. A unified
exynos4210_tmu_clear_irqs() implementation now replaces the previous
reliance on SoC-specific functions and hardcoded register mappings.
This new implementation leverages SoC-specific configuration fields
(tmu_intstat, tmu_intclear, and IRQ bit mappings) stored within
exynos_tmu_data. These fields are populated during device setup within
exynos_map_dt_data(), thereby streamlining new SoC integration, ensuring
correct interrupt handling, and improving code clarity. This refactor
simplifies the addition of new SoC support, ensures correct interrupt
handling across platforms, and improves overall code clarity.

Cc: Mateusz Majewski <m.majewski2@samsung.com>
Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
v7: new patch in this series
    split the IRQ function handler per SoC.
---
 drivers/thermal/samsung/exynos_tmu.c | 150 +++++++++++++++++----------
 1 file changed, 96 insertions(+), 54 deletions(-)

diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index 5e581055e3f3..9f94c58e1e74 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -158,6 +158,8 @@ enum soc_type {
  *	0 < reference_voltage <= 31
  * @tzd: pointer to thermal_zone_device structure
  * @enabled: current status of TMU device
+ * @tmu_intstat: interrupt status register
+ * @tmu_intclear: interrupt clear register
  * @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
@@ -184,6 +186,8 @@ struct exynos_tmu_data {
 	u8 reference_voltage;
 	struct thermal_zone_device *tzd;
 	bool enabled;
+	u32 tmu_intstat;
+	u32 tmu_intclear;
 
 	void (*tmu_set_low_temp)(struct exynos_tmu_data *data, u8 temp);
 	void (*tmu_set_high_temp)(struct exynos_tmu_data *data, u8 temp);
@@ -770,67 +774,90 @@ static irqreturn_t exynos_tmu_threaded_irq(int irq, void *id)
 }
 
 static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
+{
+	unsigned int val_irq;
+	u32 tmu_intstat = data->tmu_intstat;
+	u32 tmu_intclear = data->tmu_intclear;
+
+	val_irq = readl(data->base + tmu_intstat);
+
+	/* Exynos4210 doesn't support FALL interrupts */
+	writel(val_irq, data->base + tmu_intclear);
+}
+
+static void exynos4412_tmu_clear_irqs(struct exynos_tmu_data *data)
 {
 	unsigned int val_irq, clear_irq = 0;
-	u32 tmu_intstat, tmu_intclear;
+	u32 tmu_intstat = data->tmu_intstat;
+	u32 tmu_intclear = data->tmu_intclear;
 	struct tmu_irq_map irq_map = {0};
 
-	if (data->soc == SOC_ARCH_EXYNOS5260) {
-		tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
-		tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
-	} else if (data->soc == SOC_ARCH_EXYNOS7) {
-		tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
-		tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
-	} else if (data->soc == SOC_ARCH_EXYNOS5433) {
-		tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
-		tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
-	} else {
-		tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
-		tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
+	val_irq = readl(data->base + tmu_intstat);
+
+	/* Set SoC-specific interrupt bit mappings */
+	irq_map.fall[2] = BIT(20);
+	irq_map.fall[1] = BIT(16);
+	irq_map.fall[0] = BIT(12);
+	irq_map.rise[2] = BIT(8);
+	irq_map.rise[1] = BIT(4);
+	irq_map.rise[0] = BIT(0);
+
+	/* Map active INTSTAT bits to INTCLEAR */
+	for (int i = 0; i < 3; i++) {
+		if (val_irq & irq_map.fall[i])
+			clear_irq |= irq_map.fall[i];
+		if (val_irq & irq_map.rise[i])
+			clear_irq |= irq_map.rise[i];
 	}
 
+	if (clear_irq)
+		writel(clear_irq, data->base + tmu_intclear);
+}
+
+static void exynos5420_tmu_clear_irqs(struct exynos_tmu_data *data)
+{
+	unsigned int val_irq, clear_irq = 0;
+	u32 tmu_intstat = data->tmu_intstat;
+	u32 tmu_intclear = data->tmu_intclear;
+	struct tmu_irq_map irq_map = {0};
+
 	val_irq = readl(data->base + tmu_intstat);
 
-	/* Exynos4210 doesn't support FALL interrupts */
-	if (data->soc == SOC_ARCH_EXYNOS4210) {
-		writel(val_irq, data->base + tmu_intclear);
-		return;
+	/* Set SoC-specific interrupt bit mappings */
+	irq_map.fall[2] = BIT(24);
+	irq_map.fall[1] = BIT(20);
+	irq_map.fall[0] = BIT(16);
+	irq_map.rise[2] = BIT(8);
+	irq_map.rise[1] = BIT(4);
+	irq_map.rise[0] = BIT(0);
+
+	for (int i = 0; i < 3; i++) {
+		if (val_irq & irq_map.fall[i])
+			clear_irq |= irq_map.fall[i];
+		if (val_irq & irq_map.rise[i])
+			clear_irq |= irq_map.rise[i];
 	}
 
+	if (clear_irq)
+		writel(clear_irq, data->base + tmu_intclear);
+}
+
+static void exynos5433_tmu_clear_irqs(struct exynos_tmu_data *data)
+{
+	unsigned int val_irq, clear_irq = 0;
+	u32 tmu_intstat = data->tmu_intstat;
+	u32 tmu_intclear = data->tmu_intclear;
+	struct tmu_irq_map irq_map = {0};
+
+	val_irq = readl(data->base + tmu_intstat);
+
 	/* Set SoC-specific interrupt bit mappings */
-	switch (data->soc) {
-	case SOC_ARCH_EXYNOS3250:
-	case SOC_ARCH_EXYNOS4412:
-	case SOC_ARCH_EXYNOS5250:
-	case SOC_ARCH_EXYNOS5260:
-		irq_map.fall[2] = BIT(20);
-		irq_map.fall[1] = BIT(16);
-		irq_map.fall[0] = BIT(12);
-		irq_map.rise[2] = BIT(8);
-		irq_map.rise[1] = BIT(4);
-		irq_map.rise[0] = BIT(0);
-		break;
-	case SOC_ARCH_EXYNOS5420:
-	case SOC_ARCH_EXYNOS5420_TRIMINFO:
-		irq_map.fall[2] = BIT(24);
-		irq_map.fall[1] = BIT(20);
-		irq_map.fall[0] = BIT(16);
-		irq_map.rise[2] = BIT(8);
-		irq_map.rise[1] = BIT(4);
-		irq_map.rise[0] = BIT(0);
-		break;
-	case SOC_ARCH_EXYNOS5433:
-	case SOC_ARCH_EXYNOS7:
-		irq_map.fall[2] = BIT(23);
-		irq_map.fall[1] = BIT(17);
-		irq_map.fall[0] = BIT(16);
-		irq_map.rise[2] = BIT(7);
-		irq_map.rise[1] = BIT(1);
-		irq_map.rise[0] = BIT(0);
-		break;
-	default:
-		pr_warn("exynos-tmu: Unknown SoC type %d, using fallback IRQ mapping\n", soc);
-		break;
+	irq_map.fall[2] = BIT(23);
+	irq_map.fall[1] = BIT(17);
+	irq_map.fall[0] = BIT(16);
+	irq_map.rise[2] = BIT(7);
+	irq_map.rise[1] = BIT(1);
+	irq_map.rise[0] = BIT(0);
 
 	/* Map active INTSTAT bits to INTCLEAR */
 	for (int i = 0; i < 3; i++) {
@@ -915,6 +942,8 @@ static int exynos_map_dt_data(struct platform_device *pdev)
 		data->tmu_control = exynos4210_tmu_control;
 		data->tmu_read = exynos4210_tmu_read;
 		data->tmu_clear_irqs = exynos4210_tmu_clear_irqs;
+		data->tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
+		data->tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
 		data->gain = 15;
 		data->reference_voltage = 7;
 		data->efuse_value = 55;
@@ -934,7 +963,14 @@ static int exynos_map_dt_data(struct platform_device *pdev)
 		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->tmu_clear_irqs = exynos4412_tmu_clear_irqs;
+		if (data->soc == SOC_ARCH_EXYNOS5260) {
+			data->tmu_intstat = EXYNOS5260_TMU_REG_INTSTAT;
+			data->tmu_intclear = EXYNOS5260_TMU_REG_INTCLEAR;
+		} else {
+			data->tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
+			data->tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
+		}
 		data->gain = 8;
 		data->reference_voltage = 16;
 		data->efuse_value = 55;
@@ -952,7 +988,9 @@ static int exynos_map_dt_data(struct platform_device *pdev)
 		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->tmu_clear_irqs = exynos5420_tmu_clear_irqs;
+		data->tmu_intstat = EXYNOS_TMU_REG_INTSTAT;
+		data->tmu_intclear = EXYNOS_TMU_REG_INTCLEAR;
 		data->gain = 8;
 		data->reference_voltage = 16;
 		data->efuse_value = 55;
@@ -969,7 +1007,9 @@ static int exynos_map_dt_data(struct platform_device *pdev)
 		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->tmu_clear_irqs = exynos5433_tmu_clear_irqs;
+		data->tmu_intstat = EXYNOS5433_TMU_REG_INTPEND;
+		data->tmu_intclear = EXYNOS5433_TMU_REG_INTPEND;
 		data->gain = 8;
 		if (res.start == EXYNOS5433_G3D_BASE)
 			data->reference_voltage = 23;
@@ -989,7 +1029,9 @@ static int exynos_map_dt_data(struct platform_device *pdev)
 		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->tmu_clear_irqs = exynos5433_tmu_clear_irqs;
+		data->tmu_intstat = EXYNOS7_TMU_REG_INTPEND;
+		data->tmu_intclear = EXYNOS7_TMU_REG_INTPEND;
 		data->gain = 9;
 		data->reference_voltage = 17;
 		data->efuse_value = 75;
-- 
2.50.1


  parent reply	other threads:[~2025-08-13 13:11 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-13 13:09 [PATCH v7 0/7] Exynos Thermal code improvement Anand Moon
2025-08-13 13:09 ` [PATCH v7 1/7] thermal/drivers/exynos: Refactor clk_sec initialization inside SOC-specific case Anand Moon
2025-08-13 13:09 ` [PATCH v7 2/7] thermal/drivers/exynos: Use devm_clk_get_enabled() helpers Anand Moon
2025-08-13 13:09 ` [PATCH v7 3/7] thermal/drivers/exynos: Remove redundant IS_ERR() checks for clk_sec clock Anand Moon
2025-08-13 13:09 ` [PATCH v7 4/7] thermal/drivers/exynos: Fixed the efuse min max value for exynos5422 Anand Moon
2025-08-13 13:09 ` [PATCH v7 5/7] thermal/drivers/exynos: Remove unused base_second mapping and references Anand Moon
2025-08-13 13:09 ` [PATCH v7 6/7] thermal/drivers/exynos: Handle temperature threshold IRQs with SoC-specific mapping Anand Moon
     [not found]   ` <CGME20250819131732eucas1p26bd491e9b6b747a4857905bfd50420a9@eucas1p2.samsung.com>
2025-08-19 13:17     ` Mateusz Majewski
     [not found]       ` <CGME20250819134804eucas1p1ed14f9680e66327a86af4e98319eed11@eucas1p1.samsung.com>
2025-08-19 13:47         ` Mateusz Majewski
2025-08-20 13:28       ` Anand Moon
2025-08-13 13:09 ` Anand Moon [this message]
     [not found]   ` <CGME20250819131814eucas1p2c57ccc084cf6736fed01a8a5c0b35fab@eucas1p2.samsung.com>
2025-08-19 13:18     ` [PATCH v7 7/7] thermal/drivers/exynos: Refactor IRQ clear logic using SoC-specific config Mateusz Majewski
2025-08-20 13:28       ` Anand Moon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250813131007.343402-8-linux.amoon@gmail.com \
    --to=linux.amoon@gmail.com \
    --cc=alim.akhtar@samsung.com \
    --cc=bzolnier@gmail.com \
    --cc=daniel.lezcano@linaro.org \
    --cc=justinstitt@google.com \
    --cc=krzk@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=llvm@lists.linux.dev \
    --cc=lukasz.luba@arm.com \
    --cc=m.majewski2@samsung.com \
    --cc=morbo@google.com \
    --cc=nathan@kernel.org \
    --cc=nick.desaulniers+lkml@gmail.com \
    --cc=rafael@kernel.org \
    --cc=rui.zhang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).