1 #ifndef _NIOS2NOMMU_SEMAPHORE_H
2 #define _NIOS2NOMMU_SEMAPHORE_H
4 /*--------------------------------------------------------------------
6 * include/asm-nios2nommu/semaphore.h
8 * Interrupt-safe semaphores..
10 * Derived from M68knommu
12 * (C) Copyright 1996 Linus Torvalds
13 * m68k version by Andreas Schwab
14 * Copyright (C) 2004 Microtronix Datacom Ltd
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * Jan/20/2004 dgt NiosII
28 ---------------------------------------------------------------------*/
30 #define RW_LOCK_BIAS 0x01000000
34 #include <linux/linkage.h>
35 #include <linux/wait.h>
36 #include <linux/spinlock.h>
37 #include <linux/rwsem.h>
39 #include <asm/system.h>
40 #include <asm/atomic.h>
45 wait_queue_head_t wait
;
48 #define __SEMAPHORE_INITIALIZER(name, n) \
50 .count = ATOMIC_INIT(n), \
51 .waking = ATOMIC_INIT(0), \
52 .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
55 #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
56 struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
58 #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
59 #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
61 static inline void sema_init (struct semaphore
*sem
, int val
)
63 *sem
= (struct semaphore
)__SEMAPHORE_INITIALIZER(*sem
, val
);
66 static inline void init_MUTEX (struct semaphore
*sem
)
71 static inline void init_MUTEX_LOCKED (struct semaphore
*sem
)
76 asmlinkage
void __down_failed(void /* special register calling convention */);
77 asmlinkage
int __down_failed_interruptible(void /* params in registers */);
78 asmlinkage
int __down_failed_trylock(void /* params in registers */);
79 asmlinkage
void __up_wakeup(void /* special register calling convention */);
81 asmlinkage
void __down(struct semaphore
* sem
);
82 asmlinkage
int __down_interruptible(struct semaphore
* sem
);
83 asmlinkage
int __down_trylock(struct semaphore
* sem
);
84 asmlinkage
void __up(struct semaphore
* sem
);
86 extern spinlock_t semaphore_wake_lock
;
89 * This is ugly, but we want the default case to fall through.
90 * "down_failed" is a special asm handler that calls the C
91 * routine that actually waits.
93 static inline void down(struct semaphore
* sem
)
98 ...Nios2 has no atomic
"decrement memory"....
100 if (atomic_dec_return(&sem
->count
) < 0)
105 static inline int down_interruptible(struct semaphore
* sem
)
113 ...Nios2 has no atomic
"decrement memory"....
115 if(atomic_dec_return(&sem
->count
) < 0)
116 ret
= __down_interruptible(sem
);
121 static inline int down_trylock(struct semaphore
* sem
)
124 ...Nios2 has no atomic
"decrement memory"....
128 if (atomic_dec_return (&sem
->count
) < 0)
129 ret
= __down_trylock(sem
);
135 * Note! This is subtle. We jump to wake people up only if
136 * the semaphore was negative (== somebody was waiting on it).
137 * The default case (no contention) will result in NO
138 * jumps for both down() and up().
140 static inline void up(struct semaphore
* sem
)
143 ...Nios2 has no atomic
"increment memory"....
145 if (atomic_inc_return(&sem
->count
) <= 0)
150 #endif /* __ASSEMBLY__ */