1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97#include <linux/errno.h>
98#include <linux/sched.h>
99#include <linux/kernel.h>
100#include <linux/param.h>
101#include <linux/string.h>
102#include <linux/mm.h>
103#include <linux/vmalloc.h>
104#include <linux/interrupt.h>
105#include <linux/time.h>
106#include <linux/delay.h>
107
108#include <asm/segment.h>
109#include <asm/io.h>
110#include <asm/irq.h>
111#include <asm/delay.h>
112#include <asm/rtc.h>
113
114
115#include <asm/arch/svinto.h>
116#include <asm/fasttimer.h>
117#include <linux/proc_fs.h>
118
119
120#define DEBUG_LOG_INCLUDED
121#define FAST_TIMER_LOG
122
123
124#define FAST_TIMER_SANITY_CHECKS
125
126#ifdef FAST_TIMER_SANITY_CHECKS
127#define SANITYCHECK(x) x
128static int sanity_failed = 0;
129#else
130#define SANITYCHECK(x)
131#endif
132
133#define D1(x)
134#define D2(x)
135#define DP(x)
136
137#define __INLINE__ inline
138
139static int fast_timer_running = 0;
140static int fast_timers_added = 0;
141static int fast_timers_started = 0;
142static int fast_timers_expired = 0;
143static int fast_timers_deleted = 0;
144static int fast_timer_is_init = 0;
145static int fast_timer_ints = 0;
146
147struct fast_timer *fast_timer_list = NULL;
148
149#ifdef DEBUG_LOG_INCLUDED
150#define DEBUG_LOG_MAX 128
151static const char * debug_log_string[DEBUG_LOG_MAX];
152static unsigned long debug_log_value[DEBUG_LOG_MAX];
153static int debug_log_cnt = 0;
154static int debug_log_cnt_wrapped = 0;
155
156#define DEBUG_LOG(string, value) \
157{ \
158 unsigned long log_flags; \
159 local_irq_save(log_flags); \
160 debug_log_string[debug_log_cnt] = (string); \
161 debug_log_value[debug_log_cnt] = (unsigned long)(value); \
162 if (++debug_log_cnt >= DEBUG_LOG_MAX) \
163 { \
164 debug_log_cnt = debug_log_cnt % DEBUG_LOG_MAX; \
165 debug_log_cnt_wrapped = 1; \
166 } \
167 local_irq_restore(log_flags); \
168}
169#else
170#define DEBUG_LOG(string, value)
171#endif
172
173
174
175#define NUM_TIMER_FREQ 15
176#define MAX_USABLE_TIMER_FREQ 7
177#define MAX_DELAY_US 853333L
178const unsigned long timer_freq_100[NUM_TIMER_FREQ] =
179{
180 3,
181 6,
182 12,
183 24,
184 48,
185 96,
186 192,
187 384,
188 576,
189 1152,
190 2304,
191 4608,
192 9216,
193 18432,
194 62500,
195
196};
197#define NUM_TIMER_STATS 16
198#ifdef FAST_TIMER_LOG
199struct fast_timer timer_added_log[NUM_TIMER_STATS];
200struct fast_timer timer_started_log[NUM_TIMER_STATS];
201struct fast_timer timer_expired_log[NUM_TIMER_STATS];
202#endif
203
204int timer_div_settings[NUM_TIMER_STATS];
205int timer_freq_settings[NUM_TIMER_STATS];
206int timer_delay_settings[NUM_TIMER_STATS];
207
208
209void __INLINE__ do_gettimeofday_fast(struct timeval *tv)
210{
211 unsigned long sec = jiffies;
212 unsigned long usec = GET_JIFFIES_USEC();
213
214 usec += (sec % HZ) * (1000000 / HZ);
215 sec = sec / HZ;
216
217 if (usec > 1000000)
218 {
219 usec -= 1000000;
220 sec++;
221 }
222 tv->tv_sec = sec;
223 tv->tv_usec = usec;
224}
225
226int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1)
227{
228 if (t0->tv_sec < t1->tv_sec)
229 {
230 return -1;
231 }
232 else if (t0->tv_sec > t1->tv_sec)
233 {
234 return 1;
235 }
236 if (t0->tv_usec < t1->tv_usec)
237 {
238 return -1;
239 }
240 else if (t0->tv_usec > t1->tv_usec)
241 {
242 return 1;
243 }
244 return 0;
245}
246
247void __INLINE__ start_timer1(unsigned long delay_us)
248{
249 int freq_index = 0;
250 unsigned long upper_limit = MAX_DELAY_US;
251
252 unsigned long div;
253
254
255
256
257#if 1
258 while (delay_us < upper_limit && freq_index < MAX_USABLE_TIMER_FREQ)
259 {
260 freq_index++;
261 upper_limit >>= 1;
262 }
263 if (freq_index > 0)
264 {
265 freq_index--;
266 }
267#else
268 freq_index = 6;
269#endif
270 div = delay_us * timer_freq_100[freq_index]/10000;
271 if (div < 2)
272 {
273
274 div = 2;
275 }
276 if (div > 255)
277 {
278 div = 0;
279
280
281
282 }
283
284 timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = div;
285 timer_freq_settings[fast_timers_started % NUM_TIMER_STATS] = freq_index;
286 timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us;
287
288 D1(printk("start_timer1 : %d us freq: %i div: %i\n",
289 delay_us, freq_index, div));
290
291 *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr);
292
293
294 *R_TIMER_CTRL = r_timer_ctrl_shadow =
295 (r_timer_ctrl_shadow &
296 ~IO_MASK(R_TIMER_CTRL, timerdiv1) &
297 ~IO_MASK(R_TIMER_CTRL, tm1) &
298 ~IO_MASK(R_TIMER_CTRL, clksel1)) |
299 IO_FIELD(R_TIMER_CTRL, timerdiv1, div) |
300 IO_STATE(R_TIMER_CTRL, tm1, stop_ld) |
301 IO_FIELD(R_TIMER_CTRL, clksel1, freq_index );
302
303
304 *R_TIMER_CTRL = r_timer_ctrl_shadow |
305 IO_STATE(R_TIMER_CTRL, i1, clr);
306
307
308 *R_TIMER_CTRL = r_timer_ctrl_shadow =
309 (r_timer_ctrl_shadow & ~IO_MASK(R_TIMER_CTRL, tm1)) |
310 IO_STATE(R_TIMER_CTRL, tm1, run);
311
312
313 *R_IRQ_MASK0_SET = IO_STATE(R_IRQ_MASK0_SET, timer1, set);
314 fast_timers_started++;
315 fast_timer_running = 1;
316}
317
318
319void start_one_shot_timer(struct fast_timer *t,
320 fast_timer_function_type *function,
321 unsigned long data,
322 unsigned long delay_us,
323 const char *name)
324{
325 unsigned long flags;
326 struct fast_timer *tmp;
327
328 D1(printk("sft %s %d us\n", name, delay_us));
329
330 local_irq_save(flags);
331
332 do_gettimeofday_fast(&t->tv_set);
333 tmp = fast_timer_list;
334
335 SANITYCHECK({
336 while (tmp != NULL)
337 {
338 if (tmp == t)
339 {
340 printk(KERN_WARNING
341 "timer name: %s data: 0x%08lX already in list!\n", name, data);
342 sanity_failed++;
343 return;
344 }
345 else
346 {
347 tmp = tmp->next;
348 }
349 }
350 tmp = fast_timer_list;
351 });
352
353 t->delay_us = delay_us;
354 t->function = function;
355 t->data = data;
356 t->name = name;
357
358 t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000;
359 t->tv_expires.tv_sec = t->tv_set.tv_sec + delay_us / 1000000;
360 if (t->tv_expires.tv_usec > 1000000)
361 {
362 t->tv_expires.tv_usec -= 1000000;
363 t->tv_expires.tv_sec++;
364 }
365#ifdef FAST_TIMER_LOG
366 timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t;
367#endif
368 fast_timers_added++;
369
370
371 if (tmp == NULL || timeval_cmp(&t->tv_expires, &tmp->tv_expires) < 0)
372 {
373
374 t->prev = NULL;
375 t->next = fast_timer_list;
376 if (fast_timer_list)
377 {
378 fast_timer_list->prev = t;
379 }
380 fast_timer_list = t;
381#ifdef FAST_TIMER_LOG
382 timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
383#endif
384 start_timer1(delay_us);
385 } else {
386
387 while (tmp->next &&
388 timeval_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0)
389 {
390 tmp = tmp->next;
391 }
392
393 t->prev = tmp;
394 t->next = tmp->next;
395 if (tmp->next)
396 {
397 tmp->next->prev = t;
398 }
399 tmp->next = t;
400 }
401
402 D2(printk("start_one_shot_timer: %d us done\n", delay_us));
403
404 local_irq_restore(flags);
405}
406
407static inline int fast_timer_pending (const struct fast_timer * t)
408{
409 return (t->next != NULL) || (t->prev != NULL) || (t == fast_timer_list);
410}
411
412static inline int detach_fast_timer (struct fast_timer *t)
413{
414 struct fast_timer *next, *prev;
415 if (!fast_timer_pending(t))
416 return 0;
417 next = t->next;
418 prev = t->prev;
419 if (next)
420 next->prev = prev;
421 if (prev)
422 prev->next = next;
423 else
424 fast_timer_list = next;
425 fast_timers_deleted++;
426 return 1;
427}
428
429int del_fast_timer(struct fast_timer * t)
430{
431 unsigned long flags;
432 int ret;
433
434 local_irq_save(flags);
435 ret = detach_fast_timer(t);
436 t->next = t->prev = NULL;
437 local_irq_restore(flags);
438 return ret;
439}
440
441
442
443
444
445
446static irqreturn_t
447timer1_handler(int irq, void *dev_id, struct pt_regs *regs)
448{
449 struct fast_timer *t;
450 unsigned long flags;
451
452 local_irq_save(flags);
453
454
455 *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr);
456
457
458
459 *R_TIMER_CTRL = r_timer_ctrl_shadow =
460 (r_timer_ctrl_shadow & ~IO_MASK(R_TIMER_CTRL, tm1)) |
461 IO_STATE(R_TIMER_CTRL, tm1, stop_ld);
462
463
464 *R_TIMER_CTRL = r_timer_ctrl_shadow | IO_STATE(R_TIMER_CTRL, i1, clr);
465
466 fast_timer_running = 0;
467 fast_timer_ints++;
468
469 local_irq_restore(flags);
470
471 t = fast_timer_list;
472 while (t)
473 {
474 struct timeval tv;
475
476
477 do_gettimeofday_fast(&tv);
478 D1(printk("t: %is %06ius\n", tv.tv_sec, tv.tv_usec));
479
480 if (timeval_cmp(&t->tv_expires, &tv) <= 0)
481 {
482
483#ifdef FAST_TIMER_LOG
484 timer_expired_log[fast_timers_expired % NUM_TIMER_STATS] = *t;
485#endif
486 fast_timers_expired++;
487
488
489 local_irq_save(flags);
490 if (t->prev)
491 {
492 t->prev->next = t->next;
493 }
494 else
495 {
496 fast_timer_list = t->next;
497 }
498 if (t->next)
499 {
500 t->next->prev = t->prev;
501 }
502 t->prev = NULL;
503 t->next = NULL;
504 local_irq_restore(flags);
505
506 if (t->function != NULL)
507 {
508 t->function(t->data);
509 }
510 else
511 {
512 DEBUG_LOG("!timer1 %i function==NULL!\n", fast_timer_ints);
513 }
514 }
515 else
516 {
517
518 D1(printk(".\n"));
519 }
520
521 local_irq_save(flags);
522 if ((t = fast_timer_list) != NULL)
523 {
524
525 long us;
526 struct timeval tv;
527
528 do_gettimeofday_fast(&tv);
529 us = ((t->tv_expires.tv_sec - tv.tv_sec) * 1000000 +
530 t->tv_expires.tv_usec - tv.tv_usec);
531 if (us > 0)
532 {
533 if (!fast_timer_running)
534 {
535#ifdef FAST_TIMER_LOG
536 timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
537#endif
538 start_timer1(us);
539 }
540 local_irq_restore(flags);
541 break;
542 }
543 else
544 {
545
546
547
548 D1(printk("e! %d\n", us));
549 }
550 }
551 local_irq_restore(flags);
552 }
553
554 if (!t)
555 {
556 D1(printk("t1 stop!\n"));
557 }
558
559 return IRQ_HANDLED;
560}
561
562static void wake_up_func(unsigned long data)
563{
564#ifdef DECLARE_WAITQUEUE
565 wait_queue_head_t *sleep_wait_p = (wait_queue_head_t*)data;
566#else
567 struct wait_queue **sleep_wait_p = (struct wait_queue **)data;
568#endif
569 wake_up(sleep_wait_p);
570}
571
572
573
574
575void schedule_usleep(unsigned long us)
576{
577 struct fast_timer t;
578#ifdef DECLARE_WAITQUEUE
579 wait_queue_head_t sleep_wait;
580 init_waitqueue_head(&sleep_wait);
581 {
582 DECLARE_WAITQUEUE(wait, current);
583#else
584 struct wait_queue *sleep_wait = NULL;
585 struct wait_queue wait = { current, NULL };
586#endif
587
588 D1(printk("schedule_usleep(%d)\n", us));
589 add_wait_queue(&sleep_wait, &wait);
590 set_current_state(TASK_INTERRUPTIBLE);
591 start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us,
592 "usleep");
593 schedule();
594 set_current_state(TASK_RUNNING);
595 remove_wait_queue(&sleep_wait, &wait);
596 D1(printk("done schedule_usleep(%d)\n", us));
597#ifdef DECLARE_WAITQUEUE
598 }
599#endif
600}
601
602#ifdef CONFIG_PROC_FS
603static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
604 ,int *eof, void *data_unused);
605static struct proc_dir_entry *fasttimer_proc_entry;
606#endif
607
608#ifdef CONFIG_PROC_FS
609
610
611#define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300)
612
613static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
614 ,int *eof, void *data_unused)
615{
616 unsigned long flags;
617 int i = 0;
618 int num_to_show;
619 struct timeval tv;
620 struct fast_timer *t, *nextt;
621 static char *bigbuf = NULL;
622 static unsigned long used;
623
624 if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE)))
625 {
626 used = 0;
627 bigbuf[0] = '\0';
628 return 0;
629 }
630
631 if (!offset || !used)
632 {
633 do_gettimeofday_fast(&tv);
634
635 used = 0;
636 used += sprintf(bigbuf + used, "Fast timers added: %i\n",
637 fast_timers_added);
638 used += sprintf(bigbuf + used, "Fast timers started: %i\n",
639 fast_timers_started);
640 used += sprintf(bigbuf + used, "Fast timer interrupts: %i\n",
641 fast_timer_ints);
642 used += sprintf(bigbuf + used, "Fast timers expired: %i\n",
643 fast_timers_expired);
644 used += sprintf(bigbuf + used, "Fast timers deleted: %i\n",
645 fast_timers_deleted);
646 used += sprintf(bigbuf + used, "Fast timer running: %s\n",
647 fast_timer_running ? "yes" : "no");
648 used += sprintf(bigbuf + used, "Current time: %lu.%06lu\n",
649 (unsigned long)tv.tv_sec,
650 (unsigned long)tv.tv_usec);
651#ifdef FAST_TIMER_SANITY_CHECKS
652 used += sprintf(bigbuf + used, "Sanity failed: %i\n",
653 sanity_failed);
654#endif
655 used += sprintf(bigbuf + used, "\n");
656
657#ifdef DEBUG_LOG_INCLUDED
658 {
659 int end_i = debug_log_cnt;
660 i = 0;
661
662 if (debug_log_cnt_wrapped)
663 {
664 i = debug_log_cnt;
665 }
666
667 while ((i != end_i || (debug_log_cnt_wrapped && !used)) &&
668 used+100 < BIG_BUF_SIZE)
669 {
670 used += sprintf(bigbuf + used, debug_log_string[i],
671 debug_log_value[i]);
672 i = (i+1) % DEBUG_LOG_MAX;
673 }
674 }
675 used += sprintf(bigbuf + used, "\n");
676#endif
677
678 num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started:
679 NUM_TIMER_STATS);
680 used += sprintf(bigbuf + used, "Timers started: %i\n", fast_timers_started);
681 for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE) ; i++)
682 {
683 int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS;
684
685#if 1
686 used += sprintf(bigbuf + used, "div: %i freq: %i delay: %i"
687 "\n",
688 timer_div_settings[cur],
689 timer_freq_settings[cur],
690 timer_delay_settings[cur]
691 );
692#endif
693#ifdef FAST_TIMER_LOG
694 t = &timer_started_log[cur];
695 used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
696 "d: %6li us data: 0x%08lX"
697 "\n",
698 t->name,
699 (unsigned long)t->tv_set.tv_sec,
700 (unsigned long)t->tv_set.tv_usec,
701 (unsigned long)t->tv_expires.tv_sec,
702 (unsigned long)t->tv_expires.tv_usec,
703 t->delay_us,
704 t->data
705 );
706#endif
707 }
708 used += sprintf(bigbuf + used, "\n");
709
710#ifdef FAST_TIMER_LOG
711 num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added:
712 NUM_TIMER_STATS);
713 used += sprintf(bigbuf + used, "Timers added: %i\n", fast_timers_added);
714 for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
715 {
716 t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS];
717 used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
718 "d: %6li us data: 0x%08lX"
719 "\n",
720 t->name,
721 (unsigned long)t->tv_set.tv_sec,
722 (unsigned long)t->tv_set.tv_usec,
723 (unsigned long)t->tv_expires.tv_sec,
724 (unsigned long)t->tv_expires.tv_usec,
725 t->delay_us,
726 t->data
727 );
728 }
729 used += sprintf(bigbuf + used, "\n");
730
731 num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired:
732 NUM_TIMER_STATS);
733 used += sprintf(bigbuf + used, "Timers expired: %i\n", fast_timers_expired);
734 for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
735 {
736 t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS];
737 used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
738 "d: %6li us data: 0x%08lX"
739 "\n",
740 t->name,
741 (unsigned long)t->tv_set.tv_sec,
742 (unsigned long)t->tv_set.tv_usec,
743 (unsigned long)t->tv_expires.tv_sec,
744 (unsigned long)t->tv_expires.tv_usec,
745 t->delay_us,
746 t->data
747 );
748 }
749 used += sprintf(bigbuf + used, "\n");
750#endif
751
752 used += sprintf(bigbuf + used, "Active timers:\n");
753 local_irq_save(flags);
754 t = fast_timer_list;
755 while (t != NULL && (used+100 < BIG_BUF_SIZE))
756 {
757 nextt = t->next;
758 local_irq_restore(flags);
759 used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
760 "d: %6li us data: 0x%08lX"
761
762 "\n",
763 t->name,
764 (unsigned long)t->tv_set.tv_sec,
765 (unsigned long)t->tv_set.tv_usec,
766 (unsigned long)t->tv_expires.tv_sec,
767 (unsigned long)t->tv_expires.tv_usec,
768 t->delay_us,
769 t->data
770
771 );
772 local_irq_disable();
773 if (t->next != nextt)
774 {
775 printk(KERN_WARNING "timer removed!\n");
776 }
777 t = nextt;
778 }
779 local_irq_restore(flags);
780 }
781
782 if (used - offset < len)
783 {
784 len = used - offset;
785 }
786
787 memcpy(buf, bigbuf + offset, len);
788 *start = buf;
789 *eof = 1;
790
791 return len;
792}
793#endif
794
795#ifdef FAST_TIMER_TEST
796static volatile unsigned long i = 0;
797static volatile int num_test_timeout = 0;
798static struct fast_timer tr[10];
799static int exp_num[10];
800
801static struct timeval tv_exp[100];
802
803static void test_timeout(unsigned long data)
804{
805 do_gettimeofday_fast(&tv_exp[data]);
806 exp_num[data] = num_test_timeout;
807
808 num_test_timeout++;
809}
810
811static void test_timeout1(unsigned long data)
812{
813 do_gettimeofday_fast(&tv_exp[data]);
814 exp_num[data] = num_test_timeout;
815 if (data < 7)
816 {
817 start_one_shot_timer(&tr[i], test_timeout1, i, 1000, "timeout1");
818 i++;
819 }
820 num_test_timeout++;
821}
822
823DP(
824static char buf0[2000];
825static char buf1[2000];
826static char buf2[2000];
827static char buf3[2000];
828static char buf4[2000];
829);
830
831static char buf5[6000];
832static int j_u[1000];
833
834static void fast_timer_test(void)
835{
836 int prev_num;
837 int j;
838
839 struct timeval tv, tv0, tv1, tv2;
840
841 printk("fast_timer_test() start\n");
842 do_gettimeofday_fast(&tv);
843
844 for (j = 0; j < 1000; j++)
845 {
846 j_u[j] = GET_JIFFIES_USEC();
847 }
848 for (j = 0; j < 100; j++)
849 {
850 do_gettimeofday_fast(&tv_exp[j]);
851 }
852 printk("fast_timer_test() %is %06i\n", tv.tv_sec, tv.tv_usec);
853
854 for (j = 0; j < 1000; j++)
855 {
856 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]);
857 j += 4;
858 }
859 for (j = 0; j < 100; j++)
860 {
861 printk("%i.%i %i.%i %i.%i %i.%i %i.%i\n",
862 tv_exp[j].tv_sec,tv_exp[j].tv_usec,
863 tv_exp[j+1].tv_sec,tv_exp[j+1].tv_usec,
864 tv_exp[j+2].tv_sec,tv_exp[j+2].tv_usec,
865 tv_exp[j+3].tv_sec,tv_exp[j+3].tv_usec,
866 tv_exp[j+4].tv_sec,tv_exp[j+4].tv_usec);
867 j += 4;
868 }
869 do_gettimeofday_fast(&tv0);
870 start_one_shot_timer(&tr[i], test_timeout, i, 50000, "test0");
871 DP(proc_fasttimer_read(buf0, NULL, 0, 0, 0));
872 i++;
873 start_one_shot_timer(&tr[i], test_timeout, i, 70000, "test1");
874 DP(proc_fasttimer_read(buf1, NULL, 0, 0, 0));
875 i++;
876 start_one_shot_timer(&tr[i], test_timeout, i, 40000, "test2");
877 DP(proc_fasttimer_read(buf2, NULL, 0, 0, 0));
878 i++;
879 start_one_shot_timer(&tr[i], test_timeout, i, 60000, "test3");
880 DP(proc_fasttimer_read(buf3, NULL, 0, 0, 0));
881 i++;
882 start_one_shot_timer(&tr[i], test_timeout1, i, 55000, "test4xx");
883 DP(proc_fasttimer_read(buf4, NULL, 0, 0, 0));
884 i++;
885 do_gettimeofday_fast(&tv1);
886
887 proc_fasttimer_read(buf5, NULL, 0, 0, 0);
888
889 prev_num = num_test_timeout;
890 while (num_test_timeout < i)
891 {
892 if (num_test_timeout != prev_num)
893 {
894 prev_num = num_test_timeout;
895 }
896 }
897 do_gettimeofday_fast(&tv2);
898 printk("Timers started %is %06i\n", tv0.tv_sec, tv0.tv_usec);
899 printk("Timers started at %is %06i\n", tv1.tv_sec, tv1.tv_usec);
900 printk("Timers done %is %06i\n", tv2.tv_sec, tv2.tv_usec);
901 DP(printk("buf0:\n");
902 printk(buf0);
903 printk("buf1:\n");
904 printk(buf1);
905 printk("buf2:\n");
906 printk(buf2);
907 printk("buf3:\n");
908 printk(buf3);
909 printk("buf4:\n");
910 printk(buf4);
911 );
912 printk("buf5:\n");
913 printk(buf5);
914
915 printk("timers set:\n");
916 for(j = 0; j<i; j++)
917 {
918 struct fast_timer *t = &tr[j];
919 printk("%-10s set: %6is %06ius exp: %6is %06ius "
920 "data: 0x%08X func: 0x%08X\n",
921 t->name,
922 t->tv_set.tv_sec,
923 t->tv_set.tv_usec,
924 t->tv_expires.tv_sec,
925 t->tv_expires.tv_usec,
926 t->data,
927 t->function
928 );
929
930 printk(" del: %6ius did exp: %6is %06ius as #%i error: %6li\n",
931 t->delay_us,
932 tv_exp[j].tv_sec,
933 tv_exp[j].tv_usec,
934 exp_num[j],
935 (tv_exp[j].tv_sec - t->tv_expires.tv_sec)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec);
936 }
937 proc_fasttimer_read(buf5, NULL, 0, 0, 0);
938 printk("buf5 after all done:\n");
939 printk(buf5);
940 printk("fast_timer_test() done\n");
941}
942#endif
943
944
945void fast_timer_init(void)
946{
947
948 if (!fast_timer_is_init)
949 {
950#if 0 && defined(FAST_TIMER_TEST)
951 int i;
952#endif
953
954 printk(KERN_INFO "fast_timer_init()\n");
955
956#if 0 && defined(FAST_TIMER_TEST)
957 for (i = 0; i <= TIMER0_DIV; i++)
958 {
959
960 printk("%3i %6u\n", i, timer0_value_us[i]);
961 }
962#endif
963#ifdef CONFIG_PROC_FS
964 if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 )))
965 fasttimer_proc_entry->read_proc = proc_fasttimer_read;
966#endif
967 if(request_irq(TIMER1_IRQ_NBR, timer1_handler, 0,
968 "fast timer int", NULL))
969 {
970 printk("err: timer1 irq\n");
971 }
972 fast_timer_is_init = 1;
973#ifdef FAST_TIMER_TEST
974 printk("do test\n");
975 fast_timer_test();
976#endif
977 }
978}
979