Merge branch 'irq-fixes-for-linus-4' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6] / arch / sh / include / asm / futex-irq.h
1 #ifndef __ASM_SH_FUTEX_IRQ_H
2 #define __ASM_SH_FUTEX_IRQ_H
3
4 #include <asm/system.h>
5
6 static inline int atomic_futex_op_xchg_set(int oparg, int __user *uaddr,
7                                            int *oldval)
8 {
9         unsigned long flags;
10         int ret;
11
12         local_irq_save(flags);
13
14         ret = get_user(*oldval, uaddr);
15         if (!ret)
16                 ret = put_user(oparg, uaddr);
17
18         local_irq_restore(flags);
19
20         return ret;
21 }
22
23 static inline int atomic_futex_op_xchg_add(int oparg, int __user *uaddr,
24                                            int *oldval)
25 {
26         unsigned long flags;
27         int ret;
28
29         local_irq_save(flags);
30
31         ret = get_user(*oldval, uaddr);
32         if (!ret)
33                 ret = put_user(*oldval + oparg, uaddr);
34
35         local_irq_restore(flags);
36
37         return ret;
38 }
39
40 static inline int atomic_futex_op_xchg_or(int oparg, int __user *uaddr,
41                                           int *oldval)
42 {
43         unsigned long flags;
44         int ret;
45
46         local_irq_save(flags);
47
48         ret = get_user(*oldval, uaddr);
49         if (!ret)
50                 ret = put_user(*oldval | oparg, uaddr);
51
52         local_irq_restore(flags);
53
54         return ret;
55 }
56
57 static inline int atomic_futex_op_xchg_and(int oparg, int __user *uaddr,
58                                            int *oldval)
59 {
60         unsigned long flags;
61         int ret;
62
63         local_irq_save(flags);
64
65         ret = get_user(*oldval, uaddr);
66         if (!ret)
67                 ret = put_user(*oldval & oparg, uaddr);
68
69         local_irq_restore(flags);
70
71         return ret;
72 }
73
74 static inline int atomic_futex_op_xchg_xor(int oparg, int __user *uaddr,
75                                            int *oldval)
76 {
77         unsigned long flags;
78         int ret;
79
80         local_irq_save(flags);
81
82         ret = get_user(*oldval, uaddr);
83         if (!ret)
84                 ret = put_user(*oldval ^ oparg, uaddr);
85
86         local_irq_restore(flags);
87
88         return ret;
89 }
90
91 static inline int atomic_futex_op_cmpxchg_inatomic(int __user *uaddr,
92                                                    int oldval, int newval)
93 {
94         unsigned long flags;
95         int ret, prev = 0;
96
97         local_irq_save(flags);
98
99         ret = get_user(prev, uaddr);
100         if (!ret && oldval == prev)
101                 ret = put_user(newval, uaddr);
102
103         local_irq_restore(flags);
104
105         if (ret)
106                 return ret;
107
108         return prev;
109 }
110
111 #endif /* __ASM_SH_FUTEX_IRQ_H */