root/arch/sh/include/asm/spinlock-llsc.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. arch_spin_lock
  2. arch_spin_unlock
  3. arch_spin_trylock
  4. arch_read_lock
  5. arch_read_unlock
  6. arch_write_lock
  7. arch_write_unlock
  8. arch_read_trylock
  9. arch_write_trylock

   1 /* SPDX-License-Identifier: GPL-2.0
   2  *
   3  * include/asm-sh/spinlock-llsc.h
   4  *
   5  * Copyright (C) 2002, 2003 Paul Mundt
   6  * Copyright (C) 2006, 2007 Akio Idehara
   7  */
   8 #ifndef __ASM_SH_SPINLOCK_LLSC_H
   9 #define __ASM_SH_SPINLOCK_LLSC_H
  10 
  11 #include <asm/barrier.h>
  12 #include <asm/processor.h>
  13 
  14 /*
  15  * Your basic SMP spinlocks, allowing only a single CPU anywhere
  16  */
  17 
  18 #define arch_spin_is_locked(x)          ((x)->lock <= 0)
  19 
  20 /*
  21  * Simple spin lock operations.  There are two variants, one clears IRQ's
  22  * on the local processor, one does not.
  23  *
  24  * We make no fairness assumptions.  They have a cost.
  25  */
  26 static inline void arch_spin_lock(arch_spinlock_t *lock)
  27 {
  28         unsigned long tmp;
  29         unsigned long oldval;
  30 
  31         __asm__ __volatile__ (
  32                 "1:                                             \n\t"
  33                 "movli.l        @%2, %0 ! arch_spin_lock        \n\t"
  34                 "mov            %0, %1                          \n\t"
  35                 "mov            #0, %0                          \n\t"
  36                 "movco.l        %0, @%2                         \n\t"
  37                 "bf             1b                              \n\t"
  38                 "cmp/pl         %1                              \n\t"
  39                 "bf             1b                              \n\t"
  40                 : "=&z" (tmp), "=&r" (oldval)
  41                 : "r" (&lock->lock)
  42                 : "t", "memory"
  43         );
  44 }
  45 
  46 static inline void arch_spin_unlock(arch_spinlock_t *lock)
  47 {
  48         unsigned long tmp;
  49 
  50         /* This could be optimised with ARCH_HAS_MMIOWB */
  51         mmiowb();
  52         __asm__ __volatile__ (
  53                 "mov            #1, %0 ! arch_spin_unlock       \n\t"
  54                 "mov.l          %0, @%1                         \n\t"
  55                 : "=&z" (tmp)
  56                 : "r" (&lock->lock)
  57                 : "t", "memory"
  58         );
  59 }
  60 
  61 static inline int arch_spin_trylock(arch_spinlock_t *lock)
  62 {
  63         unsigned long tmp, oldval;
  64 
  65         __asm__ __volatile__ (
  66                 "1:                                             \n\t"
  67                 "movli.l        @%2, %0 ! arch_spin_trylock     \n\t"
  68                 "mov            %0, %1                          \n\t"
  69                 "mov            #0, %0                          \n\t"
  70                 "movco.l        %0, @%2                         \n\t"
  71                 "bf             1b                              \n\t"
  72                 "synco                                          \n\t"
  73                 : "=&z" (tmp), "=&r" (oldval)
  74                 : "r" (&lock->lock)
  75                 : "t", "memory"
  76         );
  77 
  78         return oldval;
  79 }
  80 
  81 /*
  82  * Read-write spinlocks, allowing multiple readers but only one writer.
  83  *
  84  * NOTE! it is quite common to have readers in interrupts but no interrupt
  85  * writers. For those circumstances we can "mix" irq-safe locks - any writer
  86  * needs to get a irq-safe write-lock, but readers can get non-irqsafe
  87  * read-locks.
  88  */
  89 
  90 static inline void arch_read_lock(arch_rwlock_t *rw)
  91 {
  92         unsigned long tmp;
  93 
  94         __asm__ __volatile__ (
  95                 "1:                                             \n\t"
  96                 "movli.l        @%1, %0 ! arch_read_lock        \n\t"
  97                 "cmp/pl         %0                              \n\t"
  98                 "bf             1b                              \n\t"
  99                 "add            #-1, %0                         \n\t"
 100                 "movco.l        %0, @%1                         \n\t"
 101                 "bf             1b                              \n\t"
 102                 : "=&z" (tmp)
 103                 : "r" (&rw->lock)
 104                 : "t", "memory"
 105         );
 106 }
 107 
 108 static inline void arch_read_unlock(arch_rwlock_t *rw)
 109 {
 110         unsigned long tmp;
 111 
 112         __asm__ __volatile__ (
 113                 "1:                                             \n\t"
 114                 "movli.l        @%1, %0 ! arch_read_unlock      \n\t"
 115                 "add            #1, %0                          \n\t"
 116                 "movco.l        %0, @%1                         \n\t"
 117                 "bf             1b                              \n\t"
 118                 : "=&z" (tmp)
 119                 : "r" (&rw->lock)
 120                 : "t", "memory"
 121         );
 122 }
 123 
 124 static inline void arch_write_lock(arch_rwlock_t *rw)
 125 {
 126         unsigned long tmp;
 127 
 128         __asm__ __volatile__ (
 129                 "1:                                             \n\t"
 130                 "movli.l        @%1, %0 ! arch_write_lock       \n\t"
 131                 "cmp/hs         %2, %0                          \n\t"
 132                 "bf             1b                              \n\t"
 133                 "sub            %2, %0                          \n\t"
 134                 "movco.l        %0, @%1                         \n\t"
 135                 "bf             1b                              \n\t"
 136                 : "=&z" (tmp)
 137                 : "r" (&rw->lock), "r" (RW_LOCK_BIAS)
 138                 : "t", "memory"
 139         );
 140 }
 141 
 142 static inline void arch_write_unlock(arch_rwlock_t *rw)
 143 {
 144         __asm__ __volatile__ (
 145                 "mov.l          %1, @%0 ! arch_write_unlock     \n\t"
 146                 :
 147                 : "r" (&rw->lock), "r" (RW_LOCK_BIAS)
 148                 : "t", "memory"
 149         );
 150 }
 151 
 152 static inline int arch_read_trylock(arch_rwlock_t *rw)
 153 {
 154         unsigned long tmp, oldval;
 155 
 156         __asm__ __volatile__ (
 157                 "1:                                             \n\t"
 158                 "movli.l        @%2, %0 ! arch_read_trylock     \n\t"
 159                 "mov            %0, %1                          \n\t"
 160                 "cmp/pl         %0                              \n\t"
 161                 "bf             2f                              \n\t"
 162                 "add            #-1, %0                         \n\t"
 163                 "movco.l        %0, @%2                         \n\t"
 164                 "bf             1b                              \n\t"
 165                 "2:                                             \n\t"
 166                 "synco                                          \n\t"
 167                 : "=&z" (tmp), "=&r" (oldval)
 168                 : "r" (&rw->lock)
 169                 : "t", "memory"
 170         );
 171 
 172         return (oldval > 0);
 173 }
 174 
 175 static inline int arch_write_trylock(arch_rwlock_t *rw)
 176 {
 177         unsigned long tmp, oldval;
 178 
 179         __asm__ __volatile__ (
 180                 "1:                                             \n\t"
 181                 "movli.l        @%2, %0 ! arch_write_trylock    \n\t"
 182                 "mov            %0, %1                          \n\t"
 183                 "cmp/hs         %3, %0                          \n\t"
 184                 "bf             2f                              \n\t"
 185                 "sub            %3, %0                          \n\t"
 186                 "2:                                             \n\t"
 187                 "movco.l        %0, @%2                         \n\t"
 188                 "bf             1b                              \n\t"
 189                 "synco                                          \n\t"
 190                 : "=&z" (tmp), "=&r" (oldval)
 191                 : "r" (&rw->lock), "r" (RW_LOCK_BIAS)
 192                 : "t", "memory"
 193         );
 194 
 195         return (oldval > (RW_LOCK_BIAS - 1));
 196 }
 197 
 198 #endif /* __ASM_SH_SPINLOCK_LLSC_H */

/* [<][>][^][v][top][bottom][index][help] */