Skip to content

Commit 5028f42

Browse files
committed
Merge tag 'timers-clocksource-2025-11-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull clocksource updates from Thomas Gleixner: "Updates for clocksource and clockevent drivers: - A new driver for the Realtel system timer - Prevent the unbinding of timers when the drivers do not support that - Expand the timer counter readout for the SPRD driver to 64 bit to allow IOT devices suspend times of more than 36 hours, which is the current limit of the 32-bi readout - The usual small cleanups, fixes and enhancements all over the place" * tag 'timers-clocksource-2025-11-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: clocksource/drivers: Add Realtek system timer driver dt-bindings: timer: Add Realtek SYSTIMER clocksource/drivers/stm32-lp: Drop unused module alias clocksource/drivers/rda: Add sched_clock_register for RDA8810PL SoC clocksource/drivers/nxp-stm: Prevent driver unbind clocksource/drivers/nxp-pit: Prevent driver unbind clocksource/drivers/arm_arch_timer_mmio: Prevent driver unbind clocksource/drivers/nxp-stm: Fix section mismatches clocksource/drivers/sh_cmt: Always leave device running after probe clocksource/drivers/stm: Fix double deregistration on probe failure clocksource/drivers/ralink: Fix resource leaks in init error path clocksource/drivers/timer-sp804: Fix read_current_timer() issue when clock source is not registered clocksource/drivers/sprd: Enable register for timer counter from 32 bit to 64 bit
2 parents 9ce62eb + 2437f79 commit 5028f42

14 files changed

Lines changed: 291 additions & 56 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/timer/realtek,rtd1625-systimer.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: Realtek System Timer
8+
9+
maintainers:
10+
- Hao-Wen Ting <haowen.ting@realtek.com>
11+
12+
description:
13+
The Realtek SYSTIMER (System Timer) is a 64-bit global hardware counter operating
14+
at a fixed 1MHz frequency. Thanks to its compare match interrupt capability,
15+
the timer natively supports oneshot mode for tick broadcast functionality.
16+
17+
properties:
18+
compatible:
19+
oneOf:
20+
- const: realtek,rtd1625-systimer
21+
- items:
22+
- const: realtek,rtd1635-systimer
23+
- const: realtek,rtd1625-systimer
24+
25+
reg:
26+
maxItems: 1
27+
28+
interrupts:
29+
maxItems: 1
30+
31+
required:
32+
- compatible
33+
- reg
34+
- interrupts
35+
36+
additionalProperties: false
37+
38+
examples:
39+
- |
40+
#include <dt-bindings/interrupt-controller/arm-gic.h>
41+
42+
timer@89420 {
43+
compatible = "realtek,rtd1635-systimer",
44+
"realtek,rtd1625-systimer";
45+
reg = <0x89420 0x18>;
46+
interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
47+
};

MAINTAINERS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21681,6 +21681,11 @@ S: Maintained
2168121681
F: Documentation/devicetree/bindings/spi/realtek,rtl9301-snand.yaml
2168221682
F: drivers/spi/spi-realtek-rtl-snand.c
2168321683

21684+
REALTEK SYSTIMER DRIVER
21685+
M: Hao-Wen Ting <haowen.ting@realtek.com>
21686+
S: Maintained
21687+
F: drivers/clocksource/timer-realtek.c
21688+
2168421689
REALTEK WIRELESS DRIVER (rtlwifi family)
2168521690
M: Ping-Ke Shih <pkshih@realtek.com>
2168621691
L: linux-wireless@vger.kernel.org

drivers/clocksource/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,4 +782,15 @@ config NXP_STM_TIMER
782782
Enables the support for NXP System Timer Module found in the
783783
s32g NXP platform series.
784784

785+
config RTK_SYSTIMER
786+
bool "Realtek SYSTIMER support"
787+
depends on ARM || ARM64
788+
depends on ARCH_REALTEK || COMPILE_TEST
789+
select TIMER_OF
790+
help
791+
This option enables the driver that registers the global 1 MHz hardware
792+
counter as a clock event device on Realtek SoCs. Make sure to enable
793+
this option only when building for a Realtek platform or for compilation
794+
testing.
795+
785796
endmenu

