diff options
author | Graf Yang <graf.yang@analog.com> | 2009-01-07 10:14:39 -0500 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2009-01-07 10:14:39 -0500 |
commit | 6b3087c64a92a36ae20d33479b4df6d7afc910d4 (patch) | |
tree | 95984fc623658ebf150d0d912a7f6c5a0301a5a9 /arch/blackfin/include/asm/system.h | |
parent | c51b4488cd5bff08ed5690a8f303ff7f0894da2a (diff) |
Blackfin arch: SMP supporting patchset: Blackfin header files and machine common code
Blackfin dual core BF561 processor can support SMP like features.
https://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:smp-like
In this patch, we provide SMP extend to Blackfin header files
and machine common code
Signed-off-by: Graf Yang <graf.yang@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch/blackfin/include/asm/system.h')
-rw-r--r-- | arch/blackfin/include/asm/system.h | 116 |
1 files changed, 95 insertions, 21 deletions
diff --git a/arch/blackfin/include/asm/system.h b/arch/blackfin/include/asm/system.h index 8f1627d8bf09..6b368faf30c3 100644 --- a/arch/blackfin/include/asm/system.h +++ b/arch/blackfin/include/asm/system.h | |||
@@ -37,20 +37,16 @@ | |||
37 | #include <linux/linkage.h> | 37 | #include <linux/linkage.h> |
38 | #include <linux/compiler.h> | 38 | #include <linux/compiler.h> |
39 | #include <mach/anomaly.h> | 39 | #include <mach/anomaly.h> |
40 | #include <asm/pda.h> | ||
41 | #include <asm/processor.h> | ||
42 | |||
43 | /* Forward decl needed due to cdef inter dependencies */ | ||
44 | static inline uint32_t __pure bfin_dspid(void); | ||
45 | #define blackfin_core_id() (bfin_dspid() & 0xff) | ||
40 | 46 | ||
41 | /* | 47 | /* |
42 | * Interrupt configuring macros. | 48 | * Interrupt configuring macros. |
43 | */ | 49 | */ |
44 | |||
45 | extern unsigned long irq_flags; | ||
46 | |||
47 | #define local_irq_enable() \ | ||
48 | __asm__ __volatile__( \ | ||
49 | "sti %0;" \ | ||
50 | : \ | ||
51 | : "d" (irq_flags) \ | ||
52 | ) | ||
53 | |||
54 | #define local_irq_disable() \ | 50 | #define local_irq_disable() \ |
55 | do { \ | 51 | do { \ |
56 | int __tmp_dummy; \ | 52 | int __tmp_dummy; \ |
@@ -66,6 +62,18 @@ extern unsigned long irq_flags; | |||
66 | # define NOP_PAD_ANOMALY_05000244 | 62 | # define NOP_PAD_ANOMALY_05000244 |
67 | #endif | 63 | #endif |
68 | 64 | ||
65 | #ifdef CONFIG_SMP | ||
66 | # define irq_flags cpu_pda[blackfin_core_id()].imask | ||
67 | #else | ||
68 | extern unsigned long irq_flags; | ||
69 | #endif | ||
70 | |||
71 | #define local_irq_enable() \ | ||
72 | __asm__ __volatile__( \ | ||
73 | "sti %0;" \ | ||
74 | : \ | ||
75 | : "d" (irq_flags) \ | ||
76 | ) | ||
69 | #define idle_with_irq_disabled() \ | 77 | #define idle_with_irq_disabled() \ |
70 | __asm__ __volatile__( \ | 78 | __asm__ __volatile__( \ |
71 | NOP_PAD_ANOMALY_05000244 \ | 79 | NOP_PAD_ANOMALY_05000244 \ |
@@ -129,22 +137,85 @@ extern unsigned long irq_flags; | |||
129 | #define rmb() asm volatile ("" : : :"memory") | 137 | #define rmb() asm volatile ("" : : :"memory") |
130 | #define wmb() asm volatile ("" : : :"memory") | 138 | #define wmb() asm volatile ("" : : :"memory") |
131 | #define set_mb(var, value) do { (void) xchg(&var, value); } while (0) | 139 | #define set_mb(var, value) do { (void) xchg(&var, value); } while (0) |
132 | |||
133 | #define read_barrier_depends() do { } while(0) | 140 | #define read_barrier_depends() do { } while(0) |
134 | 141 | ||
135 | #ifdef CONFIG_SMP | 142 | #ifdef CONFIG_SMP |
136 | #define smp_mb() mb() | 143 | asmlinkage unsigned long __raw_xchg_1_asm(volatile void *ptr, unsigned long value); |
137 | #define smp_rmb() rmb() | 144 | asmlinkage unsigned long __raw_xchg_2_asm(volatile void *ptr, unsigned long value); |
138 | #define smp_wmb() wmb() | 145 | asmlinkage unsigned long __raw_xchg_4_asm(volatile void *ptr, unsigned long value); |
139 | #define smp_read_barrier_depends() read_barrier_depends() | 146 | asmlinkage unsigned long __raw_cmpxchg_1_asm(volatile void *ptr, |
147 | unsigned long new, unsigned long old); | ||
148 | asmlinkage unsigned long __raw_cmpxchg_2_asm(volatile void *ptr, | ||
149 | unsigned long new, unsigned long old); | ||
150 | asmlinkage unsigned long __raw_cmpxchg_4_asm(volatile void *ptr, | ||
151 | unsigned long new, unsigned long old); | ||
152 | |||
153 | #ifdef __ARCH_SYNC_CORE_DCACHE | ||
154 | # define smp_mb() do { barrier(); smp_check_barrier(); smp_mark_barrier(); } while (0) | ||
155 | # define smp_rmb() do { barrier(); smp_check_barrier(); } while (0) | ||
156 | # define smp_wmb() do { barrier(); smp_mark_barrier(); } while (0) | ||
140 | #else | 157 | #else |
158 | # define smp_mb() barrier() | ||
159 | # define smp_rmb() barrier() | ||
160 | # define smp_wmb() barrier() | ||
161 | #endif | ||
162 | |||
163 | static inline unsigned long __xchg(unsigned long x, volatile void *ptr, | ||
164 | int size) | ||
165 | { | ||
166 | unsigned long tmp; | ||
167 | |||
168 | switch (size) { | ||
169 | case 1: | ||
170 | tmp = __raw_xchg_1_asm(ptr, x); | ||
171 | break; | ||
172 | case 2: | ||
173 | tmp = __raw_xchg_2_asm(ptr, x); | ||
174 | break; | ||
175 | case 4: | ||
176 | tmp = __raw_xchg_4_asm(ptr, x); | ||
177 | break; | ||
178 | } | ||
179 | |||
180 | return tmp; | ||
181 | } | ||
182 | |||
183 | /* | ||
184 | * Atomic compare and exchange. Compare OLD with MEM, if identical, | ||
185 | * store NEW in MEM. Return the initial value in MEM. Success is | ||
186 | * indicated by comparing RETURN with OLD. | ||
187 | */ | ||
188 | static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, | ||
189 | unsigned long new, int size) | ||
190 | { | ||
191 | unsigned long tmp; | ||
192 | |||
193 | switch (size) { | ||
194 | case 1: | ||
195 | tmp = __raw_cmpxchg_1_asm(ptr, new, old); | ||
196 | break; | ||
197 | case 2: | ||
198 | tmp = __raw_cmpxchg_2_asm(ptr, new, old); | ||
199 | break; | ||
200 | case 4: | ||
201 | tmp = __raw_cmpxchg_4_asm(ptr, new, old); | ||
202 | break; | ||
203 | } | ||
204 | |||
205 | return tmp; | ||
206 | } | ||
207 | #define cmpxchg(ptr, o, n) \ | ||
208 | ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ | ||
209 | (unsigned long)(n), sizeof(*(ptr)))) | ||
210 | |||
211 | #define smp_read_barrier_depends() smp_check_barrier() | ||
212 | |||
213 | #else /* !CONFIG_SMP */ | ||
214 | |||
141 | #define smp_mb() barrier() | 215 | #define smp_mb() barrier() |
142 | #define smp_rmb() barrier() | 216 | #define smp_rmb() barrier() |
143 | #define smp_wmb() barrier() | 217 | #define smp_wmb() barrier() |
144 | #define smp_read_barrier_depends() do { } while(0) | 218 | #define smp_read_barrier_depends() do { } while(0) |
145 | #endif | ||
146 | |||
147 | #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) | ||
148 | 219 | ||
149 | struct __xchg_dummy { | 220 | struct __xchg_dummy { |
150 | unsigned long a[100]; | 221 | unsigned long a[100]; |
@@ -194,9 +265,12 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, | |||
194 | (unsigned long)(n), sizeof(*(ptr)))) | 265 | (unsigned long)(n), sizeof(*(ptr)))) |
195 | #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) | 266 | #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) |
196 | 267 | ||
197 | #ifndef CONFIG_SMP | ||
198 | #include <asm-generic/cmpxchg.h> | 268 | #include <asm-generic/cmpxchg.h> |
199 | #endif | 269 | |
270 | #endif /* !CONFIG_SMP */ | ||
271 | |||
272 | #define xchg(ptr, x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) | ||
273 | #define tas(ptr) ((void)xchg((ptr), 1)) | ||
200 | 274 | ||
201 | #define prepare_to_switch() do { } while(0) | 275 | #define prepare_to_switch() do { } while(0) |
202 | 276 | ||
@@ -218,4 +292,4 @@ do { \ | |||
218 | (last) = resume (prev, next); \ | 292 | (last) = resume (prev, next); \ |
219 | } while (0) | 293 | } while (0) |
220 | 294 | ||
221 | #endif /* _BLACKFIN_SYSTEM_H */ | 295 | #endif /* _BLACKFIN_SYSTEM_H */ |