| 
									
										
										
										
											2007-06-18 13:58:32 +09:00
										 |  |  | #ifndef __ASM_SH_FUTEX_IRQ_H
 | 
					
						
							|  |  |  | #define __ASM_SH_FUTEX_IRQ_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-10 18:50:58 -08:00
										 |  |  | static inline int atomic_futex_op_xchg_set(int oparg, u32 __user *uaddr, | 
					
						
							| 
									
										
										
										
											2007-06-18 13:58:32 +09:00
										 |  |  | 					   int *oldval) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long flags; | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	local_irq_save(flags); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = get_user(*oldval, uaddr); | 
					
						
							|  |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		ret = put_user(oparg, uaddr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	local_irq_restore(flags); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-10 18:50:58 -08:00
										 |  |  | static inline int atomic_futex_op_xchg_add(int oparg, u32 __user *uaddr, | 
					
						
							| 
									
										
										
										
											2007-06-18 13:58:32 +09:00
										 |  |  | 					   int *oldval) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long flags; | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	local_irq_save(flags); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = get_user(*oldval, uaddr); | 
					
						
							|  |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		ret = put_user(*oldval + oparg, uaddr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	local_irq_restore(flags); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-10 18:50:58 -08:00
										 |  |  | static inline int atomic_futex_op_xchg_or(int oparg, u32 __user *uaddr, | 
					
						
							| 
									
										
										
										
											2007-06-18 13:58:32 +09:00
										 |  |  | 					  int *oldval) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long flags; | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	local_irq_save(flags); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = get_user(*oldval, uaddr); | 
					
						
							|  |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		ret = put_user(*oldval | oparg, uaddr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	local_irq_restore(flags); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-10 18:50:58 -08:00
										 |  |  | static inline int atomic_futex_op_xchg_and(int oparg, u32 __user *uaddr, | 
					
						
							| 
									
										
										
										
											2007-06-18 13:58:32 +09:00
										 |  |  | 					   int *oldval) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long flags; | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	local_irq_save(flags); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = get_user(*oldval, uaddr); | 
					
						
							|  |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		ret = put_user(*oldval & oparg, uaddr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	local_irq_restore(flags); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-10 18:50:58 -08:00
										 |  |  | static inline int atomic_futex_op_xchg_xor(int oparg, u32 __user *uaddr, | 
					
						
							| 
									
										
										
										
											2007-06-18 13:58:32 +09:00
										 |  |  | 					   int *oldval) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	unsigned long flags; | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	local_irq_save(flags); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = get_user(*oldval, uaddr); | 
					
						
							|  |  |  | 	if (!ret) | 
					
						
							|  |  |  | 		ret = put_user(*oldval ^ oparg, uaddr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	local_irq_restore(flags); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-10 18:50:58 -08:00
										 |  |  | static inline int atomic_futex_op_cmpxchg_inatomic(u32 *uval, | 
					
						
							|  |  |  | 						   u32 __user *uaddr, | 
					
						
							|  |  |  | 						   u32 oldval, u32 newval) | 
					
						
							| 
									
										
										
										
											2007-06-18 13:58:32 +09:00
										 |  |  | { | 
					
						
							|  |  |  | 	unsigned long flags; | 
					
						
							| 
									
										
										
										
											2011-03-10 18:50:58 -08:00
										 |  |  | 	int ret; | 
					
						
							|  |  |  | 	u32 prev = 0; | 
					
						
							| 
									
										
										
										
											2007-06-18 13:58:32 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	local_irq_save(flags); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = get_user(prev, uaddr); | 
					
						
							|  |  |  | 	if (!ret && oldval == prev) | 
					
						
							|  |  |  | 		ret = put_user(newval, uaddr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	local_irq_restore(flags); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-10 18:48:51 -08:00
										 |  |  | 	*uval = prev; | 
					
						
							|  |  |  | 	return ret; | 
					
						
							| 
									
										
										
										
											2007-06-18 13:58:32 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* __ASM_SH_FUTEX_IRQ_H */
 |