9 #include <linux/errno.h>
10 #include <linux/sched.h>
11 #include <linux/kernel.h>
13 #include <linux/string.h>
16 #include <linux/time.h>
21 #include <hwregs/reg_map.h>
23 #include <hwregs/timer_defs.h>
37 #define DEBUG_LOG_INCLUDED
38 #define FAST_TIMER_LOG
41 #define FAST_TIMER_SANITY_CHECKS
43 #ifdef FAST_TIMER_SANITY_CHECKS
44 static int sanity_failed;
51 static unsigned int fast_timer_running;
52 static unsigned int fast_timers_added;
53 static unsigned int fast_timers_started;
54 static unsigned int fast_timers_expired;
55 static unsigned int fast_timers_deleted;
56 static unsigned int fast_timer_is_init;
57 static unsigned int fast_timer_ints;
61 #ifdef DEBUG_LOG_INCLUDED
62 #define DEBUG_LOG_MAX 128
65 static unsigned int debug_log_cnt;
66 static unsigned int debug_log_cnt_wrapped;
68 #define DEBUG_LOG(string, value) \
70 unsigned long log_flags; \
71 local_irq_save(log_flags); \
72 debug_log_string[debug_log_cnt] = (string); \
73 debug_log_value[debug_log_cnt] = (unsigned long)(value); \
74 if (++debug_log_cnt >= DEBUG_LOG_MAX) \
76 debug_log_cnt = debug_log_cnt % DEBUG_LOG_MAX; \
77 debug_log_cnt_wrapped = 1; \
79 local_irq_restore(log_flags); \
82 #define DEBUG_LOG(string, value)
86 #define NUM_TIMER_STATS 16
115 else if (
time_after(t0->tv_jiff, t1->tv_jiff))
119 if (t0->tv_usec < t1->tv_usec)
121 else if (t0->tv_usec > t1->tv_usec)
135 unsigned char trig_wrap;
136 unsigned char time_wrap;
140 D1(
printk(
"start_timer_trig : %d us freq: %i div: %i\n",
141 delay_us, freq_index,
div));
149 trig_wrap = (trig = r_time0 + delay_us*(1000/10)) < r_time0;
165 time_wrap = r_time1 < r_time0;
167 if ((trig_wrap && !time_wrap) || (r_time1 < trig)) {
172 fast_timers_started++;
173 fast_timer_running = 1;
188 fast_timer_function_type *
function,
190 unsigned long delay_us,
194 struct fast_timer *
tmp;
196 D1(
printk(
"sft %s %d us\n", name, delay_us));
203 #ifdef FAST_TIMER_SANITY_CHECKS
205 while (tmp !=
NULL) {
208 "timer name: %s data: 0x%08lX already "
209 "in list!\n", name, data);
218 t->delay_us = delay_us;
219 t->function =
function;
223 t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000;
224 t->tv_expires.tv_jiff = t->tv_set.tv_jiff + delay_us / 1000000 /
HZ;
225 if (t->tv_expires.tv_usec > 1000000) {
226 t->tv_expires.tv_usec -= 1000000;
227 t->tv_expires.tv_jiff +=
HZ;
229 #ifdef FAST_TIMER_LOG
242 #ifdef FAST_TIMER_LOG
249 fasttime_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0)
261 D2(
printk(
"start_one_shot_timer: %d us done\n", delay_us));
267 static inline int fast_timer_pending (
const struct fast_timer *
t)
272 static inline int detach_fast_timer (
struct fast_timer *t)
275 if (!fast_timer_pending(t))
285 fast_timers_deleted++;
295 ret = detach_fast_timer(t);
296 t->next = t->prev =
NULL;
307 timer_trig_interrupt(
int irq,
void *
dev_id)
312 if (!masked_intr.
trig)
314 timer_trig_handler(
NULL);
323 struct fast_timer *
t;
349 fast_timer_running = 0;
352 fast_timer_function_type *
f;
357 struct fasttime_t tv;
362 "t: %is %06ius\n", tv.tv_jiff, tv.tv_usec));
366 #ifdef FAST_TIMER_LOG
369 fast_timers_expired++;
373 t->prev->next = t->next;
377 t->next->prev = t->prev;
397 DEBUG_LOG(
"!trimertrig %i function==NULL!\n", fast_timer_ints);
407 struct fasttime_t tv;
413 us = ((t->tv_expires.tv_jiff - tv.tv_jiff) *
414 1000000 /
HZ + t->tv_expires.tv_usec -
418 if (!fast_timer_running) {
419 #ifdef FAST_TIMER_LOG
440 static void wake_up_func(
unsigned long data)
455 D1(
printk(
"schedule_usleep(%d)\n", us));
460 wait_event(sleep_wait, !fast_timer_pending(&t));
462 D1(
printk(
"done schedule_usleep(%d)\n", us));
465 #ifdef CONFIG_PROC_FS
467 ,
int *eof,
void *data_unused);
471 #ifdef CONFIG_PROC_FS
474 #define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300)
477 ,
int *eof,
void *data_unused)
482 struct fasttime_t tv;
483 struct fast_timer *
t, *nextt;
484 static char *bigbuf =
NULL;
485 static unsigned long used;
488 bigbuf =
vmalloc(BIG_BUF_SIZE);
497 if (!offset || !used) {
501 used +=
sprintf(bigbuf + used,
"Fast timers added: %i\n",
503 used +=
sprintf(bigbuf + used,
"Fast timers started: %i\n",
504 fast_timers_started);
505 used +=
sprintf(bigbuf + used,
"Fast timer interrupts: %i\n",
507 used +=
sprintf(bigbuf + used,
"Fast timers expired: %i\n",
508 fast_timers_expired);
509 used +=
sprintf(bigbuf + used,
"Fast timers deleted: %i\n",
510 fast_timers_deleted);
511 used +=
sprintf(bigbuf + used,
"Fast timer running: %s\n",
512 fast_timer_running ?
"yes" :
"no");
513 used +=
sprintf(bigbuf + used,
"Current time: %lu.%06lu\n",
514 (
unsigned long)tv.tv_jiff,
515 (
unsigned long)tv.tv_usec);
516 #ifdef FAST_TIMER_SANITY_CHECKS
517 used +=
sprintf(bigbuf + used,
"Sanity failed: %i\n",
520 used +=
sprintf(bigbuf + used,
"\n");
522 #ifdef DEBUG_LOG_INCLUDED
524 int end_i = debug_log_cnt;
527 if (debug_log_cnt_wrapped)
530 while ((i != end_i || (debug_log_cnt_wrapped && !used)) &&
531 used+100 < BIG_BUF_SIZE)
533 used +=
sprintf(bigbuf + used, debug_log_string[i],
538 used +=
sprintf(bigbuf + used,
"\n");
541 num_to_show = (fast_timers_started <
NUM_TIMER_STATS ? fast_timers_started:
543 used +=
sprintf(bigbuf + used,
"Timers started: %i\n", fast_timers_started);
544 for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE) ; i++)
548 #if 1 //ndef FAST_TIMER_LOG
549 used +=
sprintf(bigbuf + used,
"div: %i delay: %i"
555 #ifdef FAST_TIMER_LOG
557 used +=
sprintf(bigbuf + used,
"%-14s s: %6lu.%06lu e: %6lu.%06lu "
558 "d: %6li us data: 0x%08lX"
561 (
unsigned long)t->tv_set.tv_jiff,
562 (
unsigned long)t->tv_set.tv_usec,
563 (
unsigned long)t->tv_expires.tv_jiff,
564 (
unsigned long)t->tv_expires.tv_usec,
570 used +=
sprintf(bigbuf + used,
"\n");
572 #ifdef FAST_TIMER_LOG
573 num_to_show = (fast_timers_added <
NUM_TIMER_STATS ? fast_timers_added:
575 used +=
sprintf(bigbuf + used,
"Timers added: %i\n", fast_timers_added);
576 for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
579 used +=
sprintf(bigbuf + used,
"%-14s s: %6lu.%06lu e: %6lu.%06lu "
580 "d: %6li us data: 0x%08lX"
583 (
unsigned long)t->tv_set.tv_jiff,
584 (
unsigned long)t->tv_set.tv_usec,
585 (
unsigned long)t->tv_expires.tv_jiff,
586 (
unsigned long)t->tv_expires.tv_usec,
591 used +=
sprintf(bigbuf + used,
"\n");
593 num_to_show = (fast_timers_expired <
NUM_TIMER_STATS ? fast_timers_expired:
595 used +=
sprintf(bigbuf + used,
"Timers expired: %i\n", fast_timers_expired);
596 for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
599 used +=
sprintf(bigbuf + used,
"%-14s s: %6lu.%06lu e: %6lu.%06lu "
600 "d: %6li us data: 0x%08lX"
603 (
unsigned long)t->tv_set.tv_jiff,
604 (
unsigned long)t->tv_set.tv_usec,
605 (
unsigned long)t->tv_expires.tv_jiff,
606 (
unsigned long)t->tv_expires.tv_usec,
611 used +=
sprintf(bigbuf + used,
"\n");
614 used +=
sprintf(bigbuf + used,
"Active timers:\n");
617 while (t !=
NULL && (used+100 < BIG_BUF_SIZE))
621 used +=
sprintf(bigbuf + used,
"%-14s s: %6lu.%06lu e: %6lu.%06lu "
622 "d: %6li us data: 0x%08lX"
626 (
unsigned long)t->tv_set.tv_jiff,
627 (
unsigned long)t->tv_set.tv_usec,
628 (
unsigned long)t->tv_expires.tv_jiff,
629 (
unsigned long)t->tv_expires.tv_usec,
635 if (t->next != nextt)
637 printk(
"timer removed!\n");
644 if (used - offset < len)
649 memcpy(buf, bigbuf + offset, len);
657 #ifdef FAST_TIMER_TEST
658 static volatile unsigned long i = 0;
659 static volatile int num_test_timeout = 0;
660 static struct fast_timer
tr[10];
661 static int exp_num[10];
663 static struct fasttime_t tv_exp[100];
665 static void test_timeout(
unsigned long data)
668 exp_num[
data] = num_test_timeout;
673 static void test_timeout1(
unsigned long data)
676 exp_num[
data] = num_test_timeout;
686 static char buf0[2000];
687 static char buf1[2000];
688 static char buf2[2000];
689 static char buf3[2000];
690 static char buf4[2000];
693 static char buf5[6000];
694 static int j_u[1000];
696 static void fast_timer_test(
void)
701 struct fasttime_t tv, tv0, tv1, tv2;
703 printk(
"fast_timer_test() start\n");
706 for (j = 0; j < 1000; j++)
710 for (j = 0; j < 100; j++)
716 for (j = 0; j < 1000; j++)
719 j_u[j], j_u[j+1], j_u[j+2], j_u[j+3], j_u[j+4]);
722 for (j = 0; j < 100; j++)
725 tv_exp[j].tv_jiff, tv_exp[j].
tv_usec,
726 tv_exp[j+1].tv_jiff, tv_exp[j+1].tv_usec,
727 tv_exp[j+2].tv_jiff, tv_exp[j+2].tv_usec,
728 tv_exp[j+3].tv_jiff, tv_exp[j+3].tv_usec,
729 tv_exp[j+4].tv_jiff, tv_exp[j+4].tv_usec);
734 DP(proc_fasttimer_read(buf0,
NULL, 0, 0, 0));
737 DP(proc_fasttimer_read(buf1,
NULL, 0, 0, 0));
740 DP(proc_fasttimer_read(buf2,
NULL, 0, 0, 0));
743 DP(proc_fasttimer_read(buf3,
NULL, 0, 0, 0));
746 DP(proc_fasttimer_read(buf4,
NULL, 0, 0, 0));
750 proc_fasttimer_read(buf5,
NULL, 0, 0, 0);
752 prev_num = num_test_timeout;
753 while (num_test_timeout < i)
755 if (num_test_timeout != prev_num)
756 prev_num = num_test_timeout;
760 tv0.tv_jiff, tv0.tv_usec);
762 tv1.tv_jiff, tv1.tv_usec);
764 tv2.tv_jiff, tv2.tv_usec);
782 struct fast_timer *t = &
tr[
j];
783 printk(
"%-10s set: %6is %06ius exp: %6is %06ius "
784 "data: 0x%08X func: 0x%08X\n",
788 t->tv_expires.tv_jiff,
789 t->tv_expires.tv_usec,
794 printk(
" del: %6ius did exp: %6is %06ius as #%i error: %6li\n",
799 (tv_exp[j].tv_jiff - t->tv_expires.tv_jiff) *
800 1000000 + tv_exp[j].tv_usec -
801 t->tv_expires.tv_usec);
803 proc_fasttimer_read(buf5,
NULL, 0, 0, 0);
804 printk(
"buf5 after all done:\n");
806 printk(
"fast_timer_test() done\n");
814 if (!fast_timer_is_init)
816 printk(
"fast_timer_init()\n");
818 #ifdef CONFIG_PROC_FS
820 if (fasttimer_proc_entry)
821 fasttimer_proc_entry->
read_proc = proc_fasttimer_read;
827 fast_timer_is_init = 1;
828 #ifdef FAST_TIMER_TEST