diff options
-rw-r--r-- | arch/blackfin/kernel/process.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index a57723808743..b56b0e485e0b 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c | |||
@@ -258,9 +258,12 @@ void finish_atomic_sections (struct pt_regs *regs) | |||
258 | int __user *up0 = (int __user *)regs->p0; | 258 | int __user *up0 = (int __user *)regs->p0; |
259 | 259 | ||
260 | switch (regs->pc) { | 260 | switch (regs->pc) { |
261 | default: | ||
262 | /* not in middle of an atomic step, so resume like normal */ | ||
263 | return; | ||
264 | |||
261 | case ATOMIC_XCHG32 + 2: | 265 | case ATOMIC_XCHG32 + 2: |
262 | put_user(regs->r1, up0); | 266 | put_user(regs->r1, up0); |
263 | regs->pc = ATOMIC_XCHG32 + 4; | ||
264 | break; | 267 | break; |
265 | 268 | ||
266 | case ATOMIC_CAS32 + 2: | 269 | case ATOMIC_CAS32 + 2: |
@@ -268,7 +271,6 @@ void finish_atomic_sections (struct pt_regs *regs) | |||
268 | if (regs->r0 == regs->r1) | 271 | if (regs->r0 == regs->r1) |
269 | case ATOMIC_CAS32 + 6: | 272 | case ATOMIC_CAS32 + 6: |
270 | put_user(regs->r2, up0); | 273 | put_user(regs->r2, up0); |
271 | regs->pc = ATOMIC_CAS32 + 8; | ||
272 | break; | 274 | break; |
273 | 275 | ||
274 | case ATOMIC_ADD32 + 2: | 276 | case ATOMIC_ADD32 + 2: |
@@ -276,7 +278,6 @@ void finish_atomic_sections (struct pt_regs *regs) | |||
276 | /* fall through */ | 278 | /* fall through */ |
277 | case ATOMIC_ADD32 + 4: | 279 | case ATOMIC_ADD32 + 4: |
278 | put_user(regs->r0, up0); | 280 | put_user(regs->r0, up0); |
279 | regs->pc = ATOMIC_ADD32 + 6; | ||
280 | break; | 281 | break; |
281 | 282 | ||
282 | case ATOMIC_SUB32 + 2: | 283 | case ATOMIC_SUB32 + 2: |
@@ -284,7 +285,6 @@ void finish_atomic_sections (struct pt_regs *regs) | |||
284 | /* fall through */ | 285 | /* fall through */ |
285 | case ATOMIC_SUB32 + 4: | 286 | case ATOMIC_SUB32 + 4: |
286 | put_user(regs->r0, up0); | 287 | put_user(regs->r0, up0); |
287 | regs->pc = ATOMIC_SUB32 + 6; | ||
288 | break; | 288 | break; |
289 | 289 | ||
290 | case ATOMIC_IOR32 + 2: | 290 | case ATOMIC_IOR32 + 2: |
@@ -292,7 +292,6 @@ void finish_atomic_sections (struct pt_regs *regs) | |||
292 | /* fall through */ | 292 | /* fall through */ |
293 | case ATOMIC_IOR32 + 4: | 293 | case ATOMIC_IOR32 + 4: |
294 | put_user(regs->r0, up0); | 294 | put_user(regs->r0, up0); |
295 | regs->pc = ATOMIC_IOR32 + 6; | ||
296 | break; | 295 | break; |
297 | 296 | ||
298 | case ATOMIC_AND32 + 2: | 297 | case ATOMIC_AND32 + 2: |
@@ -300,7 +299,6 @@ void finish_atomic_sections (struct pt_regs *regs) | |||
300 | /* fall through */ | 299 | /* fall through */ |
301 | case ATOMIC_AND32 + 4: | 300 | case ATOMIC_AND32 + 4: |
302 | put_user(regs->r0, up0); | 301 | put_user(regs->r0, up0); |
303 | regs->pc = ATOMIC_AND32 + 6; | ||
304 | break; | 302 | break; |
305 | 303 | ||
306 | case ATOMIC_XOR32 + 2: | 304 | case ATOMIC_XOR32 + 2: |
@@ -308,9 +306,15 @@ void finish_atomic_sections (struct pt_regs *regs) | |||
308 | /* fall through */ | 306 | /* fall through */ |
309 | case ATOMIC_XOR32 + 4: | 307 | case ATOMIC_XOR32 + 4: |
310 | put_user(regs->r0, up0); | 308 | put_user(regs->r0, up0); |
311 | regs->pc = ATOMIC_XOR32 + 6; | ||
312 | break; | 309 | break; |
313 | } | 310 | } |
311 | |||
312 | /* | ||
313 | * We've finished the atomic section, and the only thing left for | ||
314 | * userspace is to do a RTS, so we might as well handle that too | ||
315 | * since we need to update the PC anyways. | ||
316 | */ | ||
317 | regs->pc = regs->rets; | ||
314 | } | 318 | } |
315 | 319 | ||
316 | static inline | 320 | static inline |