diff options
Diffstat (limited to 'arch/sparc/lib/atomic32.c')
-rw-r--r-- | arch/sparc/lib/atomic32.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c new file mode 100644 index 000000000000..19724c5800a7 --- /dev/null +++ b/arch/sparc/lib/atomic32.c | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * atomic32.c: 32-bit atomic_t implementation | ||
3 | * | ||
4 | * Copyright (C) 2004 Keith M Wesolowski | ||
5 | * | ||
6 | * Based on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf | ||
7 | */ | ||
8 | |||
9 | #include <asm/atomic.h> | ||
10 | #include <linux/spinlock.h> | ||
11 | #include <linux/module.h> | ||
12 | |||
13 | #ifdef CONFIG_SMP | ||
14 | #define ATOMIC_HASH_SIZE 4 | ||
15 | #define ATOMIC_HASH(a) (&__atomic_hash[(((unsigned long)a)>>8) & (ATOMIC_HASH_SIZE-1)]) | ||
16 | |||
17 | spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] = { | ||
18 | [0 ... (ATOMIC_HASH_SIZE-1)] = SPIN_LOCK_UNLOCKED | ||
19 | }; | ||
20 | |||
21 | #else /* SMP */ | ||
22 | |||
23 | static spinlock_t dummy = SPIN_LOCK_UNLOCKED; | ||
24 | #define ATOMIC_HASH_SIZE 1 | ||
25 | #define ATOMIC_HASH(a) (&dummy) | ||
26 | |||
27 | #endif /* SMP */ | ||
28 | |||
29 | int __atomic_add_return(int i, atomic_t *v) | ||
30 | { | ||
31 | int ret; | ||
32 | unsigned long flags; | ||
33 | spin_lock_irqsave(ATOMIC_HASH(v), flags); | ||
34 | |||
35 | ret = (v->counter += i); | ||
36 | |||
37 | spin_unlock_irqrestore(ATOMIC_HASH(v), flags); | ||
38 | return ret; | ||
39 | } | ||
40 | |||
41 | void atomic_set(atomic_t *v, int i) | ||
42 | { | ||
43 | unsigned long flags; | ||
44 | spin_lock_irqsave(ATOMIC_HASH(v), flags); | ||
45 | |||
46 | v->counter = i; | ||
47 | |||
48 | spin_unlock_irqrestore(ATOMIC_HASH(v), flags); | ||
49 | } | ||
50 | |||
51 | EXPORT_SYMBOL(__atomic_add_return); | ||
52 | EXPORT_SYMBOL(atomic_set); | ||
53 | |||