[ltt-dev] [patch 9/9] OMAP trace clock basic PM fix

Mathieu Desnoyers compudj at krystal.dyndns.org
Wed Feb 18 22:31:30 EST 2009


(With a proper header)

This patch sets the whole trace clock when resynchronising with the 32k timer.
Just setting the cycle counter is not enough, because we would lose bits for
long sleeps.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at polymtl.ca>
---
 arch/arm/mach-omap2/trace-clock.c |   18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

Index: linux-omap-2.6/arch/arm/mach-omap2/trace-clock.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/trace-clock.c	2009-02-18 21:17:24.000000000 +0000
+++ linux-omap-2.6/arch/arm/mach-omap2/trace-clock.c	2009-02-18 21:18:04.000000000 +0000
@@ -16,6 +16,10 @@
 /* Need direct access to the clock from kernel/time/timekeeping.c */
 extern struct clocksource *clock;
 
+/* 32KHz counter count save upon PM sleep */
+static u32 saved_32k_count;
+static u64 saved_trace_clock;
+
 static void clear_ccnt_ms(unsigned long data);
 
 static DEFINE_TIMER(clear_ccnt_ms_timer, clear_ccnt_ms, 0, 0);
@@ -139,13 +143,21 @@
 	/*
 	 * Set the timer's value MSBs to the same as current 32K timer.
 	 */
+	ref_time = saved_trace_clock;
 	local_irq_save(flags);
 	count_32k = clocksource_read(clock);
-	ref_time = (u64)count_32k * (cpu_hz >> TIMER_32K_SHIFT);
+	/*
+	 * Delta done on 32-bits, then casted to u64. Must guarantee
+	 * that we are called often enough so the difference does not
+	 * overflow 32 bits anyway.
+	 */
+	ref_time += (u64)(count_32k - saved_32k_count)
+			* (cpu_hz >> TIMER_32K_SHIFT);
 	write_ctens(read_ctens() & ~(1 << 31));	/* disable counter */
-	write_ccnt((u32)ref_time);
+	write_ccnt((u32)ref_time & ~(1 << 31));
 	write_ctens(read_ctens() |  (1 << 31));	/* enable counter */
 	count_trace_clock = trace_clock_read32();
+	_trace_clock_write_synthetic_tsc(ref_time);
 	local_irq_restore(flags);
 
 	get_synthetic_tsc();
@@ -160,6 +172,8 @@
 
 void _stop_trace_clock(void)
 {
+	saved_32k_count = clocksource_read(clock);
+	saved_trace_clock = trace_clock_read64();
 	del_timer_sync(&clear_ccnt_ms_timer);
 	put_synthetic_tsc();
 }

-- 
Mathieu Desnoyers
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68




More information about the lttng-dev mailing list