Skip to content

Commit 8596e58

Browse files
committed
Merge tag 'timers-core-2021-08-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer updates from Thomas Gleixner: "Updates for timekeeping, timers and related drivers: Core code: - Cure a couple of correctness issues in the posix CPU timer code to prevent that the tick dependency for NOHZ full is kept alive for no reason. - Avoid expensive double reprogramming of the clockevent device in hrtimer_start_range_ns(). - Avoid pointless SMP function calls when the clock was set to avoid disturbing CPUs which do not have any affected timers queued. - Make the clocksource watchdog test work correctly when CONFIG_HZ is less than 100. Drivers: - Prefer the ARM architected timer over the Exynos timer which is way more expensive to access. - Add device tree bindings for new Ingenic SoCs - The usual improvements and cleanups all over the place" * tag 'timers-core-2021-08-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (29 commits) clocksource: Make clocksource watchdog test safe for slow-HZ systems dt-bindings: timer: Add ABIs for new Ingenic SoCs clocksource/drivers/fttmr010: Pass around less pointers clocksource/drivers/mediatek: Optimize systimer irq clear flow on shutdown clocksource/drivers/ingenic: Use bitfield macro helpers clocksource/drivers/sh_cmt: Fix wrong setting if don't request IRQ for clock source channel dt-bindings: timer: convert rockchip,rk-timer.txt to YAML clocksource/drivers/exynos_mct: Mark MCT device as CLOCK_EVT_FEAT_PERCPU clocksource/drivers/exynos_mct: Prioritise Arm arch timer on arm64 hrtimer: Unbreak hrtimer_force_reprogram() hrtimer: Use raw_cpu_ptr() in clock_was_set() hrtimer: Avoid more SMP function calls in clock_was_set() hrtimer: Avoid unnecessary SMP function calls in clock_was_set() hrtimer: Add bases argument to clock_was_set() time/timekeeping: Avoid invoking clock_was_set() twice timekeeping: Distangle resume and clock-was-set events timerfd: Provide timerfd_resume() hrtimer: Force clock_was_set() handling for the HIGHRES=n, NOHZ=y case hrtimer: Ensure timerfd notification for HIGHRES=n hrtimer: Consolidate reprogramming code ...
2 parents bed9166 + d25a025 commit 8596e58

22 files changed

+574
-230
lines changed

Documentation/devicetree/bindings/timer/rockchip,rk-timer.txt

Lines changed: 0 additions & 27 deletions
This file was deleted.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/timer/rockchip,rk-timer.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: Rockchip Timer Device Tree Bindings
8+
9+
maintainers:
10+
- Daniel Lezcano <daniel.lezcano@linaro.org>
11+
12+
properties:
13+
compatible:
14+
oneOf:
15+
- const: rockchip,rk3288-timer
16+
- const: rockchip,rk3399-timer
17+
- items:
18+
- enum:
19+
- rockchip,rv1108-timer
20+
- rockchip,rk3036-timer
21+
- rockchip,rk3066-timer
22+
- rockchip,rk3188-timer
23+
- rockchip,rk3228-timer
24+
- rockchip,rk3229-timer
25+
- rockchip,rk3288-timer
26+
- rockchip,rk3368-timer
27+
- rockchip,px30-timer
28+
- const: rockchip,rk3288-timer
29+
reg:
30+
maxItems: 1
31+
32+
interrupts:
33+
maxItems: 1
34+
35+
clocks:
36+
minItems: 2
37+
maxItems: 2
38+
39+
clock-names:
40+
items:
41+
- const: pclk
42+
- const: timer
43+
44+
required:
45+
- compatible
46+
- reg
47+
- interrupts
48+
- clocks
49+
- clock-names
50+
51+
additionalProperties: false
52+
53+
examples:
54+
- |
55+
#include <dt-bindings/interrupt-controller/arm-gic.h>
56+
#include <dt-bindings/clock/rk3288-cru.h>
57+
58+
timer: timer@ff810000 {
59+
compatible = "rockchip,rk3288-timer";
60+
reg = <0xff810000 0x20>;
61+
interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
62+
clocks = <&cru PCLK_TIMER>, <&xin24m>;
63+
clock-names = "pclk", "timer";
64+
};

drivers/clocksource/exynos_mct.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@
5151

5252
#define TICK_BASE_CNT 1
5353

