diff options
author | Jesper Nilsson <jesper.nilsson@axis.com> | 2010-07-30 11:33:07 -0400 |
---|---|---|
committer | Jesper Nilsson <jesper.nilsson@axis.com> | 2010-08-04 06:58:55 -0400 |
commit | 60dbd6633178a8625ed71329da0167c6d50c559c (patch) | |
tree | bcbc1004dfe356ce7cf30f183725dbbc9dad3e4f /arch/cris/arch-v10 | |
parent | 26bfeea38a4a5daf52c8f01c986ca8680bf1f6a1 (diff) |
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 <jesper.nilsson@axis.com>
Diffstat (limited to 'arch/cris/arch-v10')
-rw-r--r-- | arch/cris/arch-v10/kernel/time.c | 54 |
1 files changed, 2 insertions, 52 deletions
diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c index 30adae594aef..00eb36f8debf 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) | |||
61 | 61 | ||
62 | unsigned long do_slow_gettimeoffset(void) | 62 | unsigned long do_slow_gettimeoffset(void) |
63 | { | 63 | { |
64 | unsigned long count, t1; | 64 | unsigned long count; |
65 | unsigned long usec_count = 0; | ||
66 | unsigned short presc_count; | ||
67 | |||
68 | static unsigned long count_p = TIMER0_DIV;/* for the first call after boot */ | ||
69 | static unsigned long jiffies_p = 0; | ||
70 | |||
71 | /* | ||
72 | * cache volatile jiffies temporarily; we have IRQs turned off. | ||
73 | */ | ||
74 | unsigned long jiffies_t; | ||
75 | 65 | ||
76 | /* The timer interrupt comes from Etrax timer 0. In order to get | 66 | /* The timer interrupt comes from Etrax timer 0. In order to get |
77 | * better precision, we check the current value. It might have | 67 | * better precision, we check the current value. It might have |
78 | * underflowed already though. | 68 | * underflowed already though. |
79 | */ | 69 | */ |
80 | |||
81 | #ifndef CONFIG_SVINTO_SIM | ||
82 | /* Not available in the xsim simulator. */ | ||
83 | count = *R_TIMER0_DATA; | 70 | count = *R_TIMER0_DATA; |
84 | presc_count = *R_TIM_PRESC_STATUS; | ||
85 | /* presc_count might be wrapped */ | ||
86 | t1 = *R_TIMER0_DATA; | ||
87 | if (count != t1){ | ||
88 | /* it wrapped, read prescaler again... */ | ||
89 | presc_count = *R_TIM_PRESC_STATUS; | ||
90 | count = t1; | ||
91 | } | ||
92 | #else | ||
93 | count = 0; | ||
94 | presc_count = 0; | ||
95 | #endif | ||
96 | |||
97 | jiffies_t = jiffies; | ||
98 | 71 | ||
99 | /* | ||
100 | * avoiding timer inconsistencies (they are rare, but they happen)... | ||
101 | * there are one problem that must be avoided here: | ||
102 | * 1. the timer counter underflows | ||
103 | */ | ||
104 | if( jiffies_t == jiffies_p ) { | ||
105 | if( count > count_p ) { | ||
106 | /* Timer wrapped, use new count and prescale | ||
107 | * increase the time corresponding to one jiffie | ||
108 | */ | ||
109 | usec_count = 1000000/HZ; | ||
110 | } | ||
111 | } else | ||
112 | jiffies_p = jiffies_t; | ||
113 | count_p = count; | ||
114 | if (presc_count >= PRESCALE_VALUE/2 ){ | ||
115 | presc_count = PRESCALE_VALUE - presc_count + PRESCALE_VALUE/2; | ||
116 | } else { | ||
117 | presc_count = PRESCALE_VALUE - presc_count - PRESCALE_VALUE/2; | ||
118 | } | ||
119 | /* Convert timer value to usec */ | 72 | /* Convert timer value to usec */ |
120 | usec_count += ( (TIMER0_DIV - count) * (1000000/HZ)/TIMER0_DIV ) + | 73 | return (TIMER0_DIV - count) * ((NSEC_PER_SEC/1000)/HZ)/TIMER0_DIV; |
121 | (( (presc_count) * (1000000000/PRESCALE_FREQ))/1000); | ||
122 | |||
123 | return usec_count; | ||
124 | } | 74 | } |
125 | 75 | ||
126 | /* Excerpt from the Etrax100 HSDD about the built-in watchdog: | 76 | /* Excerpt from the Etrax100 HSDD about the built-in watchdog: |