linux-bk/include/asm-m68knommu/semaphore.h
<<
>>
Prefs
   1#ifndef _M68K_SEMAPHORE_H
   2#define _M68K_SEMAPHORE_H
   3
   4#define RW_LOCK_BIAS             0x01000000
   5
   6#ifndef __ASSEMBLY__
   7
   8#include <linux/linkage.h>
   9#include <linux/wait.h>
  10#include <linux/spinlock.h>
  11#include <linux/rwsem.h>
  12
  13#include <asm/system.h>
  14#include <asm/atomic.h>
  15
  16/*
  17 * Interrupt-safe semaphores..
  18 *
  19 * (C) Copyright 1996 Linus Torvalds
  20 *
  21 * m68k version by Andreas Schwab
  22 */
  23
  24
  25struct semaphore {
  26        atomic_t count;
  27        atomic_t waking;
  28        wait_queue_head_t wait;
  29};
  30
  31#define __SEMAPHORE_INITIALIZER(name, n)                                \
  32{                                                                       \
  33        .count          = ATOMIC_INIT(n),                               \
  34        .waking         = ATOMIC_INIT(0),                               \
  35        .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
  36}
  37
  38#define __MUTEX_INITIALIZER(name) \
  39        __SEMAPHORE_INITIALIZER(name,1)
  40
  41#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
  42        struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
  43
  44#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
  45#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
  46
  47extern inline void sema_init (struct semaphore *sem, int val)
  48{
  49        *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
  50}
  51
  52static inline void init_MUTEX (struct semaphore *sem)
  53{
  54        sema_init(sem, 1);
  55}
  56
  57static inline void init_MUTEX_LOCKED (struct semaphore *sem)
  58{
  59        sema_init(sem, 0);
  60}
  61
  62asmlinkage void __down_failed(void /* special register calling convention */);
  63asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
  64asmlinkage int  __down_failed_trylock(void  /* params in registers */);
  65asmlinkage void __up_wakeup(void /* special register calling convention */);
  66
  67asmlinkage void __down(struct semaphore * sem);
  68asmlinkage int  __down_interruptible(struct semaphore * sem);
  69asmlinkage int  __down_trylock(struct semaphore * sem);
  70asmlinkage void __up(struct semaphore * sem);
  71
  72extern spinlock_t semaphore_wake_lock;
  73
  74/*
  75 * This is ugly, but we want the default case to fall through.
  76 * "down_failed" is a special asm handler that calls the C
  77 * routine that actually waits. See arch/m68k/lib/semaphore.S
  78 */
  79extern inline void down(struct semaphore * sem)
  80{
  81        might_sleep();
  82        __asm__ __volatile__(
  83                "| atomic down operation\n\t"
  84                "movel  %0, %%a1\n\t"
  85                "lea    %%pc@(1f), %%a0\n\t"
  86                "subql  #1, %%a1@\n\t"
  87                "jmi __down_failed\n"
  88                "1:"
  89                : /* no outputs */
  90                : "g" (sem)
  91                : "cc", "%a0", "%a1", "memory");
  92}
  93
  94extern inline int down_interruptible(struct semaphore * sem)
  95{
  96        int ret;
  97
  98        might_sleep();
  99        __asm__ __volatile__(
 100                "| atomic down operation\n\t"
 101                "movel  %1, %%a1\n\t"
 102                "lea    %%pc@(1f), %%a0\n\t"
 103                "subql  #1, %%a1@\n\t"
 104                "jmi __down_failed_interruptible\n\t"
 105                "clrl   %%d0\n"
 106                "1: movel       %%d0, %0\n"
 107                : "=d" (ret)
 108                : "g" (sem)
 109                : "cc", "%d0", "%a0", "%a1", "memory");
 110        return(ret);
 111}
 112
 113extern inline int down_trylock(struct semaphore * sem)
 114{
 115        register struct semaphore *sem1 __asm__ ("%a1") = sem;
 116        register int result __asm__ ("%d0");
 117
 118        __asm__ __volatile__(
 119                "| atomic down trylock operation\n\t"
 120                "subql #1,%1@\n\t"
 121                "jmi 2f\n\t"
 122                "clrl %0\n"
 123                "1:\n"
 124                ".section .text.lock,\"ax\"\n"
 125                ".even\n"
 126                "2:\tpea 1b\n\t"
 127                "jbra __down_failed_trylock\n"
 128                ".previous"
 129                : "=d" (result)
 130                : "a" (sem1)
 131                : "memory");
 132        return result;
 133}
 134
 135/*
 136 * Note! This is subtle. We jump to wake people up only if
 137 * the semaphore was negative (== somebody was waiting on it).
 138 * The default case (no contention) will result in NO
 139 * jumps for both down() and up().
 140 */
 141extern inline void up(struct semaphore * sem)
 142{
 143        __asm__ __volatile__(
 144                "| atomic up operation\n\t"
 145                "movel  %0, %%a1\n\t"
 146                "lea    %%pc@(1f), %%a0\n\t"
 147                "addql  #1, %%a1@\n\t"
 148                "jle __up_wakeup\n"
 149                "1:"
 150                : /* no outputs */
 151                : "g" (sem)
 152                : "cc", "%a0", "%a1", "memory");
 153}
 154
 155#endif /* __ASSEMBLY__ */
 156
 157#endif
 158
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.