Skip to content

Commit 5e1b834

Browse files
committed
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer updates from Thomas Gleixner: "A rather smalish set of updates for timers and timekeeping: - Two core fixes to prevent potential undefinded behaviour about which gcc is complaining rightfully. - A fix to prevent stopping the tick on an (soon) offline CPU so it can complete the shutdown procedure. - Wait for clocks to stabilize before making decisions, so a not yet validated clock is not rejected. - The usual pile of fixes to the various clocksource drivers. - Core code typo and include fixlets" * 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: timekeeping: Include the correct header for errno definitions clocksource/drivers/ti-32k: Prevent ftrace recursion clocksource/mips-gic-timer: Stop checking cpu_has_counter clocksource/mips-gic-timer: Print an error if IRQ setup fails tick/nohz: Prevent stopping the tick on an offline CPU clocksource/drivers/oxnas: Add OX820 compatible clocksource/drivers/timer-atmel-pit: Simplify IRQ handler clocksource/drivers/timer-atmel-pit: Remove uselesss WARN_ON_ONCE clocksource/drivers/timer-atmel-pit: Drop at91sam926x_pit_common_init clocksource/drivers/moxart: Replace panic by pr_err clocksource/drivers/moxart: Replace setup_irq by request_irq clocksource/drivers/moxart: Add Aspeed support clocksource/drivers/moxart: Use struct to hold state clocksource/drivers/moxart: Refactor enable/disable time: Avoid undefined behaviour in ktime_add_safe() time: Avoid undefined behaviour in timespec64_add_safe() timekeeping: Prints the amounts of time spent during suspend clocksource: Defer override invalidation unless clock is unstable hrtimer: Spelling fixes
2 parents 49deffe + b536fd5 commit 5e1b834

File tree

15 files changed

+210
-138
lines changed

15 files changed

+210
-138
lines changed

Documentation/devicetree/bindings/timer/moxa,moxart-timer.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ MOXA ART timer
22

33
Required properties:
44

5-
- compatible : Must be "moxa,moxart-timer"
5+
- compatible : Must be one of:
6+
- "moxa,moxart-timer"
7+
- "aspeed,ast2400-timer"
68
- reg : Should contain registers location and length
79
- interrupts : Should contain the timer interrupt number
810
- clocks : Should contain phandle for the clock that drives the counter

Documentation/devicetree/bindings/timer/oxsemi,rps-timer.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Oxford Semiconductor OXNAS SoCs Family RPS Timer
22
================================================
33

44
Required properties:
5-
- compatible: Should be "oxsemi,ox810se-rps-timer"
5+
- compatible: Should be "oxsemi,ox810se-rps-timer" or "oxsemi,ox820-rps-timer"
66
- reg : Specifies base physical address and size of the registers.
77
- interrupts : The interrupts of the two timers
88
- clocks : The phandle of the timer clock source

