Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

CRISv10 improve and bugfix fasttimer

Improve and bugfix CRIS v10 fast timers.

- irq_handler_t now only takes two arguments.
- Keep interrupts disabled as long as we have a reference to the
fasttimer list and only enable them while doing the callback.
del_fast_timer may be called from other interrupt context.
- Fix bug where debug code could return without calling local_irq_restore.
- Use jiffies instead of usec (change from struct timeval to fasttime_t).
- Don't initialize static variables to zero.
- Remove obsolete #ifndef DECLARE_WAITQUEUE code.
- fast_timer_init should be __initcall.
- Change status/debug variables to unsigned.
- Remove CVS log and CVS id.

Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Mikael Starvik <mikael.starvik@axis.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Jesper Nilsson and committed by
Linus Torvalds
d8e5219f 3244c77b

+124 -207
+114 -201
arch/cris/arch-v10/kernel/fasttimer.c
··· 1 - /* $Id: fasttimer.c,v 1.9 2005/03/04 08:16:16 starvik Exp $ 1 + /* 2 2 * linux/arch/cris/kernel/fasttimer.c 3 3 * 4 4 * Fast timers for ETRAX100/ETRAX100LX 5 - * This may be useful in other OS than Linux so use 2 space indentation... 6 5 * 7 - * $Log: fasttimer.c,v $ 8 - * Revision 1.9 2005/03/04 08:16:16 starvik 9 - * Merge of Linux 2.6.11. 10 - * 11 - * Revision 1.8 2005/01/05 06:09:29 starvik 12 - * cli()/sti() will be obsolete in 2.6.11. 13 - * 14 - * Revision 1.7 2005/01/03 13:35:46 starvik 15 - * Removed obsolete stuff. 16 - * Mark fast timer IRQ as not shared. 17 - * 18 - * Revision 1.6 2004/05/14 10:18:39 starvik 19 - * Export fast_timer_list 20 - * 21 - * Revision 1.5 2004/05/14 07:58:01 starvik 22 - * Merge of changes from 2.4 23 - * 24 - * Revision 1.4 2003/07/04 08:27:41 starvik 25 - * Merge of Linux 2.5.74 26 - * 27 - * Revision 1.3 2002/12/12 08:26:32 starvik 28 - * Don't use C-comments inside CVS comments 29 - * 30 - * Revision 1.2 2002/12/11 15:42:02 starvik 31 - * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/ 32 - * 33 - * Revision 1.1 2002/11/18 07:58:06 starvik 34 - * Fast timers (from Linux 2.4) 35 - * 36 - * Revision 1.5 2002/10/15 06:21:39 starvik 37 - * Added call to init_waitqueue_head 38 - * 39 - * Revision 1.4 2002/05/28 17:47:59 johana 40 - * Added del_fast_timer() 41 - * 42 - * Revision 1.3 2002/05/28 16:16:07 johana 43 - * Handle empty fast_timer_list 44 - * 45 - * Revision 1.2 2002/05/27 15:38:42 johana 46 - * Made it compile without warnings on Linux 2.4. 47 - * (includes, wait_queue, PROC_FS and snprintf) 48 - * 49 - * Revision 1.1 2002/05/27 15:32:25 johana 50 - * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree. 51 - * 52 - * Revision 1.8 2001/11/27 13:50:40 pkj 53 - * Disable interrupts while stopping the timer and while modifying the 54 - * list of active timers in timer1_handler() as it may be interrupted 55 - * by other interrupts (e.g., the serial interrupt) which may add fast 56 - * timers. 57 - * 58 - * Revision 1.7 2001/11/22 11:50:32 pkj 59 - * * Only store information about the last 16 timers. 60 - * * proc_fasttimer_read() now uses an allocated buffer, since it 61 - * requires more space than just a page even for only writing the 62 - * last 16 timers. The buffer is only allocated on request, so 63 - * unless /proc/fasttimer is read, it is never allocated. 64 - * * Renamed fast_timer_started to fast_timers_started to match 65 - * fast_timers_added and fast_timers_expired. 66 - * * Some clean-up. 67 - * 68 - * Revision 1.6 2000/12/13 14:02:08 johana 69 - * Removed volatile for fast_timer_list 70 - * 71 - * Revision 1.5 2000/12/13 13:55:35 johana 72 - * Added DEBUG_LOG, added som cli() and cleanup 73 - * 74 - * Revision 1.4 2000/12/05 13:48:50 johana 75 - * Added range check when writing proc file, modified timer int handling 76 - * 77 - * Revision 1.3 2000/11/23 10:10:20 johana 78 - * More debug/logging possibilities. 79 - * Moved GET_JIFFIES_USEC() to timex.h and time.c 80 - * 81 - * Revision 1.2 2000/11/01 13:41:04 johana 82 - * Clean up and bugfixes. 83 - * Created new do_gettimeofday_fast() that gets a timeval struct 84 - * with time based on jiffies and *R_TIMER0_DATA, uses a table 85 - * for fast conversion of timer value to microseconds. 86 - * (Much faster the standard do_gettimeofday() and we don't really 87 - * want to use the true time - we want the "uptime" so timers don't screw up 88 - * when we change the time. 89 - * TODO: Add efficient support for continuous timers as well. 90 - * 91 - * Revision 1.1 2000/10/26 15:49:16 johana 92 - * Added fasttimer, highresolution timers. 93 - * 94 - * Copyright (C) 2000,2001 2002 Axis Communications AB, Lund, Sweden 6 + * Copyright (C) 2000-2007 Axis Communications AB, Lund, Sweden 95 7 */ 96 8 97 9 #include <linux/errno.h> ··· 37 125 38 126 #ifdef FAST_TIMER_SANITY_CHECKS 39 127 #define SANITYCHECK(x) x 40 - static int sanity_failed = 0; 128 + static int sanity_failed; 41 129 #else 42 130 #define SANITYCHECK(x) 43 131 #endif ··· 48 136 49 137 #define __INLINE__ inline 50 138 51 - static int fast_timer_running = 0; 52 - static int fast_timers_added = 0; 53 - static int fast_timers_started = 0; 54 - static int fast_timers_expired = 0; 55 - static int fast_timers_deleted = 0; 56 - static int fast_timer_is_init = 0; 57 - static int fast_timer_ints = 0; 139 + static unsigned int fast_timer_running; 140 + static unsigned int fast_timers_added; 141 + static unsigned int fast_timers_started; 142 + static unsigned int fast_timers_expired; 143 + static unsigned int fast_timers_deleted; 144 + static unsigned int fast_timer_is_init; 145 + static unsigned int fast_timer_ints; 58 146 59 147 struct fast_timer *fast_timer_list = NULL; 60 148 ··· 62 150 #define DEBUG_LOG_MAX 128 63 151 static const char * debug_log_string[DEBUG_LOG_MAX]; 64 152 static unsigned long debug_log_value[DEBUG_LOG_MAX]; 65 - static int debug_log_cnt = 0; 66 - static int debug_log_cnt_wrapped = 0; 153 + static unsigned int debug_log_cnt; 154 + static unsigned int debug_log_cnt_wrapped; 67 155 68 156 #define DEBUG_LOG(string, value) \ 69 157 { \ ··· 118 206 int timer_delay_settings[NUM_TIMER_STATS]; 119 207 120 208 /* Not true gettimeofday, only checks the jiffies (uptime) + useconds */ 121 - void __INLINE__ do_gettimeofday_fast(struct timeval *tv) 209 + void __INLINE__ do_gettimeofday_fast(struct fasttime_t *tv) 122 210 { 123 - unsigned long sec = jiffies; 124 - unsigned long usec = GET_JIFFIES_USEC(); 125 - 126 - usec += (sec % HZ) * (1000000 / HZ); 127 - sec = sec / HZ; 128 - 129 - if (usec > 1000000) 130 - { 131 - usec -= 1000000; 132 - sec++; 133 - } 134 - tv->tv_sec = sec; 135 - tv->tv_usec = usec; 211 + tv->tv_jiff = jiffies; 212 + tv->tv_usec = GET_JIFFIES_USEC(); 136 213 } 137 214 138 - int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1) 215 + int __INLINE__ timeval_cmp(struct fasttime_t *t0, struct fasttime_t *t1) 139 216 { 140 - if (t0->tv_sec < t1->tv_sec) 141 - { 142 - return -1; 143 - } 144 - else if (t0->tv_sec > t1->tv_sec) 145 - { 146 - return 1; 147 - } 148 - if (t0->tv_usec < t1->tv_usec) 149 - { 150 - return -1; 151 - } 152 - else if (t0->tv_usec > t1->tv_usec) 153 - { 154 - return 1; 155 - } 156 - return 0; 217 + /* Compare jiffies. Takes care of wrapping */ 218 + if (time_before(t0->tv_jiff, t1->tv_jiff)) 219 + return -1; 220 + else if (time_after(t0->tv_jiff, t1->tv_jiff)) 221 + return 1; 222 + 223 + /* Compare us */ 224 + if (t0->tv_usec < t1->tv_usec) 225 + return -1; 226 + else if (t0->tv_usec > t1->tv_usec) 227 + return 1; 228 + return 0; 157 229 } 158 230 159 231 void __INLINE__ start_timer1(unsigned long delay_us) ··· 181 285 timer_freq_settings[fast_timers_started % NUM_TIMER_STATS] = freq_index; 182 286 timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us; 183 287 184 - D1(printk("start_timer1 : %d us freq: %i div: %i\n", 288 + D1(printk(KERN_DEBUG "start_timer1 : %d us freq: %i div: %i\n", 185 289 delay_us, freq_index, div)); 186 290 /* Clear timer1 irq */ 187 291 *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr); ··· 236 340 printk(KERN_WARNING 237 341 "timer name: %s data: 0x%08lX already in list!\n", name, data); 238 342 sanity_failed++; 239 - return; 343 + goto done; 240 344 } 241 345 else 242 346 { ··· 252 356 t->name = name; 253 357 254 358 t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000; 255 - t->tv_expires.tv_sec = t->tv_set.tv_sec + delay_us / 1000000; 359 + t->tv_expires.tv_jiff = t->tv_set.tv_jiff + delay_us / 1000000 / HZ; 256 360 if (t->tv_expires.tv_usec > 1000000) 257 361 { 258 362 t->tv_expires.tv_usec -= 1000000; 259 - t->tv_expires.tv_sec++; 363 + t->tv_expires.tv_jiff += HZ; 260 364 } 261 365 #ifdef FAST_TIMER_LOG 262 366 timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t; ··· 297 401 298 402 D2(printk("start_one_shot_timer: %d us done\n", delay_us)); 299 403 404 + done: 300 405 local_irq_restore(flags); 301 406 } /* start_one_shot_timer */ 302 407 ··· 341 444 /* Timer 1 interrupt handler */ 342 445 343 446 static irqreturn_t 344 - timer1_handler(int irq, void *dev_id, struct pt_regs *regs) 447 + timer1_handler(int irq, void *dev_id) 345 448 { 346 449 struct fast_timer *t; 347 450 unsigned long flags; 348 451 452 + /* We keep interrupts disabled not only when we modify the 453 + * fast timer list, but any time we hold a reference to a 454 + * timer in the list, since del_fast_timer may be called 455 + * from (another) interrupt context. Thus, the only time 456 + * when interrupts are enabled is when calling the timer 457 + * callback function. 458 + */ 349 459 local_irq_save(flags); 350 460 351 461 /* Clear timer1 irq */ ··· 370 466 fast_timer_running = 0; 371 467 fast_timer_ints++; 372 468 373 - local_irq_restore(flags); 374 - 375 469 t = fast_timer_list; 376 470 while (t) 377 471 { 378 - struct timeval tv; 472 + struct fasttime_t tv; 473 + fast_timer_function_type *f; 474 + unsigned long d; 379 475 380 476 /* Has it really expired? */ 381 477 do_gettimeofday_fast(&tv); 382 - D1(printk("t: %is %06ius\n", tv.tv_sec, tv.tv_usec)); 478 + D1(printk(KERN_DEBUG "t: %is %06ius\n", 479 + tv.tv_jiff, tv.tv_usec)); 383 480 384 481 if (timeval_cmp(&t->tv_expires, &tv) <= 0) 385 482 { ··· 391 486 fast_timers_expired++; 392 487 393 488 /* Remove this timer before call, since it may reuse the timer */ 394 - local_irq_save(flags); 395 489 if (t->prev) 396 490 { 397 491 t->prev->next = t->next; ··· 405 501 } 406 502 t->prev = NULL; 407 503 t->next = NULL; 408 - local_irq_restore(flags); 409 504 410 - if (t->function != NULL) 411 - { 412 - t->function(t->data); 413 - } 414 - else 415 - { 505 + /* Save function callback data before enabling 506 + * interrupts, since the timer may be removed and 507 + * we don't know how it was allocated 508 + * (e.g. ->function and ->data may become overwritten 509 + * after deletion if the timer was stack-allocated). 510 + */ 511 + f = t->function; 512 + d = t->data; 513 + 514 + if (f != NULL) { 515 + /* Run callback with interrupts enabled. */ 516 + local_irq_restore(flags); 517 + f(d); 518 + local_irq_save(flags); 519 + } else 416 520 DEBUG_LOG("!timer1 %i function==NULL!\n", fast_timer_ints); 417 - } 418 521 } 419 522 else 420 523 { ··· 429 518 D1(printk(".\n")); 430 519 } 431 520 432 - local_irq_save(flags); 433 521 if ((t = fast_timer_list) != NULL) 434 522 { 435 523 /* Start next timer.. */ 436 - long us; 437 - struct timeval tv; 524 + long us = 0; 525 + struct fasttime_t tv; 438 526 439 527 do_gettimeofday_fast(&tv); 440 - us = ((t->tv_expires.tv_sec - tv.tv_sec) * 1000000 + 441 - t->tv_expires.tv_usec - tv.tv_usec); 528 + 529 + /* time_after_eq takes care of wrapping */ 530 + if (time_after_eq(t->tv_expires.tv_jiff, tv.tv_jiff)) 531 + us = ((t->tv_expires.tv_jiff - tv.tv_jiff) * 532 + 1000000 / HZ + t->tv_expires.tv_usec - 533 + tv.tv_usec); 534 + 442 535 if (us > 0) 443 536 { 444 537 if (!fast_timer_running) ··· 452 537 #endif 453 538 start_timer1(us); 454 539 } 455 - local_irq_restore(flags); 456 540 break; 457 541 } 458 542 else ··· 462 548 D1(printk("e! %d\n", us)); 463 549 } 464 550 } 465 - local_irq_restore(flags); 466 551 } 552 + 553 + local_irq_restore(flags); 467 554 468 555 if (!t) 469 556 { ··· 490 575 void schedule_usleep(unsigned long us) 491 576 { 492 577 struct fast_timer t; 493 - #ifdef DECLARE_WAITQUEUE 494 578 wait_queue_head_t sleep_wait; 495 579 init_waitqueue_head(&sleep_wait); 496 - { 497 - DECLARE_WAITQUEUE(wait, current); 498 - #else 499 - struct wait_queue *sleep_wait = NULL; 500 - struct wait_queue wait = { current, NULL }; 501 - #endif 502 580 503 581 D1(printk("schedule_usleep(%d)\n", us)); 504 - add_wait_queue(&sleep_wait, &wait); 505 - set_current_state(TASK_INTERRUPTIBLE); 506 582 start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us, 507 583 "usleep"); 508 - schedule(); 509 - set_current_state(TASK_RUNNING); 510 - remove_wait_queue(&sleep_wait, &wait); 584 + /* Uninterruptible sleep on the fast timer. (The condition is somewhat 585 + * redundant since the timer is what wakes us up.) */ 586 + wait_event(sleep_wait, !fast_timer_pending(&t)); 587 + 511 588 D1(printk("done schedule_usleep(%d)\n", us)); 512 - #ifdef DECLARE_WAITQUEUE 513 - } 514 - #endif 515 589 } 516 590 517 591 #ifdef CONFIG_PROC_FS ··· 520 616 unsigned long flags; 521 617 int i = 0; 522 618 int num_to_show; 523 - struct timeval tv; 619 + struct fasttime_t tv; 524 620 struct fast_timer *t, *nextt; 525 621 static char *bigbuf = NULL; 526 622 static unsigned long used; ··· 528 624 if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE))) 529 625 { 530 626 used = 0; 531 - bigbuf[0] = '\0'; 627 + if (buf) 628 + buf[0] = '\0'; 532 629 return 0; 533 630 } 534 631 ··· 551 646 used += sprintf(bigbuf + used, "Fast timer running: %s\n", 552 647 fast_timer_running ? "yes" : "no"); 553 648 used += sprintf(bigbuf + used, "Current time: %lu.%06lu\n", 554 - (unsigned long)tv.tv_sec, 649 + (unsigned long)tv.tv_jiff, 555 650 (unsigned long)tv.tv_usec); 556 651 #ifdef FAST_TIMER_SANITY_CHECKS 557 652 used += sprintf(bigbuf + used, "Sanity failed: %i\n", ··· 601 696 "d: %6li us data: 0x%08lX" 602 697 "\n", 603 698 t->name, 604 - (unsigned long)t->tv_set.tv_sec, 699 + (unsigned long)t->tv_set.tv_jiff, 605 700 (unsigned long)t->tv_set.tv_usec, 606 - (unsigned long)t->tv_expires.tv_sec, 701 + (unsigned long)t->tv_expires.tv_jiff, 607 702 (unsigned long)t->tv_expires.tv_usec, 608 703 t->delay_us, 609 704 t->data ··· 623 718 "d: %6li us data: 0x%08lX" 624 719 "\n", 625 720 t->name, 626 - (unsigned long)t->tv_set.tv_sec, 721 + (unsigned long)t->tv_set.tv_jiff, 627 722 (unsigned long)t->tv_set.tv_usec, 628 - (unsigned long)t->tv_expires.tv_sec, 723 + (unsigned long)t->tv_expires.tv_jiff, 629 724 (unsigned long)t->tv_expires.tv_usec, 630 725 t->delay_us, 631 726 t->data ··· 643 738 "d: %6li us data: 0x%08lX" 644 739 "\n", 645 740 t->name, 646 - (unsigned long)t->tv_set.tv_sec, 741 + (unsigned long)t->tv_set.tv_jiff, 647 742 (unsigned long)t->tv_set.tv_usec, 648 - (unsigned long)t->tv_expires.tv_sec, 743 + (unsigned long)t->tv_expires.tv_jiff, 649 744 (unsigned long)t->tv_expires.tv_usec, 650 745 t->delay_us, 651 746 t->data ··· 666 761 /* " func: 0x%08lX" */ 667 762 "\n", 668 763 t->name, 669 - (unsigned long)t->tv_set.tv_sec, 764 + (unsigned long)t->tv_set.tv_jiff, 670 765 (unsigned long)t->tv_set.tv_usec, 671 - (unsigned long)t->tv_expires.tv_sec, 766 + (unsigned long)t->tv_expires.tv_jiff, 672 767 (unsigned long)t->tv_expires.tv_usec, 673 768 t->delay_us, 674 769 t->data 675 770 /* , t->function */ 676 771 ); 677 - local_irq_disable(); 772 + local_irq_save(flags); 678 773 if (t->next != nextt) 679 774 { 680 775 printk(KERN_WARNING "timer removed!\n"); ··· 703 798 static struct fast_timer tr[10]; 704 799 static int exp_num[10]; 705 800 706 - static struct timeval tv_exp[100]; 801 + static struct fasttime_t tv_exp[100]; 707 802 708 803 static void test_timeout(unsigned long data) 709 804 { ··· 741 836 int prev_num; 742 837 int j; 743 838 744 - struct timeval tv, tv0, tv1, tv2; 839 + struct fasttime_t tv, tv0, tv1, tv2; 745 840 746 841 printk("fast_timer_test() start\n"); 747 842 do_gettimeofday_fast(&tv); ··· 754 849 { 755 850 do_gettimeofday_fast(&tv_exp[j]); 756 851 } 757 - printk("fast_timer_test() %is %06i\n", tv.tv_sec, tv.tv_usec); 852 + printk(KERN_DEBUG "fast_timer_test() %is %06i\n", 853 + tv.tv_jiff, tv.tv_usec); 758 854 759 855 for (j = 0; j < 1000; j++) 760 856 { ··· 764 858 } 765 859 for (j = 0; j < 100; j++) 766 860 { 767 - printk("%i.%i %i.%i %i.%i %i.%i %i.%i\n", 768 - tv_exp[j].tv_sec,tv_exp[j].tv_usec, 769 - tv_exp[j+1].tv_sec,tv_exp[j+1].tv_usec, 770 - tv_exp[j+2].tv_sec,tv_exp[j+2].tv_usec, 771 - tv_exp[j+3].tv_sec,tv_exp[j+3].tv_usec, 772 - tv_exp[j+4].tv_sec,tv_exp[j+4].tv_usec); 861 + printk(KERN_DEBUG "%i.%i %i.%i %i.%i %i.%i %i.%i\n", 862 + tv_exp[j].tv_jiff, tv_exp[j].tv_usec, 863 + tv_exp[j+1].tv_jiff, tv_exp[j+1].tv_usec, 864 + tv_exp[j+2].tv_jiff, tv_exp[j+2].tv_usec, 865 + tv_exp[j+3].tv_jiff, tv_exp[j+3].tv_usec, 866 + tv_exp[j+4].tv_jiff, tv_exp[j+4].tv_usec); 773 867 j += 4; 774 868 } 775 869 do_gettimeofday_fast(&tv0); ··· 801 895 } 802 896 } 803 897 do_gettimeofday_fast(&tv2); 804 - printk("Timers started %is %06i\n", tv0.tv_sec, tv0.tv_usec); 805 - printk("Timers started at %is %06i\n", tv1.tv_sec, tv1.tv_usec); 806 - printk("Timers done %is %06i\n", tv2.tv_sec, tv2.tv_usec); 898 + printk(KERN_DEBUG "Timers started %is %06i\n", 899 + tv0.tv_jiff, tv0.tv_usec); 900 + printk(KERN_DEBUG "Timers started at %is %06i\n", 901 + tv1.tv_jiff, tv1.tv_usec); 902 + printk(KERN_DEBUG "Timers done %is %06i\n", 903 + tv2.tv_jiff, tv2.tv_usec); 807 904 DP(printk("buf0:\n"); 808 905 printk(buf0); 809 906 printk("buf1:\n"); ··· 828 919 printk("%-10s set: %6is %06ius exp: %6is %06ius " 829 920 "data: 0x%08X func: 0x%08X\n", 830 921 t->name, 831 - t->tv_set.tv_sec, 922 + t->tv_set.tv_jiff, 832 923 t->tv_set.tv_usec, 833 - t->tv_expires.tv_sec, 924 + t->tv_expires.tv_jiff, 834 925 t->tv_expires.tv_usec, 835 926 t->data, 836 927 t->function ··· 838 929 839 930 printk(" del: %6ius did exp: %6is %06ius as #%i error: %6li\n", 840 931 t->delay_us, 841 - tv_exp[j].tv_sec, 932 + tv_exp[j].tv_jiff, 842 933 tv_exp[j].tv_usec, 843 934 exp_num[j], 844 - (tv_exp[j].tv_sec - t->tv_expires.tv_sec)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec); 935 + (tv_exp[j].tv_jiff - t->tv_expires.tv_jiff) * 936 + 1000000 + tv_exp[j].tv_usec - 937 + t->tv_expires.tv_usec); 845 938 } 846 939 proc_fasttimer_read(buf5, NULL, 0, 0, 0); 847 940 printk("buf5 after all done:\n"); ··· 853 942 #endif 854 943 855 944 856 - void fast_timer_init(void) 945 + int fast_timer_init(void) 857 946 { 858 947 /* For some reason, request_irq() hangs when called froom time_init() */ 859 948 if (!fast_timer_is_init) ··· 886 975 fast_timer_test(); 887 976 #endif 888 977 } 978 + return 0; 889 979 } 980 + __initcall(fast_timer_init);
+10 -6
include/asm-cris/fasttimer.h
··· 1 - /* $Id: fasttimer.h,v 1.3 2004/05/14 10:19:19 starvik Exp $ 1 + /* 2 2 * linux/include/asm-cris/fasttimer.h 3 3 * 4 4 * Fast timers for ETRAX100LX 5 - * This may be useful in other OS than Linux so use 2 space indentation... 6 - * Copyright (C) 2000, 2002 Axis Communications AB 5 + * Copyright (C) 2000-2007 Axis Communications AB 7 6 */ 8 7 #include <linux/time.h> /* struct timeval */ 9 8 #include <linux/timex.h> ··· 11 12 12 13 typedef void fast_timer_function_type(unsigned long); 13 14 15 + struct fasttime_t { 16 + unsigned long tv_jiff; /* jiffies */ 17 + unsigned long tv_usec; /* microseconds */ 18 + }; 19 + 14 20 struct fast_timer{ /* Close to timer_list */ 15 21 struct fast_timer *next; 16 22 struct fast_timer *prev; 17 - struct timeval tv_set; 18 - struct timeval tv_expires; 23 + struct fasttime_t tv_set; 24 + struct fasttime_t tv_expires; 19 25 unsigned long delay_us; 20 26 fast_timer_function_type *function; 21 27 unsigned long data; ··· 42 38 void schedule_usleep(unsigned long us); 43 39 44 40 45 - void fast_timer_init(void); 41 + int fast_timer_init(void); 46 42 47 43 #endif