drivers/clocksource/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,4 @@ obj-$(CONFIG_CLKSRC_LOONGSON1_PWM) += timer-loongson1-pwm.o
9595
obj-$(CONFIG_EP93XX_TIMER) += timer-ep93xx.o
9696
obj-$(CONFIG_RALINK_TIMER) += timer-ralink.o
9797
obj-$(CONFIG_NXP_STM_TIMER) += timer-nxp-stm.o
98+
obj-$(CONFIG_RTK_SYSTIMER) += timer-realtek.o

drivers/clocksource/arm_arch_timer_mmio.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ static struct platform_driver arch_timer_mmio_drv = {
426426
.driver = {
427427
.name = "arch-timer-mmio",
428428
.of_match_table = arch_timer_mmio_of_table,
429+
.suppress_bind_attrs = true,
429430
},
430431
.probe = arch_timer_mmio_probe,
431432
};
@@ -434,6 +435,7 @@ builtin_platform_driver(arch_timer_mmio_drv);
434435
static struct platform_driver arch_timer_mmio_acpi_drv = {
435436
.driver = {
436437
.name = "gtdt-arm-mmio-timer",
438+
.suppress_bind_attrs = true,
437439
},
438440
.probe = arch_timer_mmio_probe,
439441
};

drivers/clocksource/sh_cmt.c

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -355,14 +355,6 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch)
355355

356356
dev_pm_syscore_device(&ch->cmt->pdev->dev, true);
357357

358-
/* enable clock */
359-
ret = clk_enable(ch->cmt->clk);
360-
if (ret) {
361-
dev_err(&ch->cmt->pdev->dev, "ch%u: cannot enable clock\n",
362-
ch->index);
363-
goto err0;
364-
}
365-
366358
/* make sure channel is disabled */
367359
sh_cmt_start_stop_ch(ch, 0);
368360

@@ -384,19 +376,12 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch)
384376
if (ret || sh_cmt_read_cmcnt(ch)) {
385377
dev_err(&ch->cmt->pdev->dev, "ch%u: cannot clear CMCNT\n",
386378
ch->index);
387-
ret = -ETIMEDOUT;
388-
goto err1;
379+
return -ETIMEDOUT;
389380
}
390381

391382
/* enable channel */
392383
sh_cmt_start_stop_ch(ch, 1);
393384
return 0;
394-
err1:
395-
/* stop clock */
396-
clk_disable(ch->cmt->clk);
397-
398-
err0:
399-
return ret;
400385
}
401386

402387
static void sh_cmt_disable(struct sh_cmt_channel *ch)
@@ -407,9 +392,6 @@ static void sh_cmt_disable(struct sh_cmt_channel *ch)
407392
/* disable interrupts in CMT block */
408393
sh_cmt_write_cmcsr(ch, 0);
409394

410-
/* stop clock */
411-
clk_disable(ch->cmt->clk);
412-
413395
dev_pm_syscore_device(&ch->cmt->pdev->dev, false);
414396
}
415397

@@ -583,8 +565,6 @@ static int sh_cmt_start_clocksource(struct sh_cmt_channel *ch)
583565
int ret = 0;
584566
unsigned long flags;
585567

586-
pm_runtime_get_sync(&ch->cmt->pdev->dev);
587-
588568
raw_spin_lock_irqsave(&ch->lock, flags);
589569

590570
if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
@@ -619,8 +599,6 @@ static void sh_cmt_stop_clocksource(struct sh_cmt_channel *ch)
619599
sh_cmt_disable(ch);
620600

621601
raw_spin_unlock_irqrestore(&ch->lock, flags);
622-
623-
pm_runtime_put(&ch->cmt->pdev->dev);
624602
}
625603

626604
static int sh_cmt_start_clockevent(struct sh_cmt_channel *ch)
@@ -630,10 +608,8 @@ static int sh_cmt_start_clockevent(struct sh_cmt_channel *ch)
630608

