aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/arch-v10
diff options
context:
space:
mode:
authorJesper Nilsson <jesper.nilsson@axis.com>2010-07-30 11:33:07 -0400
committerJesper Nilsson <jesper.nilsson@axis.com>2010-08-04 06:58:55 -0400
commit60dbd6633178a8625ed71329da0167c6d50c559c (patch)
treebcbc1004dfe356ce7cf30f183725dbbc9dad3e4f /arch/cris/arch-v10
parent26bfeea38a4a5daf52c8f01c986ca8680bf1f6a1 (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.c54
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
62unsigned long do_slow_gettimeoffset(void) 62unsigned 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: