MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / include / asm-ppc / spinlock.h
blobd91ba524d8fde3d49007a7f014d0184a0e827e54
1 #ifndef __ASM_SPINLOCK_H
2 #define __ASM_SPINLOCK_H
4 #include <asm/system.h>
6 /*
7 * Simple spin lock operations.
8 */
10 typedef struct {
11 volatile unsigned long lock;
12 #ifdef CONFIG_DEBUG_SPINLOCK
13 volatile unsigned long owner_pc;
14 volatile unsigned long owner_cpu;
15 #endif
16 } spinlock_t;
18 #ifdef __KERNEL__
19 #ifdef CONFIG_DEBUG_SPINLOCK
20 #define SPINLOCK_DEBUG_INIT , 0, 0
21 #else
22 #define SPINLOCK_DEBUG_INIT /* */
23 #endif
25 #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 SPINLOCK_DEBUG_INIT }
27 #define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
28 #define spin_is_locked(x) ((x)->lock != 0)
29 #define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
30 #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
32 #ifndef CONFIG_DEBUG_SPINLOCK
34 static inline void _raw_spin_lock(spinlock_t *lock)
36 unsigned long tmp;
38 __asm__ __volatile__(
39 "b 1f # spin_lock\n\
40 2: lwzx %0,0,%1\n\
41 cmpwi 0,%0,0\n\
42 bne+ 2b\n\
43 1: lwarx %0,0,%1\n\
44 cmpwi 0,%0,0\n\
45 bne- 2b\n"
46 PPC405_ERR77(0,%1)
47 " stwcx. %2,0,%1\n\
48 bne- 2b\n\
49 isync"
50 : "=&r"(tmp)
51 : "r"(&lock->lock), "r"(1)
52 : "cr0", "memory");
55 static inline void _raw_spin_unlock(spinlock_t *lock)
57 __asm__ __volatile__("eieio # spin_unlock": : :"memory");
58 lock->lock = 0;
61 #define _raw_spin_trylock(l) (!test_and_set_bit(0,&(l)->lock))
63 #else
65 extern void _raw_spin_lock(spinlock_t *lock);
66 extern void _raw_spin_unlock(spinlock_t *lock);
67 extern int _raw_spin_trylock(spinlock_t *lock);
69 #endif
72 * Read-write spinlocks, allowing multiple readers
73 * but only one writer.
75 * NOTE! it is quite common to have readers in interrupts
76 * but no interrupt writers. For those circumstances we
77 * can "mix" irq-safe locks - any writer needs to get a
78 * irq-safe write-lock, but readers can get non-irqsafe
79 * read-locks.
81 typedef struct {
82 volatile unsigned long lock;
83 #ifdef CONFIG_DEBUG_SPINLOCK
84 volatile unsigned long owner_pc;
85 #endif
86 } rwlock_t;
88 #ifdef CONFIG_DEBUG_SPINLOCK
89 #define RWLOCK_DEBUG_INIT , 0
90 #else
91 #define RWLOCK_DEBUG_INIT /* */
92 #endif
94 #define RW_LOCK_UNLOCKED (rwlock_t) { 0 RWLOCK_DEBUG_INIT }
95 #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
97 #define rwlock_is_locked(x) ((x)->lock != 0)
99 #ifndef CONFIG_DEBUG_SPINLOCK
101 static __inline__ void _raw_read_lock(rwlock_t *rw)
103 unsigned int tmp;
105 __asm__ __volatile__(
106 "b 2f # read_lock\n\
107 1: lwzx %0,0,%1\n\
108 cmpwi 0,%0,0\n\
109 blt+ 1b\n\
110 2: lwarx %0,0,%1\n\
111 addic. %0,%0,1\n\
112 ble- 1b\n"
113 PPC405_ERR77(0,%1)
114 " stwcx. %0,0,%1\n\
115 bne- 2b\n\
116 isync"
117 : "=&r"(tmp)
118 : "r"(&rw->lock)
119 : "cr0", "memory");
122 static __inline__ void _raw_read_unlock(rwlock_t *rw)
124 unsigned int tmp;
126 __asm__ __volatile__(
127 "eieio # read_unlock\n\
128 1: lwarx %0,0,%1\n\
129 addic %0,%0,-1\n"
130 PPC405_ERR77(0,%1)
131 " stwcx. %0,0,%1\n\
132 bne- 1b"
133 : "=&r"(tmp)
134 : "r"(&rw->lock)
135 : "cr0", "memory");
138 static __inline__ int _raw_write_trylock(rwlock_t *rw)
140 unsigned int tmp;
142 __asm__ __volatile__(
143 "2: lwarx %0,0,%1 # write_trylock\n\
144 cmpwi 0,%0,0\n\
145 bne- 1f\n"
146 PPC405_ERR77(0,%1)
147 " stwcx. %2,0,%1\n\
148 bne- 2b\n\
149 isync\n\
151 : "=&r"(tmp)
152 : "r"(&rw->lock), "r"(-1)
153 : "cr0", "memory");
155 return tmp == 0;
158 static __inline__ void _raw_write_lock(rwlock_t *rw)
160 unsigned int tmp;
162 __asm__ __volatile__(
163 "b 2f # write_lock\n\
164 1: lwzx %0,0,%1\n\
165 cmpwi 0,%0,0\n\
166 bne+ 1b\n\
167 2: lwarx %0,0,%1\n\
168 cmpwi 0,%0,0\n\
169 bne- 1b\n"
170 PPC405_ERR77(0,%1)
171 " stwcx. %2,0,%1\n\
172 bne- 2b\n\
173 isync"
174 : "=&r"(tmp)
175 : "r"(&rw->lock), "r"(-1)
176 : "cr0", "memory");
179 static __inline__ void _raw_write_unlock(rwlock_t *rw)
181 __asm__ __volatile__("eieio # write_unlock": : :"memory");
182 rw->lock = 0;
185 #else
187 extern void _raw_read_lock(rwlock_t *rw);
188 extern void _raw_read_unlock(rwlock_t *rw);
189 extern void _raw_write_lock(rwlock_t *rw);
190 extern void _raw_write_unlock(rwlock_t *rw);
191 extern int _raw_write_trylock(rwlock_t *rw);
193 #endif
195 #endif /* __ASM_SPINLOCK_H */
196 #endif /* __KERNEL__ */