linux-mips
[Top] [All Lists]

[PATCH -v4 2/9] MIPS: add mips_timecounter_read() to get high precision

To: linux-kernel@vger.kernel.org, linux-mips@linux-mips.org
Subject: [PATCH -v4 2/9] MIPS: add mips_timecounter_read() to get high precision timestamp
From: Wu Zhangjin <wuzhangjin@gmail.com>
Date: Wed, 21 Oct 2009 22:34:56 +0800
Cc: Wu Zhangjin <wuzhangjin@gmail.com>, Thomas Gleixner <tglx@linutronix.de>, Ralf Baechle <ralf@linux-mips.org>, Nicholas Mc Guire <der.herr@hofr.at>, Steven Rostedt <rostedt@goodmis.org>
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references:in-reply-to:references; bh=xHNoUVL7jtuVw5VH1oK05eQwhoXWhhpyxOfnqPDCLL4=; b=kOtXcOsnQvM0jD6Q75Ty3G47yS6jTuPXQrOChqDV4ZgwyCdeGM6ojOeBScXCtc0TYQ OvtaAtj7arJknxWEVxBtqxwfwUV9NcLEq0L5cGCQM5syKvN5vF+/Qb70s6eIh1KhOPkV dAGzaFYxjHSvbji+PaKGiFzG7Er07Z2lMf2qk=
Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=DHzV1z8BckRGw0AGQ0Godq8BgXFW2cnYMe9neI+RiooiJ+ZnxMvC5Ckz/15Ty9/gsj ntna6EsFz0DAkBPC0v9zY7nCRQ3EQTHEAOfQdpNPR5UsMnTDD6D2nySkFAVPxn4XxrqR aQtIYXJlDTMgXu9cZ2rKNk75FSdahmO3hups0=
In-reply-to: <028867b99ec532b84963a35e7d552becc783cafc.1256135456.git.wuzhangjin@gmail.com>
In-reply-to: <cover.1256135456.git.wuzhangjin@gmail.com>
Original-recipient: rfc822;linux-mips@linux-mips.org
References: <028867b99ec532b84963a35e7d552becc783cafc.1256135456.git.wuzhangjin@gmail.com>
References: <cover.1256135456.git.wuzhangjin@gmail.com>
Sender: linux-mips-bounce@linux-mips.org
This patch implement a mips_timecounter_read(), which can be used to get
high precision timestamp without extra lock.

It is based on the clock counter register and the
timecounter/cyclecounter abstraction layer of kernel.

Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
---
 arch/mips/include/asm/time.h |   19 +++++++++++++++++++
 arch/mips/kernel/csrc-r4k.c  |   41 +++++++++++++++++++++++++++++++++++++++++
 arch/mips/kernel/time.c      |    2 ++
 3 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h
index df6a430..b8af7fa 100644
--- a/arch/mips/include/asm/time.h
+++ b/arch/mips/include/asm/time.h
@@ -73,8 +73,18 @@ static inline int mips_clockevent_init(void)
  */
 #ifdef CONFIG_CSRC_R4K_LIB
 extern int init_r4k_clocksource(void);
+extern int init_r4k_timecounter(void);
+extern u64 r4k_timecounter_read(void);
 #endif
 
+static inline u64 mips_timecounter_read(void)
+{
+#ifdef CONFIG_CSRC_R4K
+       return r4k_timecounter_read();
+#else
+       return sched_clock();
+#endif
+}
 static inline int init_mips_clocksource(void)
 {
 #ifdef CONFIG_CSRC_R4K
@@ -84,6 +94,15 @@ static inline int init_mips_clocksource(void)
 #endif
 }
 
+static inline int init_mips_timecounter(void)
+{
+#ifdef CONFIG_CSRC_R4K
+       return init_r4k_timecounter();
+#else
+       return 0;
+#endif
+}
+
 extern void clocksource_set_clock(struct clocksource *cs, unsigned int clock);
 extern void clockevent_set_clock(struct clock_event_device *cd,
                unsigned int clock);
diff --git a/arch/mips/kernel/csrc-r4k.c b/arch/mips/kernel/csrc-r4k.c
index e95a3cd..4e7705f 100644
--- a/arch/mips/kernel/csrc-r4k.c
+++ b/arch/mips/kernel/csrc-r4k.c
@@ -7,6 +7,7 @@
  */
 #include <linux/clocksource.h>
 #include <linux/init.h>
+#include <linux/sched.h>
 
 #include <asm/time.h>
 
@@ -36,3 +37,43 @@ int __init init_r4k_clocksource(void)
 
        return 0;
 }
+
+static struct timecounter r4k_tc = {
+       .cc = NULL,
+};
+
+static cycle_t r4k_cc_read(const struct cyclecounter *cc)
+{
+       return read_c0_count();
+}
+
+static struct cyclecounter r4k_cc = {
+       .read = r4k_cc_read,
+       .mask = CLOCKSOURCE_MASK(32),
+       .shift = 32,
+};
+
+int __init init_r4k_timecounter(void)
+{
+       if (!cpu_has_counter || !mips_hpt_frequency)
+               return -ENXIO;
+
+       r4k_cc.mult = div_sc((unsigned long)mips_hpt_frequency, NSEC_PER_SEC,
+                       32);
+
+       timecounter_init(&r4k_tc, &r4k_cc, sched_clock());
+
+       return 0;
+}
+
+u64 r4k_timecounter_read(void)
+{
+       u64 clock;
+
+       if (r4k_tc.cc != NULL)
+               clock = timecounter_read(&r4k_tc);
+       else
+               clock = sched_clock();
+
+       return clock;
+}
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 1f467d5..e38cca1 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -156,4 +156,6 @@ void __init time_init(void)
 
        if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())
                init_mips_clocksource();
+       if (!cpu_has_mfc0_count_bug())
+               init_mips_timecounter();
 }
-- 
1.6.2.1


<Prev in Thread] Current Thread [Next in Thread>