Initial import
[openvswitch] / datapath / linux-2.4 / compat-2.4 / include-arm / asm / atomic.h
1 #ifndef __ASM_ARM_ATOMIC_H_WRAPPER
2 #define __ASM_ARM_ATOMIC_H_WRAPPER 1
3
4 #include_next <asm/atomic.h>
5
6 #error "Cribbed from linux-2.6/include/asm-arm/atomic.h but untested"
7
8 #ifdef __KERNEL__
9
10 #if __LINUX_ARM_ARCH__ >= 6
11
12 static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
13 {
14         unsigned long oldval, res;
15
16         do {
17                 __asm__ __volatile__("@ atomic_cmpxchg\n"
18                 "ldrex  %1, [%2]\n"
19                 "mov    %0, #0\n"
20                 "teq    %1, %3\n"
21                 "strexeq %0, %4, [%2]\n"
22                     : "=&r" (res), "=&r" (oldval)
23                     : "r" (&ptr->counter), "Ir" (old), "r" (new)
24                     : "cc");
25         } while (res);
26
27         return oldval;
28 }
29
30 #else /* ARM_ARCH_6 */
31
32 #include <asm/system.h>
33
34 #ifdef CONFIG_SMP
35 #error SMP not supported on pre-ARMv6 CPUs
36 #endif
37
38 static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
39 {
40         int ret;
41         unsigned long flags;
42
43         raw_local_irq_save(flags);
44         ret = v->counter;
45         if (likely(ret == old))
46                 v->counter = new;
47         raw_local_irq_restore(flags);
48
49         return ret;
50 }
51
52 #endif /* __LINUX_ARM_ARCH__ */
53
54 #endif /* __KERNEL__ */
55
56 #endif /* asm/atomic.h */