Skip to content

Commit 4fd9435

Browse files
committed
Merge tag 'timers-core-2024-07-14' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer updates from Thomas Gleixner: "Updates for timers, timekeeping and related functionality: Core: - Make the takeover of a hrtimer based broadcast timer reliable during CPU hot-unplug. The current implementation suffers from a race which can lead to broadcast timer starvation in the worst case. - VDSO related cleanups and simplifications - Small cleanups and enhancements all over the place PTP: - Replace the architecture specific base clock to clocksource, e.g. ART to TSC, conversion function with generic functionality to avoid exposing such internals to drivers and convert all existing drivers over. This also allows to provide functionality which converts the other way round in the core code based on the same parameter set. - Provide a function to convert CLOCK_REALTIME to the base clock to support the upcoming PPS output driver on Intel platforms. Drivers: - A set of Device Tree bindings for new hardware - Cleanups and enhancements all over the place" * tag 'timers-core-2024-07-14' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (30 commits) clocksource/drivers/realtek: Add timer driver for rtl-otto platforms dt-bindings: timer: Add schema for realtek,otto-timer dt-bindings: timer: Add SOPHGO SG2002 clint dt-bindings: timer: renesas,tmu: Add R-Car Gen2 support dt-bindings: timer: renesas,tmu: Add RZ/G1 support dt-bindings: timer: renesas,tmu: Add R-Mobile APE6 support clocksource/drivers/mips-gic-timer: Correct sched_clock width clocksource/drivers/mips-gic-timer: Refine rating computation clocksource/drivers/sh_cmt: Address race condition for clock events clocksource/driver/arm_global_timer: Remove unnecessary ‘0’ values from err clocksource/drivers/arm_arch_timer: Remove unnecessary ‘0’ values from irq tick/broadcast: Make takeover of broadcast hrtimer reliable tick/sched: Combine WARN_ON_ONCE and print_once x86/vdso: Remove unused include x86/vgtod: Remove unused typedef gtod_long_t x86/vdso: Fix function reference in comment vdso: Add comment about reason for vdso struct ordering vdso/gettimeofday: Clarify comment about open coded function timekeeping: Add missing kernel-doc function comments tick: Remove unnused tick_nohz_get_idle_calls() ...
2 parents 0eff049 + b7625d6 commit 4fd9435

33 files changed

+647
-131
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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,otto-timer.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: Realtek Otto SoCs Timer/Counter
8+
9+
description:
10+
Realtek SoCs support a number of timers/counters. These are used
11+
as a per CPU clock event generator and an overall CPU clocksource.
12+
13+
maintainers:
14+
- Chris Packham <[email protected]>
15+
16+
properties:
17+
$nodename:
18+
pattern: "^timer@[0-9a-f]+$"
19+
20+
compatible:
21+
items:
22+
- enum:
23+
- realtek,rtl9302-timer
24+
- const: realtek,otto-timer
25+
26+
reg:
27+
items:
28+
- description: timer0 registers
29+
- description: timer1 registers
30+
- description: timer2 registers
31+
- description: timer3 registers
32+
- description: timer4 registers
33+
34+
clocks:
35+
maxItems: 1
36+
37+
interrupts:
38+
items:
39+
- description: timer0 interrupt
40+
- description: timer1 interrupt
41+
- description: timer2 interrupt
42+
- description: timer3 interrupt
43+
- description: timer4 interrupt
44+
45+
required:
46+
- compatible
47+
- reg
48+
- clocks
49+
- interrupts
50+
51+
additionalProperties: false
52+
53+
examples:
54+
- |
55+
timer@3200 {
56+
compatible = "realtek,rtl9302-timer", "realtek,otto-timer";
57+
reg = <0x3200 0x10>, <0x3210 0x10>, <0x3220 0x10>,
58+
<0x3230 0x10>, <0x3240 0x10>;
59+
60+
interrupt-parent = <&intc>;
61+
interrupts = <7>, <8>, <9>, <10>, <11>;
62+
clocks = <&lx_clk>;
63+
};

