diff mbox

clocksource: improve sh_cmt clocksource overflow handling

Message ID 20090428081754.16592.85760.sendpatchset@rx1.opensource.se (mailing list archive)
State Accepted
Headers show

Commit Message

Magnus Damm April 28, 2009, 8:17 a.m. UTC
From: Magnus Damm <damm@igel.co.jp>

This patch improves the sh_cmt clocksource handling.

Currently the counter value is ignored in the case of
overflow. With this patch the overflow flag is read
before and after reading the counter, removing any
counter value and overflow flag mismatch issues.

Signed-off-by: Magnus Damm <damm@igel.co.jp>
---

 drivers/clocksource/sh_cmt.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Paul Mundt April 28, 2009, 9:14 a.m. UTC | #1
On Tue, Apr 28, 2009 at 05:17:54PM +0900, Magnus Damm wrote:
> This patch improves the sh_cmt clocksource handling.
> 
> Currently the counter value is ignored in the case of
> overflow. With this patch the overflow flag is read
> before and after reading the counter, removing any
> counter value and overflow flag mismatch issues.

On Tue, Apr 28, 2009 at 05:19:50PM +0900, Magnus Damm wrote:
> This patch moves the SuperH timer setup code from time_init()
> to late_time_init(). Good things about this change:
>  - interrupts: they are enabled at late_time_init()
>  - mm: regular kmalloc() can be used at late_time_init()
> 
> Together with moving to late_time_init() this patch changes
> the sh_cmt driver to always allocate with kmalloc(). This
> simplifies the code a bit and also fixes section mismatches.

Applied to the sh-2.6.31 queue.
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

--- 0001/drivers/clocksource/sh_cmt.c
+++ work/drivers/clocksource/sh_cmt.c	2009-04-28 16:03:20.000000000 +0900
@@ -111,16 +111,21 @@  static unsigned long sh_cmt_get_counter(
 					int *has_wrapped)
 {
 	unsigned long v1, v2, v3;
+	int o1, o2;
+
+	o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit;
 
 	/* Make sure the timer value is stable. Stolen from acpi_pm.c */
 	do {
+		o2 = o1;
 		v1 = sh_cmt_read(p, CMCNT);
 		v2 = sh_cmt_read(p, CMCNT);
 		v3 = sh_cmt_read(p, CMCNT);
-	} while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
-			  || (v3 > v1 && v3 < v2)));
+		o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit;
+	} while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
+			  || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));
 
-	*has_wrapped = sh_cmt_read(p, CMCSR) & p->overflow_bit;
+	*has_wrapped = o1;
 	return v2;
 }
 
@@ -394,7 +399,7 @@  static cycle_t sh_cmt_clocksource_read(s
 	raw = sh_cmt_get_counter(p, &has_wrapped);
 
 	if (unlikely(has_wrapped))
-		raw = p->match_value;
+		raw += p->match_value;
 	spin_unlock_irqrestore(&p->lock, flags);
 
 	return value + raw;