mn10300: add the MN10300/AM33 architecture to the kernel
[pandora-kernel.git] / include / asm-mn10300 / semaphore.h
1 /* MN10300 Semaphores
2  *
3  * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public Licence
8  * as published by the Free Software Foundation; either version
9  * 2 of the Licence, or (at your option) any later version.
10  */
11 #ifndef _ASM_SEMAPHORE_H
12 #define _ASM_SEMAPHORE_H
13
14 #ifndef __ASSEMBLY__
15
16 #include <linux/linkage.h>
17 #include <linux/wait.h>
18 #include <linux/spinlock.h>
19 #include <linux/rwsem.h>
20
21 #define SEMAPHORE_DEBUG         0
22
23 /*
24  * the semaphore definition
25  * - if count is >0 then there are tokens available on the semaphore for down
26  *   to collect
27  * - if count is <=0 then there are no spare tokens, and anyone that wants one
28  *   must wait
29  * - if wait_list is not empty, then there are processes waiting for the
30  *   semaphore
31  */
32 struct semaphore {
33         atomic_t                count;          /* it's not really atomic, it's
34                                                  * just that certain modules
35                                                  * expect to be able to access
36                                                  * it directly */
37         spinlock_t              wait_lock;
38         struct list_head        wait_list;
39 #if SEMAPHORE_DEBUG
40         unsigned                __magic;
41 #endif
42 };
43
44 #if SEMAPHORE_DEBUG
45 # define __SEM_DEBUG_INIT(name) , (long)&(name).__magic
46 #else
47 # define __SEM_DEBUG_INIT(name)
48 #endif
49
50
51 #define __SEMAPHORE_INITIALIZER(name, init_count)                       \
52 {                                                                       \
53         .count          = ATOMIC_INIT(init_count),                      \
54         .wait_lock      = __SPIN_LOCK_UNLOCKED((name).wait_lock),       \
55         .wait_list      = LIST_HEAD_INIT((name).wait_list)              \
56         __SEM_DEBUG_INIT(name)                                          \
57 }
58
59 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
60         struct semaphore name = __SEMAPHORE_INITIALIZER(name, count)
61
62 #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1)
63 #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0)
64
65 static inline void sema_init(struct semaphore *sem, int val)
66 {
67         *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val);
68 }
69
70 static inline void init_MUTEX(struct semaphore *sem)
71 {
72         sema_init(sem, 1);
73 }
74
75 static inline void init_MUTEX_LOCKED(struct semaphore *sem)
76 {
77         sema_init(sem, 0);
78 }
79
80 extern void __down(struct semaphore *sem, unsigned long flags);
81 extern int  __down_interruptible(struct semaphore *sem, unsigned long flags);
82 extern void __up(struct semaphore *sem);
83
84 static inline void down(struct semaphore *sem)
85 {
86         unsigned long flags;
87         int count;
88
89 #if SEMAPHORE_DEBUG
90         CHECK_MAGIC(sem->__magic);
91 #endif
92
93         spin_lock_irqsave(&sem->wait_lock, flags);
94         count = atomic_read(&sem->count);
95         if (likely(count > 0)) {
96                 atomic_set(&sem->count, count - 1);
97                 spin_unlock_irqrestore(&sem->wait_lock, flags);
98         } else {
99                 __down(sem, flags);
100         }
101 }
102
103 static inline int down_interruptible(struct semaphore *sem)
104 {
105         unsigned long flags;
106         int count, ret = 0;
107
108 #if SEMAPHORE_DEBUG
109         CHECK_MAGIC(sem->__magic);
110 #endif
111
112         spin_lock_irqsave(&sem->wait_lock, flags);
113         count = atomic_read(&sem->count);
114         if (likely(count > 0)) {
115                 atomic_set(&sem->count, count - 1);
116                 spin_unlock_irqrestore(&sem->wait_lock, flags);
117         } else {
118                 ret = __down_interruptible(sem, flags);
119         }
120         return ret;
121 }
122
123 /*
124  * non-blockingly attempt to down() a semaphore.
125  * - returns zero if we acquired it
126  */
127 static inline int down_trylock(struct semaphore *sem)
128 {
129         unsigned long flags;
130         int count, success = 0;
131
132 #if SEMAPHORE_DEBUG
133         CHECK_MAGIC(sem->__magic);
134 #endif
135
136         spin_lock_irqsave(&sem->wait_lock, flags);
137         count = atomic_read(&sem->count);
138         if (likely(count > 0)) {
139                 atomic_set(&sem->count, count - 1);
140                 success = 1;
141         }
142         spin_unlock_irqrestore(&sem->wait_lock, flags);
143         return !success;
144 }
145
146 static inline void up(struct semaphore *sem)
147 {
148         unsigned long flags;
149
150 #if SEMAPHORE_DEBUG
151         CHECK_MAGIC(sem->__magic);
152 #endif
153
154         spin_lock_irqsave(&sem->wait_lock, flags);
155         if (!list_empty(&sem->wait_list))
156                 __up(sem);
157         else
158                 atomic_set(&sem->count, atomic_read(&sem->count) + 1);
159         spin_unlock_irqrestore(&sem->wait_lock, flags);
160 }
161
162 static inline int sem_getcount(struct semaphore *sem)
163 {
164         return atomic_read(&sem->count);
165 }
166
167 #endif /* __ASSEMBLY__ */
168
169 #endif