ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / include / asm-h8300 / atomic.h
1 #ifndef __ARCH_H8300_ATOMIC__
2 #define __ARCH_H8300_ATOMIC__
3
4 /*
5  * Atomic operations that C can't guarantee us.  Useful for
6  * resource counting etc..
7  */
8
9 typedef struct { int counter; } atomic_t;
10 #define ATOMIC_INIT(i)  { (i) }
11
12 #define atomic_read(v)          ((v)->counter)
13 #define atomic_set(v, i)        (((v)->counter) = i)
14
15 #include <asm/system.h>
16 #include <linux/kernel.h>
17
18 static __inline__ int atomic_add_return(int i, atomic_t *v)
19 {
20         int ret,flags;
21         local_irq_save(flags);
22         ret = v->counter += i;
23         local_irq_restore(flags);
24         return ret;
25 }
26
27 #define atomic_add(i, v) atomic_add_return(i, v)
28
29 static __inline__ int atomic_sub_return(int i, atomic_t *v)
30 {
31         int ret,flags;
32         local_irq_save(flags);
33         ret = v->counter -= i;
34         local_irq_restore(flags);
35         return ret;
36 }
37
38 #define atomic_sub(i, v) atomic_sub_return(i, v)
39
40 static __inline__ int atomic_inc_return(atomic_t *v)
41 {
42         int ret,flags;
43         local_irq_save(flags);
44         v->counter++;
45         ret = v->counter;
46         local_irq_restore(flags);
47         return ret;
48 }
49
50 #define atomic_inc(v) atomic_inc_return(v)
51
52 static __inline__ int atomic_dec_return(atomic_t *v)
53 {
54         int ret,flags;
55         local_irq_save(flags);
56         --v->counter;
57         ret = v->counter;
58         local_irq_restore(flags);
59         return ret;
60 }
61
62 #define atomic_dec(v) atomic_dec_return(v)
63
64 static __inline__ int atomic_dec_and_test(atomic_t *v)
65 {
66         int ret,flags;
67         local_irq_save(flags);
68         --v->counter;
69         ret = v->counter;
70         local_irq_restore(flags);
71         return ret == 0;
72 }
73
74 static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *v)
75 {
76         __asm__ __volatile__("stc ccr,r1l\n\t"
77                              "orc #0x80,ccr\n\t"
78                              "mov.l %0,er0\n\t"
79                              "and.l %1,er0\n\t"
80                              "mov.l er0,%0\n\t"
81                              "ldc r1l,ccr" 
82                              : "=m" (*v) : "g" (~(mask)) :"er0","er1");
83 }
84
85 static __inline__ void atomic_set_mask(unsigned long mask, unsigned long *v)
86 {
87         __asm__ __volatile__("stc ccr,r1l\n\t"
88                              "orc #0x80,ccr\n\t"
89                              "mov.l %0,er0\n\t"
90                              "or.l %1,er0\n\t"
91                              "mov.l er0,%0\n\t"
92                              "ldc r1l,ccr" 
93                              : "=m" (*v) : "g" (mask) :"er0","er1");
94 }
95
96 /* Atomic operations are already serializing */
97 #define smp_mb__before_atomic_dec()    barrier()
98 #define smp_mb__after_atomic_dec() barrier()
99 #define smp_mb__before_atomic_inc()    barrier()
100 #define smp_mb__after_atomic_inc() barrier()
101
102 #endif /* __ARCH_H8300_ATOMIC __ */