drivers/clocksource/mips-gic-timer.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,15 @@ static int gic_clockevent_init(void)
109109
{
110110
int ret;
111111

112-
if (!cpu_has_counter || !gic_frequency)
112+
if (!gic_frequency)
113113
return -ENXIO;
114114

115115
ret = setup_percpu_irq(gic_timer_irq, &gic_compare_irqaction);
116-
if (ret < 0)
116+
if (ret < 0) {
117+
pr_err("GIC timer IRQ %d setup failed: %d\n",
118+
gic_timer_irq, ret);
117119
return ret;
120+
}
118121

119122
cpuhp_setup_state(CPUHP_AP_MIPS_GIC_TIMER_STARTING,
120123
"AP_MIPS_GIC_TIMER_STARTING", gic_starting_cpu,

drivers/clocksource/moxart_timer.c

Lines changed: 129 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/io.h>
2222
#include <linux/clocksource.h>
2323
#include <linux/bitops.h>
24+
#include <linux/slab.h>
2425

2526
#define TIMER1_BASE 0x00
2627
#define TIMER2_BASE 0x10
@@ -36,97 +37,129 @@
3637
#define TIMER_INTR_MASK 0x38
3738

3839
/*
39-
* TIMER_CR flags:
40+
* Moxart TIMER_CR flags:
4041
*
41-
* TIMEREG_CR_*_CLOCK 0: PCLK, 1: EXT1CLK
42-
* TIMEREG_CR_*_INT overflow interrupt enable bit
42+
* MOXART_CR_*_CLOCK 0: PCLK, 1: EXT1CLK
43+
* MOXART_CR_*_INT overflow interrupt enable bit
4344
*/
44-
#define TIMEREG_CR_1_ENABLE BIT(0)
45-
#define TIMEREG_CR_1_CLOCK BIT(1)
46-
#define TIMEREG_CR_1_INT BIT(2)
47-
#define TIMEREG_CR_2_ENABLE BIT(3)
48-
#define TIMEREG_CR_2_CLOCK BIT(4)
49-
#define TIMEREG_CR_2_INT BIT(5)
50-
#define TIMEREG_CR_3_ENABLE BIT(6)
51-
#define TIMEREG_CR_3_CLOCK BIT(7)
52-
#define TIMEREG_CR_3_INT BIT(8)
53-
#define TIMEREG_CR_COUNT_UP BIT(9)
54-
55-
#define TIMER1_ENABLE (TIMEREG_CR_2_ENABLE | TIMEREG_CR_1_ENABLE)
56-
#define TIMER1_DISABLE (TIMEREG_CR_2_ENABLE)
57-
58-
static void __iomem *base;
59-
static unsigned int clock_count_per_tick;
45+
#define MOXART_CR_1_ENABLE BIT(0)
46+
#define MOXART_CR_1_CLOCK BIT(1)
47+
#define MOXART_CR_1_INT BIT(2)
48+
#define MOXART_CR_2_ENABLE BIT(3)
49+
#define MOXART_CR_2_CLOCK BIT(4)
50+
#define MOXART_CR_2_INT BIT(5)
51+
#define MOXART_CR_3_ENABLE BIT(6)
52+
#define MOXART_CR_3_CLOCK BIT(7)
53+
#define MOXART_CR_3_INT BIT(8)
54+
#define MOXART_CR_COUNT_UP BIT(9)
55+
56+
#define MOXART_TIMER1_ENABLE (MOXART_CR_2_ENABLE | MOXART_CR_1_ENABLE)
57+
#define MOXART_TIMER1_DISABLE (MOXART_CR_2_ENABLE)
58+
59+
/*
60+
* The ASpeed variant of the IP block has a different layout
61+
* for the control register
62+
*/
63+
#define ASPEED_CR_1_ENABLE BIT(0)
64+
#define ASPEED_CR_1_CLOCK BIT(1)
65+
#define ASPEED_CR_1_INT BIT(2)
66+
#define ASPEED_CR_2_ENABLE BIT(4)
67+
#define ASPEED_CR_2_CLOCK BIT(5)
68+
#define ASPEED_CR_2_INT BIT(6)
69+
#define ASPEED_CR_3_ENABLE BIT(8)
70+
#define ASPEED_CR_3_CLOCK BIT(9)
71+
#define ASPEED_CR_3_INT BIT(10)
72+
73+
#define ASPEED_TIMER1_ENABLE (ASPEED_CR_2_ENABLE | ASPEED_CR_1_ENABLE)
74+
#define ASPEED_TIMER1_DISABLE (ASPEED_CR_2_ENABLE)
75+
76+
struct moxart_timer {
77+
void __iomem *base;
78+
unsigned int t1_disable_val;
79+
unsigned int t1_enable_val;
80+
unsigned int count_per_tick;
81+
struct clock_event_device clkevt;
82+
};
83+
84+
static inline struct moxart_timer *to_moxart(struct clock_event_device *evt)
85+
{
86+
return container_of(evt, struct moxart_timer, clkevt);
87+
}
88+
89+
static inline void moxart_disable(struct clock_event_device *evt)
90+
{
91+
struct moxart_timer *timer = to_moxart(evt);
92+
93+
writel(timer->t1_disable_val, timer->base + TIMER_CR);
94+
}
95+
96+
static inline void moxart_enable(struct clock_event_device *evt)
97+
{
98+
struct moxart_timer *timer = to_moxart(evt);
99+
100+
writel(timer->t1_enable_val, timer->base + TIMER_CR);
101+
}
60102

61103
static int moxart_shutdown(struct clock_event_device *evt)
62104
{
63-
writel(TIMER1_DISABLE, base + TIMER_CR);
105+
moxart_disable(evt);
64106
return 0;
65107
}
66108

67109
static int moxart_set_oneshot(struct clock_event_device *evt)
68110
{
69-
writel(TIMER1_DISABLE, base + TIMER_CR);
70-
writel(~0, base + TIMER1_BASE + REG_LOAD);
111+
moxart_disable(evt);
112+
writel(~0, to_moxart(evt)->base + TIMER1_BASE + REG_LOAD);
71113
return 0;
72114
}
73115

74116
static int moxart_set_periodic(struct clock_event_device *evt)
75117
{
76-
writel(clock_count_per_tick, base + TIMER1_BASE + REG_LOAD);
77-
writel(TIMER1_ENABLE, base + TIMER_CR);
118+
struct moxart_timer *timer = to_moxart(evt);
119+
120+
moxart_disable(evt);
121+
writel(timer->count_per_tick, timer->base + TIMER1_BASE + REG_LOAD);
122+
writel(0, timer->base + TIMER1_BASE + REG_MATCH1);
123+
moxart_enable(evt);
78124
return 0;
79125
}
80126

81127
static int moxart_clkevt_next_event(unsigned long cycles,
82-
struct clock_event_device *unused)
128+
struct clock_event_device *evt)
83129
{
130+
struct moxart_timer *timer = to_moxart(evt);
84131
u32 u;
85132

86-
writel(TIMER1_DISABLE, base + TIMER_CR);
133+
moxart_disable(evt);
87134

88-
u = readl(base + TIMER1_BASE + REG_COUNT) - cycles;
89-
writel(u, base + TIMER1_BASE + REG_MATCH1);
135+
u = readl(timer->base + TIMER1_BASE + REG_COUNT) - cycles;
136+
writel(u, timer->base + TIMER1_BASE + REG_MATCH1);
90137

91-
writel(TIMER1_ENABLE, base + TIMER_CR);
138+
moxart_enable(evt);
92139

93140
return 0;
94141
}
95142

96-
static struct clock_event_device moxart_clockevent = {
97-
.name = "moxart_timer",
98-
.rating = 200,
99-
.features = CLOCK_EVT_FEAT_PERIODIC |
100-
CLOCK_EVT_FEAT_ONESHOT,
101-
.set_state_shutdown = moxart_shutdown,
102-
.set_state_periodic = moxart_set_periodic,
103-
.set_state_oneshot = moxart_set_oneshot,
104-
.tick_resume = moxart_set_oneshot,
105-
.set_next_event = moxart_clkevt_next_event,
106-
};
107-
108143
static irqreturn_t moxart_timer_interrupt(int irq, void *dev_id)
109144
{
110145
struct clock_event_device *evt = dev_id;
111146
evt->event_handler(evt);
112147
return IRQ_HANDLED;
113148
}
114149

115-
static struct irqaction moxart_timer_irq = {
116-
.name = "moxart-timer",
117-
.flags = IRQF_TIMER,
118-
.handler = moxart_timer_interrupt,
119-
.dev_id = &moxart_clockevent,
120-
};
121-
122150
static int __init moxart_timer_init(struct device_node *node)
123151
{
124152
int ret, irq;
125153
unsigned long pclk;
126154
struct clk *clk;
155+
struct moxart_timer *timer;
156+
157+
timer = kzalloc(sizeof(*timer), GFP_KERNEL);
158+
if (!timer)
159+
return -ENOMEM;
127160

128-
base = of_iomap(node, 0);
129-
if (!base) {
161+
timer->base = of_iomap(node, 0);
162+
if (!timer->base) {
130163
pr_err("%s: of_iomap failed\n", node->full_name);
131164
return -ENXIO;
132165
}
@@ -137,12 +170,6 @@ static int __init moxart_timer_init(struct device_node *node)
137170
return -EINVAL;
138171
}
139172

140-
ret = setup_irq(irq, &moxart_timer_irq);
141-
if (ret) {
142-
pr_err("%s: setup_irq failed\n", node->full_name);
143-
return ret;
144-
}
145-
146173
clk = of_clk_get(node, 0);
147174
if (IS_ERR(clk)) {
148175
pr_err("%s: of_clk_get failed\n", node->full_name);
@@ -151,31 +178,69 @@ static int __init moxart_timer_init(struct device_node *node)
151178

152179
pclk = clk_get_rate(clk);
153180

154-
ret = clocksource_mmio_init(base + TIMER2_BASE + REG_COUNT,
181+
if (of_device_is_compatible(node, "moxa,moxart-timer")) {
182+
timer->t1_enable_val = MOXART_TIMER1_ENABLE;
183+
timer->t1_disable_val = MOXART_TIMER1_DISABLE;
184+
} else if (of_device_is_compatible(node, "aspeed,ast2400-timer")) {
185+
timer->t1_enable_val = ASPEED_TIMER1_ENABLE;
186+
timer->t1_disable_val = ASPEED_TIMER1_DISABLE;
187+
} else {
188+
pr_err("%s: unknown platform\n", node->full_name);
189+
return -EINVAL;
190+
}
191+
192+
timer->count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ);
193+
194+
timer->clkevt.name = node->name;
195+
timer->clkevt.rating = 200;
196+
timer->clkevt.features = CLOCK_EVT_FEAT_PERIODIC |
197+
CLOCK_EVT_FEAT_ONESHOT;
198+
timer->clkevt.set_state_shutdown = moxart_shutdown;
199+
timer->clkevt.set_state_periodic = moxart_set_periodic;
200+
timer->clkevt.set_state_oneshot = moxart_set_oneshot;
201+
timer->clkevt.tick_resume = moxart_set_oneshot;
202+
timer->clkevt.set_next_event = moxart_clkevt_next_event;
203+
timer->clkevt.cpumask = cpumask_of(0);
204+
timer->clkevt.irq = irq;
205+
206+
ret = clocksource_mmio_init(timer->base + TIMER2_BASE + REG_COUNT,
155207
"moxart_timer", pclk, 200, 32,
156208
clocksource_mmio_readl_down);
157209
if (ret) {
158210
pr_err("%s: clocksource_mmio_init failed\n", node->full_name);
159211
return ret;
160212
}
161213

162-
clock_count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ);
214+
ret = request_irq(irq, moxart_timer_interrupt, IRQF_TIMER,
215+
node->name, &timer->clkevt);
216+
if (ret) {
217+
pr_err("%s: setup_irq failed\n", node->full_name);
218+
return ret;
219+
}
163220

164-
writel(~0, base + TIMER2_BASE + REG_LOAD);
165-
writel(TIMEREG_CR_2_ENABLE, base + TIMER_CR);
221+
/* Clear match registers */
222+
writel(0, timer->base + TIMER1_BASE + REG_MATCH1);
223+
writel(0, timer->base + TIMER1_BASE + REG_MATCH2);
224+
writel(0, timer->base + TIMER2_BASE + REG_MATCH1);
225+
writel(0, timer->base + TIMER2_BASE + REG_MATCH2);
166226

167-
moxart_clockevent.cpumask = cpumask_of(0);
168-
moxart_clockevent.irq = irq;
227+
/*
228+
* Start timer 2 rolling as our main wall clock source, keep timer 1
229+
* disabled
230+
*/
231+
writel(0, timer->base + TIMER_CR);
232+
writel(~0, timer->base + TIMER2_BASE + REG_LOAD);
233+
writel(timer->t1_disable_val, timer->base + TIMER_CR);
169234

170235
/*
171236
* documentation is not publicly available:
172237
* min_delta / max_delta obtained by trial-and-error,
173238
* max_delta 0xfffffffe should be ok because count
174239
* register size is u32
175240
*/
176-
clockevents_config_and_register(&moxart_clockevent, pclk,
177-
0x4, 0xfffffffe);
241+
clockevents_config_and_register(&timer->clkevt, pclk, 0x4, 0xfffffffe);
178242

179243
return 0;
180244
}
181245
CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", moxart_timer_init);
246+
CLOCKSOURCE_OF_DECLARE(aspeed, "aspeed,ast2400-timer", moxart_timer_init);

0 commit comments

Comments
 (0)