aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/arch_timer.c
diff options
context:
space:
mode:
authorMarc Zyngier <Marc.Zyngier@arm.com>2012-09-07 13:09:58 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-09-15 16:53:33 -0400
commita1b2dde70419ae947fd7c9c8fcad7da005dc600e (patch)
treecf8651233dbb03cd3ce4ad891f4c40aabf2fe8a1 /arch/arm/kernel/arch_timer.c
parentf48b5f12799dbabba4a9c799a9bef0775b2f977d (diff)
ARM: 7522/1: arch_timers: register a time/cycle counter
Some subsystems (KVM for example) need access to a cycle counter. In the KVM case, this is used to measure the time delta between host and guest in order to accurately generate timer events for the guest. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/arch_timer.c')
-rw-r--r--arch/arm/kernel/arch_timer.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
index c4e20b69197a..c04c2a6da470 100644
--- a/arch/arm/kernel/arch_timer.c
+++ b/arch/arm/kernel/arch_timer.c
@@ -333,6 +333,15 @@ int read_current_timer(unsigned long *timer_val)
333 return 0; 333 return 0;
334} 334}
335 335
336static cycle_t arch_counter_read_cc(const struct cyclecounter *cc)
337{
338 /*
339 * Always use the physical counter for the clocksource.
340 * CNTHCTL.PL1PCTEN must be set to 1.
341 */
342 return arch_counter_get_cntpct();
343}
344
336static struct clocksource clocksource_counter = { 345static struct clocksource clocksource_counter = {
337 .name = "arch_sys_counter", 346 .name = "arch_sys_counter",
338 .rating = 400, 347 .rating = 400,
@@ -341,6 +350,18 @@ static struct clocksource clocksource_counter = {
341 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 350 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
342}; 351};
343 352
353static struct cyclecounter cyclecounter = {
354 .read = arch_counter_read_cc,
355 .mask = CLOCKSOURCE_MASK(56),
356};
357
358static struct timecounter timecounter;
359
360struct timecounter *arch_timer_get_timecounter(void)
361{
362 return &timecounter;
363}
364
344static void __cpuinit arch_timer_stop(struct clock_event_device *clk) 365static void __cpuinit arch_timer_stop(struct clock_event_device *clk)
345{ 366{
346 pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n", 367 pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n",
@@ -380,6 +401,10 @@ static int __init arch_timer_register(void)
380 } 401 }
381 402
382 clocksource_register_hz(&clocksource_counter, arch_timer_rate); 403 clocksource_register_hz(&clocksource_counter, arch_timer_rate);
404 cyclecounter.mult = clocksource_counter.mult;
405 cyclecounter.shift = clocksource_counter.shift;
406 timecounter_init(&timecounter, &cyclecounter,
407 arch_counter_get_cntpct());
383 408
384 if (arch_timer_use_virtual) { 409 if (arch_timer_use_virtual) {
385 ppi = arch_timer_ppi[VIRT_PPI]; 410 ppi = arch_timer_ppi[VIRT_PPI];