1#ifndef _M68K_SEMAPHORE_HELPER_H
2#define _M68K_SEMAPHORE_HELPER_H
3
4/*
5 * SMP- and interrupt-safe semaphores helper functions.
6 *
7 * (C) Copyright 1996 Linus Torvalds
8 *
9 * m68k version by Andreas Schwab
10 */
11
12
13/*
14 * These two _must_ execute atomically wrt each other.
15 */
16static inline void wake_one_more(struct semaphore * sem)
17{
18	atomic_inc(&sem->waking);
19}
20
21static inline int waking_non_zero(struct semaphore *sem)
22{
23	int ret;
24	unsigned long flags;
25
26	spin_lock_irqsave(&semaphore_wake_lock, flags);
27	ret = 0;
28	if (atomic_read(&sem->waking) > 0) {
29		atomic_dec(&sem->waking);
30		ret = 1;
31	}
32	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
33	return ret;
34}
35
36/*
37 * waking_non_zero_interruptible:
38 *	1	got the lock
39 *	0	go to sleep
40 *	-EINTR	interrupted
41 */
42static inline int waking_non_zero_interruptible(struct semaphore *sem,
43						struct task_struct *tsk)
44{
45	int ret;
46	unsigned long flags;
47
48	spin_lock_irqsave(&semaphore_wake_lock, flags);
49	ret = 0;
50	if (atomic_read(&sem->waking) > 0) {
51		atomic_dec(&sem->waking);
52		ret = 1;
53	} else if (signal_pending(tsk)) {
54		atomic_inc(&sem->count);
55		ret = -EINTR;
56	}
57	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
58	return ret;
59}
60
61/*
62 * waking_non_zero_trylock:
63 *	1	failed to lock
64 *	0	got the lock
65 */
66static inline int waking_non_zero_trylock(struct semaphore *sem)
67{
68	int ret;
69	unsigned long flags;
70
71	spin_lock_irqsave(&semaphore_wake_lock, flags);
72	ret = 1;
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
83