Skip to content

Commit a941a03

Browse files
committed
Merge tag 'timers-core-2021-06-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer updates from Thomas Gleixner: "Time and clocksource/clockevent related updates: Core changes: - Infrastructure to support per CPU "broadcast" devices for per CPU clockevent devices which stop in deep idle states. This allows us to utilize the more efficient architected timer on certain ARM SoCs for normal operation instead of permanentely using the slow to access SoC specific clockevent device. - Print the name of the broadcast/wakeup device in /proc/timer_list - Make the clocksource watchdog more robust against delays between reading the current active clocksource and the watchdog clocksource. Such delays can be caused by NMIs, SMIs and vCPU preemption. Handle this by reading the watchdog clocksource twice, i.e. before and after reading the current active clocksource. In case that the two watchdog reads shows an excessive time delta, the read sequence is repeated up to 3 times. - Improve the debug output and add a test module for the watchdog mechanism. - Reimplementation of the venerable time64_to_tm() function with a faster and significantly smaller version. Straight from the source, i.e. the author of the related research paper contributed this! Driver changes: - No new drivers, not even new device tree bindings! - Fixes, improvements and cleanups and all over the place" * tag 'timers-core-2021-06-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (30 commits) time/kunit: Add missing MODULE_LICENSE() time: Improve performance of time64_to_tm() clockevents: Use list_move() instead of list_del()/list_add() clocksource: Print deviation in nanoseconds when a clocksource becomes unstable clocksource: Provide kernel module to test clocksource watchdog clocksource: Reduce clocksource-skew threshold clocksource: Limit number of CPUs checked for clock synchronization clocksource: Check per-CPU clock synchronization when marked unstable clocksource: Retry clock read if long delays detected clockevents: Add missing parameter documentation clocksource/drivers/timer-ti-dm: Drop unnecessary restore clocksource/arm_arch_timer: Improve Allwinner A64 timer workaround clocksource/drivers/arm_global_timer: Remove duplicated argument in arm_global_timer clocksource/drivers/arm_global_timer: Make symbol 'gt_clk_rate_change_nb' static arm: zynq: don't disable CONFIG_ARM_GLOBAL_TIMER due to CONFIG_CPU_FREQ anymore clocksource/drivers/arm_global_timer: Implement rate compensation whenever source clock changes clocksource/drivers/ingenic: Rename unreasonable array names clocksource/drivers/timer-ti-dm: Save and restore timer TIOCP_CFG clocksource/drivers/mediatek: Ack and disable interrupts on suspend clocksource/drivers/samsung_pwm: Constify source IO memory ...
2 parents 21edf50 + 2d0a9eb commit a941a03

26 files changed

+996
-144
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,28 @@
581581
loops can be debugged more effectively on production
582582
systems.
583583

584+
clocksource.max_cswd_read_retries= [KNL]
585+
Number of clocksource_watchdog() retries due to
586+
external delays before the clock will be marked
587+
unstable. Defaults to three retries, that is,
588+
four attempts to read the clock under test.
589+
590+
clocksource.verify_n_cpus= [KNL]
591+
Limit the number of CPUs checked for clocksources
592+
marked with CLOCK_SOURCE_VERIFY_PERCPU that
593+
are marked unstable due to excessive skew.
594+
A negative value says to check all CPUs, while
595+
zero says not to check any. Values larger than
596+
nr_cpu_ids are silently truncated to nr_cpu_ids.
597+
The actual CPUs are chosen randomly, with
598+
no replacement if the same CPU is chosen twice.
599+
600+
clocksource-wdtest.holdoff= [KNL]
601+
Set the time in seconds that the clocksource
602+
watchdog test waits before commencing its tests.
603+
Defaults to zero when built as a module and to
604+
10 seconds when built into the kernel.
605+
584606
clearcpuid=BITNUM[,BITNUM...] [X86]
585607
Disable CPUID feature X for the kernel. See
586608
arch/x86/include/asm/cpufeatures.h for the valid bit

arch/arm/mach-zynq/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ config ARCH_ZYNQ
66
select ARCH_SUPPORTS_BIG_ENDIAN
77
select ARM_AMBA
88
select ARM_GIC
9-
select ARM_GLOBAL_TIMER if !CPU_FREQ
9+
select ARM_GLOBAL_TIMER
1010
select CADENCE_TTC_TIMER
1111
select HAVE_ARM_SCU if SMP
1212
select HAVE_ARM_TWD if SMP

