[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250616163831.8138-3-linux.amoon@gmail.com>
Date: Mon, 16 Jun 2025 22:08:23 +0530
From: Anand Moon <linux.amoon@...il.com>
To: Bartlomiej Zolnierkiewicz <bzolnier@...il.com>,
Krzysztof Kozlowski <krzk@...nel.org>,
"Rafael J. Wysocki" <rafael@...nel.org>,
Daniel Lezcano <daniel.lezcano@...aro.org>,
Zhang Rui <rui.zhang@...el.com>,
Lukasz Luba <lukasz.luba@....com>,
Alim Akhtar <alim.akhtar@...sung.com>,
linux-pm@...r.kernel.org (open list:SAMSUNG THERMAL DRIVER),
linux-samsung-soc@...r.kernel.org (open list:SAMSUNG THERMAL DRIVER),
linux-arm-kernel@...ts.infradead.org (moderated list:ARM/SAMSUNG S3C, S5P AND EXYNOS ARM ARCHITECTURES),
linux-kernel@...r.kernel.org (open list)
Cc: Anand Moon <linux.amoon@...il.com>
Subject: [RRC v1 2/3] thermal/drivers/exynos: Handle temperature threshold interrupts and clear corresponding IRQs
As per the Exynos TMU user manual the interrupt status register, maps the
active rising and falling edges of interrupt to the appropriate clear bit,
and writes it to the interrupt clear register to acknowledge and
clear the interrupt. This ensures that only the relevant interrupt
is cleared and allows the system to respond appropriately to thermal
events. As per the comment Exynos4210 doesn't support FALL IRQs at all.
So add the check accordingly.
Signed-off-by: Anand Moon <linux.amoon@...il.com>
---
drivers/thermal/samsung/exynos_tmu.c | 48 ++++++++++++++++++++++------
1 file changed, 38 insertions(+), 10 deletions(-)
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c
index c625eddcb9f3..b7522b7b1230 100644
--- a/drivers/thermal/samsung/exynos_tmu.c
+++ b/drivers/thermal/samsung/exynos_tmu.c
@@ -70,6 +70,20 @@
#define EXYNOS_EMUL_DATA_MASK 0xFF
#define EXYNOS_EMUL_ENABLE 0x1
+#define INTSTAT_FALL2 BIT(24)
+#define INTSTAT_FALL1 BIT(20)
+#define INTSTAT_FALL0 BIT(16)
+#define INTSTAT_RISE2 BIT(8)
+#define INTSTAT_RISE1 BIT(4)
+#define INTSTAT_RISE0 BIT(0)
+
+#define INTCLEAR_FALL2 BIT(24)
+#define INTCLEAR_FALL1 BIT(20)
+#define INTCLEAR_FALL0 BIT(16)
+#define INTCLEAR_RISE2 BIT(8)
+#define INTCLEAR_RISE1 BIT(4)
+#define INTCLEAR_RISE0 BIT(0)
+
/* Exynos5260 specific */
#define EXYNOS5260_TMU_REG_INTEN 0xC0
#define EXYNOS5260_TMU_REG_INTSTAT 0xC4
@@ -773,7 +787,7 @@ 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;
+ unsigned int val_irq, clearirq = 0;
u32 tmu_intstat, tmu_intclear;
if (data->soc == SOC_ARCH_EXYNOS5260) {
@@ -791,15 +805,29 @@ static void exynos4210_tmu_clear_irqs(struct exynos_tmu_data *data)
}
val_irq = readl(data->base + tmu_intstat);
- /*
- * Clear the interrupts. Please note that the documentation for
- * Exynos3250, Exynos4412, Exynos5250 and Exynos5260 incorrectly
- * states that INTCLEAR register has a different placing of bits
- * responsible for FALL IRQs than INTSTAT register. Exynos5420
- * and Exynos5440 documentation is correct (Exynos4210 doesn't
- * support FALL IRQs at all).
- */
- writel(val_irq, data->base + tmu_intclear);
+
+ if (data->soc == SOC_ARCH_EXYNOS4210) {
+ writel(val_irq, data->base + tmu_intclear);
+ return;
+ }
+
+ /* Map INTSTAT bits to INTCLEAR bits */
+ if (val_irq & INTSTAT_FALL2)
+ clearirq |= INTCLEAR_FALL2;
+ else if (val_irq & INTSTAT_FALL1)
+ clearirq |= INTCLEAR_FALL1;
+ else if (val_irq & INTSTAT_FALL0)
+ clearirq |= INTCLEAR_FALL0;
+ else if (val_irq & INTSTAT_RISE2)
+ clearirq |= INTCLEAR_RISE2;
+ else if (val_irq & INTSTAT_RISE1)
+ clearirq |= INTCLEAR_RISE1;
+ else if (val_irq & INTSTAT_RISE0)
+ clearirq |= INTCLEAR_RISE0;
+
+ /* Perform proper task for decrease temperature */
+ if (clearirq)
+ writel(clearirq, data->base + tmu_intclear);
}
static const struct of_device_id exynos_tmu_match[] = {
--
2.49.0
Powered by blists - more mailing lists