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