blob: 5c64b75f0295bb0eec7697dd79a6b4f171269a2a [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001#ifndef __ASM_SPINLOCK_H
2#define __ASM_SPINLOCK_H
3
4#include <asm/system.h>
5
6/*
7 * Simple spin lock operations.
Ingo Molnarfb1c8f92005-09-10 00:25:56 -07008 *
9 * (the type definitions are in asm/raw_spinlock_types.h)
Linus Torvalds1da177e2005-04-16 15:20:36 -070010 */
11
Kumar Gala3efc3332005-09-22 10:13:31 -050012#define __raw_spin_is_locked(x) ((x)->slock != 0)
Ingo Molnarfb1c8f92005-09-10 00:25:56 -070013#define __raw_spin_unlock_wait(lock) \
14 do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
15#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070016
Ingo Molnarfb1c8f92005-09-10 00:25:56 -070017static inline void __raw_spin_lock(raw_spinlock_t *lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070018{
19 unsigned long tmp;
20
21 __asm__ __volatile__(
Ingo Molnarfb1c8f92005-09-10 00:25:56 -070022 "b 1f # __raw_spin_lock\n\
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232: lwzx %0,0,%1\n\
24 cmpwi 0,%0,0\n\
25 bne+ 2b\n\
261: lwarx %0,0,%1\n\
27 cmpwi 0,%0,0\n\
28 bne- 2b\n"
29 PPC405_ERR77(0,%1)
30" stwcx. %2,0,%1\n\
31 bne- 2b\n\
32 isync"
33 : "=&r"(tmp)
Kumar Gala3efc3332005-09-22 10:13:31 -050034 : "r"(&lock->slock), "r"(1)
Linus Torvalds1da177e2005-04-16 15:20:36 -070035 : "cr0", "memory");
36}
37
Ingo Molnarfb1c8f92005-09-10 00:25:56 -070038static inline void __raw_spin_unlock(raw_spinlock_t *lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070039{
Ingo Molnarfb1c8f92005-09-10 00:25:56 -070040 __asm__ __volatile__("eieio # __raw_spin_unlock": : :"memory");
Kumar Gala3efc3332005-09-22 10:13:31 -050041 lock->slock = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070042}
43
Kumar Gala3efc3332005-09-22 10:13:31 -050044#define __raw_spin_trylock(l) (!test_and_set_bit(0,(volatile unsigned long *)(&(l)->slock)))
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
46/*
47 * Read-write spinlocks, allowing multiple readers
48 * but only one writer.
49 *
50 * NOTE! it is quite common to have readers in interrupts
51 * but no interrupt writers. For those circumstances we
52 * can "mix" irq-safe locks - any writer needs to get a
53 * irq-safe write-lock, but readers can get non-irqsafe
54 * read-locks.
55 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070056
Ingo Molnarfb1c8f92005-09-10 00:25:56 -070057#define __raw_read_can_lock(rw) ((rw)->lock >= 0)
58#define __raw_write_can_lock(rw) (!(rw)->lock)
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
Ingo Molnarfb1c8f92005-09-10 00:25:56 -070060static __inline__ int __raw_read_trylock(raw_rwlock_t *rw)
Linus Torvalds1da177e2005-04-16 15:20:36 -070061{
62 signed int tmp;
63
64 __asm__ __volatile__(
65"2: lwarx %0,0,%1 # read_trylock\n\
66 addic. %0,%0,1\n\
67 ble- 1f\n"
68 PPC405_ERR77(0,%1)
69" stwcx. %0,0,%1\n\
70 bne- 2b\n\
71 isync\n\
721:"
73 : "=&r"(tmp)
74 : "r"(&rw->lock)
75 : "cr0", "memory");
76
77 return tmp > 0;
78}
79
Ingo Molnarfb1c8f92005-09-10 00:25:56 -070080static __inline__ void __raw_read_lock(raw_rwlock_t *rw)
Linus Torvalds1da177e2005-04-16 15:20:36 -070081{
82 signed int tmp;
83
84 __asm__ __volatile__(
85 "b 2f # read_lock\n\
861: lwzx %0,0,%1\n\
87 cmpwi 0,%0,0\n\
88 blt+ 1b\n\
892: lwarx %0,0,%1\n\
90 addic. %0,%0,1\n\
91 ble- 1b\n"
92 PPC405_ERR77(0,%1)
93" stwcx. %0,0,%1\n\
94 bne- 2b\n\
95 isync"
96 : "=&r"(tmp)
97 : "r"(&rw->lock)
98 : "cr0", "memory");
99}
100
Ingo Molnarfb1c8f92005-09-10 00:25:56 -0700101static __inline__ void __raw_read_unlock(raw_rwlock_t *rw)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102{
103 signed int tmp;
104
105 __asm__ __volatile__(
106 "eieio # read_unlock\n\
1071: lwarx %0,0,%1\n\
108 addic %0,%0,-1\n"
109 PPC405_ERR77(0,%1)
110" stwcx. %0,0,%1\n\
111 bne- 1b"
112 : "=&r"(tmp)
113 : "r"(&rw->lock)
114 : "cr0", "memory");
115}
116
Ingo Molnarfb1c8f92005-09-10 00:25:56 -0700117static __inline__ int __raw_write_trylock(raw_rwlock_t *rw)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118{
119 signed int tmp;
120
121 __asm__ __volatile__(
122"2: lwarx %0,0,%1 # write_trylock\n\
123 cmpwi 0,%0,0\n\
124 bne- 1f\n"
125 PPC405_ERR77(0,%1)
126" stwcx. %2,0,%1\n\
127 bne- 2b\n\
128 isync\n\
1291:"
130 : "=&r"(tmp)
131 : "r"(&rw->lock), "r"(-1)
132 : "cr0", "memory");
133
134 return tmp == 0;
135}
136
Ingo Molnarfb1c8f92005-09-10 00:25:56 -0700137static __inline__ void __raw_write_lock(raw_rwlock_t *rw)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138{
139 signed int tmp;
140
141 __asm__ __volatile__(
142 "b 2f # write_lock\n\
1431: lwzx %0,0,%1\n\
144 cmpwi 0,%0,0\n\
145 bne+ 1b\n\
1462: lwarx %0,0,%1\n\
147 cmpwi 0,%0,0\n\
148 bne- 1b\n"
149 PPC405_ERR77(0,%1)
150" stwcx. %2,0,%1\n\
151 bne- 2b\n\
152 isync"
153 : "=&r"(tmp)
154 : "r"(&rw->lock), "r"(-1)
155 : "cr0", "memory");
156}
157
Ingo Molnarfb1c8f92005-09-10 00:25:56 -0700158static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159{
160 __asm__ __volatile__("eieio # write_unlock": : :"memory");
161 rw->lock = 0;
162}
163
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164#endif /* __ASM_SPINLOCK_H */