aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k
diff options
context:
space:
mode:
authorGreg Ungerer <gerg@uclinux.org>2011-11-16 00:09:02 -0500
committerGreg Ungerer <gerg@uclinux.org>2011-12-24 06:47:58 -0500
commit1f2aab01ba2f6c591dee93daf4b57fd9785f3b41 (patch)
tree78f44c9a87f8664fcdf1569be87a89efe0bfe9ea /arch/m68k
parentec84118795fa687192de04e0dcb63178e4bf63e5 (diff)
m68knommu: fix broken ColdFire slice timer read_clk() code
There is a race on reading the ColdFire slice timer current count and the total clock count so far. Interrupts are off, and we may have just missed getting a new timer wrap event interrupt. Check for this and adjust the cycle count and current read count accordingly. Also the slice timer counts down from the terminal count. So in read_clk() we need take the current clock count away from the terminal count. Reported-by: Alexander Stein <alexander.stein@systec-electronic.com> Signed-off-by: Greg Ungerer <gerg@uclinux.org>
Diffstat (limited to 'arch/m68k')
-rw-r--r--arch/m68k/platform/coldfire/sltimers.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/arch/m68k/platform/coldfire/sltimers.c b/arch/m68k/platform/coldfire/sltimers.c
index b7f822b552bb..54e1452f853a 100644
--- a/arch/m68k/platform/coldfire/sltimers.c
+++ b/arch/m68k/platform/coldfire/sltimers.c
@@ -98,16 +98,19 @@ static struct irqaction mcfslt_timer_irq = {
98static cycle_t mcfslt_read_clk(struct clocksource *cs) 98static cycle_t mcfslt_read_clk(struct clocksource *cs)
99{ 99{
100 unsigned long flags; 100 unsigned long flags;
101 u32 cycles; 101 u32 cycles, scnt;
102 u16 scnt;
103 102
104 local_irq_save(flags); 103 local_irq_save(flags);
105 scnt = __raw_readl(TA(MCFSLT_SCNT)); 104 scnt = __raw_readl(TA(MCFSLT_SCNT));
106 cycles = mcfslt_cnt; 105 cycles = mcfslt_cnt;
106 if (__raw_readl(TA(MCFSLT_SSR)) & MCFSLT_SSR_TE) {
107 cycles += mcfslt_cycles_per_jiffy;
108 scnt = __raw_readl(TA(MCFSLT_SCNT));
109 }
107 local_irq_restore(flags); 110 local_irq_restore(flags);
108 111
109 /* subtract because slice timers count down */ 112 /* subtract because slice timers count down */
110 return cycles - scnt; 113 return cycles + ((mcfslt_cycles_per_jiffy - 1) - scnt);
111} 114}
112 115
113static struct clocksource mcfslt_clk = { 116static struct clocksource mcfslt_clk = {