Revert "clocksource: arch_timer: use virtual counters"
author黄涛 <huangtao@rock-chips.com>
Fri, 28 Mar 2014 09:56:56 +0000 (17:56 +0800)
committer黄涛 <huangtao@rock-chips.com>
Fri, 28 Mar 2014 10:04:43 +0000 (18:04 +0800)
This reverts commit 714c21cb90951905b269870087a99c37f3a7af0c.

arch/arm/include/asm/arch_timer.h
arch/arm64/include/asm/arch_timer.h
drivers/clocksource/arm_arch_timer.c
include/clocksource/arm_arch_timer.h

index f693038b88817ed10169c145c96611b4896fbbf6..4928cdacedf0169324f2aa6bd36cc2bfef869cf0 100644 (file)
@@ -80,6 +80,15 @@ static inline u32 arch_timer_get_cntfrq(void)
        return val;
 }
 
+static inline u64 arch_counter_get_cntpct(void)
+{
+       u64 cval;
+
+       isb();
+       asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
+       return cval;
+}
+
 static inline u64 arch_counter_get_cntvct(void)
 {
        u64 cval;
index d56ed11ba9a387be20f835d5f7675f9e95eb4574..bf6ab242f04725e56e8cf93d3ab6e930668651f0 100644 (file)
@@ -110,6 +110,16 @@ static inline void __cpuinit arch_counter_set_user_access(void)
        asm volatile("msr       cntkctl_el1, %0" : : "r" (cntkctl));
 }
 
+static inline u64 arch_counter_get_cntpct(void)
+{
+       u64 cval;
+
+       isb();
+       asm volatile("mrs %0, cntpct_el0" : "=r" (cval));
+
+       return cval;
+}
+
 static inline u64 arch_counter_get_cntvct(void)
 {
        u64 cval;
index 053d846ab5b108931ccbeacb67ebc7c85696d0f6..a2b25418978244d1ae129cf74f031020951f35d4 100644 (file)
@@ -186,19 +186,27 @@ u32 arch_timer_get_rate(void)
        return arch_timer_rate;
 }
 
-u64 arch_timer_read_counter(void)
+/*
+ * Some external users of arch_timer_read_counter (e.g. sched_clock) may try to
+ * call it before it has been initialised. Rather than incur a performance
+ * penalty checking for initialisation, provide a default implementation that
+ * won't lead to time appearing to jump backwards.
+ */
+static u64 arch_timer_read_zero(void)
 {
-       return arch_counter_get_cntvct();
+       return 0;
 }
 
+u64 (*arch_timer_read_counter)(void) = arch_timer_read_zero;
+
 static cycle_t arch_counter_read(struct clocksource *cs)
 {
-       return arch_counter_get_cntvct();
+       return arch_timer_read_counter();
 }
 
 static cycle_t arch_counter_read_cc(const struct cyclecounter *cc)
 {
-       return arch_counter_get_cntvct();
+       return arch_timer_read_counter();
 }
 
 static struct clocksource clocksource_counter = {
@@ -279,7 +287,7 @@ static int __init arch_timer_register(void)
        cyclecounter.mult = clocksource_counter.mult;
        cyclecounter.shift = clocksource_counter.shift;
        timecounter_init(&timecounter, &cyclecounter,
-                        arch_counter_get_cntvct());
+                        arch_counter_get_cntpct());
 
        if (arch_timer_use_virtual) {
                ppi = arch_timer_ppi[VIRT_PPI];
@@ -368,6 +376,11 @@ static void __init arch_timer_init(struct device_node *np)
                }
        }
 
+       if (arch_timer_use_virtual)
+               arch_timer_read_counter = arch_counter_get_cntvct;
+       else
+               arch_timer_read_counter = arch_counter_get_cntpct;
+
        arch_timer_register();
        arch_timer_arch_init();
 }
index c463ce990c48b9a6f5742a45ac741b91371aae4f..e6c9c4cc9b23415fad39dfd142a6ce3bd44f4b7c 100644 (file)
@@ -32,7 +32,7 @@
 #ifdef CONFIG_ARM_ARCH_TIMER
 
 extern u32 arch_timer_get_rate(void);
-extern u64 arch_timer_read_counter(void);
+extern u64 (*arch_timer_read_counter)(void);
 extern struct timecounter *arch_timer_get_timecounter(void);
 
 #else