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 38static int sanity_failed; 39#endif 40 41#define D1(x) 42#define D2(x) 43#define DP(x) 44 45static unsigned int fast_timer_running; 46static unsigned int fast_timers_added; 47static unsigned int fast_timers_started; 48static unsigned int fast_timers_expired; 49static unsigned int fast_timers_deleted; 50static unsigned int fast_timer_is_init; 51static unsigned int fast_timer_ints; 52 53struct fast_timer *fast_timer_list = NULL; 54 55#ifdef DEBUG_LOG_INCLUDED 56#define DEBUG_LOG_MAX 128 57static const char * debug_log_string[DEBUG_LOG_MAX]; 58static unsigned long debug_log_value[DEBUG_LOG_MAX]; 59static unsigned int debug_log_cnt; 60static 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 84const 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 105struct fast_timer timer_added_log[NUM_TIMER_STATS]; 106struct fast_timer timer_started_log[NUM_TIMER_STATS]; 107struct fast_timer timer_expired_log[NUM_TIMER_STATS]; 108#endif 109 110int timer_div_settings[NUM_TIMER_STATS]; 111int timer_freq_settings[NUM_TIMER_STATS]; 112int timer_delay_settings[NUM_TIMER_STATS]; 113 114/* Not true gettimeofday, only checks the jiffies (uptime) + useconds */ 115inline void do_gettimeofday_fast(struct fasttime_t *tv) 116{ 117 tv->tv_jiff = jiffies; 118 tv->tv_usec = GET_JIFFIES_USEC(); 119} 120 121inline 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 137inline 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 */ 209void 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 290done: 291 local_irq_restore(flags); 292} /* start_one_shot_timer */ 293 294static 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 299static 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 316int 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 333static irqreturn_t 334timer1_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 467static 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 476void 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 496static 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 seq_printf(m, debug_log_string[i], debug_log_value[i]); 531 if (seq_has_overflowed(m)) 532 return 0; 533 i = (i+1) % DEBUG_LOG_MAX; 534 } 535 } 536 seq_putc(m, '\n'); 537#endif 538 539 num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started: 540 NUM_TIMER_STATS); 541 seq_printf(m, "Timers started: %i\n", fast_timers_started); 542 for (i = 0; i < num_to_show; i++) { 543 int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS; 544 545#if 1 //ndef FAST_TIMER_LOG 546 seq_printf(m, "div: %i freq: %i delay: %i\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 seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu d: %6li us data: 0x%08lX\n", 554 t->name, 555 (unsigned long)t->tv_set.tv_jiff, 556 (unsigned long)t->tv_set.tv_usec, 557 (unsigned long)t->tv_expires.tv_jiff, 558 (unsigned long)t->tv_expires.tv_usec, 559 t->delay_us, 560 t->data); 561 if (seq_has_overflowed(m)) 562 return 0; 563#endif 564 } 565 seq_putc(m, '\n'); 566 567#ifdef FAST_TIMER_LOG 568 num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added: 569 NUM_TIMER_STATS); 570 seq_printf(m, "Timers added: %i\n", fast_timers_added); 571 for (i = 0; i < num_to_show; i++) { 572 t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS]; 573 seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu d: %6li us data: 0x%08lX\n", 574 t->name, 575 (unsigned long)t->tv_set.tv_jiff, 576 (unsigned long)t->tv_set.tv_usec, 577 (unsigned long)t->tv_expires.tv_jiff, 578 (unsigned long)t->tv_expires.tv_usec, 579 t->delay_us, 580 t->data); 581 if (seq_has_overflowed(m)) 582 return 0; 583 } 584 seq_putc(m, '\n'); 585 586 num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired: 587 NUM_TIMER_STATS); 588 seq_printf(m, "Timers expired: %i\n", fast_timers_expired); 589 for (i = 0; i < num_to_show; i++) { 590 t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS]; 591 seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu d: %6li us data: 0x%08lX\n", 592 t->name, 593 (unsigned long)t->tv_set.tv_jiff, 594 (unsigned long)t->tv_set.tv_usec, 595 (unsigned long)t->tv_expires.tv_jiff, 596 (unsigned long)t->tv_expires.tv_usec, 597 t->delay_us, 598 t->data); 599 if (seq_has_overflowed(m)) 600 return 0; 601 } 602 seq_putc(m, '\n'); 603#endif 604 605 seq_puts(m, "Active timers:\n"); 606 local_irq_save(flags); 607 t = fast_timer_list; 608 while (t) { 609 nextt = t->next; 610 local_irq_restore(flags); 611 seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu d: %6li us data: 0x%08lX\n", 612 t->name, 613 (unsigned long)t->tv_set.tv_jiff, 614 (unsigned long)t->tv_set.tv_usec, 615 (unsigned long)t->tv_expires.tv_jiff, 616 (unsigned long)t->tv_expires.tv_usec, 617 t->delay_us, 618 t->data); 619 if (seq_has_overflowed(m)) 620 return 0; 621 local_irq_save(flags); 622 if (t->next != nextt) 623 printk(KERN_WARNING "timer removed!\n"); 624 t = nextt; 625 } 626 local_irq_restore(flags); 627 628 return 0; 629} 630 631static int proc_fasttimer_open(struct inode *inode, struct file *file) 632{ 633 return single_open_size(file, proc_fasttimer_show, PDE_DATA(inode), BIG_BUF_SIZE); 634} 635 636static const struct file_operations proc_fasttimer_fops = { 637 .open = proc_fasttimer_open, 638 .read = seq_read, 639 .llseek = seq_lseek, 640 .release = single_release, 641}; 642#endif /* PROC_FS */ 643 644#ifdef FAST_TIMER_TEST 645static volatile unsigned long i = 0; 646static volatile int num_test_timeout = 0; 647static struct fast_timer tr[10]; 648static int exp_num[10]; 649 650static struct fasttime_t tv_exp[100]; 651 652static void test_timeout(unsigned long data) 653{ 654 do_gettimeofday_fast(&tv_exp[data]); 655 exp_num[data] = num_test_timeout; 656 657 num_test_timeout++; 658} 659 660static void test_timeout1(unsigned long data) 661{ 662 do_gettimeofday_fast(&tv_exp[data]); 663 exp_num[data] = num_test_timeout; 664 if (data < 7) 665 { 666 start_one_shot_timer(&tr[i], test_timeout1, i, 1000, "timeout1"); 667 i++; 668 } 669 num_test_timeout++; 670} 671 672DP( 673static char buf0[2000]; 674static char buf1[2000]; 675static char buf2[2000]; 676static char buf3[2000]; 677static char buf4[2000]; 678); 679 680static char buf5[6000]; 681static int j_u[1000]; 682 683static void fast_timer_test(void) 684{ 685 int prev_num; 686 int j; 687 688 struct fasttime_t tv, tv0, tv1, tv2; 689 690 printk("fast_timer_test() start\n"); 691 do_gettimeofday_fast(&tv); 692 693 for (j = 0; j < 1000; j++) 694 { 695 j_u[j] = GET_JIFFIES_USEC(); 696 } 697 for (j = 0; j < 100; j++) 698 { 699 do_gettimeofday_fast(&tv_exp[j]); 700 } 701 printk(KERN_DEBUG "fast_timer_test() %is %06i\n", 702 tv.tv_jiff, tv.tv_usec); 703 704 for (j = 0; j < 1000; j++) 705 { 706 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]); 707 j += 4; 708 } 709 for (j = 0; j < 100; j++) 710 { 711 printk(KERN_DEBUG "%i.%i %i.%i %i.%i %i.%i %i.%i\n", 712 tv_exp[j].tv_jiff, tv_exp[j].tv_usec, 713 tv_exp[j+1].tv_jiff, tv_exp[j+1].tv_usec, 714 tv_exp[j+2].tv_jiff, tv_exp[j+2].tv_usec, 715 tv_exp[j+3].tv_jiff, tv_exp[j+3].tv_usec, 716 tv_exp[j+4].tv_jiff, tv_exp[j+4].tv_usec); 717 j += 4; 718 } 719 do_gettimeofday_fast(&tv0); 720 start_one_shot_timer(&tr[i], test_timeout, i, 50000, "test0"); 721 DP(proc_fasttimer_read(buf0, NULL, 0, 0, 0)); 722 i++; 723 start_one_shot_timer(&tr[i], test_timeout, i, 70000, "test1"); 724 DP(proc_fasttimer_read(buf1, NULL, 0, 0, 0)); 725 i++; 726 start_one_shot_timer(&tr[i], test_timeout, i, 40000, "test2"); 727 DP(proc_fasttimer_read(buf2, NULL, 0, 0, 0)); 728 i++; 729 start_one_shot_timer(&tr[i], test_timeout, i, 60000, "test3"); 730 DP(proc_fasttimer_read(buf3, NULL, 0, 0, 0)); 731 i++; 732 start_one_shot_timer(&tr[i], test_timeout1, i, 55000, "test4xx"); 733 DP(proc_fasttimer_read(buf4, NULL, 0, 0, 0)); 734 i++; 735 do_gettimeofday_fast(&tv1); 736 737 proc_fasttimer_read(buf5, NULL, 0, 0, 0); 738 739 prev_num = num_test_timeout; 740 while (num_test_timeout < i) 741 { 742 if (num_test_timeout != prev_num) 743 { 744 prev_num = num_test_timeout; 745 } 746 } 747 do_gettimeofday_fast(&tv2); 748 printk(KERN_DEBUG "Timers started %is %06i\n", 749 tv0.tv_jiff, tv0.tv_usec); 750 printk(KERN_DEBUG "Timers started at %is %06i\n", 751 tv1.tv_jiff, tv1.tv_usec); 752 printk(KERN_DEBUG "Timers done %is %06i\n", 753 tv2.tv_jiff, tv2.tv_usec); 754 DP(printk("buf0:\n"); 755 printk(buf0); 756 printk("buf1:\n"); 757 printk(buf1); 758 printk("buf2:\n"); 759 printk(buf2); 760 printk("buf3:\n"); 761 printk(buf3); 762 printk("buf4:\n"); 763 printk(buf4); 764 ); 765 printk("buf5:\n"); 766 printk(buf5); 767 768 printk("timers set:\n"); 769 for(j = 0; j<i; j++) 770 { 771 struct fast_timer *t = &tr[j]; 772 printk("%-10s set: %6is %06ius exp: %6is %06ius " 773 "data: 0x%08X func: 0x%08X\n", 774 t->name, 775 t->tv_set.tv_jiff, 776 t->tv_set.tv_usec, 777 t->tv_expires.tv_jiff, 778 t->tv_expires.tv_usec, 779 t->data, 780 t->function 781 ); 782 783 printk(" del: %6ius did exp: %6is %06ius as #%i error: %6li\n", 784 t->delay_us, 785 tv_exp[j].tv_jiff, 786 tv_exp[j].tv_usec, 787 exp_num[j], 788 (tv_exp[j].tv_jiff - t->tv_expires.tv_jiff) * 789 1000000 + tv_exp[j].tv_usec - 790 t->tv_expires.tv_usec); 791 } 792 proc_fasttimer_read(buf5, NULL, 0, 0, 0); 793 printk("buf5 after all done:\n"); 794 printk(buf5); 795 printk("fast_timer_test() done\n"); 796} 797#endif 798 799 800int fast_timer_init(void) 801{ 802 /* For some reason, request_irq() hangs when called froom time_init() */ 803 if (!fast_timer_is_init) 804 { 805#if 0 && defined(FAST_TIMER_TEST) 806 int i; 807#endif 808 809 printk(KERN_INFO "fast_timer_init()\n"); 810 811#if 0 && defined(FAST_TIMER_TEST) 812 for (i = 0; i <= TIMER0_DIV; i++) 813 { 814 /* We must be careful not to get overflow... */ 815 printk("%3i %6u\n", i, timer0_value_us[i]); 816 } 817#endif 818#ifdef CONFIG_PROC_FS 819 proc_create("fasttimer", 0, NULL, &proc_fasttimer_fops); 820#endif /* PROC_FS */ 821 if(request_irq(TIMER1_IRQ_NBR, timer1_handler, 0, 822 "fast timer int", NULL)) 823 { 824 printk("err: timer1 irq\n"); 825 } 826 fast_timer_is_init = 1; 827#ifdef FAST_TIMER_TEST 828 printk("do test\n"); 829 fast_timer_test(); 830#endif 831 } 832 return 0; 833} 834__initcall(fast_timer_init); 835