diff options
Diffstat (limited to 'arch/i386/lib/delay.c')
-rw-r--r-- | arch/i386/lib/delay.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/arch/i386/lib/delay.c b/arch/i386/lib/delay.c new file mode 100644 index 00000000000..080639f262b --- /dev/null +++ b/arch/i386/lib/delay.c | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * Precise Delay Loops for i386 | ||
3 | * | ||
4 | * Copyright (C) 1993 Linus Torvalds | ||
5 | * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> | ||
6 | * | ||
7 | * The __delay function must _NOT_ be inlined as its execution time | ||
8 | * depends wildly on alignment on many x86 processors. The additional | ||
9 | * jump magic is needed to get the timing stable on all the CPU's | ||
10 | * we have to worry about. | ||
11 | */ | ||
12 | |||
13 | #include <linux/config.h> | ||
14 | #include <linux/sched.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <asm/processor.h> | ||
17 | #include <asm/delay.h> | ||
18 | #include <asm/timer.h> | ||
19 | |||
20 | #ifdef CONFIG_SMP | ||
21 | #include <asm/smp.h> | ||
22 | #endif | ||
23 | |||
24 | extern struct timer_opts* timer; | ||
25 | |||
26 | void __delay(unsigned long loops) | ||
27 | { | ||
28 | cur_timer->delay(loops); | ||
29 | } | ||
30 | |||
31 | inline void __const_udelay(unsigned long xloops) | ||
32 | { | ||
33 | int d0; | ||
34 | xloops *= 4; | ||
35 | __asm__("mull %0" | ||
36 | :"=d" (xloops), "=&a" (d0) | ||
37 | :"1" (xloops),"0" (cpu_data[_smp_processor_id()].loops_per_jiffy * (HZ/4))); | ||
38 | __delay(++xloops); | ||
39 | } | ||
40 | |||
41 | void __udelay(unsigned long usecs) | ||
42 | { | ||
43 | __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ | ||
44 | } | ||
45 | |||
46 | void __ndelay(unsigned long nsecs) | ||
47 | { | ||
48 | __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ | ||
49 | } | ||