aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Rutland <mark.rutland@arm.com>2012-11-12 11:18:00 -0500
committerMark Rutland <mark.rutland@arm.com>2013-01-31 10:51:22 -0500
commitec944c93a293bee6b4cc6b6f1c9560526c7ed635 (patch)
tree564dda7943e789ade94ec3aa4a4c70fa3204da5c
parentfd5583a4c271ec03e2da04196aaaab177b385eb8 (diff)
arm: arch_timer: factor out register accessors
Currently the arch_timer register accessors are thrown together with the main driver, preventing us from porting the driver to other architectures. This patch moves the register accessors into a header file, as with the arm64 version. Constants required by the accessors are also moved. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Marc Zyngier <marc.zyngier@arm.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
-rw-r--r--arch/arm/include/asm/arch_timer.h94
-rw-r--r--arch/arm/kernel/arch_timer.c92
2 files changed, 94 insertions, 92 deletions
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
index d40229d9a1c9..db0fdc4cc9cc 100644
--- a/arch/arm/include/asm/arch_timer.h
+++ b/arch/arm/include/asm/arch_timer.h
@@ -1,13 +1,107 @@
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/types.h>
6 8
7#ifdef CONFIG_ARM_ARCH_TIMER 9#ifdef CONFIG_ARM_ARCH_TIMER
8int arch_timer_of_register(void); 10int arch_timer_of_register(void);
9int arch_timer_sched_clock_init(void); 11int arch_timer_sched_clock_init(void);
10struct timecounter *arch_timer_get_timecounter(void); 12struct timecounter *arch_timer_get_timecounter(void);
13
14#define ARCH_TIMER_CTRL_ENABLE (1 << 0)
15#define ARCH_TIMER_CTRL_IT_MASK (1 << 1)
16#define ARCH_TIMER_CTRL_IT_STAT (1 << 2)
17
18#define ARCH_TIMER_REG_CTRL 0
19#define ARCH_TIMER_REG_TVAL 1
20
21#define ARCH_TIMER_PHYS_ACCESS 0
22#define ARCH_TIMER_VIRT_ACCESS 1
23
24/*
25 * These register accessors are marked inline so the compiler can
26 * nicely work out which register we want, and chuck away the rest of
27 * the code. At least it does so with a recent GCC (4.6.3).
28 */
29static inline void arch_timer_reg_write(const int access, const int reg, u32 val)
30{
31 if (access == ARCH_TIMER_PHYS_ACCESS) {
32 switch (reg) {
33 case ARCH_TIMER_REG_CTRL:
34 asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
35 break;
36 case ARCH_TIMER_REG_TVAL:
37 asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val));
38 break;
39 }
40 }
41
42 if (access == ARCH_TIMER_VIRT_ACCESS) {
43 switch (reg) {
44 case ARCH_TIMER_REG_CTRL:
45 asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val));
46 break;
47 case ARCH_TIMER_REG_TVAL:
48 asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val));
49 break;
50 }
51 }
52}
53
54static inline u32 arch_timer_reg_read(const int access, const int reg)
55{
56 u32 val = 0;
57
58 if (access == ARCH_TIMER_PHYS_ACCESS) {
59 switch (reg) {
60 case ARCH_TIMER_REG_CTRL:
61 asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
62 break;
63 case ARCH_TIMER_REG_TVAL:
64 asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
65 break;
66 }
67 }
68
69 if (access == ARCH_TIMER_VIRT_ACCESS) {
70 switch (reg) {
71 case ARCH_TIMER_REG_CTRL:
72 asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
73 break;
74 case ARCH_TIMER_REG_TVAL:
75 asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val));
76 break;
77 }
78 }
79
80 return val;
81}
82
83static inline u32 arch_timer_get_cntfrq(void)
84{
85 u32 val;
86 asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
87 return val;
88}
89
90static inline u64 arch_counter_get_cntpct(void)
91{
92 u64 cval;
93
94 asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
95 return cval;
96}
97
98static inline u64 arch_counter_get_cntvct(void)
99{
100 u64 cval;
101
102 asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval));
103 return cval;
104}
11#else 105#else
12static inline int arch_timer_of_register(void) 106static inline int arch_timer_of_register(void)
13{ 107{
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
index f31c9ee18af2..e973cc0eaad1 100644
--- a/arch/arm/kernel/arch_timer.c
+++ b/arch/arm/kernel/arch_timer.c
@@ -46,98 +46,6 @@ static bool arch_timer_use_virtual = true;
46 * Architected system timer support. 46 * Architected system timer support.
47 */ 47 */
48 48
49#define ARCH_TIMER_CTRL_ENABLE (1 << 0)
50#define ARCH_TIMER_CTRL_IT_MASK (1 << 1)
51#define ARCH_TIMER_CTRL_IT_STAT (1 << 2)
52
53#define ARCH_TIMER_REG_CTRL 0
54#define ARCH_TIMER_REG_TVAL 1
55
56#define ARCH_TIMER_PHYS_ACCESS 0
57#define ARCH_TIMER_VIRT_ACCESS 1
58
59/*
60 * These register accessors are marked inline so the compiler can
61 * nicely work out which register we want, and chuck away the rest of
62 * the code. At least it does so with a recent GCC (4.6.3).
63 */
64static inline void arch_timer_reg_write(const int access, const int reg, u32 val)
65{
66 if (access == ARCH_TIMER_PHYS_ACCESS) {
67 switch (reg) {
68 case ARCH_TIMER_REG_CTRL:
69 asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
70 break;
71 case ARCH_TIMER_REG_TVAL:
72 asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val));
73 break;
74 }
75 }
76
77 if (access == ARCH_TIMER_VIRT_ACCESS) {
78 switch (reg) {
79 case ARCH_TIMER_REG_CTRL:
80 asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" (val));
81 break;
82 case ARCH_TIMER_REG_TVAL:
83 asm volatile("mcr p15, 0, %0, c14, c3, 0" : : "r" (val));
84 break;
85 }
86 }
87
88 isb();
89}
90
91static inline u32 arch_timer_reg_read(const int access, const int reg)
92{
93 u32 val = 0;
94
95 if (access == ARCH_TIMER_PHYS_ACCESS) {
96 switch (reg) {
97 case ARCH_TIMER_REG_CTRL:
98 asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
99 break;
100 case ARCH_TIMER_REG_TVAL:
101 asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
102 break;
103 }
104 }
105
106 if (access == ARCH_TIMER_VIRT_ACCESS) {
107 switch (reg) {
108 case ARCH_TIMER_REG_CTRL:
109 asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
110 break;
111 case ARCH_TIMER_REG_TVAL:
112 asm volatile("mrc p15, 0, %0, c14, c3, 0" : "=r" (val));
113 break;
114 }
115 }
116
117 return val;
118}
119
120static inline u32 arch_timer_get_cntfrq(void)
121{
122 u32 val;
123 asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
124 return val;
125}
126
127static inline u64 arch_counter_get_cntpct(void)
128{
129 u64 cval;
130 asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
131 return cval;
132}
133
134static inline u64 arch_counter_get_cntvct(void)
135{
136 u64 cval;
137 asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval));
138 return cval;
139}
140
141static irqreturn_t inline timer_handler(const int access, 49static irqreturn_t inline timer_handler(const int access,
142 struct clock_event_device *evt) 50 struct clock_event_device *evt)
143{ 51{