blackfin architecture
[safe/jmp/linux-2.6] / include / asm-blackfin / semaphore-helper.h
1 /* Based on M68K version,       Lineo Inc.      May 2001 */
2
3 #ifndef _BFIN_SEMAPHORE_HELPER_H
4 #define _BFIN_SEMAPHORE_HELPER_H
5
6 /*
7  * SMP- and interrupt-safe semaphores helper functions.
8  *
9  * (C) Copyright 1996 Linus Torvalds
10  *
11  */
12
13 #include <asm/errno.h>
14
15 /*
16  * These two _must_ execute atomically wrt each other.
17  */
18 static inline void wake_one_more(struct semaphore *sem)
19 {
20         atomic_inc(&sem->waking);
21 }
22
23 static inline int waking_non_zero(struct semaphore *sem)
24 {
25         int ret;
26         unsigned long flags = 0;
27
28         spin_lock_irqsave(&semaphore_wake_lock, flags);
29         ret = 0;
30         if (atomic_read(&sem->waking) > 0) {
31                 atomic_dec(&sem->waking);
32                 ret = 1;
33         }
34         spin_unlock_irqrestore(&semaphore_wake_lock, flags);
35         return ret;
36 }
37
38 /*
39  * waking_non_zero_interruptible:
40  *      1       got the lock
41  *      0       go to sleep
42  *      -EINTR  interrupted
43  */
44 static inline int waking_non_zero_interruptible(struct semaphore *sem,
45                                                 struct task_struct *tsk)
46 {
47         int ret = 0;
48         unsigned long flags = 0;
49
50         spin_lock_irqsave(&semaphore_wake_lock, flags);
51         if (atomic_read(&sem->waking) > 0) {
52                 atomic_dec(&sem->waking);
53                 ret = 1;
54         } else if (signal_pending(tsk)) {
55                 atomic_inc(&sem->count);
56                 ret = -EINTR;
57         }
58         spin_unlock_irqrestore(&semaphore_wake_lock, flags);
59         return ret;
60 }
61
62 /*
63  * waking_non_zero_trylock:
64  *      1       failed to lock
65  *      0       got the lock
66  */
67 static inline int waking_non_zero_trylock(struct semaphore *sem)
68 {
69         int ret = 1;
70         unsigned long flags = 0;
71
72         spin_lock_irqsave(&semaphore_wake_lock, flags);
73         if (atomic_read(&sem->waking) > 0) {
74                 atomic_dec(&sem->waking);
75                 ret = 0;
76         } else
77                 atomic_inc(&sem->count);
78         spin_unlock_irqrestore(&semaphore_wake_lock, flags);
79         return ret;
80 }
81
82 #endif                          /* _BFIN_SEMAPHORE_HELPER_H */