Commit | Line | Data |
---|---|---|
1394f032 | 1 | /* |
9e83b98a MF |
2 | * delay.h - delay functions |
3 | * | |
4 | * Copyright (c) 2004-2007 Analog Devices Inc. | |
5 | * | |
6 | * Licensed under the GPL-2 or later. | |
7 | */ | |
8 | ||
9 | #ifndef __ASM_DELAY_H__ | |
10 | #define __ASM_DELAY_H__ | |
1394f032 | 11 | |
9e83b98a | 12 | #include <asm/mach/anomaly.h> |
1394f032 | 13 | |
9e83b98a MF |
14 | static inline void __delay(unsigned long loops) |
15 | { | |
16 | if (ANOMALY_05000312) { | |
17 | /* Interrupted loads to loop registers -> bad */ | |
18 | unsigned long tmp; | |
19 | __asm__ __volatile__( | |
20 | "[--SP] = LC0;" | |
21 | "[--SP] = LT0;" | |
22 | "[--SP] = LB0;" | |
23 | "LSETUP (1f,1f) LC0 = %1;" | |
24 | "1: NOP;" | |
25 | /* We take advantage of the fact that LC0 is 0 at | |
26 | * the end of the loop. Otherwise we'd need some | |
27 | * NOPs after the CLI here. | |
28 | */ | |
29 | "CLI %0;" | |
30 | "LB0 = [SP++];" | |
31 | "LT0 = [SP++];" | |
32 | "LC0 = [SP++];" | |
33 | "STI %0;" | |
34 | : "=d" (tmp) | |
35 | : "a" (loops) | |
36 | ); | |
37 | } else | |
38 | __asm__ __volatile__ ( | |
39 | "LSETUP(1f, 1f) LC0 = %0;" | |
40 | "1: NOP;" | |
41 | : | |
42 | : "a" (loops) | |
43 | : "LT0", "LB0", "LC0" | |
44 | ); | |
1394f032 BW |
45 | } |
46 | ||
47 | #include <linux/param.h> /* needed for HZ */ | |
48 | ||
49 | /* | |
50 | * Use only for very small delays ( < 1 msec). Should probably use a | |
51 | * lookup table, really, as the multiplications take much too long with | |
52 | * short delays. This is a "reasonable" implementation, though (and the | |
53 | * first constant multiplications gets optimized away if the delay is | |
54 | * a constant) | |
55 | */ | |
56 | static inline void udelay(unsigned long usecs) | |
57 | { | |
58 | extern unsigned long loops_per_jiffy; | |
59 | __delay(usecs * loops_per_jiffy / (1000000 / HZ)); | |
60 | } | |
61 | ||
9e83b98a | 62 | #endif |