1/* 2 * linux/include/asm-xtensa/semaphore.h 3 * 4 * This file is subject to the terms and conditions of the GNU General Public 5 * License. See the file "COPYING" in the main directory of this archive 6 * for more details. 7 * 8 * Copyright (C) 2001 - 2005 Tensilica Inc. 9 */ 10 11#ifndef _XTENSA_SEMAPHORE_H 12#define _XTENSA_SEMAPHORE_H 13 14#include <asm/atomic.h> 15#include <asm/system.h> 16#include <linux/wait.h> 17#include <linux/rwsem.h> 18 19struct semaphore { 20 atomic_t count; 21 int sleepers; 22 wait_queue_head_t wait; 23}; 24 25#define __SEMAPHORE_INITIALIZER(name,n) \ 26{ \ 27 .count = ATOMIC_INIT(n), \ 28 .sleepers = 0, \ 29 .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ 30} 31 32#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ 33 struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) 34 35#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) 36#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) 37 38static inline void sema_init (struct semaphore *sem, int val) 39{ 40 atomic_set(&sem->count, val); 41 sem->sleepers = 0; 42 init_waitqueue_head(&sem->wait); 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 62static inline void down(struct semaphore * sem) 63{ 64 might_sleep(); 65 66 if (atomic_sub_return(1, &sem->count) < 0) 67 __down(sem); 68} 69 70static inline int down_interruptible(struct semaphore * sem) 71{ 72 int ret = 0; 73 74 might_sleep(); 75 76 if (atomic_sub_return(1, &sem->count) < 0) 77 ret = __down_interruptible(sem); 78 return ret; 79} 80 81static inline int down_trylock(struct semaphore * sem) 82{ 83 int ret = 0; 84 85 if (atomic_sub_return(1, &sem->count) < 0) 86 ret = __down_trylock(sem); 87 return ret; 88} 89 90/* 91 * Note! This is subtle. We jump to wake people up only if 92 * the semaphore was negative (== somebody was waiting on it). 93 */ 94static inline void up(struct semaphore * sem) 95{ 96 if (atomic_add_return(1, &sem->count) <= 0) 97 __up(sem); 98} 99 100#endif /* _XTENSA_SEMAPHORE_H */ 101