Documentation/devicetree/bindings/timer/renesas,tmu.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,24 @@ properties:
2121
compatible:
2222
items:
2323
- enum:
24+
- renesas,tmu-r8a73a4 # R-Mobile APE6
2425
- renesas,tmu-r8a7740 # R-Mobile A1
26+
- renesas,tmu-r8a7742 # RZ/G1H
27+
- renesas,tmu-r8a7743 # RZ/G1M
28+
- renesas,tmu-r8a7744 # RZ/G1N
29+
- renesas,tmu-r8a7745 # RZ/G1E
30+
- renesas,tmu-r8a77470 # RZ/G1C
2531
- renesas,tmu-r8a774a1 # RZ/G2M
2632
- renesas,tmu-r8a774b1 # RZ/G2N
2733
- renesas,tmu-r8a774c0 # RZ/G2E
2834
- renesas,tmu-r8a774e1 # RZ/G2H
2935
- renesas,tmu-r8a7778 # R-Car M1A
3036
- renesas,tmu-r8a7779 # R-Car H1
37+
- renesas,tmu-r8a7790 # R-Car H2
38+
- renesas,tmu-r8a7791 # R-Car M2-W
39+
- renesas,tmu-r8a7792 # R-Car V2H
40+
- renesas,tmu-r8a7793 # R-Car M2-N
41+
- renesas,tmu-r8a7794 # R-Car E2
3142
- renesas,tmu-r8a7795 # R-Car H3
3243
- renesas,tmu-r8a7796 # R-Car M3-W
3344
- renesas,tmu-r8a77961 # R-Car M3-W+
@@ -94,6 +105,7 @@ if:
94105
compatible:
95106
contains:
96107
enum:
108+
- renesas,tmu-r8a73a4
97109
- renesas,tmu-r8a7740
98110
- renesas,tmu-r8a7778
99111
- renesas,tmu-r8a7779

Documentation/devicetree/bindings/timer/sifive,clint.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ properties:
4040
- allwinner,sun20i-d1-clint
4141
- sophgo,cv1800b-clint
4242
- sophgo,cv1812h-clint
43+
- sophgo,sg2002-clint
4344
- thead,th1520-clint
4445
- const: thead,c900-clint
4546
- items:

arch/x86/include/asm/tsc.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ static inline cycles_t get_cycles(void)
2828
}
2929
#define get_cycles get_cycles
3030

31-
extern struct system_counterval_t convert_art_to_tsc(u64 art);
32-
extern struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns);
33-
3431
extern void tsc_early_init(void);
3532
extern void tsc_init(void);
3633
extern void mark_tsc_unstable(char *reason);

