aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/arch-v32/kernel/fasttimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/cris/arch-v32/kernel/fasttimer.c')
-rw-r--r--arch/cris/arch-v32/kernel/fasttimer.c535
1 files changed, 202 insertions, 333 deletions
diff --git a/arch/cris/arch-v32/kernel/fasttimer.c b/arch/cris/arch-v32/kernel/fasttimer.c
index b40551f9f40d..2de9d5849ef0 100644
--- a/arch/cris/arch-v32/kernel/fasttimer.c
+++ b/arch/cris/arch-v32/kernel/fasttimer.c
@@ -1,110 +1,9 @@
1/* $Id: fasttimer.c,v 1.11 2005/01/04 11:15:46 starvik Exp $ 1/*
2 * linux/arch/cris/kernel/fasttimer.c 2 * linux/arch/cris/kernel/fasttimer.c
3 * 3 *
4 * Fast timers for ETRAX FS 4 * Fast timers for ETRAX FS
5 * This may be useful in other OS than Linux so use 2 space indentation...
6 *
7 * $Log: fasttimer.c,v $
8 * Revision 1.11 2005/01/04 11:15:46 starvik
9 * Don't share timer IRQ.
10 *
11 * Revision 1.10 2004/12/07 09:19:38 starvik
12 * Corrected includes.
13 * Use correct interrupt macros.
14 *
15 * Revision 1.9 2004/05/14 10:18:58 starvik
16 * Export fast_timer_list
17 *
18 * Revision 1.8 2004/05/14 07:58:03 starvik
19 * Merge of changes from 2.4
20 *
21 * Revision 1.7 2003/07/10 12:06:14 starvik
22 * Return IRQ_NONE if irq wasn't handled
23 *
24 * Revision 1.6 2003/07/04 08:27:49 starvik
25 * Merge of Linux 2.5.74
26 *
27 * Revision 1.5 2003/06/05 10:16:22 johana
28 * New INTR_VECT macros.
29 *
30 * Revision 1.4 2003/06/03 08:49:45 johana
31 * Fixed typo.
32 *
33 * Revision 1.3 2003/06/02 12:51:27 johana
34 * Now compiles.
35 * Commented some include files that probably can be removed.
36 *
37 * Revision 1.2 2003/06/02 12:09:41 johana
38 * Ported to ETRAX FS using the trig interrupt instead of timer1.
39 *
40 * Revision 1.3 2002/12/12 08:26:32 starvik
41 * Don't use C-comments inside CVS comments
42 *
43 * Revision 1.2 2002/12/11 15:42:02 starvik
44 * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/
45 *
46 * Revision 1.1 2002/11/18 07:58:06 starvik
47 * Fast timers (from Linux 2.4)
48 *
49 * Revision 1.5 2002/10/15 06:21:39 starvik
50 * Added call to init_waitqueue_head
51 * 5 *
52 * Revision 1.4 2002/05/28 17:47:59 johana 6 * Copyright (C) 2000-2006 Axis Communications AB, Lund, Sweden
53 * Added del_fast_timer()
54 *
55 * Revision 1.3 2002/05/28 16:16:07 johana
56 * Handle empty fast_timer_list
57 *
58 * Revision 1.2 2002/05/27 15:38:42 johana
59 * Made it compile without warnings on Linux 2.4.
60 * (includes, wait_queue, PROC_FS and snprintf)
61 *
62 * Revision 1.1 2002/05/27 15:32:25 johana
63 * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree.
64 *
65 * Revision 1.8 2001/11/27 13:50:40 pkj
66 * Disable interrupts while stopping the timer and while modifying the
67 * list of active timers in timer1_handler() as it may be interrupted
68 * by other interrupts (e.g., the serial interrupt) which may add fast
69 * timers.
70 *
71 * Revision 1.7 2001/11/22 11:50:32 pkj
72 * * Only store information about the last 16 timers.
73 * * proc_fasttimer_read() now uses an allocated buffer, since it
74 * requires more space than just a page even for only writing the
75 * last 16 timers. The buffer is only allocated on request, so
76 * unless /proc/fasttimer is read, it is never allocated.
77 * * Renamed fast_timer_started to fast_timers_started to match
78 * fast_timers_added and fast_timers_expired.
79 * * Some clean-up.
80 *
81 * Revision 1.6 2000/12/13 14:02:08 johana
82 * Removed volatile for fast_timer_list
83 *
84 * Revision 1.5 2000/12/13 13:55:35 johana
85 * Added DEBUG_LOG, added som cli() and cleanup
86 *
87 * Revision 1.4 2000/12/05 13:48:50 johana
88 * Added range check when writing proc file, modified timer int handling
89 *
90 * Revision 1.3 2000/11/23 10:10:20 johana
91 * More debug/logging possibilities.
92 * Moved GET_JIFFIES_USEC() to timex.h and time.c
93 *
94 * Revision 1.2 2000/11/01 13:41:04 johana
95 * Clean up and bugfixes.
96 * Created new do_gettimeofday_fast() that gets a timeval struct
97 * with time based on jiffies and *R_TIMER0_DATA, uses a table
98 * for fast conversion of timer value to microseconds.
99 * (Much faster the standard do_gettimeofday() and we don't really
100 * want to use the true time - we want the "uptime" so timers don't screw up
101 * when we change the time.
102 * TODO: Add efficient support for continuous timers as well.
103 *
104 * Revision 1.1 2000/10/26 15:49:16 johana
105 * Added fasttimer, highresolution timers.
106 *
107 * Copyright (C) 2000,2001 2002, 2003 Axis Communications AB, Lund, Sweden
108 */ 7 */
109 8
110#include <linux/errno.h> 9#include <linux/errno.h>
@@ -122,9 +21,9 @@
122 21
123#include <linux/version.h> 22#include <linux/version.h>
124 23
125#include <asm/arch/hwregs/reg_map.h> 24#include <hwregs/reg_map.h>
126#include <asm/arch/hwregs/reg_rdwr.h> 25#include <hwregs/reg_rdwr.h>
127#include <asm/arch/hwregs/timer_defs.h> 26#include <hwregs/timer_defs.h>
128#include <asm/fasttimer.h> 27#include <asm/fasttimer.h>
129#include <linux/proc_fs.h> 28#include <linux/proc_fs.h>
130 29
@@ -140,30 +39,25 @@
140 39
141#define DEBUG_LOG_INCLUDED 40#define DEBUG_LOG_INCLUDED
142#define FAST_TIMER_LOG 41#define FAST_TIMER_LOG
143//#define FAST_TIMER_TEST 42/* #define FAST_TIMER_TEST */
144 43
145#define FAST_TIMER_SANITY_CHECKS 44#define FAST_TIMER_SANITY_CHECKS
146 45
147#ifdef FAST_TIMER_SANITY_CHECKS 46#ifdef FAST_TIMER_SANITY_CHECKS
148#define SANITYCHECK(x) x 47static int sanity_failed;
149static int sanity_failed = 0;
150#else
151#define SANITYCHECK(x)
152#endif 48#endif
153 49
154#define D1(x) 50#define D1(x)
155#define D2(x) 51#define D2(x)
156#define DP(x) 52#define DP(x)
157 53
158#define __INLINE__ inline 54static unsigned int fast_timer_running;
159 55static unsigned int fast_timers_added;
160static int fast_timer_running = 0; 56static unsigned int fast_timers_started;
161static int fast_timers_added = 0; 57static unsigned int fast_timers_expired;
162static int fast_timers_started = 0; 58static unsigned int fast_timers_deleted;
163static int fast_timers_expired = 0; 59static unsigned int fast_timer_is_init;
164static int fast_timers_deleted = 0; 60static unsigned int fast_timer_ints;
165static int fast_timer_is_init = 0;
166static int fast_timer_ints = 0;
167 61
168struct fast_timer *fast_timer_list = NULL; 62struct fast_timer *fast_timer_list = NULL;
169 63
@@ -171,8 +65,8 @@ struct fast_timer *fast_timer_list = NULL;
171#define DEBUG_LOG_MAX 128 65#define DEBUG_LOG_MAX 128
172static const char * debug_log_string[DEBUG_LOG_MAX]; 66static const char * debug_log_string[DEBUG_LOG_MAX];
173static unsigned long debug_log_value[DEBUG_LOG_MAX]; 67static unsigned long debug_log_value[DEBUG_LOG_MAX];
174static int debug_log_cnt = 0; 68static unsigned int debug_log_cnt;
175static int debug_log_cnt_wrapped = 0; 69static unsigned int debug_log_cnt_wrapped;
176 70
177#define DEBUG_LOG(string, value) \ 71#define DEBUG_LOG(string, value) \
178{ \ 72{ \
@@ -202,103 +96,92 @@ struct fast_timer timer_expired_log[NUM_TIMER_STATS];
202int timer_div_settings[NUM_TIMER_STATS]; 96int timer_div_settings[NUM_TIMER_STATS];
203int timer_delay_settings[NUM_TIMER_STATS]; 97int timer_delay_settings[NUM_TIMER_STATS];
204 98
99struct work_struct fast_work;
205 100
206static void 101static void
207timer_trig_handler(void); 102timer_trig_handler(struct work_struct *work);
208 103
209 104
210 105
211/* Not true gettimeofday, only checks the jiffies (uptime) + useconds */ 106/* Not true gettimeofday, only checks the jiffies (uptime) + useconds */
212void __INLINE__ do_gettimeofday_fast(struct timeval *tv) 107inline void do_gettimeofday_fast(struct fasttime_t *tv)
213{ 108{
214 unsigned long sec = jiffies; 109 tv->tv_jiff = jiffies;
215 unsigned long usec = GET_JIFFIES_USEC(); 110 tv->tv_usec = GET_JIFFIES_USEC();
216
217 usec += (sec % HZ) * (1000000 / HZ);
218 sec = sec / HZ;
219
220 if (usec > 1000000)
221 {
222 usec -= 1000000;
223 sec++;
224 }
225 tv->tv_sec = sec;
226 tv->tv_usec = usec;
227} 111}
228 112
229int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1) 113inline int fasttime_cmp(struct fasttime_t *t0, struct fasttime_t *t1)
230{ 114{
231 if (t0->tv_sec < t1->tv_sec) 115 /* Compare jiffies. Takes care of wrapping */
232 { 116 if (time_before(t0->tv_jiff, t1->tv_jiff))
233 return -1; 117 return -1;
234 } 118 else if (time_after(t0->tv_jiff, t1->tv_jiff))
235 else if (t0->tv_sec > t1->tv_sec) 119 return 1;
236 { 120
237 return 1; 121 /* Compare us */
238 } 122 if (t0->tv_usec < t1->tv_usec)
239 if (t0->tv_usec < t1->tv_usec) 123 return -1;
240 { 124 else if (t0->tv_usec > t1->tv_usec)
241 return -1; 125 return 1;
242 } 126 return 0;
243 else if (t0->tv_usec > t1->tv_usec)
244 {
245 return 1;
246 }
247 return 0;
248} 127}
249 128
250/* Called with ints off */ 129/* Called with ints off */
251void __INLINE__ start_timer_trig(unsigned long delay_us) 130inline void start_timer_trig(unsigned long delay_us)
252{ 131{
253 reg_timer_rw_ack_intr ack_intr = { 0 }; 132 reg_timer_rw_ack_intr ack_intr = { 0 };
254 reg_timer_rw_intr_mask intr_mask; 133 reg_timer_rw_intr_mask intr_mask;
255 reg_timer_rw_trig trig; 134 reg_timer_rw_trig trig;
256 reg_timer_rw_trig_cfg trig_cfg = { 0 }; 135 reg_timer_rw_trig_cfg trig_cfg = { 0 };
257 reg_timer_r_time r_time; 136 reg_timer_r_time r_time0;
137 reg_timer_r_time r_time1;
138 unsigned char trig_wrap;
139 unsigned char time_wrap;
258 140
259 r_time = REG_RD(timer, regi_timer, r_time); 141 r_time0 = REG_RD(timer, regi_timer0, r_time);
260 142
261 D1(printk("start_timer_trig : %d us freq: %i div: %i\n", 143 D1(printk("start_timer_trig : %d us freq: %i div: %i\n",
262 delay_us, freq_index, div)); 144 delay_us, freq_index, div));
263 /* Clear trig irq */ 145 /* Clear trig irq */
264 intr_mask = REG_RD(timer, regi_timer, rw_intr_mask); 146 intr_mask = REG_RD(timer, regi_timer0, rw_intr_mask);
265 intr_mask.trig = 0; 147 intr_mask.trig = 0;
266 REG_WR(timer, regi_timer, rw_intr_mask, intr_mask); 148 REG_WR(timer, regi_timer0, rw_intr_mask, intr_mask);
267 149
268 /* Set timer values */ 150 /* Set timer values and check if trigger wraps. */
269 /* r_time is 100MHz (10 ns resolution) */ 151 /* r_time is 100MHz (10 ns resolution) */
270 trig = r_time + delay_us*(1000/10); 152 trig_wrap = (trig = r_time0 + delay_us*(1000/10)) < r_time0;
271 153
272 timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = trig; 154 timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = trig;
273 timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us; 155 timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us;
274 156
275 /* Ack interrupt */ 157 /* Ack interrupt */
276 ack_intr.trig = 1; 158 ack_intr.trig = 1;
277 REG_WR(timer, regi_timer, rw_ack_intr, ack_intr); 159 REG_WR(timer, regi_timer0, rw_ack_intr, ack_intr);
278 160
279 /* Start timer */ 161 /* Start timer */
280 REG_WR(timer, regi_timer, rw_trig, trig); 162 REG_WR(timer, regi_timer0, rw_trig, trig);
281 trig_cfg.tmr = regk_timer_time; 163 trig_cfg.tmr = regk_timer_time;
282 REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg); 164 REG_WR(timer, regi_timer0, rw_trig_cfg, trig_cfg);
283 165
284 /* Check if we have already passed the trig time */ 166 /* Check if we have already passed the trig time */
285 r_time = REG_RD(timer, regi_timer, r_time); 167 r_time1 = REG_RD(timer, regi_timer0, r_time);
286 if (r_time < trig) { 168 time_wrap = r_time1 < r_time0;
169
170 if ((trig_wrap && !time_wrap) || (r_time1 < trig)) {
287 /* No, Enable trig irq */ 171 /* No, Enable trig irq */
288 intr_mask = REG_RD(timer, regi_timer, rw_intr_mask); 172 intr_mask = REG_RD(timer, regi_timer0, rw_intr_mask);
289 intr_mask.trig = 1; 173 intr_mask.trig = 1;
290 REG_WR(timer, regi_timer, rw_intr_mask, intr_mask); 174 REG_WR(timer, regi_timer0, rw_intr_mask, intr_mask);
291 fast_timers_started++; 175 fast_timers_started++;
292 fast_timer_running = 1; 176 fast_timer_running = 1;
293 } 177 } else {
294 else
295 {
296 /* We have passed the time, disable trig point, ack intr */ 178 /* We have passed the time, disable trig point, ack intr */
297 trig_cfg.tmr = regk_timer_off; 179 trig_cfg.tmr = regk_timer_off;
298 REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg); 180 REG_WR(timer, regi_timer0, rw_trig_cfg, trig_cfg);
299 REG_WR(timer, regi_timer, rw_ack_intr, ack_intr); 181 REG_WR(timer, regi_timer0, rw_ack_intr, ack_intr);
300 /* call the int routine directly */ 182 /* call the int routine */
301 timer_trig_handler(); 183 INIT_WORK(&fast_work, timer_trig_handler);
184 schedule_work(&fast_work);
302 } 185 }
303 186
304} 187}
@@ -320,22 +203,20 @@ void start_one_shot_timer(struct fast_timer *t,
320 do_gettimeofday_fast(&t->tv_set); 203 do_gettimeofday_fast(&t->tv_set);
321 tmp = fast_timer_list; 204 tmp = fast_timer_list;
322 205
323 SANITYCHECK({ /* Check so this is not in the list already... */ 206#ifdef FAST_TIMER_SANITY_CHECKS
324 while (tmp != NULL) 207 /* Check so this is not in the list already... */
325 { 208 while (tmp != NULL) {
326 if (tmp == t) 209 if (tmp == t) {
327 { 210 printk(KERN_DEBUG
328 printk("timer name: %s data: 0x%08lX already in list!\n", name, data); 211 "timer name: %s data: 0x%08lX already "
329 sanity_failed++; 212 "in list!\n", name, data);
330 return; 213 sanity_failed++;
331 } 214 goto done;
332 else 215 } else
333 { 216 tmp = tmp->next;
334 tmp = tmp->next; 217 }
335 } 218 tmp = fast_timer_list;
336 } 219#endif
337 tmp = fast_timer_list;
338 });
339 220
340 t->delay_us = delay_us; 221 t->delay_us = delay_us;
341 t->function = function; 222 t->function = function;
@@ -343,11 +224,10 @@ void start_one_shot_timer(struct fast_timer *t,
343 t->name = name; 224 t->name = name;
344 225
345 t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000; 226 t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000;
346 t->tv_expires.tv_sec = t->tv_set.tv_sec + delay_us / 1000000; 227 t->tv_expires.tv_jiff = t->tv_set.tv_jiff + delay_us / 1000000 / HZ;
347 if (t->tv_expires.tv_usec > 1000000) 228 if (t->tv_expires.tv_usec > 1000000) {
348 {
349 t->tv_expires.tv_usec -= 1000000; 229 t->tv_expires.tv_usec -= 1000000;
350 t->tv_expires.tv_sec++; 230 t->tv_expires.tv_jiff += HZ;
351 } 231 }
352#ifdef FAST_TIMER_LOG 232#ifdef FAST_TIMER_LOG
353 timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t; 233 timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t;
@@ -355,15 +235,12 @@ void start_one_shot_timer(struct fast_timer *t,
355 fast_timers_added++; 235 fast_timers_added++;
356 236
357 /* Check if this should timeout before anything else */ 237 /* Check if this should timeout before anything else */
358 if (tmp == NULL || timeval_cmp(&t->tv_expires, &tmp->tv_expires) < 0) 238 if (tmp == NULL || fasttime_cmp(&t->tv_expires, &tmp->tv_expires) < 0) {
359 {
360 /* Put first in list and modify the timer value */ 239 /* Put first in list and modify the timer value */
361 t->prev = NULL; 240 t->prev = NULL;
362 t->next = fast_timer_list; 241 t->next = fast_timer_list;
363 if (fast_timer_list) 242 if (fast_timer_list)
364 {
365 fast_timer_list->prev = t; 243 fast_timer_list->prev = t;
366 }
367 fast_timer_list = t; 244 fast_timer_list = t;
368#ifdef FAST_TIMER_LOG 245#ifdef FAST_TIMER_LOG
369 timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t; 246 timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
@@ -372,10 +249,8 @@ void start_one_shot_timer(struct fast_timer *t,
372 } else { 249 } else {
373 /* Put in correct place in list */ 250 /* Put in correct place in list */
374 while (tmp->next && 251 while (tmp->next &&
375 timeval_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0) 252 fasttime_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0)
376 {
377 tmp = tmp->next; 253 tmp = tmp->next;
378 }
379 /* Insert t after tmp */ 254 /* Insert t after tmp */
380 t->prev = tmp; 255 t->prev = tmp;
381 t->next = tmp->next; 256 t->next = tmp->next;
@@ -388,6 +263,7 @@ void start_one_shot_timer(struct fast_timer *t,
388 263
389 D2(printk("start_one_shot_timer: %d us done\n", delay_us)); 264 D2(printk("start_one_shot_timer: %d us done\n", delay_us));
390 265
266done:
391 local_irq_restore(flags); 267 local_irq_restore(flags);
392} /* start_one_shot_timer */ 268} /* start_one_shot_timer */
393 269
@@ -431,19 +307,18 @@ int del_fast_timer(struct fast_timer * t)
431/* Timer interrupt handler for trig interrupts */ 307/* Timer interrupt handler for trig interrupts */
432 308
433static irqreturn_t 309static irqreturn_t
434timer_trig_interrupt(int irq, void *dev_id, struct pt_regs *regs) 310timer_trig_interrupt(int irq, void *dev_id)
435{ 311{
436 reg_timer_r_masked_intr masked_intr; 312 reg_timer_r_masked_intr masked_intr;
437
438 /* Check if the timer interrupt is for us (a trig int) */ 313 /* Check if the timer interrupt is for us (a trig int) */
439 masked_intr = REG_RD(timer, regi_timer, r_masked_intr); 314 masked_intr = REG_RD(timer, regi_timer0, r_masked_intr);
440 if (!masked_intr.trig) 315 if (!masked_intr.trig)
441 return IRQ_NONE; 316 return IRQ_NONE;
442 timer_trig_handler(); 317 timer_trig_handler(NULL);
443 return IRQ_HANDLED; 318 return IRQ_HANDLED;
444} 319}
445 320
446static void timer_trig_handler(void) 321static void timer_trig_handler(struct work_struct *work)
447{ 322{
448 reg_timer_rw_ack_intr ack_intr = { 0 }; 323 reg_timer_rw_ack_intr ack_intr = { 0 };
449 reg_timer_rw_intr_mask intr_mask; 324 reg_timer_rw_intr_mask intr_mask;
@@ -451,38 +326,45 @@ static void timer_trig_handler(void)
451 struct fast_timer *t; 326 struct fast_timer *t;
452 unsigned long flags; 327 unsigned long flags;
453 328
329 /* We keep interrupts disabled not only when we modify the
330 * fast timer list, but any time we hold a reference to a
331 * timer in the list, since del_fast_timer may be called
332 * from (another) interrupt context. Thus, the only time
333 * when interrupts are enabled is when calling the timer
334 * callback function.
335 */
454 local_irq_save(flags); 336 local_irq_save(flags);
455 337
456 /* Clear timer trig interrupt */ 338 /* Clear timer trig interrupt */
457 intr_mask = REG_RD(timer, regi_timer, rw_intr_mask); 339 intr_mask = REG_RD(timer, regi_timer0, rw_intr_mask);
458 intr_mask.trig = 0; 340 intr_mask.trig = 0;
459 REG_WR(timer, regi_timer, rw_intr_mask, intr_mask); 341 REG_WR(timer, regi_timer0, rw_intr_mask, intr_mask);
460 342
461 /* First stop timer, then ack interrupt */ 343 /* First stop timer, then ack interrupt */
462 /* Stop timer */ 344 /* Stop timer */
463 trig_cfg.tmr = regk_timer_off; 345 trig_cfg.tmr = regk_timer_off;
464 REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg); 346 REG_WR(timer, regi_timer0, rw_trig_cfg, trig_cfg);
465 347
466 /* Ack interrupt */ 348 /* Ack interrupt */
467 ack_intr.trig = 1; 349 ack_intr.trig = 1;
468 REG_WR(timer, regi_timer, rw_ack_intr, ack_intr); 350 REG_WR(timer, regi_timer0, rw_ack_intr, ack_intr);
469 351
470 fast_timer_running = 0; 352 fast_timer_running = 0;
471 fast_timer_ints++; 353 fast_timer_ints++;
472 354
473 local_irq_restore(flags); 355 fast_timer_function_type *f;
356 unsigned long d;
474 357
475 t = fast_timer_list; 358 t = fast_timer_list;
476 while (t) 359 while (t) {
477 { 360 struct fasttime_t tv;
478 struct timeval tv;
479 361
480 /* Has it really expired? */ 362 /* Has it really expired? */
481 do_gettimeofday_fast(&tv); 363 do_gettimeofday_fast(&tv);
482 D1(printk("t: %is %06ius\n", tv.tv_sec, tv.tv_usec)); 364 D1(printk(KERN_DEBUG
365 "t: %is %06ius\n", tv.tv_jiff, tv.tv_usec));
483 366
484 if (timeval_cmp(&t->tv_expires, &tv) <= 0) 367 if (fasttime_cmp(&t->tv_expires, &tv) <= 0) {
485 {
486 /* Yes it has expired */ 368 /* Yes it has expired */
487#ifdef FAST_TIMER_LOG 369#ifdef FAST_TIMER_LOG
488 timer_expired_log[fast_timers_expired % NUM_TIMER_STATS] = *t; 370 timer_expired_log[fast_timers_expired % NUM_TIMER_STATS] = *t;
@@ -490,84 +372,77 @@ static void timer_trig_handler(void)
490 fast_timers_expired++; 372 fast_timers_expired++;
491 373
492 /* Remove this timer before call, since it may reuse the timer */ 374 /* Remove this timer before call, since it may reuse the timer */
493 local_irq_save(flags);
494 if (t->prev) 375 if (t->prev)
495 {
496 t->prev->next = t->next; 376 t->prev->next = t->next;
497 }
498 else 377 else
499 {
500 fast_timer_list = t->next; 378 fast_timer_list = t->next;
501 }
502 if (t->next) 379 if (t->next)
503 {
504 t->next->prev = t->prev; 380 t->next->prev = t->prev;
505 }
506 t->prev = NULL; 381 t->prev = NULL;
507 t->next = NULL; 382 t->next = NULL;
508 local_irq_restore(flags);
509 383
510 if (t->function != NULL) 384 /* Save function callback data before enabling
511 { 385 * interrupts, since the timer may be removed and we
512 t->function(t->data); 386 * don't know how it was allocated (e.g. ->function
513 } 387 * and ->data may become overwritten after deletion
514 else 388 * if the timer was stack-allocated).
515 { 389 */
390 f = t->function;
391 d = t->data;
392
393 if (f != NULL) {
394 /* Run the callback function with interrupts
395 * enabled. */
396 local_irq_restore(flags);
397 f(d);
398 local_irq_save(flags);
399 } else
516 DEBUG_LOG("!trimertrig %i function==NULL!\n", fast_timer_ints); 400 DEBUG_LOG("!trimertrig %i function==NULL!\n", fast_timer_ints);
517 } 401 } else {
518 }
519 else
520 {
521 /* Timer is to early, let's set it again using the normal routines */ 402 /* Timer is to early, let's set it again using the normal routines */
522 D1(printk(".\n")); 403 D1(printk(".\n"));
523 } 404 }
524 405
525 local_irq_save(flags); 406 t = fast_timer_list;
526 if ((t = fast_timer_list) != NULL) 407 if (t != NULL) {
527 {
528 /* Start next timer.. */ 408 /* Start next timer.. */
529 long us; 409 long us = 0;
530 struct timeval tv; 410 struct fasttime_t tv;
531 411
532 do_gettimeofday_fast(&tv); 412 do_gettimeofday_fast(&tv);
533 us = ((t->tv_expires.tv_sec - tv.tv_sec) * 1000000 + 413
534 t->tv_expires.tv_usec - tv.tv_usec); 414 /* time_after_eq takes care of wrapping */
535 if (us > 0) 415 if (time_after_eq(t->tv_expires.tv_jiff, tv.tv_jiff))
536 { 416 us = ((t->tv_expires.tv_jiff - tv.tv_jiff) *
537 if (!fast_timer_running) 417 1000000 / HZ + t->tv_expires.tv_usec -
538 { 418 tv.tv_usec);
419
420 if (us > 0) {
421 if (!fast_timer_running) {
539#ifdef FAST_TIMER_LOG 422#ifdef FAST_TIMER_LOG
540 timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t; 423 timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
541#endif 424#endif
542 start_timer_trig(us); 425 start_timer_trig(us);
543 } 426 }
544 local_irq_restore(flags);
545 break; 427 break;
546 } 428 } else {
547 else
548 {
549 /* Timer already expired, let's handle it better late than never. 429 /* Timer already expired, let's handle it better late than never.
550 * The normal loop handles it 430 * The normal loop handles it
551 */ 431 */
552 D1(printk("e! %d\n", us)); 432 D1(printk("e! %d\n", us));
553 } 433 }
554 } 434 }
555 local_irq_restore(flags);
556 } 435 }
557 436
558 if (!t) 437 local_irq_restore(flags);
559 { 438
439 if (!t)
560 D1(printk("ttrig stop!\n")); 440 D1(printk("ttrig stop!\n"));
561 }
562} 441}
563 442
564static void wake_up_func(unsigned long data) 443static void wake_up_func(unsigned long data)
565{ 444{
566#ifdef DECLARE_WAITQUEUE
567 wait_queue_head_t *sleep_wait_p = (wait_queue_head_t*)data; 445 wait_queue_head_t *sleep_wait_p = (wait_queue_head_t*)data;
568#else
569 struct wait_queue **sleep_wait_p = (struct wait_queue **)data;
570#endif
571 wake_up(sleep_wait_p); 446 wake_up(sleep_wait_p);
572} 447}
573 448
@@ -577,28 +452,17 @@ static void wake_up_func(unsigned long data)
577void schedule_usleep(unsigned long us) 452void schedule_usleep(unsigned long us)
578{ 453{
579 struct fast_timer t; 454 struct fast_timer t;
580#ifdef DECLARE_WAITQUEUE
581 wait_queue_head_t sleep_wait; 455 wait_queue_head_t sleep_wait;
582 init_waitqueue_head(&sleep_wait); 456 init_waitqueue_head(&sleep_wait);
583 {
584 DECLARE_WAITQUEUE(wait, current);
585#else
586 struct wait_queue *sleep_wait = NULL;
587 struct wait_queue wait = { current, NULL };
588#endif
589 457
590 D1(printk("schedule_usleep(%d)\n", us)); 458 D1(printk("schedule_usleep(%d)\n", us));
591 add_wait_queue(&sleep_wait, &wait);
592 set_current_state(TASK_INTERRUPTIBLE);
593 start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us, 459 start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us,
594 "usleep"); 460 "usleep");
595 schedule(); 461 /* Uninterruptible sleep on the fast timer. (The condition is
596 set_current_state(TASK_RUNNING); 462 * somewhat redundant since the timer is what wakes us up.) */
597 remove_wait_queue(&sleep_wait, &wait); 463 wait_event(sleep_wait, !fast_timer_pending(&t));
464
598 D1(printk("done schedule_usleep(%d)\n", us)); 465 D1(printk("done schedule_usleep(%d)\n", us));
599#ifdef DECLARE_WAITQUEUE
600 }
601#endif
602} 466}
603 467
604#ifdef CONFIG_PROC_FS 468#ifdef CONFIG_PROC_FS
@@ -618,20 +482,22 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
618 unsigned long flags; 482 unsigned long flags;
619 int i = 0; 483 int i = 0;
620 int num_to_show; 484 int num_to_show;
621 struct timeval tv; 485 struct fasttime_t tv;
622 struct fast_timer *t, *nextt; 486 struct fast_timer *t, *nextt;
623 static char *bigbuf = NULL; 487 static char *bigbuf = NULL;
624 static unsigned long used; 488 static unsigned long used;
625 489
626 if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE))) 490 if (!bigbuf) {
627 { 491 bigbuf = vmalloc(BIG_BUF_SIZE);
628 used = 0; 492 if (!bigbuf) {
629 bigbuf[0] = '\0'; 493 used = 0;
630 return 0; 494 if (buf)
631 } 495 buf[0] = '\0';
632 496 return 0;
633 if (!offset || !used) 497 }
634 { 498 }
499
500 if (!offset || !used) {
635 do_gettimeofday_fast(&tv); 501 do_gettimeofday_fast(&tv);
636 502
637 used = 0; 503 used = 0;
@@ -648,7 +514,7 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
648 used += sprintf(bigbuf + used, "Fast timer running: %s\n", 514 used += sprintf(bigbuf + used, "Fast timer running: %s\n",
649 fast_timer_running ? "yes" : "no"); 515 fast_timer_running ? "yes" : "no");
650 used += sprintf(bigbuf + used, "Current time: %lu.%06lu\n", 516 used += sprintf(bigbuf + used, "Current time: %lu.%06lu\n",
651 (unsigned long)tv.tv_sec, 517 (unsigned long)tv.tv_jiff,
652 (unsigned long)tv.tv_usec); 518 (unsigned long)tv.tv_usec);
653#ifdef FAST_TIMER_SANITY_CHECKS 519#ifdef FAST_TIMER_SANITY_CHECKS
654 used += sprintf(bigbuf + used, "Sanity failed: %i\n", 520 used += sprintf(bigbuf + used, "Sanity failed: %i\n",
@@ -661,10 +527,8 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
661 int end_i = debug_log_cnt; 527 int end_i = debug_log_cnt;
662 i = 0; 528 i = 0;
663 529
664 if (debug_log_cnt_wrapped) 530 if (debug_log_cnt_wrapped)
665 {
666 i = debug_log_cnt; 531 i = debug_log_cnt;
667 }
668 532
669 while ((i != end_i || (debug_log_cnt_wrapped && !used)) && 533 while ((i != end_i || (debug_log_cnt_wrapped && !used)) &&
670 used+100 < BIG_BUF_SIZE) 534 used+100 < BIG_BUF_SIZE)
@@ -697,9 +561,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
697 "d: %6li us data: 0x%08lX" 561 "d: %6li us data: 0x%08lX"
698 "\n", 562 "\n",
699 t->name, 563 t->name,
700 (unsigned long)t->tv_set.tv_sec, 564 (unsigned long)t->tv_set.tv_jiff,
701 (unsigned long)t->tv_set.tv_usec, 565 (unsigned long)t->tv_set.tv_usec,
702 (unsigned long)t->tv_expires.tv_sec, 566 (unsigned long)t->tv_expires.tv_jiff,
703 (unsigned long)t->tv_expires.tv_usec, 567 (unsigned long)t->tv_expires.tv_usec,
704 t->delay_us, 568 t->delay_us,
705 t->data 569 t->data
@@ -719,9 +583,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
719 "d: %6li us data: 0x%08lX" 583 "d: %6li us data: 0x%08lX"
720 "\n", 584 "\n",
721 t->name, 585 t->name,
722 (unsigned long)t->tv_set.tv_sec, 586 (unsigned long)t->tv_set.tv_jiff,
723 (unsigned long)t->tv_set.tv_usec, 587 (unsigned long)t->tv_set.tv_usec,
724 (unsigned long)t->tv_expires.tv_sec, 588 (unsigned long)t->tv_expires.tv_jiff,
725 (unsigned long)t->tv_expires.tv_usec, 589 (unsigned long)t->tv_expires.tv_usec,
726 t->delay_us, 590 t->delay_us,
727 t->data 591 t->data
@@ -739,9 +603,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
739 "d: %6li us data: 0x%08lX" 603 "d: %6li us data: 0x%08lX"
740 "\n", 604 "\n",
741 t->name, 605 t->name,
742 (unsigned long)t->tv_set.tv_sec, 606 (unsigned long)t->tv_set.tv_jiff,
743 (unsigned long)t->tv_set.tv_usec, 607 (unsigned long)t->tv_set.tv_usec,
744 (unsigned long)t->tv_expires.tv_sec, 608 (unsigned long)t->tv_expires.tv_jiff,
745 (unsigned long)t->tv_expires.tv_usec, 609 (unsigned long)t->tv_expires.tv_usec,
746 t->delay_us, 610 t->delay_us,
747 t->data 611 t->data
@@ -752,26 +616,25 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
752 616
753 used += sprintf(bigbuf + used, "Active timers:\n"); 617 used += sprintf(bigbuf + used, "Active timers:\n");
754 local_irq_save(flags); 618 local_irq_save(flags);
755 local_irq_save(flags);
756 t = fast_timer_list; 619 t = fast_timer_list;
757 while (t != NULL && (used+100 < BIG_BUF_SIZE)) 620 while (t != NULL && (used+100 < BIG_BUF_SIZE))
758 { 621 {
759 nextt = t->next; 622 nextt = t->next;
760 local_irq_restore(flags); 623 local_irq_restore(flags);
761 used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " 624 used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
762 "d: %6li us data: 0x%08lX" 625 "d: %6li us data: 0x%08lX"
763/* " func: 0x%08lX" */ 626/* " func: 0x%08lX" */
764 "\n", 627 "\n",
765 t->name, 628 t->name,
766 (unsigned long)t->tv_set.tv_sec, 629 (unsigned long)t->tv_set.tv_jiff,
767 (unsigned long)t->tv_set.tv_usec, 630 (unsigned long)t->tv_set.tv_usec,
768 (unsigned long)t->tv_expires.tv_sec, 631 (unsigned long)t->tv_expires.tv_jiff,
769 (unsigned long)t->tv_expires.tv_usec, 632 (unsigned long)t->tv_expires.tv_usec,
770 t->delay_us, 633 t->delay_us,
771 t->data 634 t->data
772/* , t->function */ 635/* , t->function */
773 ); 636 );
774 local_irq_disable(); 637 local_irq_save(flags);
775 if (t->next != nextt) 638 if (t->next != nextt)
776 { 639 {
777 printk("timer removed!\n"); 640 printk("timer removed!\n");
@@ -800,7 +663,7 @@ static volatile int num_test_timeout = 0;
800static struct fast_timer tr[10]; 663static struct fast_timer tr[10];
801static int exp_num[10]; 664static int exp_num[10];
802 665
803static struct timeval tv_exp[100]; 666static struct fasttime_t tv_exp[100];
804 667
805static void test_timeout(unsigned long data) 668static void test_timeout(unsigned long data)
806{ 669{
@@ -838,7 +701,7 @@ static void fast_timer_test(void)
838 int prev_num; 701 int prev_num;
839 int j; 702 int j;
840 703
841 struct timeval tv, tv0, tv1, tv2; 704 struct fasttime_t tv, tv0, tv1, tv2;
842 705
843 printk("fast_timer_test() start\n"); 706 printk("fast_timer_test() start\n");
844 do_gettimeofday_fast(&tv); 707 do_gettimeofday_fast(&tv);
@@ -851,21 +714,22 @@ static void fast_timer_test(void)
851 { 714 {
852 do_gettimeofday_fast(&tv_exp[j]); 715 do_gettimeofday_fast(&tv_exp[j]);
853 } 716 }
854 printk("fast_timer_test() %is %06i\n", tv.tv_sec, tv.tv_usec); 717 printk(KERN_DEBUG "fast_timer_test() %is %06i\n", tv.tv_jiff, tv.tv_usec);
855 718
856 for (j = 0; j < 1000; j++) 719 for (j = 0; j < 1000; j++)
857 { 720 {
858 printk("%i %i %i %i %i\n",j_u[j], j_u[j+1], j_u[j+2], j_u[j+3], j_u[j+4]); 721 printk(KERN_DEBUG "%i %i %i %i %i\n",
722 j_u[j], j_u[j+1], j_u[j+2], j_u[j+3], j_u[j+4]);
859 j += 4; 723 j += 4;
860 } 724 }
861 for (j = 0; j < 100; j++) 725 for (j = 0; j < 100; j++)
862 { 726 {
863 printk("%i.%i %i.%i %i.%i %i.%i %i.%i\n", 727 printk(KERN_DEBUG "%i.%i %i.%i %i.%i %i.%i %i.%i\n",
864 tv_exp[j].tv_sec,tv_exp[j].tv_usec, 728 tv_exp[j].tv_jiff, tv_exp[j].tv_usec,
865 tv_exp[j+1].tv_sec,tv_exp[j+1].tv_usec, 729 tv_exp[j+1].tv_jiff, tv_exp[j+1].tv_usec,
866 tv_exp[j+2].tv_sec,tv_exp[j+2].tv_usec, 730 tv_exp[j+2].tv_jiff, tv_exp[j+2].tv_usec,
867 tv_exp[j+3].tv_sec,tv_exp[j+3].tv_usec, 731 tv_exp[j+3].tv_jiff, tv_exp[j+3].tv_usec,
868 tv_exp[j+4].tv_sec,tv_exp[j+4].tv_usec); 732 tv_exp[j+4].tv_jiff, tv_exp[j+4].tv_usec);
869 j += 4; 733 j += 4;
870 } 734 }
871 do_gettimeofday_fast(&tv0); 735 do_gettimeofday_fast(&tv0);
@@ -892,14 +756,15 @@ static void fast_timer_test(void)
892 while (num_test_timeout < i) 756 while (num_test_timeout < i)
893 { 757 {
894 if (num_test_timeout != prev_num) 758 if (num_test_timeout != prev_num)
895 {
896 prev_num = num_test_timeout; 759 prev_num = num_test_timeout;
897 }
898 } 760 }
899 do_gettimeofday_fast(&tv2); 761 do_gettimeofday_fast(&tv2);
900 printk("Timers started %is %06i\n", tv0.tv_sec, tv0.tv_usec); 762 printk(KERN_INFO "Timers started %is %06i\n",
901 printk("Timers started at %is %06i\n", tv1.tv_sec, tv1.tv_usec); 763 tv0.tv_jiff, tv0.tv_usec);
902 printk("Timers done %is %06i\n", tv2.tv_sec, tv2.tv_usec); 764 printk(KERN_INFO "Timers started at %is %06i\n",
765 tv1.tv_jiff, tv1.tv_usec);
766 printk(KERN_INFO "Timers done %is %06i\n",
767 tv2.tv_jiff, tv2.tv_usec);
903 DP(printk("buf0:\n"); 768 DP(printk("buf0:\n");
904 printk(buf0); 769 printk(buf0);
905 printk("buf1:\n"); 770 printk("buf1:\n");
@@ -921,9 +786,9 @@ static void fast_timer_test(void)
921 printk("%-10s set: %6is %06ius exp: %6is %06ius " 786 printk("%-10s set: %6is %06ius exp: %6is %06ius "
922 "data: 0x%08X func: 0x%08X\n", 787 "data: 0x%08X func: 0x%08X\n",
923 t->name, 788 t->name,
924 t->tv_set.tv_sec, 789 t->tv_set.tv_jiff,
925 t->tv_set.tv_usec, 790 t->tv_set.tv_usec,
926 t->tv_expires.tv_sec, 791 t->tv_expires.tv_jiff,
927 t->tv_expires.tv_usec, 792 t->tv_expires.tv_usec,
928 t->data, 793 t->data,
929 t->function 794 t->function
@@ -931,10 +796,12 @@ static void fast_timer_test(void)
931 796
932 printk(" del: %6ius did exp: %6is %06ius as #%i error: %6li\n", 797 printk(" del: %6ius did exp: %6is %06ius as #%i error: %6li\n",
933 t->delay_us, 798 t->delay_us,
934 tv_exp[j].tv_sec, 799 tv_exp[j].tv_jiff,
935 tv_exp[j].tv_usec, 800 tv_exp[j].tv_usec,
936 exp_num[j], 801 exp_num[j],
937 (tv_exp[j].tv_sec - t->tv_expires.tv_sec)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec); 802 (tv_exp[j].tv_jiff - t->tv_expires.tv_jiff) *
803 1000000 + tv_exp[j].tv_usec -
804 t->tv_expires.tv_usec);
938 } 805 }
939 proc_fasttimer_read(buf5, NULL, 0, 0, 0); 806 proc_fasttimer_read(buf5, NULL, 0, 0, 0);
940 printk("buf5 after all done:\n"); 807 printk("buf5 after all done:\n");
@@ -944,7 +811,7 @@ static void fast_timer_test(void)
944#endif 811#endif
945 812
946 813
947void fast_timer_init(void) 814int fast_timer_init(void)
948{ 815{
949 /* For some reason, request_irq() hangs when called froom time_init() */ 816 /* For some reason, request_irq() hangs when called froom time_init() */
950 if (!fast_timer_is_init) 817 if (!fast_timer_is_init)
@@ -952,18 +819,20 @@ void fast_timer_init(void)
952 printk("fast_timer_init()\n"); 819 printk("fast_timer_init()\n");
953 820
954#ifdef CONFIG_PROC_FS 821#ifdef CONFIG_PROC_FS
955 if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 ))) 822 fasttimer_proc_entry = create_proc_entry("fasttimer", 0, 0);
956 fasttimer_proc_entry->read_proc = proc_fasttimer_read; 823 if (fasttimer_proc_entry)
824 fasttimer_proc_entry->read_proc = proc_fasttimer_read;
957#endif /* PROC_FS */ 825#endif /* PROC_FS */
958 if(request_irq(TIMER_INTR_VECT, timer_trig_interrupt, IRQF_DISABLED, 826 if (request_irq(TIMER0_INTR_VECT, timer_trig_interrupt,
959 "fast timer int", NULL)) 827 IRQF_SHARED | IRQF_DISABLED,
960 { 828 "fast timer int", &fast_timer_list))
961 printk("err: timer1 irq\n"); 829 printk(KERN_ERR "err: fasttimer irq\n");
962 }
963 fast_timer_is_init = 1; 830 fast_timer_is_init = 1;
964#ifdef FAST_TIMER_TEST 831#ifdef FAST_TIMER_TEST
965 printk("do test\n"); 832 printk("do test\n");
966 fast_timer_test(); 833 fast_timer_test();
967#endif 834#endif
968 } 835 }
836 return 0;
969} 837}
838__initcall(fast_timer_init);