blob: 63d33129ea2348c9228d42987b7e8dab77887745 [file] [log] [blame]
Kaz Kojimafc1d4c92007-06-18 13:58:32 +09001#ifndef __ASM_SH_FUTEX_IRQ_H
2#define __ASM_SH_FUTEX_IRQ_H
3
Kaz Kojimafc1d4c92007-06-18 13:58:32 +09004
Michel Lespinasse8d7718a2011-03-10 18:50:58 -08005static inline int atomic_futex_op_xchg_set(int oparg, u32 __user *uaddr,
Kaz Kojimafc1d4c92007-06-18 13:58:32 +09006 int *oldval)
7{
8 unsigned long flags;
9 int ret;
10
11 local_irq_save(flags);
12
13 ret = get_user(*oldval, uaddr);
14 if (!ret)
15 ret = put_user(oparg, uaddr);
16
17 local_irq_restore(flags);
18
19 return ret;
20}
21
Michel Lespinasse8d7718a2011-03-10 18:50:58 -080022static inline int atomic_futex_op_xchg_add(int oparg, u32 __user *uaddr,
Kaz Kojimafc1d4c92007-06-18 13:58:32 +090023 int *oldval)
24{
25 unsigned long flags;
26 int ret;
27
28 local_irq_save(flags);
29
30 ret = get_user(*oldval, uaddr);
31 if (!ret)
32 ret = put_user(*oldval + oparg, uaddr);
33
34 local_irq_restore(flags);
35
36 return ret;
37}
38
Michel Lespinasse8d7718a2011-03-10 18:50:58 -080039static inline int atomic_futex_op_xchg_or(int oparg, u32 __user *uaddr,
Kaz Kojimafc1d4c92007-06-18 13:58:32 +090040 int *oldval)
41{
42 unsigned long flags;
43 int ret;
44
45 local_irq_save(flags);
46
47 ret = get_user(*oldval, uaddr);
48 if (!ret)
49 ret = put_user(*oldval | oparg, uaddr);
50
51 local_irq_restore(flags);
52
53 return ret;
54}
55
Michel Lespinasse8d7718a2011-03-10 18:50:58 -080056static inline int atomic_futex_op_xchg_and(int oparg, u32 __user *uaddr,
Kaz Kojimafc1d4c92007-06-18 13:58:32 +090057 int *oldval)
58{
59 unsigned long flags;
60 int ret;
61
62 local_irq_save(flags);
63
64 ret = get_user(*oldval, uaddr);
65 if (!ret)
66 ret = put_user(*oldval & oparg, uaddr);
67
68 local_irq_restore(flags);
69
70 return ret;
71}
72
Michel Lespinasse8d7718a2011-03-10 18:50:58 -080073static inline int atomic_futex_op_xchg_xor(int oparg, u32 __user *uaddr,
Kaz Kojimafc1d4c92007-06-18 13:58:32 +090074 int *oldval)
75{
76 unsigned long flags;
77 int ret;
78
79 local_irq_save(flags);
80
81 ret = get_user(*oldval, uaddr);
82 if (!ret)
83 ret = put_user(*oldval ^ oparg, uaddr);
84
85 local_irq_restore(flags);
86
87 return ret;
88}
89
Michel Lespinasse8d7718a2011-03-10 18:50:58 -080090static inline int atomic_futex_op_cmpxchg_inatomic(u32 *uval,
91 u32 __user *uaddr,
92 u32 oldval, u32 newval)
Kaz Kojimafc1d4c92007-06-18 13:58:32 +090093{
94 unsigned long flags;
Michel Lespinasse8d7718a2011-03-10 18:50:58 -080095 int ret;
96 u32 prev = 0;
Kaz Kojimafc1d4c92007-06-18 13:58:32 +090097
98 local_irq_save(flags);
99
100 ret = get_user(prev, uaddr);
101 if (!ret && oldval == prev)
102 ret = put_user(newval, uaddr);
103
104 local_irq_restore(flags);
105
Michel Lespinasse37a9d912011-03-10 18:48:51 -0800106 *uval = prev;
107 return ret;
Kaz Kojimafc1d4c92007-06-18 13:58:32 +0900108}
109
110#endif /* __ASM_SH_FUTEX_IRQ_H */