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.
Change-Id: Ica870d279dba38304581763654c683cd09f87153
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
[sambley@codeaurora.org Fix conflicts due to patched code not
against latest version of arch_timer.c]
Signed-off-by: Sathish Ambley <sambley@codeaurora.org>
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
index e8493dc..5b76911 100644
--- a/arch/arm/kernel/arch_timer.c
+++ b/arch/arm/kernel/arch_timer.c
@@ -25,6 +25,7 @@
static unsigned long arch_timer_rate;
static int arch_timer_ppi;
static int arch_timer_ppi2;
+static DEFINE_CLOCK_DATA(cd);
static struct clock_event_device __percpu *arch_timer_evt;
@@ -225,6 +226,30 @@
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
+static u32 arch_counter_get_cntvct32(void)
+{
+ cycle_t cntvct;
+
+ cntvct = arch_counter_get_cntvct();
+
+ /*
+ * The sched_clock infrastructure only knows about counters
+ * with at most 32bits. Forget about the upper 24 bits for the
+ * time being...
+ */
+ return (u32)(cntvct & (u32)~0);
+}
+
+DEFINE_SCHED_CLOCK_FUNC(arch_timer_sched_clock)
+{
+ return cyc_to_sched_clock(&cd, arch_counter_get_cntvct32(), (u32)~0);
+}
+
+static void notrace arch_timer_update_sched_clock(void)
+{
+ update_sched_clock(&cd, arch_counter_get_cntvct32(), (u32)~0);
+}
+
static void __cpuinit arch_timer_teardown(void *data)
{
struct clock_event_device *clk = data;
@@ -282,6 +307,9 @@
clocksource_register_hz(&clocksource_counter, arch_timer_rate);
+ init_arch_sched_clock(&cd, arch_timer_update_sched_clock,
+ arch_timer_sched_clock, 32, arch_timer_rate);
+
/* Immediately configure the timer on the boot CPU */
arch_timer_setup(per_cpu_ptr(arch_timer_evt, smp_processor_id()));