From fc4c47b3b5b8fe2b5d2940b9bd6203609b571b50 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Sat, 1 Dec 2018 11:53:10 +1100 Subject: m68k: mvme147: Convert to clocksource API Add a platform clocksource by adapting the existing arch_gettimeoffset implementation. Signed-off-by: Finn Thain Acked-by: Linus Walleij Signed-off-by: Geert Uytterhoeven --- arch/m68k/include/asm/mvme147hw.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/m68k/include/asm') diff --git a/arch/m68k/include/asm/mvme147hw.h b/arch/m68k/include/asm/mvme147hw.h index 9c7ff67c5ffd..7c3dd513128e 100644 --- a/arch/m68k/include/asm/mvme147hw.h +++ b/arch/m68k/include/asm/mvme147hw.h @@ -66,7 +66,6 @@ struct pcc_regs { #define PCC_INT_ENAB 0x08 #define PCC_TIMER_INT_CLR 0x80 -#define PCC_TIMER_PRELOAD 63936l #define PCC_LEVEL_ABORT 0x07 #define PCC_LEVEL_SERIAL 0x04 -- cgit v1.2.3 From 7529b90d051e4629884771ba2b1d3a87d2c6a9d7 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Sat, 1 Dec 2018 11:53:10 +1100 Subject: m68k: mvme147: Handle timer counter overflow Reading the timer counter races with timer overflow (and the corresponding interrupt). This is resolved by reading the overflow register and taking this value into account. The interrupt handler must clear the overflow register when it eventually executes. Suggested-by: Thomas Gleixner Signed-off-by: Finn Thain Signed-off-by: Geert Uytterhoeven --- arch/m68k/include/asm/mvme147hw.h | 1 + arch/m68k/mvme147/config.c | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'arch/m68k/include/asm') 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; -- cgit v1.2.3