ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / include / asm-i386 / mach-pc9800 / do_timer.h
1 /* defines for inline arch setup functions */
2
3 #include <asm/apic.h>
4
5 /**
6  * do_timer_interrupt_hook - hook into timer tick
7  * @regs:       standard registers from interrupt
8  *
9  * Description:
10  *      This hook is called immediately after the timer interrupt is ack'd.
11  *      It's primary purpose is to allow architectures that don't possess
12  *      individual per CPU clocks (like the CPU APICs supply) to broadcast the
13  *      timer interrupt as a means of triggering reschedules etc.
14  **/
15
16 static inline void do_timer_interrupt_hook(struct pt_regs *regs)
17 {
18         do_timer(regs);
19 /*
20  * In the SMP case we use the local APIC timer interrupt to do the
21  * profiling, except when we simulate SMP mode on a uniprocessor
22  * system, in that case we have to call the local interrupt handler.
23  */
24 #ifndef CONFIG_X86_LOCAL_APIC
25         x86_do_profile(regs);
26 #else
27         if (!using_apic_timer)
28                 smp_local_timer_interrupt(regs);
29 #endif
30 }
31
32
33 /* you can safely undefine this if you don't have the Neptune chipset */
34
35 #define BUGGY_NEPTUN_TIMER
36
37 /**
38  * do_timer_overflow - process a detected timer overflow condition
39  * @count:      hardware timer interrupt count on overflow
40  *
41  * Description:
42  *      This call is invoked when the jiffies count has not incremented but
43  *      the hardware timer interrupt has.  It means that a timer tick interrupt
44  *      came along while the previous one was pending, thus a tick was missed
45  **/
46 static inline int do_timer_overflow(int count)
47 {
48         int i;
49
50         spin_lock(&i8259A_lock);
51         /*
52          * This is tricky when I/O APICs are used;
53          * see do_timer_interrupt().
54          */
55         i = inb(0x00);
56         spin_unlock(&i8259A_lock);
57         
58         /* assumption about timer being IRQ0 */
59         if (i & 0x01) {
60                 /*
61                  * We cannot detect lost timer interrupts ... 
62                  * well, that's why we call them lost, don't we? :)
63                  * [hmm, on the Pentium and Alpha we can ... sort of]
64                  */
65                 count -= LATCH;
66         } else {
67 #ifdef BUGGY_NEPTUN_TIMER
68                 /*
69                  * for the Neptun bug we know that the 'latch'
70                  * command doesn't latch the high and low value
71                  * of the counter atomically. Thus we have to 
72                  * substract 256 from the counter 
73                  * ... funny, isnt it? :)
74                  */
75                 
76                 count -= 256;
77 #else
78                 printk("do_slow_gettimeoffset(): hardware timer problem?\n");
79 #endif
80         }
81         return count;
82 }