arch/x86/include/asm/vdso/gettimeofday.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,8 @@ static __always_inline u64 vdso_calc_ns(const struct vdso_data *vd, u64 cycles,
328328
* due to unsigned comparison.
329329
*
330330
* Due to the MSB/Sign-bit being used as invalid marker (see
331-
* arch_vdso_cycles_valid() above), the effective mask is S64_MAX,
332-
* but that case is also unlikely and will also take the unlikely path
333-
* here.
331+
* arch_vdso_cycles_ok() above), the effective mask is S64_MAX, but that
332+
* case is also unlikely and will also take the unlikely path here.
334333
*/
335334
if (unlikely(delta > vd->max_cycles)) {
336335
/*

arch/x86/include/asm/vdso/vsyscall.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
#ifndef __ASSEMBLY__
66

7-
#include <linux/hrtimer.h>
87
#include <linux/timekeeper_internal.h>
98
#include <vdso/datapage.h>
109
#include <asm/vgtod.h>

arch/x86/include/asm/vgtod.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@
1414

1515
#include <uapi/linux/time.h>
1616

17-
#ifdef BUILD_VDSO32_64
18-
typedef u64 gtod_long_t;
19-
#else
20-
typedef unsigned long gtod_long_t;
21-
#endif
2217
#endif /* CONFIG_GENERIC_GETTIMEOFDAY */
2318

2419
#endif /* _ASM_X86_VGTOD_H */

arch/x86/kernel/tsc.c

Lines changed: 19 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ int tsc_clocksource_reliable;
5050

5151
static int __read_mostly tsc_force_recalibrate;
5252

53-
static u32 art_to_tsc_numerator;
54-
static u32 art_to_tsc_denominator;
55-
static u64 art_to_tsc_offset;
53+
static struct clocksource_base art_base_clk = {
54+
.id = CSID_X86_ART,
55+
};
5656
static bool have_art;
5757

5858
struct cyc2ns {
@@ -1074,7 +1074,7 @@ core_initcall(cpufreq_register_tsc_scaling);
10741074
*/
10751075
static void __init detect_art(void)
10761076
{
1077-
unsigned int unused[2];
1077+
unsigned int unused;
10781078

10791079
if (boot_cpu_data.cpuid_level < ART_CPUID_LEAF)
10801080
return;
@@ -1089,13 +1089,14 @@ static void __init detect_art(void)
10891089
tsc_async_resets)
10901090
return;
10911091

1092-
cpuid(ART_CPUID_LEAF, &art_to_tsc_denominator,
1093-
&art_to_tsc_numerator, unused, unused+1);
1092+
cpuid(ART_CPUID_LEAF, &art_base_clk.denominator,
1093+
&art_base_clk.numerator, &art_base_clk.freq_khz, &unused);
10941094

1095-
if (art_to_tsc_denominator < ART_MIN_DENOMINATOR)
1095+
art_base_clk.freq_khz /= KHZ;
1096+
if (art_base_clk.denominator < ART_MIN_DENOMINATOR)
10961097
return;
10971098

1098-
rdmsrl(MSR_IA32_TSC_ADJUST, art_to_tsc_offset);
1099+
rdmsrl(MSR_IA32_TSC_ADJUST, art_base_clk.offset);
10991100

11001101
/* Make this sticky over multiple CPU init calls */
11011102
setup_force_cpu_cap(X86_FEATURE_ART);
@@ -1296,67 +1297,6 @@ int unsynchronized_tsc(void)
12961297
return 0;
12971298
}
12981299

1299-
/*
1300-
* Convert ART to TSC given numerator/denominator found in detect_art()
1301-
*/
1302-
struct system_counterval_t convert_art_to_tsc(u64 art)
1303-
{
1304-
u64 tmp, res, rem;
1305-
1306-
rem = do_div(art, art_to_tsc_denominator);
1307-
1308-
res = art * art_to_tsc_numerator;
1309-
tmp = rem * art_to_tsc_numerator;
1310-
1311-
do_div(tmp, art_to_tsc_denominator);
1312-
res += tmp + art_to_tsc_offset;
1313-
1314-
return (struct system_counterval_t) {
1315-
.cs_id = have_art ? CSID_X86_TSC : CSID_GENERIC,
1316-
.cycles = res,
1317-
};
1318-
}
1319-
EXPORT_SYMBOL(convert_art_to_tsc);
1320-
1321-
/**
1322-
* convert_art_ns_to_tsc() - Convert ART in nanoseconds to TSC.
1323-
* @art_ns: ART (Always Running Timer) in unit of nanoseconds
1324-
*
1325-
* PTM requires all timestamps to be in units of nanoseconds. When user
1326-
* software requests a cross-timestamp, this function converts system timestamp
1327-
* to TSC.
1328-
*
1329-
* This is valid when CPU feature flag X86_FEATURE_TSC_KNOWN_FREQ is set
1330-
* indicating the tsc_khz is derived from CPUID[15H]. Drivers should check
1331-
* that this flag is set before conversion to TSC is attempted.
1332-
*
1333-
* Return:
1334-
* struct system_counterval_t - system counter value with the ID of the
1335-
* corresponding clocksource:
1336-
* cycles: System counter value
1337-
* cs_id: The clocksource ID for validating comparability
1338-
*/
1339-
1340-
struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns)
1341-
{
1342-
u64 tmp, res, rem;
1343-
1344-
rem = do_div(art_ns, USEC_PER_SEC);
1345-
1346-
res = art_ns * tsc_khz;
1347-
tmp = rem * tsc_khz;
1348-
1349-
do_div(tmp, USEC_PER_SEC);
1350-
res += tmp;
1351-
1352-
return (struct system_counterval_t) {
1353-
.cs_id = have_art ? CSID_X86_TSC : CSID_GENERIC,
1354-
.cycles = res,
1355-
};
1356-
}
1357-
EXPORT_SYMBOL(convert_art_ns_to_tsc);
1358-
1359-
13601300
static void tsc_refine_calibration_work(struct work_struct *work);
13611301
static DECLARE_DELAYED_WORK(tsc_irqwork, tsc_refine_calibration_work);
13621302
/**
@@ -1458,8 +1398,10 @@ static void tsc_refine_calibration_work(struct work_struct *work)
14581398
if (tsc_unstable)
14591399
goto unreg;
14601400

1461-
if (boot_cpu_has(X86_FEATURE_ART))
1401+
if (boot_cpu_has(X86_FEATURE_ART)) {
14621402
have_art = true;
1403+
clocksource_tsc.base = &art_base_clk;
1404+
}
14631405
clocksource_register_khz(&clocksource_tsc, tsc_khz);
14641406
unreg:
14651407
clocksource_unregister(&clocksource_tsc_early);
@@ -1484,8 +1426,10 @@ static int __init init_tsc_clocksource(void)
14841426
* the refined calibration and directly register it as a clocksource.
14851427
*/
14861428
if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
1487-
if (boot_cpu_has(X86_FEATURE_ART))
1429+
if (boot_cpu_has(X86_FEATURE_ART)) {
14881430
have_art = true;
1431+
clocksource_tsc.base = &art_base_clk;
1432+
}
14891433
clocksource_register_khz(&clocksource_tsc, tsc_khz);
14901434
clocksource_unregister(&clocksource_tsc_early);
14911435

