From 60dbd6633178a8625ed71329da0167c6d50c559c Mon Sep 17 00:00:00 2001 From: Jesper Nilsson Date: Fri, 30 Jul 2010 17:33:07 +0200 Subject: CRIS: GENERIC_TIME fixes GENERIC_TIME was not functional for CRIS, giving random backward time jumps. For CRISv32 implement a new clocksource using the free running counter and ditch the arch_gettimeoffset. The random time jumps still existed, but turned out to be the write_seqlock which was missing around our do_timer() call. So switch over to GENERIC_TIME using the clocksource for CRISv32. CRISv10 doesn't have the free running counter needed for the clocksource trick, but we can still use GENERIC_TIME with arch_gettimeoffset. Unfortunately, there were problems in using the prescaler register to timer0 for the gettimeoffset calculation, so it is now ignored, making our resolution worse by the tune of 40usec (0.4%) worst case. At the same time, clean up some formatting and use NSEC_PER_SEC instead of 1000000000. Signed-off-by: Jesper Nilsson --- arch/cris/arch-v10/kernel/time.c | 54 ++-------------------------------------- 1 file changed, 2 insertions(+), 52 deletions(-) (limited to 'arch/cris/arch-v10') diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c index 30adae5..00eb36f 100644 --- a/arch/cris/arch-v10/kernel/time.c +++ b/arch/cris/arch-v10/kernel/time.c @@ -61,66 +61,16 @@ unsigned long get_ns_in_jiffie(void) unsigned long do_slow_gettimeoffset(void) { - unsigned long count, t1; - unsigned long usec_count = 0; - unsigned short presc_count; - - static unsigned long count_p = TIMER0_DIV;/* for the first call after boot */ - static unsigned long jiffies_p = 0; - - /* - * cache volatile jiffies temporarily; we have IRQs turned off. - */ - unsigned long jiffies_t; + unsigned long count; /* The timer interrupt comes from Etrax timer 0. In order to get * better precision, we check the current value. It might have * underflowed already though. */ - -#ifndef CONFIG_SVINTO_SIM - /* Not available in the xsim simulator. */ count = *R_TIMER0_DATA; - presc_count = *R_TIM_PRESC_STATUS; - /* presc_count might be wrapped */ - t1 = *R_TIMER0_DATA; - if (count != t1){ - /* it wrapped, read prescaler again... */ - presc_count = *R_TIM_PRESC_STATUS; - count = t1; - } -#else - count = 0; - presc_count = 0; -#endif - - jiffies_t = jiffies; - /* - * avoiding timer inconsistencies (they are rare, but they happen)... - * there are one problem that must be avoided here: - * 1. the timer counter underflows - */ - if( jiffies_t == jiffies_p ) { - if( count > count_p ) { - /* Timer wrapped, use new count and prescale - * increase the time corresponding to one jiffie - */ - usec_count = 1000000/HZ; - } - } else - jiffies_p = jiffies_t; - count_p = count; - if (presc_count >= PRESCALE_VALUE/2 ){ - presc_count = PRESCALE_VALUE - presc_count + PRESCALE_VALUE/2; - } else { - presc_count = PRESCALE_VALUE - presc_count - PRESCALE_VALUE/2; - } /* Convert timer value to usec */ - usec_count += ( (TIMER0_DIV - count) * (1000000/HZ)/TIMER0_DIV ) + - (( (presc_count) * (1000000000/PRESCALE_FREQ))/1000); - - return usec_count; + return (TIMER0_DIV - count) * ((NSEC_PER_SEC/1000)/HZ)/TIMER0_DIV; } /* Excerpt from the Etrax100 HSDD about the built-in watchdog: -- cgit v1.1