• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * linux/arch/cris/kernel/fasttimer.c
3  *
4  * Fast timers for ETRAX100/ETRAX100LX
5  *
6  * Copyright (C) 2000-2007 Axis Communications AB, Lund, Sweden
7  */
8 
9 #include <linux/errno.h>
10 #include <linux/sched.h>
11 #include <linux/kernel.h>
12 #include <linux/param.h>
13 #include <linux/string.h>
14 #include <linux/mm.h>
15 #include <linux/vmalloc.h>
16 #include <linux/interrupt.h>
17 #include <linux/time.h>
18 #include <linux/delay.h>
19 
20 #include <asm/segment.h>
21 #include <asm/io.h>
22 #include <asm/irq.h>
23 #include <asm/delay.h>
24 
25 #include <arch/svinto.h>
26 #include <asm/fasttimer.h>
27 #include <linux/proc_fs.h>
28 #include <linux/seq_file.h>
29 
30 
31 #define DEBUG_LOG_INCLUDED
32 #define FAST_TIMER_LOG
33 /* #define FAST_TIMER_TEST */
34 
35 #define FAST_TIMER_SANITY_CHECKS
36 
37 #ifdef FAST_TIMER_SANITY_CHECKS
38 static int sanity_failed;
39 #endif
40 
41 #define D1(x)
42 #define D2(x)
43 #define DP(x)
44 
45 static unsigned int fast_timer_running;
46 static unsigned int fast_timers_added;
47 static unsigned int fast_timers_started;
48 static unsigned int fast_timers_expired;
49 static unsigned int fast_timers_deleted;
50 static unsigned int fast_timer_is_init;
51 static unsigned int fast_timer_ints;
52 
53 struct fast_timer *fast_timer_list = NULL;
54 
55 #ifdef DEBUG_LOG_INCLUDED
56 #define DEBUG_LOG_MAX 128
57 static const char * debug_log_string[DEBUG_LOG_MAX];
58 static unsigned long debug_log_value[DEBUG_LOG_MAX];
59 static unsigned int debug_log_cnt;
60 static unsigned int debug_log_cnt_wrapped;
61 
62 #define DEBUG_LOG(string, value) \
63 { \
64   unsigned long log_flags; \
65   local_irq_save(log_flags); \
66   debug_log_string[debug_log_cnt] = (string); \
67   debug_log_value[debug_log_cnt] = (unsigned long)(value); \
68   if (++debug_log_cnt >= DEBUG_LOG_MAX) \
69   { \
70     debug_log_cnt = debug_log_cnt % DEBUG_LOG_MAX; \
71     debug_log_cnt_wrapped = 1; \
72   } \
73   local_irq_restore(log_flags); \
74 }
75 #else
76 #define DEBUG_LOG(string, value)
77 #endif
78 
79 
80 /* The frequencies for index = clkselx number in R_TIMER_CTRL */
81 #define NUM_TIMER_FREQ 15
82 #define MAX_USABLE_TIMER_FREQ 7
83 #define MAX_DELAY_US  853333L
84 const unsigned long timer_freq_100[NUM_TIMER_FREQ] =
85 {
86   3,   /* 0 3333 - 853333 us */
87   6,   /* 1 1666 - 426666 us */
88   12,  /* 2  833 - 213333 us */
89   24,  /* 3  416 - 106666 us */
90   48,  /* 4  208 -  53333 us */
91   96,  /* 5  104 -  26666 us */
92   192, /* 6   52 -  13333 us */
93   384, /* 7   26 -   6666 us */
94   576,
95   1152,
96   2304,
97   4608,
98   9216,
99   18432,
100   62500,
101   /* 15 = cascade */
102 };
103 #define NUM_TIMER_STATS 16
104 #ifdef FAST_TIMER_LOG
105 struct fast_timer timer_added_log[NUM_TIMER_STATS];
106 struct fast_timer timer_started_log[NUM_TIMER_STATS];
107 struct fast_timer timer_expired_log[NUM_TIMER_STATS];
108 #endif
109 
110 int timer_div_settings[NUM_TIMER_STATS];
111 int timer_freq_settings[NUM_TIMER_STATS];
112 int timer_delay_settings[NUM_TIMER_STATS];
113 
114 /* Not true gettimeofday, only checks the jiffies (uptime) + useconds */
do_gettimeofday_fast(struct fasttime_t * tv)115 inline void do_gettimeofday_fast(struct fasttime_t *tv)
116 {
117 	tv->tv_jiff = jiffies;
118 	tv->tv_usec = GET_JIFFIES_USEC();
119 }
120 
fasttime_cmp(struct fasttime_t * t0,struct fasttime_t * t1)121 inline int fasttime_cmp(struct fasttime_t *t0, struct fasttime_t *t1)
122 {
123 	/* Compare jiffies. Takes care of wrapping */
124 	if (time_before(t0->tv_jiff, t1->tv_jiff))
125 		return -1;
126 	else if (time_after(t0->tv_jiff, t1->tv_jiff))
127 		return 1;
128 
129 	/* Compare us */
130 	if (t0->tv_usec < t1->tv_usec)
131 		return -1;
132 	else if (t0->tv_usec > t1->tv_usec)
133 		return 1;
134 	return 0;
135 }
136 
start_timer1(unsigned long delay_us)137 inline void start_timer1(unsigned long delay_us)
138 {
139   int freq_index = 0; /* This is the lowest resolution */
140   unsigned long upper_limit = MAX_DELAY_US;
141 
142   unsigned long div;
143   /* Start/Restart the timer to the new shorter value */
144   /* t = 1/freq = 1/19200 = 53us
145    * T=div*t,  div = T/t = delay_us*freq/1000000
146    */
147 #if 1 /* Adaptive timer settings */
148   while (delay_us < upper_limit && freq_index < MAX_USABLE_TIMER_FREQ)
149   {
150     freq_index++;
151     upper_limit >>= 1; /* Divide by 2 using shift */
152   }
153   if (freq_index > 0)
154   {
155     freq_index--;
156   }
157 #else
158   freq_index = 6;
159 #endif
160   div = delay_us * timer_freq_100[freq_index]/10000;
161   if (div < 2)
162   {
163     /* Maybe increase timer freq? */
164     div = 2;
165   }
166   if (div > 255)
167   {
168     div = 0; /* This means 256, the max the timer takes */
169     /* If a longer timeout than the timer can handle is used,
170      * then we must restart it when it goes off.
171      */
172   }
173 
174   timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = div;
175   timer_freq_settings[fast_timers_started % NUM_TIMER_STATS] = freq_index;
176   timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us;
177 
178 	D1(printk(KERN_DEBUG "start_timer1 : %d us freq: %i div: %i\n",
179             delay_us, freq_index, div));
180   /* Clear timer1 irq */
181   *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr);
182 
183   /* Set timer values */
184   *R_TIMER_CTRL = r_timer_ctrl_shadow =
185     (r_timer_ctrl_shadow &
186      ~IO_MASK(R_TIMER_CTRL, timerdiv1) &
187      ~IO_MASK(R_TIMER_CTRL, tm1) &
188      ~IO_MASK(R_TIMER_CTRL, clksel1)) |
189     IO_FIELD(R_TIMER_CTRL, timerdiv1, div) |
190     IO_STATE(R_TIMER_CTRL, tm1, stop_ld) |
191     IO_FIELD(R_TIMER_CTRL, clksel1, freq_index ); /* 6=c19k2Hz */
192 
193   /* Ack interrupt */
194   *R_TIMER_CTRL =  r_timer_ctrl_shadow |
195     IO_STATE(R_TIMER_CTRL, i1, clr);
196 
197   /* Start timer */
198   *R_TIMER_CTRL = r_timer_ctrl_shadow =
199     (r_timer_ctrl_shadow & ~IO_MASK(R_TIMER_CTRL, tm1)) |
200     IO_STATE(R_TIMER_CTRL, tm1, run);
201 
202   /* Enable timer1 irq */
203   *R_IRQ_MASK0_SET = IO_STATE(R_IRQ_MASK0_SET, timer1, set);
204   fast_timers_started++;
205   fast_timer_running = 1;
206 }
207 
208 /* In version 1.4 this function takes 27 - 50 us */
start_one_shot_timer(struct fast_timer * t,fast_timer_function_type * function,unsigned long data,unsigned long delay_us,const char * name)209 void start_one_shot_timer(struct fast_timer *t,
210                           fast_timer_function_type *function,
211                           unsigned long data,
212                           unsigned long delay_us,
213                           const char *name)
214 {
215   unsigned long flags;
216   struct fast_timer *tmp;
217 
218   D1(printk("sft %s %d us\n", name, delay_us));
219 
220   local_irq_save(flags);
221 
222   do_gettimeofday_fast(&t->tv_set);
223   tmp = fast_timer_list;
224 
225 #ifdef FAST_TIMER_SANITY_CHECKS
226 	/* Check so this is not in the list already... */
227 	while (tmp != NULL) {
228 		if (tmp == t) {
229 			printk(KERN_WARNING "timer name: %s data: "
230 				"0x%08lX already in list!\n", name, data);
231 			sanity_failed++;
232 			goto done;
233 		} else
234 			tmp = tmp->next;
235 	}
236 	tmp = fast_timer_list;
237 #endif
238 
239   t->delay_us = delay_us;
240   t->function = function;
241   t->data = data;
242   t->name = name;
243 
244   t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000;
245 	t->tv_expires.tv_jiff = t->tv_set.tv_jiff + delay_us / 1000000 / HZ;
246   if (t->tv_expires.tv_usec > 1000000)
247   {
248     t->tv_expires.tv_usec -= 1000000;
249 		t->tv_expires.tv_jiff += HZ;
250   }
251 #ifdef FAST_TIMER_LOG
252   timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t;
253 #endif
254   fast_timers_added++;
255 
256   /* Check if this should timeout before anything else */
257 	if (tmp == NULL || fasttime_cmp(&t->tv_expires, &tmp->tv_expires) < 0)
258   {
259     /* Put first in list and modify the timer value */
260     t->prev = NULL;
261     t->next = fast_timer_list;
262     if (fast_timer_list)
263     {
264       fast_timer_list->prev = t;
265     }
266     fast_timer_list = t;
267 #ifdef FAST_TIMER_LOG
268     timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
269 #endif
270     start_timer1(delay_us);
271   } else {
272     /* Put in correct place in list */
273 		while (tmp->next && fasttime_cmp(&t->tv_expires,
274 				&tmp->next->tv_expires) > 0)
275     {
276       tmp = tmp->next;
277     }
278     /* Insert t after tmp */
279     t->prev = tmp;
280     t->next = tmp->next;
281     if (tmp->next)
282     {
283       tmp->next->prev = t;
284     }
285     tmp->next = t;
286   }
287 
288   D2(printk("start_one_shot_timer: %d us done\n", delay_us));
289 
290 done:
291   local_irq_restore(flags);
292 } /* start_one_shot_timer */
293 
fast_timer_pending(const struct fast_timer * t)294 static inline int fast_timer_pending (const struct fast_timer * t)
295 {
296   return (t->next != NULL) || (t->prev != NULL) || (t == fast_timer_list);
297 }
298 
detach_fast_timer(struct fast_timer * t)299 static inline int detach_fast_timer (struct fast_timer *t)
300 {
301   struct fast_timer *next, *prev;
302   if (!fast_timer_pending(t))
303     return 0;
304   next = t->next;
305   prev = t->prev;
306   if (next)
307     next->prev = prev;
308   if (prev)
309     prev->next = next;
310   else
311     fast_timer_list = next;
312   fast_timers_deleted++;
313   return 1;
314 }
315 
del_fast_timer(struct fast_timer * t)316 int del_fast_timer(struct fast_timer * t)
317 {
318   unsigned long flags;
319   int ret;
320 
321   local_irq_save(flags);
322   ret = detach_fast_timer(t);
323   t->next = t->prev = NULL;
324   local_irq_restore(flags);
325   return ret;
326 } /* del_fast_timer */
327 
328 
329 /* Interrupt routines or functions called in interrupt context */
330 
331 /* Timer 1 interrupt handler */
332 
333 static irqreturn_t
timer1_handler(int irq,void * dev_id)334 timer1_handler(int irq, void *dev_id)
335 {
336   struct fast_timer *t;
337   unsigned long flags;
338 
339 	/* We keep interrupts disabled not only when we modify the
340 	 * fast timer list, but any time we hold a reference to a
341 	 * timer in the list, since del_fast_timer may be called
342 	 * from (another) interrupt context.  Thus, the only time
343 	 * when interrupts are enabled is when calling the timer
344 	 * callback function.
345 	 */
346   local_irq_save(flags);
347 
348   /* Clear timer1 irq */
349   *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr);
350 
351   /* First stop timer, then ack interrupt */
352   /* Stop timer */
353   *R_TIMER_CTRL = r_timer_ctrl_shadow =
354     (r_timer_ctrl_shadow & ~IO_MASK(R_TIMER_CTRL, tm1)) |
355     IO_STATE(R_TIMER_CTRL, tm1, stop_ld);
356 
357   /* Ack interrupt */
358   *R_TIMER_CTRL =  r_timer_ctrl_shadow | IO_STATE(R_TIMER_CTRL, i1, clr);
359 
360   fast_timer_running = 0;
361   fast_timer_ints++;
362 
363   t = fast_timer_list;
364   while (t)
365   {
366 		struct fasttime_t tv;
367 		fast_timer_function_type *f;
368 		unsigned long d;
369 
370     /* Has it really expired? */
371     do_gettimeofday_fast(&tv);
372 		D1(printk(KERN_DEBUG "t: %is %06ius\n",
373 			tv.tv_jiff, tv.tv_usec));
374 
375 		if (fasttime_cmp(&t->tv_expires, &tv) <= 0)
376     {
377       /* Yes it has expired */
378 #ifdef FAST_TIMER_LOG
379       timer_expired_log[fast_timers_expired % NUM_TIMER_STATS] = *t;
380 #endif
381       fast_timers_expired++;
382 
383       /* Remove this timer before call, since it may reuse the timer */
384       if (t->prev)
385       {
386         t->prev->next = t->next;
387       }
388       else
389       {
390         fast_timer_list = t->next;
391       }
392       if (t->next)
393       {
394         t->next->prev = t->prev;
395       }
396       t->prev = NULL;
397       t->next = NULL;
398 
399 			/* Save function callback data before enabling
400 			 * interrupts, since the timer may be removed and
401 			 * we don't know how it was allocated
402 			 * (e.g. ->function and ->data may become overwritten
403 			 * after deletion if the timer was stack-allocated).
404 			 */
405 			f = t->function;
406 			d = t->data;
407 
408 			if (f != NULL) {
409 				/* Run callback with interrupts enabled. */
410 				local_irq_restore(flags);
411 				f(d);
412 				local_irq_save(flags);
413 			} else
414         DEBUG_LOG("!timer1 %i function==NULL!\n", fast_timer_ints);
415     }
416     else
417     {
418       /* Timer is to early, let's set it again using the normal routines */
419       D1(printk(".\n"));
420     }
421 
422     if ((t = fast_timer_list) != NULL)
423     {
424       /* Start next timer.. */
425 			long us = 0;
426 			struct fasttime_t tv;
427 
428       do_gettimeofday_fast(&tv);
429 
430 			/* time_after_eq takes care of wrapping */
431 			if (time_after_eq(t->tv_expires.tv_jiff, tv.tv_jiff))
432 				us = ((t->tv_expires.tv_jiff - tv.tv_jiff) *
433 					1000000 / HZ + t->tv_expires.tv_usec -
434 					tv.tv_usec);
435 
436       if (us > 0)
437       {
438         if (!fast_timer_running)
439         {
440 #ifdef FAST_TIMER_LOG
441           timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
442 #endif
443           start_timer1(us);
444         }
445         break;
446       }
447       else
448       {
449         /* Timer already expired, let's handle it better late than never.
450          * The normal loop handles it
451          */
452         D1(printk("e! %d\n", us));
453       }
454     }
455   }
456 
457 	local_irq_restore(flags);
458 
459   if (!t)
460   {
461     D1(printk("t1 stop!\n"));
462   }
463 
464   return IRQ_HANDLED;
465 }
466 
wake_up_func(unsigned long data)467 static void wake_up_func(unsigned long data)
468 {
469   wait_queue_head_t *sleep_wait_p = (wait_queue_head_t *)data;
470   wake_up(sleep_wait_p);
471 }
472 
473 
474 /* Useful API */
475 
schedule_usleep(unsigned long us)476 void schedule_usleep(unsigned long us)
477 {
478   struct fast_timer t;
479   wait_queue_head_t sleep_wait;
480   init_waitqueue_head(&sleep_wait);
481 
482   D1(printk("schedule_usleep(%d)\n", us));
483   start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us,
484                        "usleep");
485 	/* Uninterruptible sleep on the fast timer. (The condition is somewhat
486 	 * redundant since the timer is what wakes us up.) */
487 	wait_event(sleep_wait, !fast_timer_pending(&t));
488 
489   D1(printk("done schedule_usleep(%d)\n", us));
490 }
491 
492 #ifdef CONFIG_PROC_FS
493 /* This value is very much based on testing */
494 #define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300)
495 
proc_fasttimer_show(struct seq_file * m,void * v)496 static int proc_fasttimer_show(struct seq_file *m, void *v)
497 {
498 	unsigned long flags;
499 	int i = 0;
500 	int num_to_show;
501 	struct fasttime_t tv;
502 	struct fast_timer *t, *nextt;
503 
504 	do_gettimeofday_fast(&tv);
505 
506 	seq_printf(m, "Fast timers added:     %i\n", fast_timers_added);
507 	seq_printf(m, "Fast timers started:   %i\n", fast_timers_started);
508 	seq_printf(m, "Fast timer interrupts: %i\n", fast_timer_ints);
509 	seq_printf(m, "Fast timers expired:   %i\n", fast_timers_expired);
510 	seq_printf(m, "Fast timers deleted:   %i\n", fast_timers_deleted);
511 	seq_printf(m, "Fast timer running:    %s\n",
512 		   fast_timer_running ? "yes" : "no");
513 	seq_printf(m, "Current time:          %lu.%06lu\n",
514 		   (unsigned long)tv.tv_jiff,
515 		   (unsigned long)tv.tv_usec);
516 #ifdef FAST_TIMER_SANITY_CHECKS
517 	seq_printf(m, "Sanity failed:         %i\n", sanity_failed);
518 #endif
519 	seq_putc(m, '\n');
520 
521 #ifdef DEBUG_LOG_INCLUDED
522 	{
523 		int end_i = debug_log_cnt;
524 		i = 0;
525 
526 		if (debug_log_cnt_wrapped)
527 			i = debug_log_cnt;
528 
529 		while (i != end_i || debug_log_cnt_wrapped) {
530 			if (seq_printf(m, debug_log_string[i], debug_log_value[i]) < 0)
531 				return 0;
532 			i = (i+1) % DEBUG_LOG_MAX;
533 		}
534 	}
535 	seq_putc(m, '\n');
536 #endif
537 
538 	num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started:
539 		       NUM_TIMER_STATS);
540 	seq_printf(m, "Timers started: %i\n", fast_timers_started);
541 	for (i = 0; i < num_to_show; i++) {
542 		int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS;
543 
544 #if 1 //ndef FAST_TIMER_LOG
545 		seq_printf(m, "div: %i freq: %i delay: %i"
546 			   "\n",
547 			   timer_div_settings[cur],
548 			   timer_freq_settings[cur],
549 			   timer_delay_settings[cur]);
550 #endif
551 #ifdef FAST_TIMER_LOG
552 		t = &timer_started_log[cur];
553 		if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
554 			       "d: %6li us data: 0x%08lX"
555 			       "\n",
556 			       t->name,
557 			       (unsigned long)t->tv_set.tv_jiff,
558 			       (unsigned long)t->tv_set.tv_usec,
559 			       (unsigned long)t->tv_expires.tv_jiff,
560 			       (unsigned long)t->tv_expires.tv_usec,
561 			       t->delay_us,
562 			       t->data) < 0)
563 			return 0;
564 #endif
565 	}
566 	seq_putc(m, '\n');
567 
568 #ifdef FAST_TIMER_LOG
569 	num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added:
570 		       NUM_TIMER_STATS);
571 	seq_printf(m, "Timers added: %i\n", fast_timers_added);
572 	for (i = 0; i < num_to_show; i++) {
573 		t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS];
574 		if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
575 			       "d: %6li us data: 0x%08lX"
576 			       "\n",
577 			       t->name,
578 			       (unsigned long)t->tv_set.tv_jiff,
579 			       (unsigned long)t->tv_set.tv_usec,
580 			       (unsigned long)t->tv_expires.tv_jiff,
581 			       (unsigned long)t->tv_expires.tv_usec,
582 			       t->delay_us,
583 			       t->data) < 0)
584 			return 0;
585 	}
586 	seq_putc(m, '\n');
587 
588 	num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired:
589 		       NUM_TIMER_STATS);
590 	seq_printf(m, "Timers expired: %i\n", fast_timers_expired);
591 	for (i = 0; i < num_to_show; i++) {
592 		t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS];
593 		if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
594 			       "d: %6li us data: 0x%08lX"
595 			       "\n",
596 			       t->name,
597 			       (unsigned long)t->tv_set.tv_jiff,
598 			       (unsigned long)t->tv_set.tv_usec,
599 			       (unsigned long)t->tv_expires.tv_jiff,
600 			       (unsigned long)t->tv_expires.tv_usec,
601 			       t->delay_us,
602 			       t->data) < 0)
603 			return 0;
604 	}
605 	seq_putc(m, '\n');
606 #endif
607 
608 	seq_puts(m, "Active timers:\n");
609 	local_irq_save(flags);
610 	t = fast_timer_list;
611 	while (t) {
612 		nextt = t->next;
613 		local_irq_restore(flags);
614 		if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
615 			       "d: %6li us data: 0x%08lX"
616 /*                      " func: 0x%08lX" */
617 			       "\n",
618 			       t->name,
619 			       (unsigned long)t->tv_set.tv_jiff,
620 			       (unsigned long)t->tv_set.tv_usec,
621 			       (unsigned long)t->tv_expires.tv_jiff,
622 			       (unsigned long)t->tv_expires.tv_usec,
623 			       t->delay_us,
624 			       t->data
625 /*                      , t->function */
626 			       ) < 0)
627 			return 0;
628 		local_irq_save(flags);
629 		if (t->next != nextt)
630 			printk(KERN_WARNING "timer removed!\n");
631 		t = nextt;
632 	}
633 	local_irq_restore(flags);
634 
635 	return 0;
636 }
637 
proc_fasttimer_open(struct inode * inode,struct file * file)638 static int proc_fasttimer_open(struct inode *inode, struct file *file)
639 {
640 	return single_open_size(file, proc_fasttimer_show, PDE_DATA(inode), BIG_BUF_SIZE);
641 }
642 
643 static const struct file_operations proc_fasttimer_fops = {
644 	.open		= proc_fasttimer_open,
645 	.read		= seq_read,
646 	.llseek		= seq_lseek,
647 	.release	= single_release,
648 };
649 #endif /* PROC_FS */
650 
651 #ifdef FAST_TIMER_TEST
652 static volatile unsigned long i = 0;
653 static volatile int num_test_timeout = 0;
654 static struct fast_timer tr[10];
655 static int exp_num[10];
656 
657 static struct fasttime_t tv_exp[100];
658 
test_timeout(unsigned long data)659 static void test_timeout(unsigned long data)
660 {
661   do_gettimeofday_fast(&tv_exp[data]);
662   exp_num[data] = num_test_timeout;
663 
664   num_test_timeout++;
665 }
666 
test_timeout1(unsigned long data)667 static void test_timeout1(unsigned long data)
668 {
669   do_gettimeofday_fast(&tv_exp[data]);
670   exp_num[data] = num_test_timeout;
671   if (data < 7)
672   {
673     start_one_shot_timer(&tr[i], test_timeout1, i, 1000, "timeout1");
674     i++;
675   }
676   num_test_timeout++;
677 }
678 
679 DP(
680 static char buf0[2000];
681 static char buf1[2000];
682 static char buf2[2000];
683 static char buf3[2000];
684 static char buf4[2000];
685 );
686 
687 static char buf5[6000];
688 static int j_u[1000];
689 
fast_timer_test(void)690 static void fast_timer_test(void)
691 {
692   int prev_num;
693   int j;
694 
695 	struct fasttime_t tv, tv0, tv1, tv2;
696 
697   printk("fast_timer_test() start\n");
698   do_gettimeofday_fast(&tv);
699 
700   for (j = 0; j < 1000; j++)
701   {
702     j_u[j] = GET_JIFFIES_USEC();
703   }
704   for (j = 0; j < 100; j++)
705   {
706     do_gettimeofday_fast(&tv_exp[j]);
707   }
708 	printk(KERN_DEBUG "fast_timer_test() %is %06i\n",
709 		tv.tv_jiff, tv.tv_usec);
710 
711   for (j = 0; j < 1000; j++)
712   {
713     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]);
714     j += 4;
715   }
716   for (j = 0; j < 100; j++)
717   {
718 		printk(KERN_DEBUG "%i.%i %i.%i %i.%i %i.%i %i.%i\n",
719 			tv_exp[j].tv_jiff, tv_exp[j].tv_usec,
720 			tv_exp[j+1].tv_jiff, tv_exp[j+1].tv_usec,
721 			tv_exp[j+2].tv_jiff, tv_exp[j+2].tv_usec,
722 			tv_exp[j+3].tv_jiff, tv_exp[j+3].tv_usec,
723 			tv_exp[j+4].tv_jiff, tv_exp[j+4].tv_usec);
724     j += 4;
725   }
726   do_gettimeofday_fast(&tv0);
727   start_one_shot_timer(&tr[i], test_timeout, i, 50000, "test0");
728   DP(proc_fasttimer_read(buf0, NULL, 0, 0, 0));
729   i++;
730   start_one_shot_timer(&tr[i], test_timeout, i, 70000, "test1");
731   DP(proc_fasttimer_read(buf1, NULL, 0, 0, 0));
732   i++;
733   start_one_shot_timer(&tr[i], test_timeout, i, 40000, "test2");
734   DP(proc_fasttimer_read(buf2, NULL, 0, 0, 0));
735   i++;
736   start_one_shot_timer(&tr[i], test_timeout, i, 60000, "test3");
737   DP(proc_fasttimer_read(buf3, NULL, 0, 0, 0));
738   i++;
739   start_one_shot_timer(&tr[i], test_timeout1, i, 55000, "test4xx");
740   DP(proc_fasttimer_read(buf4, NULL, 0, 0, 0));
741   i++;
742   do_gettimeofday_fast(&tv1);
743 
744   proc_fasttimer_read(buf5, NULL, 0, 0, 0);
745 
746   prev_num = num_test_timeout;
747   while (num_test_timeout < i)
748   {
749     if (num_test_timeout != prev_num)
750     {
751       prev_num = num_test_timeout;
752     }
753   }
754   do_gettimeofday_fast(&tv2);
755 	printk(KERN_DEBUG "Timers started    %is %06i\n",
756 		tv0.tv_jiff, tv0.tv_usec);
757 	printk(KERN_DEBUG "Timers started at %is %06i\n",
758 		tv1.tv_jiff, tv1.tv_usec);
759 	printk(KERN_DEBUG "Timers done       %is %06i\n",
760 		tv2.tv_jiff, tv2.tv_usec);
761   DP(printk("buf0:\n");
762      printk(buf0);
763      printk("buf1:\n");
764      printk(buf1);
765      printk("buf2:\n");
766      printk(buf2);
767      printk("buf3:\n");
768      printk(buf3);
769      printk("buf4:\n");
770      printk(buf4);
771   );
772   printk("buf5:\n");
773   printk(buf5);
774 
775   printk("timers set:\n");
776   for(j = 0; j<i; j++)
777   {
778     struct fast_timer *t = &tr[j];
779     printk("%-10s set: %6is %06ius exp: %6is %06ius "
780            "data: 0x%08X func: 0x%08X\n",
781            t->name,
782 			t->tv_set.tv_jiff,
783            t->tv_set.tv_usec,
784 			t->tv_expires.tv_jiff,
785            t->tv_expires.tv_usec,
786            t->data,
787            t->function
788            );
789 
790     printk("           del: %6ius     did exp: %6is %06ius as #%i error: %6li\n",
791            t->delay_us,
792 			tv_exp[j].tv_jiff,
793            tv_exp[j].tv_usec,
794            exp_num[j],
795 			(tv_exp[j].tv_jiff - t->tv_expires.tv_jiff) *
796 				1000000 + tv_exp[j].tv_usec -
797 				t->tv_expires.tv_usec);
798   }
799   proc_fasttimer_read(buf5, NULL, 0, 0, 0);
800   printk("buf5 after all done:\n");
801   printk(buf5);
802   printk("fast_timer_test() done\n");
803 }
804 #endif
805 
806 
fast_timer_init(void)807 int fast_timer_init(void)
808 {
809   /* For some reason, request_irq() hangs when called froom time_init() */
810   if (!fast_timer_is_init)
811   {
812 #if 0 && defined(FAST_TIMER_TEST)
813     int i;
814 #endif
815 
816     printk(KERN_INFO "fast_timer_init()\n");
817 
818 #if 0 && defined(FAST_TIMER_TEST)
819     for (i = 0; i <= TIMER0_DIV; i++)
820     {
821       /* We must be careful not to get overflow... */
822       printk("%3i %6u\n", i, timer0_value_us[i]);
823     }
824 #endif
825 #ifdef CONFIG_PROC_FS
826    proc_create("fasttimer", 0, NULL, &proc_fasttimer_fops);
827 #endif /* PROC_FS */
828     if(request_irq(TIMER1_IRQ_NBR, timer1_handler, 0,
829                    "fast timer int", NULL))
830     {
831       printk("err: timer1 irq\n");
832     }
833     fast_timer_is_init = 1;
834 #ifdef FAST_TIMER_TEST
835     printk("do test\n");
836     fast_timer_test();
837 #endif
838   }
839 	return 0;
840 }
841 __initcall(fast_timer_init);
842