54+
#ifdef CONFIG_ARM
55+
/* Use values higher than ARM arch timer. See 6282edb72bed. */
56+
#define MCT_CLKSOURCE_RATING 450
57+
#define MCT_CLKEVENTS_RATING 500
58+
#else
59+
#define MCT_CLKSOURCE_RATING 350
60+
#define MCT_CLKEVENTS_RATING 350
61+
#endif
62+
5463
enum {
5564
MCT_INT_SPI,
5665
MCT_INT_PPI
@@ -206,7 +215,7 @@ static void exynos4_frc_resume(struct clocksource *cs)
206215

207216
static struct clocksource mct_frc = {
208217
.name = "mct-frc",
209-
.rating = 450, /* use value higher than ARM arch timer */
218+
.rating = MCT_CLKSOURCE_RATING,
210219
.read = exynos4_frc_read,
211220
.mask = CLOCKSOURCE_MASK(32),
212221
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
@@ -456,8 +465,9 @@ static int exynos4_mct_starting_cpu(unsigned int cpu)
456465
evt->set_state_oneshot = set_state_shutdown;
457466
evt->set_state_oneshot_stopped = set_state_shutdown;
458467
evt->tick_resume = set_state_shutdown;
459-
evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
460-
evt->rating = 500; /* use value higher than ARM arch timer */
468+
evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
469+
CLOCK_EVT_FEAT_PERCPU;
470+
evt->rating = MCT_CLKEVENTS_RATING,
461471

462472
exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
463473

drivers/clocksource/ingenic-sysost.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright (c) 2020 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
55
*/
66

7+
#include <linux/bitfield.h>
78
#include <linux/bitops.h>
89
#include <linux/clk.h>
910
#include <linux/clk-provider.h>
@@ -34,8 +35,6 @@
3435
/* bits within the OSTCCR register */
3536
#define OSTCCR_PRESCALE1_MASK 0x3
3637
#define OSTCCR_PRESCALE2_MASK 0xc
37-
#define OSTCCR_PRESCALE1_LSB 0
38-
#define OSTCCR_PRESCALE2_LSB 2
3938

4039
/* bits within the OSTCR register */
4140
#define OSTCR_OST1CLR BIT(0)
@@ -98,7 +97,7 @@ static unsigned long ingenic_ost_percpu_timer_recalc_rate(struct clk_hw *hw,
9897

9998
prescale = readl(ost_clk->ost->base + info->ostccr_reg);
10099

101-
prescale = (prescale & OSTCCR_PRESCALE1_MASK) >> OSTCCR_PRESCALE1_LSB;
100+
prescale = FIELD_GET(OSTCCR_PRESCALE1_MASK, prescale);
102101

103102
return parent_rate >> (prescale * 2);
104103
}
@@ -112,7 +111,7 @@ static unsigned long ingenic_ost_global_timer_recalc_rate(struct clk_hw *hw,
112111

113112
prescale = readl(ost_clk->ost->base + info->ostccr_reg);
114113

115-
prescale = (prescale & OSTCCR_PRESCALE2_MASK) >> OSTCCR_PRESCALE2_LSB;
114+
prescale = FIELD_GET(OSTCCR_PRESCALE2_MASK, prescale);
116115

117116
return parent_rate >> (prescale * 2);
118117
}
@@ -151,7 +150,8 @@ static int ingenic_ost_percpu_timer_set_rate(struct clk_hw *hw, unsigned long re
151150
int val;
152151

153152
val = readl(ost_clk->ost->base + info->ostccr_reg);
154-
val = (val & ~OSTCCR_PRESCALE1_MASK) | (prescale << OSTCCR_PRESCALE1_LSB);
153+
val &= ~OSTCCR_PRESCALE1_MASK;
154+
val |= FIELD_PREP(OSTCCR_PRESCALE1_MASK, prescale);
155155
writel(val, ost_clk->ost->base + info->ostccr_reg);
156156

157157
return 0;
@@ -166,7 +166,8 @@ static int ingenic_ost_global_timer_set_rate(struct clk_hw *hw, unsigned long re
166166
int val;
167167

168168
val = readl(ost_clk->ost->base + info->ostccr_reg);
169-
val = (val & ~OSTCCR_PRESCALE2_MASK) | (prescale << OSTCCR_PRESCALE2_LSB);
169+
val &= ~OSTCCR_PRESCALE2_MASK;
170+
val |= FIELD_PREP(OSTCCR_PRESCALE2_MASK, prescale);
170171
writel(val, ost_clk->ost->base + info->ostccr_reg);
171172

172173
return 0;

drivers/clocksource/sh_cmt.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,8 @@ static int sh_cmt_start(struct sh_cmt_channel *ch, unsigned long flag)
579579
ch->flags |= flag;
580580

581581
/* setup timeout if no clockevent */
582-
if ((flag == FLAG_CLOCKSOURCE) && (!(ch->flags & FLAG_CLOCKEVENT)))
582+
if (ch->cmt->num_channels == 1 &&
583+
flag == FLAG_CLOCKSOURCE && (!(ch->flags & FLAG_CLOCKEVENT)))
583584
__sh_cmt_set_next(ch, ch->max_match_value);
584585
out:
585586
raw_spin_unlock_irqrestore(&ch->lock, flags);
@@ -621,20 +622,25 @@ static struct sh_cmt_channel *cs_to_sh_cmt(struct clocksource *cs)
621622
static u64 sh_cmt_clocksource_read(struct clocksource *cs)
622623
{
623624
struct sh_cmt_channel *ch = cs_to_sh_cmt(cs);
624-
unsigned long flags;
625625
u32 has_wrapped;
626-
u64 value;
627-
u32 raw;
628626

629-
raw_spin_lock_irqsave(&ch->lock, flags);
630-
value = ch->total_cycles;
631-
raw = sh_cmt_get_counter(ch, &has_wrapped);
627+
if (ch->cmt->num_channels == 1) {
628+
unsigned long flags;
629+
u64 value;
630+
u32 raw;
632631

633-
if (unlikely(has_wrapped))
634-
raw += ch->match_value + 1;
635-
raw_spin_unlock_irqrestore(&ch->lock, flags);
632+
raw_spin_lock_irqsave(&ch->lock, flags);
633+
value = ch->total_cycles;
634+
raw = sh_cmt_get_counter(ch, &has_wrapped);
635+
636+
if (unlikely(has_wrapped))
637+
raw += ch->match_value + 1;
638+
raw_spin_unlock_irqrestore(&ch->lock, flags);
639+
640+
return value + raw;
641+
}
636642

637-
return value + raw;
643+
return sh_cmt_get_counter(ch, &has_wrapped);
638644
}
639645

640646
static int sh_cmt_clocksource_enable(struct clocksource *cs)
@@ -697,7 +703,7 @@ static int sh_cmt_register_clocksource(struct sh_cmt_channel *ch,
697703
cs->disable = sh_cmt_clocksource_disable;
698704
cs->suspend = sh_cmt_clocksource_suspend;
699705
cs->resume = sh_cmt_clocksource_resume;
700-
cs->mask = CLOCKSOURCE_MASK(sizeof(u64) * 8);
706+
cs->mask = CLOCKSOURCE_MASK(ch->cmt->info->width);
701707
cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
702708

703709
dev_info(&ch->cmt->pdev->dev, "ch%u: used as clock source\n",

drivers/clocksource/timer-fttmr010.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -271,9 +271,7 @@ static irqreturn_t ast2600_timer_interrupt(int irq, void *dev_id)
271271
}
272272

273273
static int __init fttmr010_common_init(struct device_node *np,
274-
bool is_aspeed,
275-
int (*timer_shutdown)(struct clock_event_device *),
276-
irq_handler_t irq_handler)
274+
bool is_aspeed, bool is_ast2600)
277275
{
278276
struct fttmr010 *fttmr010;
279277
int irq;
@@ -374,17 +372,25 @@ static int __init fttmr010_common_init(struct device_node *np,
374372
fttmr010->tick_rate);
375373
}
376374

377-
fttmr010->timer_shutdown = timer_shutdown;
378-
379375
/*
380376
* Setup clockevent timer (interrupt-driven) on timer 1.
381377
*/
382378
writel(0, fttmr010->base + TIMER1_COUNT);
383379
writel(0, fttmr010->base + TIMER1_LOAD);
384380
writel(0, fttmr010->base + TIMER1_MATCH1);
385381
writel(0, fttmr010->base + TIMER1_MATCH2);
386-
ret = request_irq(irq, irq_handler, IRQF_TIMER,
387-
"FTTMR010-TIMER1", &fttmr010->clkevt);
382+
383+
if (is_ast2600) {
384+
fttmr010->timer_shutdown = ast2600_timer_shutdown;
385+
ret = request_irq(irq, ast2600_timer_interrupt,
386+
IRQF_TIMER, "FTTMR010-TIMER1",
387+
&fttmr010->clkevt);
388+
} else {
389+
fttmr010->timer_shutdown = fttmr010_timer_shutdown;
390+
ret = request_irq(irq, fttmr010_timer_interrupt,
391+
IRQF_TIMER, "FTTMR010-TIMER1",
392+
&fttmr010->clkevt);
393+
}
388394
if (ret) {
389395
pr_err("FTTMR010-TIMER1 no IRQ\n");
390396
goto out_unmap;
@@ -432,23 +438,17 @@ static int __init fttmr010_common_init(struct device_node *np,
432438

433439
static __init int ast2600_timer_init(struct device_node *np)
434440
{
435-
return fttmr010_common_init(np, true,
436-
ast2600_timer_shutdown,
437-
ast2600_timer_interrupt);
441+
return fttmr010_common_init(np, true, true);
438442
}
439443

440444
static __init int aspeed_timer_init(struct device_node *np)
441445
{
442-
return fttmr010_common_init(np, true,
443-
fttmr010_timer_shutdown,
444-
fttmr010_timer_interrupt);
446+
return fttmr010_common_init(np, true, false);
445447
}
446448

447449
static __init int fttmr010_timer_init(struct device_node *np)
448450
{
449-
return fttmr010_common_init(np, false,
450-
fttmr010_timer_shutdown,
451-
fttmr010_timer_interrupt);
451+
return fttmr010_common_init(np, false, false);
452452
}
453453

454454
TIMER_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_init);

drivers/clocksource/timer-mediatek.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@
6060
* SYST_CON_EN: Clock enable. Shall be set to
6161
* - Start timer countdown.
6262
* - Allow timeout ticks being updated.
63-
* - Allow changing interrupt functions.
63+
* - Allow changing interrupt status,like clear irq pending.
6464
*
65-
* SYST_CON_IRQ_EN: Set to allow interrupt.
65+
* SYST_CON_IRQ_EN: Set to enable interrupt.
6666
*
6767
* SYST_CON_IRQ_CLR: Set to clear interrupt.
6868
*/
@@ -75,6 +75,7 @@ static void __iomem *gpt_sched_reg __read_mostly;
7575
static void mtk_syst_ack_irq(struct timer_of *to)
7676
{
7777
/* Clear and disable interrupt */
78+
writel(SYST_CON_EN, SYST_CON_REG(to));
7879
writel(SYST_CON_IRQ_CLR | SYST_CON_EN, SYST_CON_REG(to));
7980
}
8081

@@ -111,6 +112,9 @@ static int mtk_syst_clkevt_next_event(unsigned long ticks,
111112

112113
static int mtk_syst_clkevt_shutdown(struct clock_event_device *clkevt)
113114
{
115+
/* Clear any irq */
116+
mtk_syst_ack_irq(to_timer_of(clkevt));
117+
114118
/* Disable timer */
115119
writel(0, SYST_CON_REG(to_timer_of(clkevt)));
116120

fs/timerfd.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,22 @@ void timerfd_clock_was_set(void)
115115
rcu_read_unlock();
116116
}
117117

118+
static void timerfd_resume_work(struct work_struct *work)
119+
{
120+
timerfd_clock_was_set();
121+
}
122+
123+
static DECLARE_WORK(timerfd_work, timerfd_resume_work);
124+
125+
/*
126+
* Invoked from timekeeping_resume(). Defer the actual update to work so
127+
* timerfd_clock_was_set() runs in task context.
128+
*/
129+
void timerfd_resume(void)
130+
{
131+
schedule_work(&timerfd_work);
132+
}
133+
118134
static void __timerfd_remove_cancel(struct timerfd_ctx *ctx)
119135
{
120136
if (ctx->might_cancel) {

include/dt-bindings/clock/ingenic,sysost.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,23 @@
1313
#define OST_CLK_PERCPU_TIMER2 3
1414
#define OST_CLK_PERCPU_TIMER3 4
1515

16+
#define OST_CLK_EVENT_TIMER 1
17+
18+
#define OST_CLK_EVENT_TIMER0 0
19+
#define OST_CLK_EVENT_TIMER1 1
20+
#define OST_CLK_EVENT_TIMER2 2
21+
#define OST_CLK_EVENT_TIMER3 3
22+
#define OST_CLK_EVENT_TIMER4 4
23+
#define OST_CLK_EVENT_TIMER5 5
24+
#define OST_CLK_EVENT_TIMER6 6
25+
#define OST_CLK_EVENT_TIMER7 7
26+
#define OST_CLK_EVENT_TIMER8 8
27+
#define OST_CLK_EVENT_TIMER9 9
28+
#define OST_CLK_EVENT_TIMER10 10
29+
#define OST_CLK_EVENT_TIMER11 11
30+
#define OST_CLK_EVENT_TIMER12 12
31+
#define OST_CLK_EVENT_TIMER13 13
32+
#define OST_CLK_EVENT_TIMER14 14
33+
#define OST_CLK_EVENT_TIMER15 15
34+
1635
#endif /* __DT_BINDINGS_CLOCK_INGENIC_OST_H__ */

0 commit comments

Comments
 (0)