2005-06-24 09:01:26 +04:00
/*
* linux / include / asm - xtensa / semaphore . h
*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*
* Copyright ( C ) 2001 - 2005 Tensilica Inc .
*/
# ifndef _XTENSA_SEMAPHORE_H
# define _XTENSA_SEMAPHORE_H
# include <asm/atomic.h>
# include <asm/system.h>
# include <linux/wait.h>
# include <linux/rwsem.h>
struct semaphore {
atomic_t count ;
int sleepers ;
wait_queue_head_t wait ;
} ;
2005-09-23 08:44:23 +04:00
# define __SEMAPHORE_INITIALIZER(name,n) \
{ \
. count = ATOMIC_INIT ( n ) , \
. sleepers = 0 , \
. wait = __WAIT_QUEUE_HEAD_INITIALIZER ( ( name ) . wait ) \
}
2005-06-24 09:01:26 +04:00
2005-09-23 08:44:23 +04:00
# define __DECLARE_SEMAPHORE_GENERIC(name,count) \
2005-06-24 09:01:26 +04:00
struct semaphore name = __SEMAPHORE_INITIALIZER ( name , count )
# define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
# define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
2005-09-04 02:57:53 +04:00
static inline void sema_init ( struct semaphore * sem , int val )
2005-06-24 09:01:26 +04:00
{
atomic_set ( & sem - > count , val ) ;
2005-11-07 11:59:01 +03:00
sem - > sleepers = 0 ;
2005-06-24 09:01:26 +04:00
init_waitqueue_head ( & sem - > wait ) ;
}
static inline void init_MUTEX ( struct semaphore * sem )
{
sema_init ( sem , 1 ) ;
}
static inline void init_MUTEX_LOCKED ( struct semaphore * sem )
{
sema_init ( sem , 0 ) ;
}
asmlinkage void __down ( struct semaphore * sem ) ;
asmlinkage int __down_interruptible ( struct semaphore * sem ) ;
asmlinkage int __down_trylock ( struct semaphore * sem ) ;
asmlinkage void __up ( struct semaphore * sem ) ;
extern spinlock_t semaphore_wake_lock ;
2005-09-04 02:57:53 +04:00
static inline void down ( struct semaphore * sem )
2005-06-24 09:01:26 +04:00
{
2005-09-23 08:44:23 +04:00
might_sleep ( ) ;
2005-06-24 09:01:26 +04:00
if ( atomic_sub_return ( 1 , & sem - > count ) < 0 )
__down ( sem ) ;
}
2005-09-04 02:57:53 +04:00
static inline int down_interruptible ( struct semaphore * sem )
2005-06-24 09:01:26 +04:00
{
int ret = 0 ;
2005-09-23 08:44:23 +04:00
might_sleep ( ) ;
2005-06-24 09:01:26 +04:00
if ( atomic_sub_return ( 1 , & sem - > count ) < 0 )
ret = __down_interruptible ( sem ) ;
return ret ;
}
2005-09-04 02:57:53 +04:00
static inline int down_trylock ( struct semaphore * sem )
2005-06-24 09:01:26 +04:00
{
int ret = 0 ;
if ( atomic_sub_return ( 1 , & sem - > count ) < 0 )
ret = __down_trylock ( sem ) ;
return ret ;
}
/*
* Note ! This is subtle . We jump to wake people up only if
* the semaphore was negative ( = = somebody was waiting on it ) .
*/
2005-09-04 02:57:53 +04:00
static inline void up ( struct semaphore * sem )
2005-06-24 09:01:26 +04:00
{
if ( atomic_add_return ( 1 , & sem - > count ) < = 0 )
__up ( sem ) ;
}
# endif /* _XTENSA_SEMAPHORE_H */