Message ID | 20090428081754.16592.85760.sendpatchset@rx1.opensource.se (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
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
--- 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;