diff options
author | Mark Rutland <mark.rutland@arm.com> | 2012-11-12 11:18:00 -0500 |
---|---|---|
committer | Mark Rutland <mark.rutland@arm.com> | 2013-01-31 10:51:22 -0500 |
commit | ec944c93a293bee6b4cc6b6f1c9560526c7ed635 (patch) | |
tree | 564dda7943e789ade94ec3aa4a4c70fa3204da5c | |
parent | fd5583a4c271ec03e2da04196aaaab177b385eb8 (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.h | 94 | ||||
-rw-r--r-- | arch/arm/kernel/arch_timer.c | 92 |
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 |
8 | int arch_timer_of_register(void); | 10 | int arch_timer_of_register(void); |
9 | int arch_timer_sched_clock_init(void); | 11 | int arch_timer_sched_clock_init(void); |
10 | struct timecounter *arch_timer_get_timecounter(void); | 12 | struct 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 | */ | ||
29 | static 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 | |||
54 | static 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 | |||
83 | static 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 | |||
90 | static 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 | |||
98 | static 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 |
12 | static inline int arch_timer_of_register(void) | 106 | static 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 | */ | ||
64 | static 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 | |||
91 | static 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 | |||
120 | static 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 | |||
127 | static 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 | |||
134 | static 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 | |||
141 | static irqreturn_t inline timer_handler(const int access, | 49 | static irqreturn_t inline timer_handler(const int access, |
142 | struct clock_event_device *evt) | 50 | struct clock_event_device *evt) |
143 | { | 51 | { |