aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-i386/mach-default/do_timer.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-i386/mach-default/do_timer.h')
-rw-r--r--include/asm-i386/mach-default/do_timer.h85
1 files changed, 85 insertions, 0 deletions
diff --git a/include/asm-i386/mach-default/do_timer.h b/include/asm-i386/mach-default/do_timer.h
new file mode 100644
index 000000000000..03dd13a48a8c
--- /dev/null
+++ b/include/asm-i386/mach-default/do_timer.h
@@ -0,0 +1,85 @@
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
16static inline void do_timer_interrupt_hook(struct pt_regs *regs)
17{
18 do_timer(regs);
19#ifndef CONFIG_SMP
20 update_process_times(user_mode(regs));
21#endif
22/*
23 * In the SMP case we use the local APIC timer interrupt to do the
24 * profiling, except when we simulate SMP mode on a uniprocessor
25 * system, in that case we have to call the local interrupt handler.
26 */
27#ifndef CONFIG_X86_LOCAL_APIC
28 profile_tick(CPU_PROFILING, regs);
29#else
30 if (!using_apic_timer)
31 smp_local_timer_interrupt(regs);
32#endif
33}
34
35
36/* you can safely undefine this if you don't have the Neptune chipset */
37
38#define BUGGY_NEPTUN_TIMER
39
40/**
41 * do_timer_overflow - process a detected timer overflow condition
42 * @count: hardware timer interrupt count on overflow
43 *
44 * Description:
45 * This call is invoked when the jiffies count has not incremented but
46 * the hardware timer interrupt has. It means that a timer tick interrupt
47 * came along while the previous one was pending, thus a tick was missed
48 **/
49static inline int do_timer_overflow(int count)
50{
51 int i;
52
53 spin_lock(&i8259A_lock);
54 /*
55 * This is tricky when I/O APICs are used;
56 * see do_timer_interrupt().
57 */
58 i = inb(0x20);
59 spin_unlock(&i8259A_lock);
60
61 /* assumption about timer being IRQ0 */
62 if (i & 0x01) {
63 /*
64 * We cannot detect lost timer interrupts ...
65 * well, that's why we call them lost, don't we? :)
66 * [hmm, on the Pentium and Alpha we can ... sort of]
67 */
68 count -= LATCH;
69 } else {
70#ifdef BUGGY_NEPTUN_TIMER
71 /*
72 * for the Neptun bug we know that the 'latch'
73 * command doesn't latch the high and low value
74 * of the counter atomically. Thus we have to
75 * substract 256 from the counter
76 * ... funny, isnt it? :)
77 */
78
79 count -= 256;
80#else
81 printk("do_slow_gettimeoffset(): hardware timer problem?\n");
82#endif
83 }
84 return count;
85}