@@ -1509,10 +1453,12 @@ static bool __init determine_cpu_tsc_frequencies(bool early)
15091453

15101454
if (early) {
15111455
cpu_khz = x86_platform.calibrate_cpu();
1512-
if (tsc_early_khz)
1456+
if (tsc_early_khz) {
15131457
tsc_khz = tsc_early_khz;
1514-
else
1458+
} else {
15151459
tsc_khz = x86_platform.calibrate_tsc();
1460+
clocksource_tsc.freq_khz = tsc_khz;
1461+
}
15161462
} else {
15171463
/* We should not be here with non-native cpu calibration */
15181464
WARN_ON(x86_platform.calibrate_cpu != native_calibrate_cpu);

drivers/clocksource/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,16 @@ config RDA_TIMER
134134
help
135135
Enables the support for the RDA Micro timer driver.
136136

137+
config REALTEK_OTTO_TIMER
138+
bool "Clocksource/timer for the Realtek Otto platform" if COMPILE_TEST
139+
select TIMER_OF
140+
help
141+
This driver adds support for the timers found in the Realtek RTL83xx
142+
and RTL93xx SoCs series. This includes chips such as RTL8380, RTL8381
143+
and RTL832, as well as chips from the RTL839x series, such as RTL8390
144+
RT8391, RTL8392, RTL8393 and RTL8396 and chips of the RTL930x series
145+
such as RTL9301, RTL9302 or RTL9303.
146+
137147
config SUN4I_TIMER
138148
bool "Sun4i timer driver" if COMPILE_TEST
139149
depends on HAS_IOMEM

drivers/clocksource/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ obj-$(CONFIG_MILBEAUT_TIMER) += timer-milbeaut.o
5959
obj-$(CONFIG_SPRD_TIMER) += timer-sprd.o
6060
obj-$(CONFIG_NPCM7XX_TIMER) += timer-npcm7xx.o
6161
obj-$(CONFIG_RDA_TIMER) += timer-rda.o
62+
obj-$(CONFIG_REALTEK_OTTO_TIMER) += timer-rtl-otto.o
6263

6364
obj-$(CONFIG_ARC_TIMERS) += arc_timer.o
6465
obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o

0 commit comments

Comments
 (0)