]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * include/asm-sh/spinlock.h | |
3 | * | |
4 | * Copyright (C) 2002, 2003 Paul Mundt | |
5 | * | |
6 | * This file is subject to the terms and conditions of the GNU General Public | |
7 | * License. See the file "COPYING" in the main directory of this archive | |
8 | * for more details. | |
9 | */ | |
10 | #ifndef __ASM_SH_SPINLOCK_H | |
11 | #define __ASM_SH_SPINLOCK_H | |
12 | ||
13 | #include <asm/atomic.h> | |
66c5227e | 14 | #include <asm/spinlock_types.h> |
1da177e4 LT |
15 | |
16 | /* | |
17 | * Your basic SMP spinlocks, allowing only a single CPU anywhere | |
18 | */ | |
1da177e4 | 19 | |
fb1c8f93 IM |
20 | #define __raw_spin_is_locked(x) ((x)->lock != 0) |
21 | #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) | |
22 | #define __raw_spin_unlock_wait(x) \ | |
23 | do { cpu_relax(); } while (__raw_spin_is_locked(x)) | |
1da177e4 LT |
24 | |
25 | /* | |
26 | * Simple spin lock operations. There are two variants, one clears IRQ's | |
27 | * on the local processor, one does not. | |
28 | * | |
29 | * We make no fairness assumptions. They have a cost. | |
30 | */ | |
fb1c8f93 | 31 | static inline void __raw_spin_lock(raw_spinlock_t *lock) |
1da177e4 LT |
32 | { |
33 | __asm__ __volatile__ ( | |
34 | "1:\n\t" | |
35 | "tas.b @%0\n\t" | |
36 | "bf/s 1b\n\t" | |
37 | "nop\n\t" | |
38 | : "=r" (lock->lock) | |
39 | : "r" (&lock->lock) | |
40 | : "t", "memory" | |
41 | ); | |
42 | } | |
43 | ||
fb1c8f93 | 44 | static inline void __raw_spin_unlock(raw_spinlock_t *lock) |
1da177e4 | 45 | { |
66c5227e | 46 | //assert_spin_locked(lock); |
1da177e4 LT |
47 | |
48 | lock->lock = 0; | |
49 | } | |
50 | ||
fb1c8f93 | 51 | #define __raw_spin_trylock(x) (!test_and_set_bit(0, &(x)->lock)) |
1da177e4 LT |
52 | |
53 | /* | |
54 | * Read-write spinlocks, allowing multiple readers but only one writer. | |
55 | * | |
56 | * NOTE! it is quite common to have readers in interrupts but no interrupt | |
57 | * writers. For those circumstances we can "mix" irq-safe locks - any writer | |
58 | * needs to get a irq-safe write-lock, but readers can get non-irqsafe | |
59 | * read-locks. | |
60 | */ | |
fb1c8f93 IM |
61 | |
62 | static inline void __raw_read_lock(raw_rwlock_t *rw) | |
1da177e4 | 63 | { |
fb1c8f93 | 64 | __raw_spin_lock(&rw->lock); |
1da177e4 LT |
65 | |
66 | atomic_inc(&rw->counter); | |
67 | ||
fb1c8f93 | 68 | __raw_spin_unlock(&rw->lock); |
1da177e4 LT |
69 | } |
70 | ||
fb1c8f93 | 71 | static inline void __raw_read_unlock(raw_rwlock_t *rw) |
1da177e4 | 72 | { |
fb1c8f93 | 73 | __raw_spin_lock(&rw->lock); |
1da177e4 LT |
74 | |
75 | atomic_dec(&rw->counter); | |
76 | ||
fb1c8f93 | 77 | __raw_spin_unlock(&rw->lock); |
1da177e4 LT |
78 | } |
79 | ||
fb1c8f93 | 80 | static inline void __raw_write_lock(raw_rwlock_t *rw) |
1da177e4 | 81 | { |
fb1c8f93 | 82 | __raw_spin_lock(&rw->lock); |
1da177e4 LT |
83 | atomic_set(&rw->counter, -1); |
84 | } | |
85 | ||
fb1c8f93 | 86 | static inline void __raw_write_unlock(raw_rwlock_t *rw) |
1da177e4 LT |
87 | { |
88 | atomic_set(&rw->counter, 0); | |
fb1c8f93 | 89 | __raw_spin_unlock(&rw->lock); |
1da177e4 LT |
90 | } |
91 | ||
66c5227e EP |
92 | static inline int __raw_write_can_lock(raw_rwlock_t *rw) |
93 | { | |
94 | return (atomic_read(&rw->counter) == RW_LOCK_BIAS); | |
95 | } | |
96 | ||
fac99d97 PM |
97 | static inline int __raw_read_trylock(raw_rwlock_t *lock) |
98 | { | |
99 | atomic_t *count = (atomic_t*)lock; | |
100 | if (atomic_dec_return(count) >= 0) | |
101 | return 1; | |
102 | atomic_inc(count); | |
103 | return 0; | |
104 | } | |
1da177e4 | 105 | |
fb1c8f93 | 106 | static inline int __raw_write_trylock(raw_rwlock_t *rw) |
1da177e4 LT |
107 | { |
108 | if (atomic_sub_and_test(RW_LOCK_BIAS, &rw->counter)) | |
109 | return 1; | |
110 | ||
111 | atomic_add(RW_LOCK_BIAS, &rw->counter); | |
112 | ||
113 | return 0; | |
114 | } | |
115 | ||
ef6edc97 MS |
116 | #define _raw_spin_relax(lock) cpu_relax() |
117 | #define _raw_read_relax(lock) cpu_relax() | |
118 | #define _raw_write_relax(lock) cpu_relax() | |
119 | ||
1da177e4 | 120 | #endif /* __ASM_SH_SPINLOCK_H */ |