1#ifndef _BFIN_SEMAPHORE_H 2#define _BFIN_SEMAPHORE_H 3 4#ifndef __ASSEMBLY__ 5 6#include <linux/linkage.h> 7#include <linux/wait.h> 8#include <linux/spinlock.h> 9#include <linux/rwsem.h> 10#include <asm/atomic.h> 11 12/* 13 * Interrupt-safe semaphores.. 14 * 15 * (C) Copyright 1996 Linus Torvalds 16 * 17 * BFIN version by akbar hussain Lineo Inc April 2001 18 * 19 */ 20 21struct semaphore { 22 atomic_t count; 23 int sleepers; 24 wait_queue_head_t wait; 25}; 26 27#define __SEMAPHORE_INITIALIZER(name, n) \ 28{ \ 29 .count = ATOMIC_INIT(n), \ 30 .sleepers = 0, \ 31 .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ 32} 33 34#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ 35 struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) 36 37#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) 38#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) 39 40static inline void sema_init(struct semaphore *sem, int val) 41{ 42 *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val); 43} 44 45static inline void init_MUTEX(struct semaphore *sem) 46{ 47 sema_init(sem, 1); 48} 49 50static inline void init_MUTEX_LOCKED(struct semaphore *sem) 51{ 52 sema_init(sem, 0); 53} 54 55asmlinkage void __down(struct semaphore *sem); 56asmlinkage int __down_interruptible(struct semaphore *sem); 57asmlinkage int __down_trylock(struct semaphore *sem); 58asmlinkage void __up(struct semaphore *sem); 59 60extern spinlock_t semaphore_wake_lock; 61 62/* 63 * This is ugly, but we want the default case to fall through. 64 * "down_failed" is a special asm handler that calls the C 65 * routine that actually waits. 66 */ 67static inline void down(struct semaphore *sem) 68{ 69 might_sleep(); 70 if (atomic_dec_return(&sem->count) < 0) 71 __down(sem); 72} 73 74static inline int down_interruptible(struct semaphore *sem) 75{ 76 int ret = 0; 77 78 might_sleep(); 79 if (atomic_dec_return(&sem->count) < 0) 80 ret = __down_interruptible(sem); 81 return (ret); 82} 83 84static inline int down_trylock(struct semaphore *sem) 85{ 86 int ret = 0; 87 88 if (atomic_dec_return(&sem->count) < 0) 89 ret = __down_trylock(sem); 90 return ret; 91} 92 93/* 94 * Note! This is subtle. We jump to wake people up only if 95 * the semaphore was negative (== somebody was waiting on it). 96 * The default case (no contention) will result in NO 97 * jumps for both down() and up(). 98 */ 99static inline void up(struct semaphore *sem) 100{ 101 if (atomic_inc_return(&sem->count) <= 0) 102 __up(sem); 103} 104 105#endif /* __ASSEMBLY__ */ 106#endif /* _BFIN_SEMAPHORE_H */ 107