1#ifndef _H8300_SEMAPHORE_HELPER_H
2#define _H8300_SEMAPHORE_HELPER_H
3
4/*
5 * SMP- and interrupt-safe semaphores helper functions.
6 *
7 * (C) Copyright 1996 Linus Torvalds
8 *
9 * based on
10 * m68k version by Andreas Schwab
11 */
12
13#include <linux/errno.h>
14
15/*
16 * These two _must_ execute atomically wrt each other.
17 */
18static inline void wake_one_more(struct semaphore * sem)
19{
20	atomic_inc((atomic_t *)&sem->sleepers);
21}
22
23static inline int waking_non_zero(struct semaphore *sem)
24{
25	int ret;
26	unsigned long flags;
27
28	spin_lock_irqsave(&semaphore_wake_lock, flags);
29	ret = 0;
30	if (sem->sleepers > 0) {
31		sem->sleepers--;
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 */
44static inline int waking_non_zero_interruptible(struct semaphore *sem,
45						struct task_struct *tsk)
46{
47	int ret;
48	unsigned long flags;
49
50	spin_lock_irqsave(&semaphore_wake_lock, flags);
51	ret = 0;
52	if (sem->sleepers > 0) {
53		sem->sleepers--;
54		ret = 1;
55	} else if (signal_pending(tsk)) {
56		atomic_inc(&sem->count);
57		ret = -EINTR;
58	}
59	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
60	return ret;
61}
62
63/*
64 * waking_non_zero_trylock:
65 *	1	failed to lock
66 *	0	got the lock
67 */
68static inline int waking_non_zero_trylock(struct semaphore *sem)
69{
70	int ret;
71	unsigned long flags;
72
73	spin_lock_irqsave(&semaphore_wake_lock, flags);
74	ret = 1;
75	if (sem->sleepers <= 0)
76		atomic_inc(&sem->count);
77	else {
78		sem->sleepers--;
79		ret = 0;
80	}
81	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
82	return ret;
83}
84
85#endif
86