diff options
Diffstat (limited to 'include/asm-sparc/spinlock.h')
-rw-r--r-- | include/asm-sparc/spinlock.h | 140 |
1 files changed, 21 insertions, 119 deletions
diff --git a/include/asm-sparc/spinlock.h b/include/asm-sparc/spinlock.h index 0cbd87ad4912..111727a2bb4e 100644 --- a/include/asm-sparc/spinlock.h +++ b/include/asm-sparc/spinlock.h | |||
@@ -12,96 +12,12 @@ | |||
12 | 12 | ||
13 | #include <asm/psr.h> | 13 | #include <asm/psr.h> |
14 | 14 | ||
15 | #ifdef CONFIG_DEBUG_SPINLOCK | 15 | #define __raw_spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0) |
16 | struct _spinlock_debug { | ||
17 | unsigned char lock; | ||
18 | unsigned long owner_pc; | ||
19 | #ifdef CONFIG_PREEMPT | ||
20 | unsigned int break_lock; | ||
21 | #endif | ||
22 | }; | ||
23 | typedef struct _spinlock_debug spinlock_t; | ||
24 | |||
25 | #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0, 0 } | ||
26 | #define spin_lock_init(lp) do { *(lp)= SPIN_LOCK_UNLOCKED; } while(0) | ||
27 | #define spin_is_locked(lp) (*((volatile unsigned char *)(&((lp)->lock))) != 0) | ||
28 | #define spin_unlock_wait(lp) do { barrier(); } while(*(volatile unsigned char *)(&(lp)->lock)) | ||
29 | |||
30 | extern void _do_spin_lock(spinlock_t *lock, char *str); | ||
31 | extern int _spin_trylock(spinlock_t *lock); | ||
32 | extern void _do_spin_unlock(spinlock_t *lock); | ||
33 | |||
34 | #define _raw_spin_trylock(lp) _spin_trylock(lp) | ||
35 | #define _raw_spin_lock(lock) _do_spin_lock(lock, "spin_lock") | ||
36 | #define _raw_spin_unlock(lock) _do_spin_unlock(lock) | ||
37 | |||
38 | struct _rwlock_debug { | ||
39 | volatile unsigned int lock; | ||
40 | unsigned long owner_pc; | ||
41 | unsigned long reader_pc[NR_CPUS]; | ||
42 | #ifdef CONFIG_PREEMPT | ||
43 | unsigned int break_lock; | ||
44 | #endif | ||
45 | }; | ||
46 | typedef struct _rwlock_debug rwlock_t; | ||
47 | |||
48 | #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, {0} } | ||
49 | |||
50 | #define rwlock_init(lp) do { *(lp)= RW_LOCK_UNLOCKED; } while(0) | ||
51 | |||
52 | extern void _do_read_lock(rwlock_t *rw, char *str); | ||
53 | extern void _do_read_unlock(rwlock_t *rw, char *str); | ||
54 | extern void _do_write_lock(rwlock_t *rw, char *str); | ||
55 | extern void _do_write_unlock(rwlock_t *rw); | ||
56 | |||
57 | #define _raw_read_lock(lock) \ | ||
58 | do { unsigned long flags; \ | ||
59 | local_irq_save(flags); \ | ||
60 | _do_read_lock(lock, "read_lock"); \ | ||
61 | local_irq_restore(flags); \ | ||
62 | } while(0) | ||
63 | |||
64 | #define _raw_read_unlock(lock) \ | ||
65 | do { unsigned long flags; \ | ||
66 | local_irq_save(flags); \ | ||
67 | _do_read_unlock(lock, "read_unlock"); \ | ||
68 | local_irq_restore(flags); \ | ||
69 | } while(0) | ||
70 | |||
71 | #define _raw_write_lock(lock) \ | ||
72 | do { unsigned long flags; \ | ||
73 | local_irq_save(flags); \ | ||
74 | _do_write_lock(lock, "write_lock"); \ | ||
75 | local_irq_restore(flags); \ | ||
76 | } while(0) | ||
77 | |||
78 | #define _raw_write_unlock(lock) \ | ||
79 | do { unsigned long flags; \ | ||
80 | local_irq_save(flags); \ | ||
81 | _do_write_unlock(lock); \ | ||
82 | local_irq_restore(flags); \ | ||
83 | } while(0) | ||
84 | |||
85 | #else /* !CONFIG_DEBUG_SPINLOCK */ | ||
86 | |||
87 | typedef struct { | ||
88 | unsigned char lock; | ||
89 | #ifdef CONFIG_PREEMPT | ||
90 | unsigned int break_lock; | ||
91 | #endif | ||
92 | } spinlock_t; | ||
93 | |||
94 | #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } | ||
95 | |||
96 | #define spin_lock_init(lock) (*((unsigned char *)(lock)) = 0) | ||
97 | #define spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0) | ||
98 | 16 | ||
99 | #define spin_unlock_wait(lock) \ | 17 | #define __raw_spin_unlock_wait(lock) \ |
100 | do { \ | 18 | do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) |
101 | barrier(); \ | ||
102 | } while(*((volatile unsigned char *)lock)) | ||
103 | 19 | ||
104 | extern __inline__ void _raw_spin_lock(spinlock_t *lock) | 20 | extern __inline__ void __raw_spin_lock(raw_spinlock_t *lock) |
105 | { | 21 | { |
106 | __asm__ __volatile__( | 22 | __asm__ __volatile__( |
107 | "\n1:\n\t" | 23 | "\n1:\n\t" |
@@ -121,7 +37,7 @@ extern __inline__ void _raw_spin_lock(spinlock_t *lock) | |||
121 | : "g2", "memory", "cc"); | 37 | : "g2", "memory", "cc"); |
122 | } | 38 | } |
123 | 39 | ||
124 | extern __inline__ int _raw_spin_trylock(spinlock_t *lock) | 40 | extern __inline__ int __raw_spin_trylock(raw_spinlock_t *lock) |
125 | { | 41 | { |
126 | unsigned int result; | 42 | unsigned int result; |
127 | __asm__ __volatile__("ldstub [%1], %0" | 43 | __asm__ __volatile__("ldstub [%1], %0" |
@@ -131,7 +47,7 @@ extern __inline__ int _raw_spin_trylock(spinlock_t *lock) | |||
131 | return (result == 0); | 47 | return (result == 0); |
132 | } | 48 | } |
133 | 49 | ||
134 | extern __inline__ void _raw_spin_unlock(spinlock_t *lock) | 50 | extern __inline__ void __raw_spin_unlock(raw_spinlock_t *lock) |
135 | { | 51 | { |
136 | __asm__ __volatile__("stb %%g0, [%0]" : : "r" (lock) : "memory"); | 52 | __asm__ __volatile__("stb %%g0, [%0]" : : "r" (lock) : "memory"); |
137 | } | 53 | } |
@@ -147,23 +63,11 @@ extern __inline__ void _raw_spin_unlock(spinlock_t *lock) | |||
147 | * | 63 | * |
148 | * XXX This might create some problems with my dual spinlock | 64 | * XXX This might create some problems with my dual spinlock |
149 | * XXX scheme, deadlocks etc. -DaveM | 65 | * XXX scheme, deadlocks etc. -DaveM |
150 | */ | 66 | * |
151 | typedef struct { | 67 | * Sort of like atomic_t's on Sparc, but even more clever. |
152 | volatile unsigned int lock; | ||
153 | #ifdef CONFIG_PREEMPT | ||
154 | unsigned int break_lock; | ||
155 | #endif | ||
156 | } rwlock_t; | ||
157 | |||
158 | #define RW_LOCK_UNLOCKED (rwlock_t) { 0 } | ||
159 | |||
160 | #define rwlock_init(lp) do { *(lp)= RW_LOCK_UNLOCKED; } while(0) | ||
161 | |||
162 | |||
163 | /* Sort of like atomic_t's on Sparc, but even more clever. | ||
164 | * | 68 | * |
165 | * ------------------------------------ | 69 | * ------------------------------------ |
166 | * | 24-bit counter | wlock | rwlock_t | 70 | * | 24-bit counter | wlock | raw_rwlock_t |
167 | * ------------------------------------ | 71 | * ------------------------------------ |
168 | * 31 8 7 0 | 72 | * 31 8 7 0 |
169 | * | 73 | * |
@@ -174,9 +78,9 @@ typedef struct { | |||
174 | * | 78 | * |
175 | * Unfortunately this scheme limits us to ~16,000,000 cpus. | 79 | * Unfortunately this scheme limits us to ~16,000,000 cpus. |
176 | */ | 80 | */ |
177 | extern __inline__ void _read_lock(rwlock_t *rw) | 81 | extern __inline__ void __read_lock(raw_rwlock_t *rw) |
178 | { | 82 | { |
179 | register rwlock_t *lp asm("g1"); | 83 | register raw_rwlock_t *lp asm("g1"); |
180 | lp = rw; | 84 | lp = rw; |
181 | __asm__ __volatile__( | 85 | __asm__ __volatile__( |
182 | "mov %%o7, %%g4\n\t" | 86 | "mov %%o7, %%g4\n\t" |
@@ -187,16 +91,16 @@ extern __inline__ void _read_lock(rwlock_t *rw) | |||
187 | : "g2", "g4", "memory", "cc"); | 91 | : "g2", "g4", "memory", "cc"); |
188 | } | 92 | } |
189 | 93 | ||
190 | #define _raw_read_lock(lock) \ | 94 | #define __raw_read_lock(lock) \ |
191 | do { unsigned long flags; \ | 95 | do { unsigned long flags; \ |
192 | local_irq_save(flags); \ | 96 | local_irq_save(flags); \ |
193 | _read_lock(lock); \ | 97 | __raw_read_lock(lock); \ |
194 | local_irq_restore(flags); \ | 98 | local_irq_restore(flags); \ |
195 | } while(0) | 99 | } while(0) |
196 | 100 | ||
197 | extern __inline__ void _read_unlock(rwlock_t *rw) | 101 | extern __inline__ void __read_unlock(raw_rwlock_t *rw) |
198 | { | 102 | { |
199 | register rwlock_t *lp asm("g1"); | 103 | register raw_rwlock_t *lp asm("g1"); |
200 | lp = rw; | 104 | lp = rw; |
201 | __asm__ __volatile__( | 105 | __asm__ __volatile__( |
202 | "mov %%o7, %%g4\n\t" | 106 | "mov %%o7, %%g4\n\t" |
@@ -207,16 +111,16 @@ extern __inline__ void _read_unlock(rwlock_t *rw) | |||
207 | : "g2", "g4", "memory", "cc"); | 111 | : "g2", "g4", "memory", "cc"); |
208 | } | 112 | } |
209 | 113 | ||
210 | #define _raw_read_unlock(lock) \ | 114 | #define __raw_read_unlock(lock) \ |
211 | do { unsigned long flags; \ | 115 | do { unsigned long flags; \ |
212 | local_irq_save(flags); \ | 116 | local_irq_save(flags); \ |
213 | _read_unlock(lock); \ | 117 | __raw_read_unlock(lock); \ |
214 | local_irq_restore(flags); \ | 118 | local_irq_restore(flags); \ |
215 | } while(0) | 119 | } while(0) |
216 | 120 | ||
217 | extern __inline__ void _raw_write_lock(rwlock_t *rw) | 121 | extern __inline__ void __raw_write_lock(raw_rwlock_t *rw) |
218 | { | 122 | { |
219 | register rwlock_t *lp asm("g1"); | 123 | register raw_rwlock_t *lp asm("g1"); |
220 | lp = rw; | 124 | lp = rw; |
221 | __asm__ __volatile__( | 125 | __asm__ __volatile__( |
222 | "mov %%o7, %%g4\n\t" | 126 | "mov %%o7, %%g4\n\t" |
@@ -227,11 +131,9 @@ extern __inline__ void _raw_write_lock(rwlock_t *rw) | |||
227 | : "g2", "g4", "memory", "cc"); | 131 | : "g2", "g4", "memory", "cc"); |
228 | } | 132 | } |
229 | 133 | ||
230 | #define _raw_write_unlock(rw) do { (rw)->lock = 0; } while(0) | 134 | #define __raw_write_unlock(rw) do { (rw)->lock = 0; } while(0) |
231 | |||
232 | #endif /* CONFIG_DEBUG_SPINLOCK */ | ||
233 | 135 | ||
234 | #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) | 136 | #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) |
235 | 137 | ||
236 | #endif /* !(__ASSEMBLY__) */ | 138 | #endif /* !(__ASSEMBLY__) */ |
237 | 139 | ||