arch/x86/kernel/tsc.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,7 @@ static int tsc_cs_enable(struct clocksource *cs)
11281128
static struct clocksource clocksource_tsc_early = {
11291129
.name = "tsc-early",
11301130
.rating = 299,
1131+
.uncertainty_margin = 32 * NSEC_PER_MSEC,
11311132
.read = read_tsc,
11321133
.mask = CLOCKSOURCE_MASK(64),
11331134
.flags = CLOCK_SOURCE_IS_CONTINUOUS |
@@ -1152,7 +1153,8 @@ static struct clocksource clocksource_tsc = {
11521153
.mask = CLOCKSOURCE_MASK(64),
11531154
.flags = CLOCK_SOURCE_IS_CONTINUOUS |
11541155
CLOCK_SOURCE_VALID_FOR_HRES |
1155-
CLOCK_SOURCE_MUST_VERIFY,
1156+
CLOCK_SOURCE_MUST_VERIFY |
1157+
CLOCK_SOURCE_VERIFY_PERCPU,
11561158
.vdso_clock_mode = VDSO_CLOCKMODE_TSC,
11571159
.enable = tsc_cs_enable,
11581160
.resume = tsc_resume,

drivers/clocksource/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,20 @@ config ARM_GLOBAL_TIMER
358358
help
359359
This option enables support for the ARM global timer unit.
360360

361+
config ARM_GT_INITIAL_PRESCALER_VAL
362+
int "ARM global timer initial prescaler value"
363+
default 2 if ARCH_ZYNQ
364+
default 1
365+
depends on ARM_GLOBAL_TIMER
366+
help
367+
When the ARM global timer initializes, its current rate is declared
368+
to the kernel and maintained forever. Should it's parent clock
369+
change, the driver tries to fix the timer's internal prescaler.
370+
On some machs (i.e. Zynq) the initial prescaler value thus poses
371+
bounds about how much the parent clock is allowed to decrease or
372+
increase wrt the initial clock value.
373+
This affects CPU_FREQ max delta from the initial frequency.
374+
361375
config ARM_TIMER_SP804
362376
bool "Support for Dual Timer SP804 module" if COMPILE_TEST
363377
depends on GENERIC_SCHED_CLOCK && CLKDEV_LOOKUP

drivers/clocksource/arm_arch_timer.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ struct arch_timer {
6464
#define to_arch_timer(e) container_of(e, struct arch_timer, evt)
6565

6666
static u32 arch_timer_rate __ro_after_init;
67-
u32 arch_timer_rate1 __ro_after_init;
6867
static int arch_timer_ppi[ARCH_TIMER_MAX_TIMER_PPI] __ro_after_init;
6968

7069
static const char *arch_timer_ppi_names[ARCH_TIMER_MAX_TIMER_PPI] = {
@@ -365,7 +364,7 @@ static u64 notrace arm64_858921_read_cntvct_el0(void)
365364
do { \
366365
_val = read_sysreg(reg); \
367366
_retries--; \
368-
} while (((_val + 1) & GENMASK(9, 0)) <= 1 && _retries); \
367+
} while (((_val + 1) & GENMASK(8, 0)) <= 1 && _retries); \
369368
\
370369
WARN_ON_ONCE(!_retries); \
371370
_val; \

drivers/clocksource/arm_global_timer.c

Lines changed: 112 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131
#define GT_CONTROL_COMP_ENABLE BIT(1) /* banked */
3232
#define GT_CONTROL_IRQ_ENABLE BIT(2) /* banked */
3333
#define GT_CONTROL_AUTO_INC BIT(3) /* banked */
34+
#define GT_CONTROL_PRESCALER_SHIFT 8
35+
#define GT_CONTROL_PRESCALER_MAX 0xF
36+
#define GT_CONTROL_PRESCALER_MASK (GT_CONTROL_PRESCALER_MAX << \
37+
GT_CONTROL_PRESCALER_SHIFT)
3438

3539
#define GT_INT_STATUS 0x0c
3640
#define GT_INT_STATUS_EVENT_FLAG BIT(0)
@@ -39,14 +43,16 @@
3943
#define GT_COMP1 0x14
4044
#define GT_AUTO_INC 0x18
4145

46+
#define MAX_F_ERR 50
4247
/*
4348
* We are expecting to be clocked by the ARM peripheral clock.
4449
*
4550
* Note: it is assumed we are using a prescaler value of zero, so this is
4651
* the units for all operations.
4752
*/
4853
static void __iomem *gt_base;
49-
static unsigned long gt_clk_rate;
54+
static struct notifier_block gt_clk_rate_change_nb;
55+
static u32 gt_psv_new, gt_psv_bck, gt_target_rate;
5056
static int gt_ppi;
5157
static struct clock_event_device __percpu *gt_evt;
5258

@@ -96,7 +102,10 @@ static void gt_compare_set(unsigned long delta, int periodic)
96102
unsigned long ctrl;
97103

98104
counter += delta;
99-
ctrl = GT_CONTROL_TIMER_ENABLE;
105+
ctrl = readl(gt_base + GT_CONTROL);
106+
ctrl &= ~(GT_CONTROL_COMP_ENABLE | GT_CONTROL_IRQ_ENABLE |
107+
GT_CONTROL_AUTO_INC);
108+
ctrl |= GT_CONTROL_TIMER_ENABLE;
100109
writel_relaxed(ctrl, gt_base + GT_CONTROL);
101110
writel_relaxed(lower_32_bits(counter), gt_base + GT_COMP0);
102111
writel_relaxed(upper_32_bits(counter), gt_base + GT_COMP1);
@@ -123,7 +132,7 @@ static int gt_clockevent_shutdown(struct clock_event_device *evt)
123132

124133
static int gt_clockevent_set_periodic(struct clock_event_device *evt)
125134
{
126-
gt_compare_set(DIV_ROUND_CLOSEST(gt_clk_rate, HZ), 1);
135+
gt_compare_set(DIV_ROUND_CLOSEST(gt_target_rate, HZ), 1);
127136
return 0;
128137
}
129138

@@ -177,7 +186,7 @@ static int gt_starting_cpu(unsigned int cpu)
177186
clk->cpumask = cpumask_of(cpu);
178187
clk->rating = 300;
179188
clk->irq = gt_ppi;
180-
clockevents_config_and_register(clk, gt_clk_rate,
189+
clockevents_config_and_register(clk, gt_target_rate,
181190
1, 0xffffffff);
182191
enable_percpu_irq(clk->irq, IRQ_TYPE_NONE);
183192
return 0;
@@ -232,9 +241,28 @@ static struct delay_timer gt_delay_timer = {
232241
.read_current_timer = gt_read_long,
233242
};
234243

244+
static void gt_write_presc(u32 psv)
245+
{
246+
u32 reg;
247+
248+
reg = readl(gt_base + GT_CONTROL);
249+
reg &= ~GT_CONTROL_PRESCALER_MASK;
250+
reg |= psv << GT_CONTROL_PRESCALER_SHIFT;
251+
writel(reg, gt_base + GT_CONTROL);
252+
}
253+
254+
static u32 gt_read_presc(void)
255+
{
256+
u32 reg;
257+
258+
reg = readl(gt_base + GT_CONTROL);
259+
reg &= GT_CONTROL_PRESCALER_MASK;
260+
return reg >> GT_CONTROL_PRESCALER_SHIFT;
261+
}
262+
235263
static void __init gt_delay_timer_init(void)
236264
{
237-
gt_delay_timer.freq = gt_clk_rate;
265+
gt_delay_timer.freq = gt_target_rate;
238266
register_current_timer_delay(&gt_delay_timer);
239267
}
240268

@@ -243,18 +271,81 @@ static int __init gt_clocksource_init(void)
243271
writel(0, gt_base + GT_CONTROL);
244272
writel(0, gt_base + GT_COUNTER0);
245273
writel(0, gt_base + GT_COUNTER1);
246-
/* enables timer on all the cores */
247-
writel(GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
274+
/* set prescaler and enable timer on all the cores */
275+
writel(((CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) <<
276+
GT_CONTROL_PRESCALER_SHIFT)
277+
| GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL);
248278

249279
#ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
250-
sched_clock_register(gt_sched_clock_read, 64, gt_clk_rate);
280+
sched_clock_register(gt_sched_clock_read, 64, gt_target_rate);
251281
#endif
252-
return clocksource_register_hz(&gt_clocksource, gt_clk_rate);
282+
return clocksource_register_hz(&gt_clocksource, gt_target_rate);
283+
}
284+
285+
static int gt_clk_rate_change_cb(struct notifier_block *nb,
286+
unsigned long event, void *data)
287+
{
288+
struct clk_notifier_data *ndata = data;
289+
290+
switch (event) {
291+
case PRE_RATE_CHANGE:
292+
{
293+
int psv;
294+
295+
psv = DIV_ROUND_CLOSEST(ndata->new_rate,
296+
gt_target_rate);
297+
298+
if (abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR)
299+
return NOTIFY_BAD;
300+
301+
psv--;
302+
303+
/* prescaler within legal range? */
304+
if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX)
305+
return NOTIFY_BAD;
306+
307+
/*
308+
* store timer clock ctrl register so we can restore it in case
309+
* of an abort.
310+
*/
311+
gt_psv_bck = gt_read_presc();
312+
gt_psv_new = psv;
313+
/* scale down: adjust divider in post-change notification */
314+
if (ndata->new_rate < ndata->old_rate)
315+
return NOTIFY_DONE;
316+
317+
/* scale up: adjust divider now - before frequency change */
318+
gt_write_presc(psv);
319+
break;
320+
}
321+
case POST_RATE_CHANGE:
322+
/* scale up: pre-change notification did the adjustment */
323+
if (ndata->new_rate > ndata->old_rate)
324+
return NOTIFY_OK;
325+
326+
/* scale down: adjust divider now - after frequency change */
327+
gt_write_presc(gt_psv_new);
328+
break;
329+
330+
case ABORT_RATE_CHANGE:
331+
/* we have to undo the adjustment in case we scale up */
332+
if (ndata->new_rate < ndata->old_rate)
333+
return NOTIFY_OK;
334+
335+
/* restore original register value */
336+
gt_write_presc(gt_psv_bck);
337+
break;
338+
default:
339+
return NOTIFY_DONE;
340+
}
341+
342+
return NOTIFY_DONE;
253343
}
254344

255345
static int __init global_timer_of_register(struct device_node *np)
256346
{
257347
struct clk *gt_clk;
348+
static unsigned long gt_clk_rate;
258349
int err = 0;
259350

260351
/*
@@ -292,11 +383,20 @@ static int __init global_timer_of_register(struct device_node *np)
292383
}
293384

294385
gt_clk_rate = clk_get_rate(gt_clk);
386+
gt_target_rate = gt_clk_rate / CONFIG_ARM_GT_INITIAL_PRESCALER_VAL;
387+
gt_clk_rate_change_nb.notifier_call =
388+
gt_clk_rate_change_cb;
389+
err = clk_notifier_register(gt_clk, &gt_clk_rate_change_nb);
390+
if (err) {
391+
pr_warn("Unable to register clock notifier\n");
392+
goto out_clk;
393+
}
394+
295395
gt_evt = alloc_percpu(struct clock_event_device);
296396
if (!gt_evt) {
297397
pr_warn("global-timer: can't allocate memory\n");
298398
err = -ENOMEM;
299-
goto out_clk;
399+
goto out_clk_nb;
300400
}
301401

302402
err = request_percpu_irq(gt_ppi, gt_clockevent_interrupt,
@@ -326,6 +426,8 @@ static int __init global_timer_of_register(struct device_node *np)
326426
free_percpu_irq(gt_ppi, gt_evt);
327427
out_free:
328428
free_percpu(gt_evt);
429+
out_clk_nb:
430+
clk_notifier_unregister(gt_clk, &gt_clk_rate_change_nb);
329431
out_clk:
330432
clk_disable_unprepare(gt_clk);
331433
out_unmap:

drivers/clocksource/ingenic-sysost.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ static const struct clk_ops ingenic_ost_global_timer_ops = {
186186

187187
static const char * const ingenic_ost_clk_parents[] = { "ext" };
188188

189-
static const struct ingenic_ost_clk_info ingenic_ost_clk_info[] = {
189+
static const struct ingenic_ost_clk_info x1000_ost_clk_info[] = {
190190
[OST_CLK_PERCPU_TIMER] = {
191191
.init_data = {
192192
.name = "percpu timer",
@@ -414,14 +414,14 @@ static const struct ingenic_soc_info x1000_soc_info = {
414414
.num_channels = 2,
415415
};
416416

417-
static const struct of_device_id __maybe_unused ingenic_ost_of_match[] __initconst = {
418-
{ .compatible = "ingenic,x1000-ost", .data = &x1000_soc_info, },
417+
static const struct of_device_id __maybe_unused ingenic_ost_of_matches[] __initconst = {
418+
{ .compatible = "ingenic,x1000-ost", .data = &x1000_soc_info },
419419
{ /* sentinel */ }
420420
};
421421

422422
static int __init ingenic_ost_probe(struct device_node *np)
423423
{
424-
const struct of_device_id *id = of_match_node(ingenic_ost_of_match, np);
424+
const struct of_device_id *id = of_match_node(ingenic_ost_of_matches, np);
425425
struct ingenic_ost *ost;
426426
unsigned int i;
427427
int ret;
@@ -462,7 +462,7 @@ static int __init ingenic_ost_probe(struct device_node *np)
462462
ost->clocks->num = ost->soc_info->num_channels;
463463

464464
for (i = 0; i < ost->clocks->num; i++) {
465-
ret = ingenic_ost_register_clock(ost, i, &ingenic_ost_clk_info[i], ost->clocks);
465+
ret = ingenic_ost_register_clock(ost, i, &x1000_ost_clk_info[i], ost->clocks);
466466
if (ret) {
467467
pr_crit("%s: Cannot register clock %d\n", __func__, i);
468468
goto err_unregister_ost_clocks;

0 commit comments

Comments
 (0)