diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2011-01-14 10:32:36 -0500 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2012-04-27 08:35:33 -0400 |
commit | 3f61c80eb7dff0fb35beb8068852d3fc902315a6 (patch) | |
tree | 33f1285e1bac944b3279993b14cbfc196abf570e /arch/arm | |
parent | 022c03a2d650c641fa0f94dbc9d9ff77f8057678 (diff) |
ARM: architected timers: Add A15 specific sched_clock implementation
Provide an A15 sched_clock implementation using the virtual counter,
which is thought to be more useful than the physical one in a
virtualised environment, as it can offset the time spent in another
VM or the hypervisor.
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/include/asm/arch_timer.h | 6 | ||||
-rw-r--r-- | arch/arm/kernel/arch_timer.c | 25 |
2 files changed, 31 insertions, 0 deletions
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index 827305d77b3e..dc008c696b5a 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h | |||
@@ -9,11 +9,17 @@ struct arch_timer { | |||
9 | 9 | ||
10 | #ifdef CONFIG_ARM_ARCH_TIMER | 10 | #ifdef CONFIG_ARM_ARCH_TIMER |
11 | int arch_timer_register(struct arch_timer *); | 11 | int arch_timer_register(struct arch_timer *); |
12 | int arch_timer_sched_clock_init(void); | ||
12 | #else | 13 | #else |
13 | static inline int arch_timer_register(struct arch_timer *at) | 14 | static inline int arch_timer_register(struct arch_timer *at) |
14 | { | 15 | { |
15 | return -ENXIO; | 16 | return -ENXIO; |
16 | } | 17 | } |
18 | |||
19 | static inline int arch_timer_sched_clock_init(void) | ||
20 | { | ||
21 | return -ENXIO; | ||
22 | } | ||
17 | #endif | 23 | #endif |
18 | 24 | ||
19 | #endif | 25 | #endif |
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c index bb9a8b45bffa..dd907048f571 100644 --- a/arch/arm/kernel/arch_timer.c +++ b/arch/arm/kernel/arch_timer.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <asm/localtimer.h> | 23 | #include <asm/localtimer.h> |
24 | #include <asm/arch_timer.h> | 24 | #include <asm/arch_timer.h> |
25 | #include <asm/system_info.h> | 25 | #include <asm/system_info.h> |
26 | #include <asm/sched_clock.h> | ||
26 | 27 | ||
27 | static unsigned long arch_timer_rate; | 28 | static unsigned long arch_timer_rate; |
28 | static int arch_timer_ppi; | 29 | static int arch_timer_ppi; |
@@ -204,6 +205,18 @@ static inline cycle_t arch_counter_get_cntvct(void) | |||
204 | return ((cycle_t) cvalh << 32) | cvall; | 205 | return ((cycle_t) cvalh << 32) | cvall; |
205 | } | 206 | } |
206 | 207 | ||
208 | static u32 notrace arch_counter_get_cntvct32(void) | ||
209 | { | ||
210 | cycle_t cntvct = arch_counter_get_cntvct(); | ||
211 | |||
212 | /* | ||
213 | * The sched_clock infrastructure only knows about counters | ||
214 | * with at most 32bits. Forget about the upper 24 bits for the | ||
215 | * time being... | ||
216 | */ | ||
217 | return (u32)(cntvct & (u32)~0); | ||
218 | } | ||
219 | |||
207 | static cycle_t arch_counter_read(struct clocksource *cs) | 220 | static cycle_t arch_counter_read(struct clocksource *cs) |
208 | { | 221 | { |
209 | return arch_counter_get_cntpct(); | 222 | return arch_counter_get_cntpct(); |
@@ -286,3 +299,15 @@ out_free: | |||
286 | 299 | ||
287 | return err; | 300 | return err; |
288 | } | 301 | } |
302 | |||
303 | int __init arch_timer_sched_clock_init(void) | ||
304 | { | ||
305 | int err; | ||
306 | |||
307 | err = arch_timer_available(); | ||
308 | if (err) | ||
309 | return err; | ||
310 | |||
311 | setup_sched_clock(arch_counter_get_cntvct32, 32, arch_timer_rate); | ||
312 | return 0; | ||
313 | } | ||