Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
[pandora-kernel.git] / arch / blackfin / include / asm / delay.h
1 /*
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__
11
12 #include <mach/anomaly.h>
13
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                 );
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
62 #endif