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