1#ifndef __ASM_SH64_SEMAPHORE_H 2#define __ASM_SH64_SEMAPHORE_H 3 4/* 5 * This file is subject to the terms and conditions of the GNU General Public 6 * License. See the file "COPYING" in the main directory of this archive 7 * for more details. 8 * 9 * include/asm-sh64/semaphore.h 10 * 11 * Copyright (C) 2000, 2001 Paolo Alberelli 12 * 13 * SMP- and interrupt-safe semaphores. 14 * 15 * (C) Copyright 1996 Linus Torvalds 16 * 17 * SuperH verison by Niibe Yutaka 18 * (Currently no asm implementation but generic C code...) 19 * 20 */ 21 22#include <linux/linkage.h> 23#include <linux/spinlock.h> 24#include <linux/wait.h> 25#include <linux/rwsem.h> 26 27#include <asm/system.h> 28#include <asm/atomic.h> 29 30struct semaphore { 31 atomic_t count; 32 int sleepers; 33 wait_queue_head_t wait; 34}; 35 36#define __SEMAPHORE_INITIALIZER(name, n) \ 37{ \ 38 .count = ATOMIC_INIT(n), \ 39 .sleepers = 0, \ 40 .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ 41} 42 43#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ 44 struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) 45 46#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) 47#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) 48 49static inline void sema_init (struct semaphore *sem, int val) 50{ 51/* 52 * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); 53 * 54 * i'd rather use the more flexible initialization above, but sadly 55 * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well. 56 */ 57 atomic_set(&sem->count, val); 58 sem->sleepers = 0; 59 init_waitqueue_head(&sem->wait); 60} 61 62static inline void init_MUTEX (struct semaphore *sem) 63{ 64 sema_init(sem, 1); 65} 66 67static inline void init_MUTEX_LOCKED (struct semaphore *sem) 68{ 69 sema_init(sem, 0); 70} 71 72 73asmlinkage void __down(struct semaphore * sem); 74asmlinkage int __down_interruptible(struct semaphore * sem); 75asmlinkage int __down_trylock(struct semaphore * sem); 76asmlinkage void __up(struct semaphore * sem); 77 78extern spinlock_t semaphore_wake_lock; 79 80static inline void down(struct semaphore * sem) 81{ 82 if (atomic_dec_return(&sem->count) < 0) 83 __down(sem); 84} 85 86static inline int down_interruptible(struct semaphore * sem) 87{ 88 int ret = 0; 89 90 if (atomic_dec_return(&sem->count) < 0) 91 ret = __down_interruptible(sem); 92 return ret; 93} 94 95static inline int down_trylock(struct semaphore * sem) 96{ 97 int ret = 0; 98 99 if (atomic_dec_return(&sem->count) < 0) 100 ret = __down_trylock(sem); 101 return ret; 102} 103 104/* 105 * Note! This is subtle. We jump to wake people up only if 106 * the semaphore was negative (== somebody was waiting on it). 107 */ 108static inline void up(struct semaphore * sem) 109{ 110 if (atomic_inc_return(&sem->count) <= 0) 111 __up(sem); 112} 113 114#endif /* __ASM_SH64_SEMAPHORE_H */ 115