ad0aaf0a284acaad9855796743497de0f3082bf2
[openwrt/openwrt.git] / target / linux / ubicom32 / files / arch / ubicom32 / include / asm / semaphore-helper.h
1 /*
2 * arch/ubicom32/include/asm/semaphore-helper.h
3 * Semaphore related definitions for Ubicom32 architecture.
4 *
5 * (C) Copyright 2009, Ubicom, Inc.
6 *
7 * This file is part of the Ubicom32 Linux Kernel Port.
8 *
9 * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10 * it and/or modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation, either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with the Ubicom32 Linux Kernel Port. If not,
21 * see <http://www.gnu.org/licenses/>.
22 *
23 * Ubicom32 implementation derived from (with many thanks):
24 * arch/m68knommu
25 * arch/blackfin
26 * arch/parisc
27 */
28 #ifndef _ASM_UBICOM32_SEMAPHORE_HELPER_H
29 #define _ASM_UBICOM32_SEMAPHORE_HELPER_H
30
31 /*
32 * SMP- and interrupt-safe semaphores helper functions.
33 *
34 * (C) Copyright 1996 Linus Torvalds
35 *
36 * m68k version by Andreas Schwab
37 */
38
39
40 /*
41 * These two _must_ execute atomically wrt each other.
42 */
43 static inline void wake_one_more(struct semaphore * sem)
44 {
45 atomic_inc(&sem->waking);
46 }
47
48 static inline int waking_non_zero(struct semaphore *sem)
49 {
50 int ret;
51 unsigned long flags;
52
53 spin_lock_irqsave(&semaphore_wake_lock, flags);
54 ret = 0;
55 if (atomic_read(&sem->waking) > 0) {
56 atomic_dec(&sem->waking);
57 ret = 1;
58 }
59 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
60 return ret;
61 }
62
63 /*
64 * waking_non_zero_interruptible:
65 * 1 got the lock
66 * 0 go to sleep
67 * -EINTR interrupted
68 */
69 static inline int waking_non_zero_interruptible(struct semaphore *sem,
70 struct task_struct *tsk)
71 {
72 int ret;
73 unsigned long flags;
74
75 spin_lock_irqsave(&semaphore_wake_lock, flags);
76 ret = 0;
77 if (atomic_read(&sem->waking) > 0) {
78 atomic_dec(&sem->waking);
79 ret = 1;
80 } else if (signal_pending(tsk)) {
81 atomic_inc(&sem->count);
82 ret = -EINTR;
83 }
84 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
85 return ret;
86 }
87
88 /*
89 * waking_non_zero_trylock:
90 * 1 failed to lock
91 * 0 got the lock
92 */
93 static inline int waking_non_zero_trylock(struct semaphore *sem)
94 {
95 int ret;
96 unsigned long flags;
97
98 spin_lock_irqsave(&semaphore_wake_lock, flags);
99 ret = 1;
100 if (atomic_read(&sem->waking) > 0) {
101 atomic_dec(&sem->waking);
102 ret = 0;
103 } else
104 atomic_inc(&sem->count);
105 spin_unlock_irqrestore(&semaphore_wake_lock, flags);
106 return ret;
107 }
108
109 #endif /* _ASM_UBICOM32_SEMAPHORE_HELPER_H */