xref: /openbmc/linux/arch/sh/include/asm/futex-irq.h (revision 25985edc)
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, u32 __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, u32 __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, u32 __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, u32 __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, u32 __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(u32 *uval,
92 						   u32 __user *uaddr,
93 						   u32 oldval, u32 newval)
94 {
95 	unsigned long flags;
96 	int ret;
97 	u32 prev = 0;
98 
99 	local_irq_save(flags);
100 
101 	ret = get_user(prev, uaddr);
102 	if (!ret && oldval == prev)
103 		ret = put_user(newval, uaddr);
104 
105 	local_irq_restore(flags);
106 
107 	*uval = prev;
108 	return ret;
109 }
110 
111 #endif /* __ASM_SH_FUTEX_IRQ_H */
112