diff --git a/arch/m68k/include/asm/mvme147hw.h b/arch/m68k/include/asm/mvme147hw.h index 7c3dd513128e..257b29184af9 100644 --- a/arch/m68k/include/asm/mvme147hw.h +++ b/arch/m68k/include/asm/mvme147hw.h @@ -66,6 +66,7 @@ struct pcc_regs { #define PCC_INT_ENAB 0x08 #define PCC_TIMER_INT_CLR 0x80 +#define PCC_TIMER_CLR_OVF 0x04 #define PCC_LEVEL_ABORT 0x07 #define PCC_LEVEL_SERIAL 0x04 diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c index c44a254e8a8c..545a1fe0e119 100644 --- a/arch/m68k/mvme147/config.c +++ b/arch/m68k/mvme147/config.c @@ -118,7 +118,7 @@ static irqreturn_t mvme147_timer_int (int irq, void *dev_id) local_irq_save(flags); m147_pcc->t1_int_cntrl = PCC_TIMER_INT_CLR; - m147_pcc->t1_int_cntrl = PCC_INT_ENAB|PCC_LEVEL_TIMER1; + m147_pcc->t1_cntrl = PCC_TIMER_CLR_OVF; clk_total += PCC_TIMER_CYCLES; timer_routine(0, NULL); local_irq_restore(flags); @@ -144,21 +144,22 @@ void mvme147_sched_init (irq_handler_t timer_routine) clocksource_register_hz(&mvme147_clk, PCC_TIMER_CLOCK_FREQ); } -/* XXX There are race hazards in this code XXX */ static u64 mvme147_read_clk(struct clocksource *cs) { unsigned long flags; - volatile unsigned short *cp = (volatile unsigned short *)0xfffe1012; - unsigned short n; + u8 overflow, tmp; + u16 count; u32 ticks; local_irq_save(flags); - n = *cp; - while (n != *cp) - n = *cp; - - n -= PCC_TIMER_PRELOAD; - ticks = clk_total + n; + tmp = m147_pcc->t1_cntrl >> 4; + count = m147_pcc->t1_count; + overflow = m147_pcc->t1_cntrl >> 4; + if (overflow != tmp) + count = m147_pcc->t1_count; + count -= PCC_TIMER_PRELOAD; + ticks = count + overflow * PCC_TIMER_CYCLES; + ticks += clk_total; local_irq_restore(flags); return ticks;