diff options
author | Marc Zyngier <Marc.Zyngier@arm.com> | 2012-09-07 18:09:58 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-09-15 21:53:33 +0100 |
commit | a1b2dde70419ae947fd7c9c8fcad7da005dc600e (patch) | |
tree | cf8651233dbb03cd3ce4ad891f4c40aabf2fe8a1 /arch/arm/kernel/arch_timer.c | |
parent | f48b5f12799dbabba4a9c799a9bef0775b2f977d (diff) | |
download | blackbird-op-linux-a1b2dde70419ae947fd7c9c8fcad7da005dc600e.tar.gz blackbird-op-linux-a1b2dde70419ae947fd7c9c8fcad7da005dc600e.zip |
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.c | 25 |
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) return 0; } +static cycle_t arch_counter_read_cc(const struct cyclecounter *cc) +{ + /* + * Always use the physical counter for the clocksource. + * CNTHCTL.PL1PCTEN must be set to 1. + */ + return arch_counter_get_cntpct(); +} + static struct clocksource clocksource_counter = { .name = "arch_sys_counter", .rating = 400, @@ -341,6 +350,18 @@ static struct clocksource clocksource_counter = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +static struct cyclecounter cyclecounter = { + .read = arch_counter_read_cc, + .mask = CLOCKSOURCE_MASK(56), +}; + +static struct timecounter timecounter; + +struct timecounter *arch_timer_get_timecounter(void) +{ + return &timecounter; +} + static void __cpuinit arch_timer_stop(struct clock_event_device *clk) { pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n", @@ -380,6 +401,10 @@ static int __init arch_timer_register(void) } clocksource_register_hz(&clocksource_counter, arch_timer_rate); + cyclecounter.mult = clocksource_counter.mult; + cyclecounter.shift = clocksource_counter.shift; + timecounter_init(&timecounter, &cyclecounter, + arch_counter_get_cntpct()); if (arch_timer_use_virtual) { ppi = arch_timer_ppi[VIRT_PPI]; |