summaryrefslogtreecommitdiff
path: root/drivers/clocksource/timer-sprd.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2025-11-26 15:36:52 +0100
committerThomas Gleixner <tglx@linutronix.de>2025-11-26 15:36:52 +0100
commit2437f798809d4420350b0118e4723024ce8d203b (patch)
treecc396159b8498affd66a563981d97965af0d2c42 /drivers/clocksource/timer-sprd.c
parentdcb6fa37fd7bc9c3d2b066329b0d27dedf8becaa (diff)
parentd1780dce9575072303b9c574614b72b5c8c5c44c (diff)
Merge tag 'timers-v6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/daniel.lezcano/linux into timers/clocksource
Pull clocksource/event changes from Daniel Lezcano: - Use 64-bits for timer compensation for IoT usage where the suspend time is much longer than what 32-bits can provide (Enlin Mu) - Add delay support on sp804 for ARM32 platforms (Stephen Eta Zhou) - Fix missing resource release on error in the probe path of in the ralink driver (Haotian Zhang) - Fix double deregistration on probe failure in the NXP STM driver (Johan Hovold) - Disable runtime PM for the Renesas SH CMT timer because it is incompatible with PREEMPT_RT=y (Niklas Söderlund) - Fix section mismatches in the NXP STM driver (Johan Hovold) - Preventing unbinding the NXP PIT, STM and MMIO ARM Arch timers as the code does not suppport bind/unbind (Johan Hovold) - Use the clocksource instead of ticks on the RDA8810PL platform (Enlin Mu) - Drop the unused module alias for the STM32-LP (Johan Hovold) - Add Realtek system timer driver (Hao-Wen Ting) Link: https://lore.kernel.org/all/9303b790-28d4-4bd9-b01d-28fb05493596@linaro.org
Diffstat (limited to 'drivers/clocksource/timer-sprd.c')
-rw-r--r--drivers/clocksource/timer-sprd.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/clocksource/timer-sprd.c b/drivers/clocksource/timer-sprd.c
index 430cb99d8d79..2c07dd2af760 100644
--- a/drivers/clocksource/timer-sprd.c
+++ b/drivers/clocksource/timer-sprd.c
@@ -30,6 +30,7 @@
#define TIMER_VALUE_SHDW_HI 0x1c
#define TIMER_VALUE_LO_MASK GENMASK(31, 0)
+#define TIMER_VALUE_HI_MASK GENMASK(31, 0)
static void sprd_timer_enable(void __iomem *base, u32 flag)
{
@@ -162,15 +163,26 @@ static struct timer_of suspend_to = {
static u64 sprd_suspend_timer_read(struct clocksource *cs)
{
- return ~(u64)readl_relaxed(timer_of_base(&suspend_to) +
- TIMER_VALUE_SHDW_LO) & cs->mask;
+ u32 lo, hi;
+
+ do {
+ hi = readl_relaxed(timer_of_base(&suspend_to) +
+ TIMER_VALUE_SHDW_HI);
+ lo = readl_relaxed(timer_of_base(&suspend_to) +
+ TIMER_VALUE_SHDW_LO);
+ } while (hi != readl_relaxed(timer_of_base(&suspend_to) + TIMER_VALUE_SHDW_HI));
+
+ return ~(((u64)hi << 32) | lo);
}
static int sprd_suspend_timer_enable(struct clocksource *cs)
{
- sprd_timer_update_counter(timer_of_base(&suspend_to),
- TIMER_VALUE_LO_MASK);
- sprd_timer_enable(timer_of_base(&suspend_to), TIMER_CTL_PERIOD_MODE);
+ writel_relaxed(TIMER_VALUE_LO_MASK,
+ timer_of_base(&suspend_to) + TIMER_LOAD_LO);
+ writel_relaxed(TIMER_VALUE_HI_MASK,
+ timer_of_base(&suspend_to) + TIMER_LOAD_HI);
+ sprd_timer_enable(timer_of_base(&suspend_to),
+ TIMER_CTL_PERIOD_MODE|TIMER_CTL_64BIT_WIDTH);
return 0;
}
@@ -186,7 +198,7 @@ static struct clocksource suspend_clocksource = {
.read = sprd_suspend_timer_read,
.enable = sprd_suspend_timer_enable,
.disable = sprd_suspend_timer_disable,
- .mask = CLOCKSOURCE_MASK(32),
+ .mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP,
};