aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/arch_timer.txt7
-rw-r--r--arch/arm/Kconfig3
-rw-r--r--arch/arm/include/asm/arch_timer.h109
-rw-r--r--arch/arm/kernel/arch_timer.c504
-rw-r--r--arch/arm/mach-omap2/Kconfig2
-rw-r--r--arch/arm64/Kconfig1
-rw-r--r--arch/arm64/include/asm/arch_timer.h133
-rw-r--r--arch/arm64/include/asm/arm_generic.h100
-rw-r--r--arch/arm64/kernel/time.c29
-rw-r--r--drivers/clocksource/Kconfig6
-rw-r--r--drivers/clocksource/Makefile2
-rw-r--r--drivers/clocksource/arm_arch_timer.c391
-rw-r--r--drivers/clocksource/arm_generic.c232
-rw-r--r--include/clocksource/arm_arch_timer.h63
-rw-r--r--include/clocksource/arm_generic.h21
15 files changed, 748 insertions, 855 deletions
diff --git a/Documentation/devicetree/bindings/arm/arch_timer.txt b/Documentation/devicetree/bindings/arm/arch_timer.txt
index 52478c83d0cc..20746e5abe6f 100644
--- a/Documentation/devicetree/bindings/arm/arch_timer.txt
+++ b/Documentation/devicetree/bindings/arm/arch_timer.txt
@@ -1,13 +1,14 @@
1* ARM architected timer 1* ARM architected timer
2 2
3ARM Cortex-A7 and Cortex-A15 have a per-core architected timer, which 3ARM cores may have a per-core architected timer, which provides per-cpu timers.
4provides per-cpu timers.
5 4
6The timer is attached to a GIC to deliver its per-processor interrupts. 5The timer is attached to a GIC to deliver its per-processor interrupts.
7 6
8** Timer node properties: 7** Timer node properties:
9 8
10- compatible : Should at least contain "arm,armv7-timer". 9- compatible : Should at least contain one of
10 "arm,armv7-timer"
11 "arm,armv8-timer"
11 12
12- interrupts : Interrupt list for secure, non-secure, virtual and 13- interrupts : Interrupt list for secure, non-secure, virtual and
13 hypervisor timers, in that order. 14 hypervisor timers, in that order.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 65ae7375c6c1..9e8c0be7b5ca 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1573,9 +1573,10 @@ config HAVE_ARM_SCU
1573 help 1573 help
1574 This option enables support for the ARM system coherency unit 1574 This option enables support for the ARM system coherency unit
1575 1575
1576config ARM_ARCH_TIMER 1576config HAVE_ARM_ARCH_TIMER
1577 bool "Architected timer support" 1577 bool "Architected timer support"
1578 depends on CPU_V7 1578 depends on CPU_V7
1579 select ARM_ARCH_TIMER
1579 help 1580 help
1580 This option enables support for the ARM architected timer 1581 This option enables support for the ARM architected timer
1581 1582
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index d40229d9a1c9..7ade91d8cc6f 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -1,13 +1,115 @@
1#ifndef __ASMARM_ARCH_TIMER_H 1#ifndef __ASMARM_ARCH_TIMER_H
2#define __ASMARM_ARCH_TIMER_H 2#define __ASMARM_ARCH_TIMER_H
3 3
4#include <asm/barrier.h>
4#include <asm/errno.h> 5#include <asm/errno.h>
5#include <linux/clocksource.h> 6#include <linux/clocksource.h>
7#include <linux/init.h>
8#include <linux/types.h>
9
10#include <clocksource/arm_arch_timer.h>
6 11
7#ifdef CONFIG_ARM_ARCH_TIMER 12#ifdef CONFIG_ARM_ARCH_TIMER
8int arch_timer_of_register(void); 13int arch_timer_of_register(void);
9int arch_timer_sched_clock_init(void); 14int arch_timer_sched_clock_init(void);
10struct timecounter *arch_timer_get_timecounter(void); 15
16/*
17 * These register accessors are marked inline so the compiler can
18 * nicely work out which register we want, and chuck away the rest of
19 * the code. At least it does so with a recent GCC (4.6.3).
20 */
21static inline void arch_timer_reg_write(const int access, const int reg, u32 val)
22{
23 if (access == ARCH_TIMER_PHYS_ACCESS) {
24 switch (reg) {
25 case ARCH_TIMER_REG_CTRL:
26 asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
27 break;
28 case ARCH_TIMER_REG_TVAL:
29 asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val));
30 break;
31 }
32 }
33
34 if (access == ARCH_TIMER_VIRT_ACCESS) {
35 switch (reg) {
36 case ARCH_TIMER_REG_CTRL:
37 asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val));
38 break;
39 case ARCH_TIMER_REG_TVAL:
40 asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val));
41 break;
42 }
43 }
44
45 isb();
46}
47
48static inline u32 arch_timer_reg_read(const int access, const int reg)
49{
50 u32 val = 0;
51
52 if (access == ARCH_TIMER_PHYS_ACCESS) {
53 switch (reg) {
54 case ARCH_TIMER_REG_CTRL:
55 asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
56 break;
57 case ARCH_TIMER_REG_TVAL:
58 asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
59 break;
60 }
61 }
62
63 if (access == ARCH_TIMER_VIRT_ACCESS) {
64 switch (reg) {
65 case ARCH_TIMER_REG_CTRL:
66 asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
67 break;
68 case ARCH_TIMER_REG_TVAL:
69 asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val));
70 break;
71 }
72 }
73
74 return val;
75}
76
77static inline u32 arch_timer_get_cntfrq(void)
78{
79 u32 val;
80 asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
81 return val;
82}
83
84static inline u64 arch_counter_get_cntpct(void)
85{
86 u64 cval;
87
88 isb();
89 asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
90 return cval;
91}
92
93static inline u64 arch_counter_get_cntvct(void)
94{
95 u64 cval;
96
97 isb();
98 asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval));
99 return cval;
100}
101
102static inline void __cpuinit arch_counter_set_user_access(void)
103{
104 u32 cntkctl;
105
106 asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r" (cntkctl));
107
108 /* disable user access to everything */
109 cntkctl &= ~((3 << 8) | (7 << 0));
110
111 asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl));
112}
11#else 113#else
12static inline int arch_timer_of_register(void) 114static inline int arch_timer_of_register(void)
13{ 115{
@@ -18,11 +120,6 @@ static inline int arch_timer_sched_clock_init(void)
18{ 120{
19 return -ENXIO; 121 return -ENXIO;
20} 122}
21
22static inline struct timecounter *arch_timer_get_timecounter(void)
23{
24 return NULL;
25}
26#endif 123#endif
27 124
28#endif 125#endif
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
index c8ef20747ee7..36ebcf4b516f 100644
--- a/arch/arm/kernel/arch_timer.c
+++ b/arch/arm/kernel/arch_timer.c
@@ -9,516 +9,52 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/kernel.h> 12#include <linux/types.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/smp.h>
16#include <linux/cpu.h>
17#include <linux/jiffies.h>
18#include <linux/clockchips.h>
19#include <linux/interrupt.h>
20#include <linux/of_irq.h>
21#include <linux/io.h>
22 13
23#include <asm/cputype.h>
24#include <asm/delay.h> 14#include <asm/delay.h>
25#include <asm/localtimer.h>
26#include <asm/arch_timer.h>
27#include <asm/system_info.h>
28#include <asm/sched_clock.h> 15#include <asm/sched_clock.h>
29 16
30static unsigned long arch_timer_rate; 17#include <clocksource/arm_arch_timer.h>
31 18
32enum ppi_nr { 19static unsigned long arch_timer_read_counter_long(void)
33 PHYS_SECURE_PPI,
34 PHYS_NONSECURE_PPI,
35 VIRT_PPI,
36 HYP_PPI,
37 MAX_TIMER_PPI
38};
39
40static int arch_timer_ppi[MAX_TIMER_PPI];
41
42static struct clock_event_device __percpu **arch_timer_evt;
43static struct delay_timer arch_delay_timer;
44
45static bool arch_timer_use_virtual = true;
46
47/*
48 * Architected system timer support.
49 */
50
51#define ARCH_TIMER_CTRL_ENABLE (1 << 0)
52#define ARCH_TIMER_CTRL_IT_MASK (1 << 1)
53#define ARCH_TIMER_CTRL_IT_STAT (1 << 2)
54
55#define ARCH_TIMER_REG_CTRL 0
56#define ARCH_TIMER_REG_FREQ 1
57#define ARCH_TIMER_REG_TVAL 2
58
59#define ARCH_TIMER_PHYS_ACCESS 0
60#define ARCH_TIMER_VIRT_ACCESS 1
61
62/*
63 * These register accessors are marked inline so the compiler can
64 * nicely work out which register we want, and chuck away the rest of
65 * the code. At least it does so with a recent GCC (4.6.3).
66 */
67static inline void arch_timer_reg_write(const int access, const int reg, u32 val)
68{
69 if (access == ARCH_TIMER_PHYS_ACCESS) {
70 switch (reg) {
71 case ARCH_TIMER_REG_CTRL:
72 asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
73 break;
74 case ARCH_TIMER_REG_TVAL:
75 asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val));
76 break;
77 }
78 }
79
80 if (access == ARCH_TIMER_VIRT_ACCESS) {
81 switch (reg) {
82 case ARCH_TIMER_REG_CTRL:
83 asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val));
84 break;
85 case ARCH_TIMER_REG_TVAL:
86 asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val));
87 break;
88 }
89 }
90
91 isb();
92}
93
94static inline u32 arch_timer_reg_read(const int access, const int reg)
95{
96 u32 val = 0;
97
98 if (access == ARCH_TIMER_PHYS_ACCESS) {
99 switch (reg) {
100 case ARCH_TIMER_REG_CTRL:
101 asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
102 break;
103 case ARCH_TIMER_REG_TVAL:
104 asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
105 break;
106 case ARCH_TIMER_REG_FREQ:
107 asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
108 break;
109 }
110 }
111
112 if (access == ARCH_TIMER_VIRT_ACCESS) {
113 switch (reg) {
114 case ARCH_TIMER_REG_CTRL:
115 asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
116 break;
117 case ARCH_TIMER_REG_TVAL:
118 asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val));
119 break;
120 }
121 }
122
123 return val;
124}
125
126static inline cycle_t arch_timer_counter_read(const int access)
127{
128 cycle_t cval = 0;
129
130 if (access == ARCH_TIMER_PHYS_ACCESS)
131 asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
132
133 if (access == ARCH_TIMER_VIRT_ACCESS)
134 asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval));
135
136 return cval;
137}
138
139static inline cycle_t arch_counter_get_cntpct(void)
140{
141 return arch_timer_counter_read(ARCH_TIMER_PHYS_ACCESS);
142}
143
144static inline cycle_t arch_counter_get_cntvct(void)
145{
146 return arch_timer_counter_read(ARCH_TIMER_VIRT_ACCESS);
147}
148
149static irqreturn_t inline timer_handler(const int access,
150 struct clock_event_device *evt)
151{
152 unsigned long ctrl;
153 ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL);
154 if (ctrl & ARCH_TIMER_CTRL_IT_STAT) {
155 ctrl |= ARCH_TIMER_CTRL_IT_MASK;
156 arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl);
157 evt->event_handler(evt);
158 return IRQ_HANDLED;
159 }
160
161 return IRQ_NONE;
162}
163
164static irqreturn_t arch_timer_handler_virt(int irq, void *dev_id)
165{
166 struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
167
168 return timer_handler(ARCH_TIMER_VIRT_ACCESS, evt);
169}
170
171static irqreturn_t arch_timer_handler_phys(int irq, void *dev_id)
172{
173 struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
174
175 return timer_handler(ARCH_TIMER_PHYS_ACCESS, evt);
176}
177
178static inline void timer_set_mode(const int access, int mode)
179{
180 unsigned long ctrl;
181 switch (mode) {
182 case CLOCK_EVT_MODE_UNUSED:
183 case CLOCK_EVT_MODE_SHUTDOWN:
184 ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL);
185 ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
186 arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl);
187 break;
188 default:
189 break;
190 }
191}
192
193static void arch_timer_set_mode_virt(enum clock_event_mode mode,
194 struct clock_event_device *clk)
195{
196 timer_set_mode(ARCH_TIMER_VIRT_ACCESS, mode);
197}
198
199static void arch_timer_set_mode_phys(enum clock_event_mode mode,
200 struct clock_event_device *clk)
201{
202 timer_set_mode(ARCH_TIMER_PHYS_ACCESS, mode);
203}
204
205static inline void set_next_event(const int access, unsigned long evt)
206{
207 unsigned long ctrl;
208 ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL);
209 ctrl |= ARCH_TIMER_CTRL_ENABLE;
210 ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
211 arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt);
212 arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl);
213}
214
215static int arch_timer_set_next_event_virt(unsigned long evt,
216 struct clock_event_device *unused)
217{
218 set_next_event(ARCH_TIMER_VIRT_ACCESS, evt);
219 return 0;
220}
221
222static int arch_timer_set_next_event_phys(unsigned long evt,
223 struct clock_event_device *unused)
224{
225 set_next_event(ARCH_TIMER_PHYS_ACCESS, evt);
226 return 0;
227}
228
229static int __cpuinit arch_timer_setup(struct clock_event_device *clk)
230{
231 clk->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP;
232 clk->name = "arch_sys_timer";
233 clk->rating = 450;
234 if (arch_timer_use_virtual) {
235 clk->irq = arch_timer_ppi[VIRT_PPI];
236 clk->set_mode = arch_timer_set_mode_virt;
237 clk->set_next_event = arch_timer_set_next_event_virt;
238 } else {
239 clk->irq = arch_timer_ppi[PHYS_SECURE_PPI];
240 clk->set_mode = arch_timer_set_mode_phys;
241 clk->set_next_event = arch_timer_set_next_event_phys;
242 }
243
244 clk->set_mode(CLOCK_EVT_MODE_SHUTDOWN, NULL);
245
246 clockevents_config_and_register(clk, arch_timer_rate,
247 0xf, 0x7fffffff);
248
249 *__this_cpu_ptr(arch_timer_evt) = clk;
250
251 if (arch_timer_use_virtual)
252 enable_percpu_irq(arch_timer_ppi[VIRT_PPI], 0);
253 else {
254 enable_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI], 0);
255 if (arch_timer_ppi[PHYS_NONSECURE_PPI])
256 enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], 0);
257 }
258
259 return 0;
260}
261
262/* Is the optional system timer available? */
263static int local_timer_is_architected(void)
264{
265 return (cpu_architecture() >= CPU_ARCH_ARMv7) &&
266 ((read_cpuid_ext(CPUID_EXT_PFR1) >> 16) & 0xf) == 1;
267}
268
269static int arch_timer_available(void)
270{
271 unsigned long freq;
272
273 if (!local_timer_is_architected())
274 return -ENXIO;
275
276 if (arch_timer_rate == 0) {
277 freq = arch_timer_reg_read(ARCH_TIMER_PHYS_ACCESS,
278 ARCH_TIMER_REG_FREQ);
279
280 /* Check the timer frequency. */
281 if (freq == 0) {
282 pr_warn("Architected timer frequency not available\n");
283 return -EINVAL;
284 }
285
286 arch_timer_rate = freq;
287 }
288
289 pr_info_once("Architected local timer running at %lu.%02luMHz (%s).\n",
290 arch_timer_rate / 1000000, (arch_timer_rate / 10000) % 100,
291 arch_timer_use_virtual ? "virt" : "phys");
292 return 0;
293}
294
295static u32 notrace arch_counter_get_cntpct32(void)
296{
297 cycle_t cnt = arch_counter_get_cntpct();
298
299 /*
300 * The sched_clock infrastructure only knows about counters
301 * with at most 32bits. Forget about the upper 24 bits for the
302 * time being...
303 */
304 return (u32)cnt;
305}
306
307static u32 notrace arch_counter_get_cntvct32(void)
308{
309 cycle_t cnt = arch_counter_get_cntvct();
310
311 /*
312 * The sched_clock infrastructure only knows about counters
313 * with at most 32bits. Forget about the upper 24 bits for the
314 * time being...
315 */
316 return (u32)cnt;
317}
318
319static cycle_t arch_counter_read(struct clocksource *cs)
320{
321 /*
322 * Always use the physical counter for the clocksource.
323 * CNTHCTL.PL1PCTEN must be set to 1.
324 */
325 return arch_counter_get_cntpct();
326}
327
328static unsigned long arch_timer_read_current_timer(void)
329{ 20{
330 return arch_counter_get_cntpct(); 21 return arch_timer_read_counter();
331} 22}
332 23
333static cycle_t arch_counter_read_cc(const struct cyclecounter *cc) 24static u32 arch_timer_read_counter_u32(void)
334{ 25{
335 /* 26 return arch_timer_read_counter();
336 * Always use the physical counter for the clocksource.
337 * CNTHCTL.PL1PCTEN must be set to 1.
338 */
339 return arch_counter_get_cntpct();
340} 27}
341 28
342static struct clocksource clocksource_counter = { 29static struct delay_timer arch_delay_timer;
343 .name = "arch_sys_counter",
344 .rating = 400,
345 .read = arch_counter_read,
346 .mask = CLOCKSOURCE_MASK(56),
347 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
348};
349
350static struct cyclecounter cyclecounter = {
351 .read = arch_counter_read_cc,
352 .mask = CLOCKSOURCE_MASK(56),
353};
354
355static struct timecounter timecounter;
356
357struct timecounter *arch_timer_get_timecounter(void)
358{
359 return &timecounter;
360}
361
362static void __cpuinit arch_timer_stop(struct clock_event_device *clk)
363{
364 pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n",
365 clk->irq, smp_processor_id());
366
367 if (arch_timer_use_virtual)
368 disable_percpu_irq(arch_timer_ppi[VIRT_PPI]);
369 else {
370 disable_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI]);
371 if (arch_timer_ppi[PHYS_NONSECURE_PPI])
372 disable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI]);
373 }
374
375 clk->set_mode(CLOCK_EVT_MODE_UNUSED, clk);
376}
377
378static struct local_timer_ops arch_timer_ops __cpuinitdata = {
379 .setup = arch_timer_setup,
380 .stop = arch_timer_stop,
381};
382
383static struct clock_event_device arch_timer_global_evt;
384 30
385static int __init arch_timer_register(void) 31static void __init arch_timer_delay_timer_register(void)
386{ 32{
387 int err;
388 int ppi;
389
390 err = arch_timer_available();
391 if (err)
392 goto out;
393
394 arch_timer_evt = alloc_percpu(struct clock_event_device *);
395 if (!arch_timer_evt) {
396 err = -ENOMEM;
397 goto out;
398 }
399
400 clocksource_register_hz(&clocksource_counter, arch_timer_rate);
401 cyclecounter.mult = clocksource_counter.mult;
402 cyclecounter.shift = clocksource_counter.shift;
403 timecounter_init(&timecounter, &cyclecounter,
404 arch_counter_get_cntpct());
405
406 if (arch_timer_use_virtual) {
407 ppi = arch_timer_ppi[VIRT_PPI];
408 err = request_percpu_irq(ppi, arch_timer_handler_virt,
409 "arch_timer", arch_timer_evt);
410 } else {
411 ppi = arch_timer_ppi[PHYS_SECURE_PPI];
412 err = request_percpu_irq(ppi, arch_timer_handler_phys,
413 "arch_timer", arch_timer_evt);
414 if (!err && arch_timer_ppi[PHYS_NONSECURE_PPI]) {
415 ppi = arch_timer_ppi[PHYS_NONSECURE_PPI];
416 err = request_percpu_irq(ppi, arch_timer_handler_phys,
417 "arch_timer", arch_timer_evt);
418 if (err)
419 free_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI],
420 arch_timer_evt);
421 }
422 }
423
424 if (err) {
425 pr_err("arch_timer: can't register interrupt %d (%d)\n",
426 ppi, err);
427 goto out_free;
428 }
429
430 err = local_timer_register(&arch_timer_ops);
431 if (err) {
432 /*
433 * We couldn't register as a local timer (could be
434 * because we're on a UP platform, or because some
435 * other local timer is already present...). Try as a
436 * global timer instead.
437 */
438 arch_timer_global_evt.cpumask = cpumask_of(0);
439 err = arch_timer_setup(&arch_timer_global_evt);
440 }
441 if (err)
442 goto out_free_irq;
443
444 /* Use the architected timer for the delay loop. */ 33 /* Use the architected timer for the delay loop. */
445 arch_delay_timer.read_current_timer = &arch_timer_read_current_timer; 34 arch_delay_timer.read_current_timer = arch_timer_read_counter_long;
446 arch_delay_timer.freq = arch_timer_rate; 35 arch_delay_timer.freq = arch_timer_get_rate();
447 register_current_timer_delay(&arch_delay_timer); 36 register_current_timer_delay(&arch_delay_timer);
448 return 0;
449
450out_free_irq:
451 if (arch_timer_use_virtual)
452 free_percpu_irq(arch_timer_ppi[VIRT_PPI], arch_timer_evt);
453 else {
454 free_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI],
455 arch_timer_evt);
456 if (arch_timer_ppi[PHYS_NONSECURE_PPI])
457 free_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI],
458 arch_timer_evt);
459 }
460
461out_free:
462 free_percpu(arch_timer_evt);
463out:
464 return err;
465} 37}
466 38
467static const struct of_device_id arch_timer_of_match[] __initconst = {
468 { .compatible = "arm,armv7-timer", },
469 {},
470};
471
472int __init arch_timer_of_register(void) 39int __init arch_timer_of_register(void)
473{ 40{
474 struct device_node *np; 41 int ret;
475 u32 freq;
476 int i;
477
478 np = of_find_matching_node(NULL, arch_timer_of_match);
479 if (!np) {
480 pr_err("arch_timer: can't find DT node\n");
481 return -ENODEV;
482 }
483
484 /* Try to determine the frequency from the device tree or CNTFRQ */
485 if (!of_property_read_u32(np, "clock-frequency", &freq))
486 arch_timer_rate = freq;
487
488 for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
489 arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
490 42
491 /* 43 ret = arch_timer_init();
492 * If no interrupt provided for virtual timer, we'll have to 44 if (ret)
493 * stick to the physical timer. It'd better be accessible... 45 return ret;
494 */
495 if (!arch_timer_ppi[VIRT_PPI]) {
496 arch_timer_use_virtual = false;
497 46
498 if (!arch_timer_ppi[PHYS_SECURE_PPI] || 47 arch_timer_delay_timer_register();
499 !arch_timer_ppi[PHYS_NONSECURE_PPI]) {
500 pr_warn("arch_timer: No interrupt available, giving up\n");
501 return -EINVAL;
502 }
503 }
504 48
505 return arch_timer_register(); 49 return 0;
506} 50}
507 51
508int __init arch_timer_sched_clock_init(void) 52int __init arch_timer_sched_clock_init(void)
509{ 53{
510 u32 (*cnt32)(void); 54 if (arch_timer_get_rate() == 0)
511 int err; 55 return -ENXIO;
512
513 err = arch_timer_available();
514 if (err)
515 return err;
516
517 if (arch_timer_use_virtual)
518 cnt32 = arch_counter_get_cntvct32;
519 else
520 cnt32 = arch_counter_get_cntpct32;
521 56
522 setup_sched_clock(cnt32, 32, arch_timer_rate); 57 setup_sched_clock(arch_timer_read_counter_u32,
58 32, arch_timer_get_rate());
523 return 0; 59 return 0;
524} 60}
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 41b581fd0213..9d7909e58980 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -76,12 +76,12 @@ config ARCH_OMAP4
76 76
77config SOC_OMAP5 77config SOC_OMAP5
78 bool "TI OMAP5" 78 bool "TI OMAP5"
79 select ARM_ARCH_TIMER
80 select ARM_CPU_SUSPEND if PM 79 select ARM_CPU_SUSPEND if PM
81 select ARM_GIC 80 select ARM_GIC
82 select CPU_V7 81 select CPU_V7
83 select HAVE_SMP 82 select HAVE_SMP
84 select COMMON_CLK 83 select COMMON_CLK
84 select HAVE_ARM_ARCH_TIMER
85 85
86comment "OMAP Core Type" 86comment "OMAP Core Type"
87 depends on ARCH_OMAP2 87 depends on ARCH_OMAP2
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index f8f362aafee9..2b6cef6ad17f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -3,6 +3,7 @@ config ARM64
3 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE 3 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
4 select ARCH_WANT_COMPAT_IPC_PARSE_VERSION 4 select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
5 select ARM_AMBA 5 select ARM_AMBA
6 select ARM_ARCH_TIMER
6 select CLONE_BACKWARDS 7 select CLONE_BACKWARDS
7 select COMMON_CLK 8 select COMMON_CLK
8 select GENERIC_CLOCKEVENTS 9 select GENERIC_CLOCKEVENTS
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
new file mode 100644
index 000000000000..91e2a6a6fcd4
--- /dev/null
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -0,0 +1,133 @@
1/*
2 * arch/arm64/include/asm/arch_timer.h
3 *
4 * Copyright (C) 2012 ARM Ltd.
5 * Author: Marc Zyngier <marc.zyngier@arm.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_ARCH_TIMER_H
20#define __ASM_ARCH_TIMER_H
21
22#include <asm/barrier.h>
23
24#include <linux/init.h>
25#include <linux/types.h>
26
27#include <clocksource/arm_arch_timer.h>
28
29static inline void arch_timer_reg_write(int access, int reg, u32 val)
30{
31 if (access == ARCH_TIMER_PHYS_ACCESS) {
32 switch (reg) {
33 case ARCH_TIMER_REG_CTRL:
34 asm volatile("msr cntp_ctl_el0, %0" : : "r" (val));
35 break;
36 case ARCH_TIMER_REG_TVAL:
37 asm volatile("msr cntp_tval_el0, %0" : : "r" (val));
38 break;
39 default:
40 BUILD_BUG();
41 }
42 } else if (access == ARCH_TIMER_VIRT_ACCESS) {
43 switch (reg) {
44 case ARCH_TIMER_REG_CTRL:
45 asm volatile("msr cntv_ctl_el0, %0" : : "r" (val));
46 break;
47 case ARCH_TIMER_REG_TVAL:
48 asm volatile("msr cntv_tval_el0, %0" : : "r" (val));
49 break;
50 default:
51 BUILD_BUG();
52 }
53 } else {
54 BUILD_BUG();
55 }
56
57 isb();
58}
59
60static inline u32 arch_timer_reg_read(int access, int reg)
61{
62 u32 val;
63
64 if (access == ARCH_TIMER_PHYS_ACCESS) {
65 switch (reg) {
66 case ARCH_TIMER_REG_CTRL:
67 asm volatile("mrs %0, cntp_ctl_el0" : "=r" (val));
68 break;
69 case ARCH_TIMER_REG_TVAL:
70 asm volatile("mrs %0, cntp_tval_el0" : "=r" (val));
71 break;
72 default:
73 BUILD_BUG();
74 }
75 } else if (access == ARCH_TIMER_VIRT_ACCESS) {
76 switch (reg) {
77 case ARCH_TIMER_REG_CTRL:
78 asm volatile("mrs %0, cntv_ctl_el0" : "=r" (val));
79 break;
80 case ARCH_TIMER_REG_TVAL:
81 asm volatile("mrs %0, cntv_tval_el0" : "=r" (val));
82 break;
83 default:
84 BUILD_BUG();
85 }
86 } else {
87 BUILD_BUG();
88 }
89
90 return val;
91}
92
93static inline u32 arch_timer_get_cntfrq(void)
94{
95 u32 val;
96 asm volatile("mrs %0, cntfrq_el0" : "=r" (val));
97 return val;
98}
99
100static inline void __cpuinit arch_counter_set_user_access(void)
101{
102 u32 cntkctl;
103
104 /* Disable user access to the timers and the physical counter. */
105 asm volatile("mrs %0, cntkctl_el1" : "=r" (cntkctl));
106 cntkctl &= ~((3 << 8) | (1 << 0));
107
108 /* Enable user access to the virtual counter and frequency. */
109 cntkctl |= (1 << 1);
110 asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl));
111}
112
113static inline u64 arch_counter_get_cntpct(void)
114{
115 u64 cval;
116
117 isb();
118 asm volatile("mrs %0, cntpct_el0" : "=r" (cval));
119
120 return cval;
121}
122
123static inline u64 arch_counter_get_cntvct(void)
124{
125 u64 cval;
126
127 isb();
128 asm volatile("mrs %0, cntvct_el0" : "=r" (cval));
129
130 return cval;
131}
132
133#endif
diff --git a/arch/arm64/include/asm/arm_generic.h b/arch/arm64/include/asm/arm_generic.h
deleted file mode 100644
index df2aeb82f74e..000000000000
--- a/arch/arm64/include/asm/arm_generic.h
+++ /dev/null
@@ -1,100 +0,0 @@
1/*
2 * arch/arm64/include/asm/arm_generic.h
3 *
4 * Copyright (C) 2012 ARM Ltd.
5 * Author: Marc Zyngier <marc.zyngier@arm.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_ARM_GENERIC_H
20#define __ASM_ARM_GENERIC_H
21
22#include <linux/clocksource.h>
23
24#define ARCH_TIMER_CTRL_ENABLE (1 << 0)
25#define ARCH_TIMER_CTRL_IMASK (1 << 1)
26#define ARCH_TIMER_CTRL_ISTATUS (1 << 2)
27
28#define ARCH_TIMER_REG_CTRL 0
29#define ARCH_TIMER_REG_FREQ 1
30#define ARCH_TIMER_REG_TVAL 2
31
32static inline void arch_timer_reg_write(int reg, u32 val)
33{
34 switch (reg) {
35 case ARCH_TIMER_REG_CTRL:
36 asm volatile("msr cntp_ctl_el0, %0" : : "r" (val));
37 break;
38 case ARCH_TIMER_REG_TVAL:
39 asm volatile("msr cntp_tval_el0, %0" : : "r" (val));
40 break;
41 default:
42 BUILD_BUG();
43 }
44
45 isb();
46}
47
48static inline u32 arch_timer_reg_read(int reg)
49{
50 u32 val;
51
52 switch (reg) {
53 case ARCH_TIMER_REG_CTRL:
54 asm volatile("mrs %0, cntp_ctl_el0" : "=r" (val));
55 break;
56 case ARCH_TIMER_REG_FREQ:
57 asm volatile("mrs %0, cntfrq_el0" : "=r" (val));
58 break;
59 case ARCH_TIMER_REG_TVAL:
60 asm volatile("mrs %0, cntp_tval_el0" : "=r" (val));
61 break;
62 default:
63 BUILD_BUG();
64 }
65
66 return val;
67}
68
69static inline void __cpuinit arch_counter_enable_user_access(void)
70{
71 u32 cntkctl;
72
73 /* Disable user access to the timers and the physical counter. */
74 asm volatile("mrs %0, cntkctl_el1" : "=r" (cntkctl));
75 cntkctl &= ~((3 << 8) | (1 << 0));
76
77 /* Enable user access to the virtual counter and frequency. */
78 cntkctl |= (1 << 1);
79 asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl));
80}
81
82static inline cycle_t arch_counter_get_cntpct(void)
83{
84 cycle_t cval;
85
86 asm volatile("mrs %0, cntpct_el0" : "=r" (cval));
87
88 return cval;
89}
90
91static inline cycle_t arch_counter_get_cntvct(void)
92{
93 cycle_t cval;
94
95 asm volatile("mrs %0, cntvct_el0" : "=r" (cval));
96
97 return cval;
98}
99
100#endif
diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
index 3b4b7258f492..b0ef18d14c3b 100644
--- a/arch/arm64/kernel/time.c
+++ b/arch/arm64/kernel/time.c
@@ -31,8 +31,9 @@
31#include <linux/syscore_ops.h> 31#include <linux/syscore_ops.h>
32#include <linux/timer.h> 32#include <linux/timer.h>
33#include <linux/irq.h> 33#include <linux/irq.h>
34#include <linux/delay.h>
34 35
35#include <clocksource/arm_generic.h> 36#include <clocksource/arm_arch_timer.h>
36 37
37#include <asm/thread_info.h> 38#include <asm/thread_info.h>
38#include <asm/stacktrace.h> 39#include <asm/stacktrace.h>
@@ -59,7 +60,31 @@ unsigned long profile_pc(struct pt_regs *regs)
59EXPORT_SYMBOL(profile_pc); 60EXPORT_SYMBOL(profile_pc);
60#endif 61#endif
61 62
63static u64 sched_clock_mult __read_mostly;
64
65unsigned long long notrace sched_clock(void)
66{
67 return arch_timer_read_counter() * sched_clock_mult;
68}
69
70int read_current_timer(unsigned long *timer_value)
71{
72 *timer_value = arch_timer_read_counter();
73 return 0;
74}
75
62void __init time_init(void) 76void __init time_init(void)
63{ 77{
64 arm_generic_timer_init(); 78 u32 arch_timer_rate;
79
80 if (arch_timer_init())
81 panic("Unable to initialise architected timer.\n");
82
83 arch_timer_rate = arch_timer_get_rate();
84
85 /* Cache the sched_clock multiplier to save a divide in the hot path. */
86 sched_clock_mult = NSEC_PER_SEC / arch_timer_rate;
87
88 /* Calibrate the delay loop directly */
89 lpj_fine = arch_timer_rate / HZ;
65} 90}
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 7fdcbd3f4da5..64798424b6cb 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -54,7 +54,5 @@ config CLKSRC_DBX500_PRCMU_SCHED_CLOCK
54 help 54 help
55 Use the always on PRCMU Timer as sched_clock 55 Use the always on PRCMU Timer as sched_clock
56 56
57config CLKSRC_ARM_GENERIC 57config ARM_ARCH_TIMER
58 def_bool y if ARM64 58 bool
59 help
60 This option enables support for the ARM generic timer.
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index f93453d01673..e69511c4c66e 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -17,4 +17,4 @@ obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o
17obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o 17obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o
18obj-$(CONFIG_SUNXI_TIMER) += sunxi_timer.o 18obj-$(CONFIG_SUNXI_TIMER) += sunxi_timer.o
19 19
20obj-$(CONFIG_CLKSRC_ARM_GENERIC) += arm_generic.o 20obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
new file mode 100644
index 000000000000..d7ad425ab9b3
--- /dev/null
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -0,0 +1,391 @@
1/*
2 * linux/drivers/clocksource/arm_arch_timer.c
3 *
4 * Copyright (C) 2011 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/device.h>
14#include <linux/smp.h>
15#include <linux/cpu.h>
16#include <linux/clockchips.h>
17#include <linux/interrupt.h>
18#include <linux/of_irq.h>
19#include <linux/io.h>
20
21#include <asm/arch_timer.h>
22#include <asm/virt.h>
23
24#include <clocksource/arm_arch_timer.h>
25
26static u32 arch_timer_rate;
27
28enum ppi_nr {
29 PHYS_SECURE_PPI,
30 PHYS_NONSECURE_PPI,
31 VIRT_PPI,
32 HYP_PPI,
33 MAX_TIMER_PPI
34};
35
36static int arch_timer_ppi[MAX_TIMER_PPI];
37
38static struct clock_event_device __percpu *arch_timer_evt;
39
40static bool arch_timer_use_virtual = true;
41
42/*
43 * Architected system timer support.
44 */
45
46static inline irqreturn_t timer_handler(const int access,
47 struct clock_event_device *evt)
48{
49 unsigned long ctrl;
50 ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL);
51 if (ctrl & ARCH_TIMER_CTRL_IT_STAT) {
52 ctrl |= ARCH_TIMER_CTRL_IT_MASK;
53 arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl);
54 evt->event_handler(evt);
55 return IRQ_HANDLED;
56 }
57
58 return IRQ_NONE;
59}
60
61static irqreturn_t arch_timer_handler_virt(int irq, void *dev_id)
62{
63 struct clock_event_device *evt = dev_id;
64
65 return timer_handler(ARCH_TIMER_VIRT_ACCESS, evt);
66}
67
68static irqreturn_t arch_timer_handler_phys(int irq, void *dev_id)
69{
70 struct clock_event_device *evt = dev_id;
71
72 return timer_handler(ARCH_TIMER_PHYS_ACCESS, evt);
73}
74
75static inline void timer_set_mode(const int access, int mode)
76{
77 unsigned long ctrl;
78 switch (mode) {
79 case CLOCK_EVT_MODE_UNUSED:
80 case CLOCK_EVT_MODE_SHUTDOWN:
81 ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL);
82 ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
83 arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl);
84 break;
85 default:
86 break;
87 }
88}
89
90static void arch_timer_set_mode_virt(enum clock_event_mode mode,
91 struct clock_event_device *clk)
92{
93 timer_set_mode(ARCH_TIMER_VIRT_ACCESS, mode);
94}
95
96static void arch_timer_set_mode_phys(enum clock_event_mode mode,
97 struct clock_event_device *clk)
98{
99 timer_set_mode(ARCH_TIMER_PHYS_ACCESS, mode);
100}
101
102static inline void set_next_event(const int access, unsigned long evt)
103{
104 unsigned long ctrl;
105 ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL);
106 ctrl |= ARCH_TIMER_CTRL_ENABLE;
107 ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
108 arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt);
109 arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl);
110}
111
112static int arch_timer_set_next_event_virt(unsigned long evt,
113 struct clock_event_device *unused)
114{
115 set_next_event(ARCH_TIMER_VIRT_ACCESS, evt);
116 return 0;
117}
118
119static int arch_timer_set_next_event_phys(unsigned long evt,
120 struct clock_event_device *unused)
121{
122 set_next_event(ARCH_TIMER_PHYS_ACCESS, evt);
123 return 0;
124}
125
126static int __cpuinit arch_timer_setup(struct clock_event_device *clk)
127{
128 clk->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP;
129 clk->name = "arch_sys_timer";
130 clk->rating = 450;
131 if (arch_timer_use_virtual) {
132 clk->irq = arch_timer_ppi[VIRT_PPI];
133 clk->set_mode = arch_timer_set_mode_virt;
134 clk->set_next_event = arch_timer_set_next_event_virt;
135 } else {
136 clk->irq = arch_timer_ppi[PHYS_SECURE_PPI];
137 clk->set_mode = arch_timer_set_mode_phys;
138 clk->set_next_event = arch_timer_set_next_event_phys;
139 }
140
141 clk->cpumask = cpumask_of(smp_processor_id());
142
143 clk->set_mode(CLOCK_EVT_MODE_SHUTDOWN, NULL);
144
145 clockevents_config_and_register(clk, arch_timer_rate,
146 0xf, 0x7fffffff);
147
148 if (arch_timer_use_virtual)
149 enable_percpu_irq(arch_timer_ppi[VIRT_PPI], 0);
150 else {
151 enable_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI], 0);
152 if (arch_timer_ppi[PHYS_NONSECURE_PPI])
153 enable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI], 0);
154 }
155
156 arch_counter_set_user_access();
157
158 return 0;
159}
160
161static int arch_timer_available(void)
162{
163 u32 freq;
164
165 if (arch_timer_rate == 0) {
166 freq = arch_timer_get_cntfrq();
167
168 /* Check the timer frequency. */
169 if (freq == 0) {
170 pr_warn("Architected timer frequency not available\n");
171 return -EINVAL;
172 }
173
174 arch_timer_rate = freq;
175 }
176
177 pr_info_once("Architected local timer running at %lu.%02luMHz (%s).\n",
178 (unsigned long)arch_timer_rate / 1000000,
179 (unsigned long)(arch_timer_rate / 10000) % 100,
180 arch_timer_use_virtual ? "virt" : "phys");
181 return 0;
182}
183
184u32 arch_timer_get_rate(void)
185{
186 return arch_timer_rate;
187}
188
189/*
190 * Some external users of arch_timer_read_counter (e.g. sched_clock) may try to
191 * call it before it has been initialised. Rather than incur a performance
192 * penalty checking for initialisation, provide a default implementation that
193 * won't lead to time appearing to jump backwards.
194 */
195static u64 arch_timer_read_zero(void)
196{
197 return 0;
198}
199
200u64 (*arch_timer_read_counter)(void) = arch_timer_read_zero;
201
202static cycle_t arch_counter_read(struct clocksource *cs)
203{
204 return arch_timer_read_counter();
205}
206
207static cycle_t arch_counter_read_cc(const struct cyclecounter *cc)
208{
209 return arch_timer_read_counter();
210}
211
212static struct clocksource clocksource_counter = {
213 .name = "arch_sys_counter",
214 .rating = 400,
215 .read = arch_counter_read,
216 .mask = CLOCKSOURCE_MASK(56),
217 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
218};
219
220static struct cyclecounter cyclecounter = {
221 .read = arch_counter_read_cc,
222 .mask = CLOCKSOURCE_MASK(56),
223};
224
225static struct timecounter timecounter;
226
227struct timecounter *arch_timer_get_timecounter(void)
228{
229 return &timecounter;
230}
231
232static void __cpuinit arch_timer_stop(struct clock_event_device *clk)
233{
234 pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n",
235 clk->irq, smp_processor_id());
236
237 if (arch_timer_use_virtual)
238 disable_percpu_irq(arch_timer_ppi[VIRT_PPI]);
239 else {
240 disable_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI]);
241 if (arch_timer_ppi[PHYS_NONSECURE_PPI])
242 disable_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI]);
243 }
244
245 clk->set_mode(CLOCK_EVT_MODE_UNUSED, clk);
246}
247
248static int __cpuinit arch_timer_cpu_notify(struct notifier_block *self,
249 unsigned long action, void *hcpu)
250{
251 struct clock_event_device *evt = this_cpu_ptr(arch_timer_evt);
252
253 switch (action & ~CPU_TASKS_FROZEN) {
254 case CPU_STARTING:
255 arch_timer_setup(evt);
256 break;
257 case CPU_DYING:
258 arch_timer_stop(evt);
259 break;
260 }
261
262 return NOTIFY_OK;
263}
264
265static struct notifier_block arch_timer_cpu_nb __cpuinitdata = {
266 .notifier_call = arch_timer_cpu_notify,
267};
268
269static int __init arch_timer_register(void)
270{
271 int err;
272 int ppi;
273
274 err = arch_timer_available();
275 if (err)
276 goto out;
277
278 arch_timer_evt = alloc_percpu(struct clock_event_device);
279 if (!arch_timer_evt) {
280 err = -ENOMEM;
281 goto out;
282 }
283
284 clocksource_register_hz(&clocksource_counter, arch_timer_rate);
285 cyclecounter.mult = clocksource_counter.mult;
286 cyclecounter.shift = clocksource_counter.shift;
287 timecounter_init(&timecounter, &cyclecounter,
288 arch_counter_get_cntpct());
289
290 if (arch_timer_use_virtual) {
291 ppi = arch_timer_ppi[VIRT_PPI];
292 err = request_percpu_irq(ppi, arch_timer_handler_virt,
293 "arch_timer", arch_timer_evt);
294 } else {
295 ppi = arch_timer_ppi[PHYS_SECURE_PPI];
296 err = request_percpu_irq(ppi, arch_timer_handler_phys,
297 "arch_timer", arch_timer_evt);
298 if (!err && arch_timer_ppi[PHYS_NONSECURE_PPI]) {
299 ppi = arch_timer_ppi[PHYS_NONSECURE_PPI];
300 err = request_percpu_irq(ppi, arch_timer_handler_phys,
301 "arch_timer", arch_timer_evt);
302 if (err)
303 free_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI],
304 arch_timer_evt);
305 }
306 }
307
308 if (err) {
309 pr_err("arch_timer: can't register interrupt %d (%d)\n",
310 ppi, err);
311 goto out_free;
312 }
313
314 err = register_cpu_notifier(&arch_timer_cpu_nb);
315 if (err)
316 goto out_free_irq;
317
318 /* Immediately configure the timer on the boot CPU */
319 arch_timer_setup(this_cpu_ptr(arch_timer_evt));
320
321 return 0;
322
323out_free_irq:
324 if (arch_timer_use_virtual)
325 free_percpu_irq(arch_timer_ppi[VIRT_PPI], arch_timer_evt);
326 else {
327 free_percpu_irq(arch_timer_ppi[PHYS_SECURE_PPI],
328 arch_timer_evt);
329 if (arch_timer_ppi[PHYS_NONSECURE_PPI])
330 free_percpu_irq(arch_timer_ppi[PHYS_NONSECURE_PPI],
331 arch_timer_evt);
332 }
333
334out_free:
335 free_percpu(arch_timer_evt);
336out:
337 return err;
338}
339
340static const struct of_device_id arch_timer_of_match[] __initconst = {
341 { .compatible = "arm,armv7-timer", },
342 { .compatible = "arm,armv8-timer", },
343 {},
344};
345
346int __init arch_timer_init(void)
347{
348 struct device_node *np;
349 u32 freq;
350 int i;
351
352 np = of_find_matching_node(NULL, arch_timer_of_match);
353 if (!np) {
354 pr_err("arch_timer: can't find DT node\n");
355 return -ENODEV;
356 }
357
358 /* Try to determine the frequency from the device tree or CNTFRQ */
359 if (!of_property_read_u32(np, "clock-frequency", &freq))
360 arch_timer_rate = freq;
361
362 for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++)
363 arch_timer_ppi[i] = irq_of_parse_and_map(np, i);
364
365 of_node_put(np);
366
367 /*
368 * If HYP mode is available, we know that the physical timer
369 * has been configured to be accessible from PL1. Use it, so
370 * that a guest can use the virtual timer instead.
371 *
372 * If no interrupt provided for virtual timer, we'll have to
373 * stick to the physical timer. It'd better be accessible...
374 */
375 if (is_hyp_mode_available() || !arch_timer_ppi[VIRT_PPI]) {
376 arch_timer_use_virtual = false;
377
378 if (!arch_timer_ppi[PHYS_SECURE_PPI] ||
379 !arch_timer_ppi[PHYS_NONSECURE_PPI]) {
380 pr_warn("arch_timer: No interrupt available, giving up\n");
381 return -EINVAL;
382 }
383 }
384
385 if (arch_timer_use_virtual)
386 arch_timer_read_counter = arch_counter_get_cntvct;
387 else
388 arch_timer_read_counter = arch_counter_get_cntpct;
389
390 return arch_timer_register();
391}
diff --git a/drivers/clocksource/arm_generic.c b/drivers/clocksource/arm_generic.c
deleted file mode 100644
index 8ae1a61523ff..000000000000
--- a/drivers/clocksource/arm_generic.c
+++ /dev/null
@@ -1,232 +0,0 @@
1/*
2 * Generic timers support
3 *
4 * Copyright (C) 2012 ARM Ltd.
5 * Author: Marc Zyngier <marc.zyngier@arm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/init.h>
21#include <linux/kernel.h>
22#include <linux/delay.h>
23#include <linux/device.h>
24#include <linux/smp.h>
25#include <linux/cpu.h>
26#include <linux/jiffies.h>
27#include <linux/interrupt.h>
28#include <linux/clockchips.h>
29#include <linux/of_irq.h>
30#include <linux/io.h>
31
32#include <clocksource/arm_generic.h>
33
34#include <asm/arm_generic.h>
35
36static u32 arch_timer_rate;
37static u64 sched_clock_mult __read_mostly;
38static DEFINE_PER_CPU(struct clock_event_device, arch_timer_evt);
39static int arch_timer_ppi;
40
41static irqreturn_t arch_timer_handle_irq(int irq, void *dev_id)
42{
43 struct clock_event_device *evt = dev_id;
44 unsigned long ctrl;
45
46 ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
47 if (ctrl & ARCH_TIMER_CTRL_ISTATUS) {
48 ctrl |= ARCH_TIMER_CTRL_IMASK;
49 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
50 evt->event_handler(evt);
51 return IRQ_HANDLED;
52 }
53
54 return IRQ_NONE;
55}
56
57static void arch_timer_stop(void)
58{
59 unsigned long ctrl;
60
61 ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
62 ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
63 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
64}
65
66static void arch_timer_set_mode(enum clock_event_mode mode,
67 struct clock_event_device *clk)
68{
69 switch (mode) {
70 case CLOCK_EVT_MODE_UNUSED:
71 case CLOCK_EVT_MODE_SHUTDOWN:
72 arch_timer_stop();
73 break;
74 default:
75 break;
76 }
77}
78
79static int arch_timer_set_next_event(unsigned long evt,
80 struct clock_event_device *unused)
81{
82 unsigned long ctrl;
83
84 ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
85 ctrl |= ARCH_TIMER_CTRL_ENABLE;
86 ctrl &= ~ARCH_TIMER_CTRL_IMASK;
87
88 arch_timer_reg_write(ARCH_TIMER_REG_TVAL, evt);
89 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
90
91 return 0;
92}
93
94static void __cpuinit arch_timer_setup(struct clock_event_device *clk)
95{
96 /* Let's make sure the timer is off before doing anything else */
97 arch_timer_stop();
98
99 clk->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP;
100 clk->name = "arch_sys_timer";
101 clk->rating = 400;
102 clk->set_mode = arch_timer_set_mode;
103 clk->set_next_event = arch_timer_set_next_event;
104 clk->irq = arch_timer_ppi;
105 clk->cpumask = cpumask_of(smp_processor_id());
106
107 clockevents_config_and_register(clk, arch_timer_rate,
108 0xf, 0x7fffffff);
109
110 enable_percpu_irq(clk->irq, 0);
111
112 /* Ensure the virtual counter is visible to userspace for the vDSO. */
113 arch_counter_enable_user_access();
114}
115
116static void __init arch_timer_calibrate(void)
117{
118 if (arch_timer_rate == 0) {
119 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, 0);
120 arch_timer_rate = arch_timer_reg_read(ARCH_TIMER_REG_FREQ);
121
122 /* Check the timer frequency. */
123 if (arch_timer_rate == 0)
124 panic("Architected timer frequency is set to zero.\n"
125 "You must set this in your .dts file\n");
126 }
127
128 /* Cache the sched_clock multiplier to save a divide in the hot path. */
129
130 sched_clock_mult = DIV_ROUND_CLOSEST(NSEC_PER_SEC, arch_timer_rate);
131
132 pr_info("Architected local timer running at %u.%02uMHz.\n",
133 arch_timer_rate / 1000000, (arch_timer_rate / 10000) % 100);
134}
135
136static cycle_t arch_counter_read(struct clocksource *cs)
137{
138 return arch_counter_get_cntpct();
139}
140
141static struct clocksource clocksource_counter = {
142 .name = "arch_sys_counter",
143 .rating = 400,
144 .read = arch_counter_read,
145 .mask = CLOCKSOURCE_MASK(56),
146 .flags = (CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_VALID_FOR_HRES),
147};
148
149int read_current_timer(unsigned long *timer_value)
150{
151 *timer_value = arch_counter_get_cntpct();
152 return 0;
153}
154
155unsigned long long notrace sched_clock(void)
156{
157 return arch_counter_get_cntvct() * sched_clock_mult;
158}
159
160static int __cpuinit arch_timer_cpu_notify(struct notifier_block *self,
161 unsigned long action, void *hcpu)
162{
163 int cpu = (long)hcpu;
164 struct clock_event_device *clk = per_cpu_ptr(&arch_timer_evt, cpu);
165
166 switch(action) {
167 case CPU_STARTING:
168 case CPU_STARTING_FROZEN:
169 arch_timer_setup(clk);
170 break;
171
172 case CPU_DYING:
173 case CPU_DYING_FROZEN:
174 pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n",
175 clk->irq, cpu);
176 disable_percpu_irq(clk->irq);
177 arch_timer_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
178 break;
179 }
180
181 return NOTIFY_OK;
182}
183
184static struct notifier_block __cpuinitdata arch_timer_cpu_nb = {
185 .notifier_call = arch_timer_cpu_notify,
186};
187
188static const struct of_device_id arch_timer_of_match[] __initconst = {
189 { .compatible = "arm,armv8-timer" },
190 {},
191};
192
193int __init arm_generic_timer_init(void)
194{
195 struct device_node *np;
196 int err;
197 u32 freq;
198
199 np = of_find_matching_node(NULL, arch_timer_of_match);
200 if (!np) {
201 pr_err("arch_timer: can't find DT node\n");
202 return -ENODEV;
203 }
204
205 /* Try to determine the frequency from the device tree or CNTFRQ */
206 if (!of_property_read_u32(np, "clock-frequency", &freq))
207 arch_timer_rate = freq;
208 arch_timer_calibrate();
209
210 arch_timer_ppi = irq_of_parse_and_map(np, 0);
211 pr_info("arch_timer: found %s irq %d\n", np->name, arch_timer_ppi);
212
213 err = request_percpu_irq(arch_timer_ppi, arch_timer_handle_irq,
214 np->name, &arch_timer_evt);
215 if (err) {
216 pr_err("arch_timer: can't register interrupt %d (%d)\n",
217 arch_timer_ppi, err);
218 return err;
219 }
220
221 clocksource_register_hz(&clocksource_counter, arch_timer_rate);
222
223 /* Calibrate the delay loop directly */
224 lpj_fine = DIV_ROUND_CLOSEST(arch_timer_rate, HZ);
225
226 /* Immediately configure the timer on the boot CPU */
227 arch_timer_setup(this_cpu_ptr(&arch_timer_evt));
228
229 register_cpu_notifier(&arch_timer_cpu_nb);
230
231 return 0;
232}
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
new file mode 100644
index 000000000000..b61f9961b0cc
--- /dev/null
+++ b/include/clocksource/arm_arch_timer.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __CLKSOURCE_ARM_ARCH_TIMER_H
17#define __CLKSOURCE_ARM_ARCH_TIMER_H
18
19#include <linux/clocksource.h>
20#include <linux/types.h>
21
22#define ARCH_TIMER_CTRL_ENABLE (1 << 0)
23#define ARCH_TIMER_CTRL_IT_MASK (1 << 1)
24#define ARCH_TIMER_CTRL_IT_STAT (1 << 2)
25
26#define ARCH_TIMER_REG_CTRL 0
27#define ARCH_TIMER_REG_TVAL 1
28
29#define ARCH_TIMER_PHYS_ACCESS 0
30#define ARCH_TIMER_VIRT_ACCESS 1
31
32#ifdef CONFIG_ARM_ARCH_TIMER
33
34extern int arch_timer_init(void);
35extern u32 arch_timer_get_rate(void);
36extern u64 (*arch_timer_read_counter)(void);
37extern struct timecounter *arch_timer_get_timecounter(void);
38
39#else
40
41static inline int arch_timer_init(void)
42{
43 return -ENXIO;
44}
45
46static inline u32 arch_timer_get_rate(void)
47{
48 return 0;
49}
50
51static inline u64 arch_timer_read_counter(void)
52{
53 return 0;
54}
55
56static struct timecounter *arch_timer_get_timecounter(void)
57{
58 return NULL;
59}
60
61#endif
62
63#endif
diff --git a/include/clocksource/arm_generic.h b/include/clocksource/arm_generic.h
deleted file mode 100644
index 5b41b0d27f0f..000000000000
--- a/include/clocksource/arm_generic.h
+++ /dev/null
@@ -1,21 +0,0 @@
1/*
2 * Copyright (C) 2012 ARM Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef __CLKSOURCE_ARM_GENERIC_H
17#define __CLKSOURCE_ARM_GENERIC_H
18
19extern int arm_generic_timer_init(void);
20
21#endif