- Alan Cox: synch. PA-RISC arch and bitops cleanups
[davej-history.git] / arch / parisc / lib / bitops.c
blob37797eec5c9bd43d144edc76f4c3a36722226d3c
1 /* atomic.c: atomic operations which got too long to be inlined all over
2 * the place.
3 *
4 * Copyright 1999 Philipp Rumpf (prumpf@tux.org */
6 #include <linux/kernel.h>
7 #include <linux/spinlock.h>
8 #include <asm/system.h>
9 #include <asm/atomic.h>
11 #ifdef CONFIG_SMP
12 spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] = {
13 [0 ... (ATOMIC_HASH_SIZE-1)] = SPIN_LOCK_UNLOCKED
15 #endif
17 spinlock_t __atomic_lock = SPIN_LOCK_UNLOCKED;
19 #ifndef __LP64__
20 unsigned long __xchg(unsigned long x, unsigned long *ptr, int size)
22 unsigned long temp, flags;
24 if (size != sizeof x) {
25 printk("__xchg called with bad pointer\n");
27 spin_lock_irqsave(&__atomic_lock, flags);
28 temp = *ptr;
29 *ptr = x;
30 spin_unlock_irqrestore(&__atomic_lock, flags);
31 return temp;
33 #else
34 unsigned long __xchg(unsigned long x, unsigned long *ptr, int size)
36 unsigned long temp, flags;
37 unsigned int *ptr32;
39 if (size == 8) {
40 try_long:
41 spin_lock_irqsave(&__atomic_lock, flags);
42 temp = *ptr;
43 *ptr = x;
44 spin_unlock_irqrestore(&__atomic_lock, flags);
45 return temp;
47 if (size == 4) {
48 ptr32 = (unsigned int *)ptr;
49 spin_lock_irqsave(&__atomic_lock, flags);
50 temp = (unsigned long)*ptr32;
51 *ptr32 = (unsigned int)x;
52 spin_unlock_irqrestore(&__atomic_lock, flags);
53 return temp;
56 printk("__xchg called with bad pointer\n");
57 goto try_long;
59 #endif