631609
raw_spin_lock_irqsave(&ch->lock, flags);
632610

633-
if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE))) {
634-
pm_runtime_get_sync(&ch->cmt->pdev->dev);
611+
if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
635612
ret = sh_cmt_enable(ch);
636-
}
637613

638614
if (ret)
639615
goto out;
@@ -656,10 +632,8 @@ static void sh_cmt_stop_clockevent(struct sh_cmt_channel *ch)
656632

657633
ch->flags &= ~FLAG_CLOCKEVENT;
658634

659-
if (f && !(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE))) {
635+
if (f && !(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
660636
sh_cmt_disable(ch);
661-
pm_runtime_put(&ch->cmt->pdev->dev);
662-
}
663637

664638
/* adjust the timeout to maximum if only clocksource left */
665639
if (ch->flags & FLAG_CLOCKSOURCE)
@@ -1134,8 +1108,6 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
11341108
mask &= ~(1 << hwidx);
11351109
}
11361110

1137-
clk_disable(cmt->clk);
1138-
11391111
platform_set_drvdata(pdev, cmt);
11401112

11411113
return 0;
@@ -1183,8 +1155,6 @@ static int sh_cmt_probe(struct platform_device *pdev)
11831155
out:
11841156
if (cmt->has_clockevent || cmt->has_clocksource)
11851157
pm_runtime_irq_safe(&pdev->dev);
1186-
else
1187-
pm_runtime_idle(&pdev->dev);
11881158

11891159
return 0;
11901160
}

drivers/clocksource/timer-nxp-pit.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,10 @@ static struct platform_driver nxp_pit_driver = {
374374
.driver = {
375375
.name = "nxp-pit",
376376
.of_match_table = pit_timer_of_match,
377+
.suppress_bind_attrs = true,
377378
},
378379
.probe = pit_timer_probe,
379380
};
380-
module_platform_driver(nxp_pit_driver);
381+
builtin_platform_driver(nxp_pit_driver);
381382

382383
TIMER_OF_DECLARE(vf610, "fsl,vf610-pit", pit_timer_init);

drivers/clocksource/timer-nxp-stm.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -177,15 +177,15 @@ static void nxp_stm_clocksource_resume(struct clocksource *cs)
177177
nxp_stm_clocksource_enable(cs);
178178
}
179179

180-
static void __init devm_clocksource_unregister(void *data)
180+
static void devm_clocksource_unregister(void *data)
181181
{
182182
struct stm_timer *stm_timer = data;
183183

184184
clocksource_unregister(&stm_timer->cs);
185185
}
186186

