Kaz Kojima | fc1d4c9 | 2007-06-18 13:58:32 +0900 | [diff] [blame] | 1 | #ifndef __ASM_SH_FUTEX_IRQ_H |
| 2 | #define __ASM_SH_FUTEX_IRQ_H |
| 3 | |
Kaz Kojima | fc1d4c9 | 2007-06-18 13:58:32 +0900 | [diff] [blame] | 4 | |
Michel Lespinasse | 8d7718a | 2011-03-10 18:50:58 -0800 | [diff] [blame] | 5 | static inline int atomic_futex_op_xchg_set(int oparg, u32 __user *uaddr, |
Kaz Kojima | fc1d4c9 | 2007-06-18 13:58:32 +0900 | [diff] [blame] | 6 | 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 Lespinasse | 8d7718a | 2011-03-10 18:50:58 -0800 | [diff] [blame] | 22 | static inline int atomic_futex_op_xchg_add(int oparg, u32 __user *uaddr, |
Kaz Kojima | fc1d4c9 | 2007-06-18 13:58:32 +0900 | [diff] [blame] | 23 | 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 Lespinasse | 8d7718a | 2011-03-10 18:50:58 -0800 | [diff] [blame] | 39 | static inline int atomic_futex_op_xchg_or(int oparg, u32 __user *uaddr, |
Kaz Kojima | fc1d4c9 | 2007-06-18 13:58:32 +0900 | [diff] [blame] | 40 | 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 Lespinasse | 8d7718a | 2011-03-10 18:50:58 -0800 | [diff] [blame] | 56 | static inline int atomic_futex_op_xchg_and(int oparg, u32 __user *uaddr, |
Kaz Kojima | fc1d4c9 | 2007-06-18 13:58:32 +0900 | [diff] [blame] | 57 | 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 Lespinasse | 8d7718a | 2011-03-10 18:50:58 -0800 | [diff] [blame] | 73 | static inline int atomic_futex_op_xchg_xor(int oparg, u32 __user *uaddr, |
Kaz Kojima | fc1d4c9 | 2007-06-18 13:58:32 +0900 | [diff] [blame] | 74 | 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 Lespinasse | 8d7718a | 2011-03-10 18:50:58 -0800 | [diff] [blame] | 90 | static inline int atomic_futex_op_cmpxchg_inatomic(u32 *uval, |
| 91 | u32 __user *uaddr, |
| 92 | u32 oldval, u32 newval) |
Kaz Kojima | fc1d4c9 | 2007-06-18 13:58:32 +0900 | [diff] [blame] | 93 | { |
| 94 | unsigned long flags; |
Michel Lespinasse | 8d7718a | 2011-03-10 18:50:58 -0800 | [diff] [blame] | 95 | int ret; |
| 96 | u32 prev = 0; |
Kaz Kojima | fc1d4c9 | 2007-06-18 13:58:32 +0900 | [diff] [blame] | 97 | |
| 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 Lespinasse | 37a9d91 | 2011-03-10 18:48:51 -0800 | [diff] [blame] | 106 | *uval = prev; |
| 107 | return ret; |
Kaz Kojima | fc1d4c9 | 2007-06-18 13:58:32 +0900 | [diff] [blame] | 108 | } |
| 109 | |
| 110 | #endif /* __ASM_SH_FUTEX_IRQ_H */ |