187-
static int __init nxp_stm_clocksource_init(struct device *dev, struct stm_timer *stm_timer,
188-
const char *name, void __iomem *base, struct clk *clk)
187+
static int nxp_stm_clocksource_init(struct device *dev, struct stm_timer *stm_timer,
188+
const char *name, void __iomem *base, struct clk *clk)
189189
{
190190
int ret;
191191

@@ -208,10 +208,8 @@ static int __init nxp_stm_clocksource_init(struct device *dev, struct stm_timer
208208
return ret;
209209

210210
ret = devm_add_action_or_reset(dev, devm_clocksource_unregister, stm_timer);
211-
if (ret) {
212-
clocksource_unregister(&stm_timer->cs);
211+
if (ret)
213212
return ret;
214-
}
215213

216214
stm_sched_clock = stm_timer;
217215

@@ -298,9 +296,9 @@ static void nxp_stm_clockevent_resume(struct clock_event_device *ced)
298296
nxp_stm_module_get(stm_timer);
299297
}
300298

301-
static int __init nxp_stm_clockevent_per_cpu_init(struct device *dev, struct stm_timer *stm_timer,
302-
const char *name, void __iomem *base, int irq,
303-
struct clk *clk, int cpu)
299+
static int nxp_stm_clockevent_per_cpu_init(struct device *dev, struct stm_timer *stm_timer,
300+
const char *name, void __iomem *base, int irq,
301+
struct clk *clk, int cpu)
304302
{
305303
stm_timer->base = base;
306304
stm_timer->rate = clk_get_rate(clk);
@@ -388,7 +386,7 @@ static irqreturn_t nxp_stm_module_interrupt(int irq, void *dev_id)
388386
return IRQ_HANDLED;
389387
}
390388

391-
static int __init nxp_stm_timer_probe(struct platform_device *pdev)
389+
static int nxp_stm_timer_probe(struct platform_device *pdev)
392390
{
393391
struct stm_timer *stm_timer;
394392
struct device *dev = &pdev->dev;
@@ -484,14 +482,15 @@ static const struct of_device_id nxp_stm_of_match[] = {
484482
};
485483
MODULE_DEVICE_TABLE(of, nxp_stm_of_match);
486484

487-
static struct platform_driver nxp_stm_probe = {
485+
static struct platform_driver nxp_stm_driver = {
488486
.probe = nxp_stm_timer_probe,
489487
.driver = {
490488
.name = "nxp-stm",
491489
.of_match_table = nxp_stm_of_match,
490+
.suppress_bind_attrs = true,
492491
},
493492
};
494-
module_platform_driver(nxp_stm_probe);
493+
builtin_platform_driver(nxp_stm_driver);
495494

496495
MODULE_DESCRIPTION("NXP System Timer Module driver");
497496
MODULE_LICENSE("GPL");

drivers/clocksource/timer-ralink.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,21 +130,28 @@ static int __init ralink_systick_init(struct device_node *np)
130130
systick.dev.irq = irq_of_parse_and_map(np, 0);
131131
if (!systick.dev.irq) {
132132
pr_err("%pOFn: request_irq failed", np);
133-
return -EINVAL;
133+
ret = -EINVAL;
134+
goto err_iounmap;
134135
}
135136

136137
ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
137138
SYSTICK_FREQ, 301, 16,
138139
clocksource_mmio_readl_up);
139140
if (ret)
140-
return ret;
141+
goto err_free_irq;
141142

142143
clockevents_register_device(&systick.dev);
143144

144145
pr_info("%pOFn: running - mult: %d, shift: %d\n",
145146
np, systick.dev.mult, systick.dev.shift);
146147

147148
return 0;
149+
150+
err_free_irq:
151+
irq_dispose_mapping(systick.dev.irq);
152+
err_iounmap:
153+
iounmap(systick.membase);
154+
return ret;
148155
}
149156

150157
TIMER_OF_DECLARE(systick, "ralink,cevt-systick", ralink_systick_init);

drivers/clocksource/timer-rda.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include <linux/init.h>
1515
#include <linux/interrupt.h>
16+
#include <linux/sched_clock.h>
1617

1718
#include "timer-of.h"
1819

@@ -153,7 +154,7 @@ static struct timer_of rda_ostimer_of = {
153154
},
154155
};
155156

156-
static u64 rda_hwtimer_read(struct clocksource *cs)
157+
static u64 rda_hwtimer_clocksource_read(void)
157158
{
158159
void __iomem *base = timer_of_base(&rda_ostimer_of);
159160
u32 lo, hi;
@@ -167,6 +168,11 @@ static u64 rda_hwtimer_read(struct clocksource *cs)
167168
return ((u64)hi << 32) | lo;
168169
}
169170

171+
static u64 rda_hwtimer_read(struct clocksource *cs)
172+
{
173+
return rda_hwtimer_clocksource_read();
174+
}
175+
170176
static struct clocksource rda_hwtimer_clocksource = {
171177
.name = "rda-timer",
172178
.rating = 400,
@@ -185,6 +191,7 @@ static int __init rda_timer_init(struct device_node *np)
185191
return ret;
186192

187193
clocksource_register_hz(&rda_hwtimer_clocksource, rate);
194+
sched_clock_register(rda_hwtimer_clocksource_read, 64, rate);
188195

189196
clockevents_config_and_register(&rda_ostimer_of.clkevt, rate,
190197
0x2, UINT_MAX);

0 commit comments

Comments
 (0)