linux/arch/blackfin/include/asm/atomic.h
<<
>>
Prefs
   1#ifndef __ARCH_BLACKFIN_ATOMIC__
   2#define __ARCH_BLACKFIN_ATOMIC__
   3
   4#include <linux/types.h>
   5#include <asm/system.h> /* local_irq_XXX() */
   6
   7/*
   8 * Atomic operations that C can't guarantee us.  Useful for
   9 * resource counting etc..
  10 *
  11 * Generally we do not concern about SMP BFIN systems, so we don't have
  12 * to deal with that.
  13 *
  14 * Tony Kou (tonyko@lineo.ca)   Lineo Inc.   2001
  15 */
  16
  17#define ATOMIC_INIT(i)  { (i) }
  18#define atomic_set(v, i)        (((v)->counter) = i)
  19
  20#ifdef CONFIG_SMP
  21
  22#define atomic_read(v)  __raw_uncached_fetch_asm(&(v)->counter)
  23
  24asmlinkage int __raw_uncached_fetch_asm(const volatile int *ptr);
  25
  26asmlinkage int __raw_atomic_update_asm(volatile int *ptr, int value);
  27
  28asmlinkage int __raw_atomic_clear_asm(volatile int *ptr, int value);
  29
  30asmlinkage int __raw_atomic_set_asm(volatile int *ptr, int value);
  31
  32asmlinkage int __raw_atomic_xor_asm(volatile int *ptr, int value);
  33
  34asmlinkage int __raw_atomic_test_asm(const volatile int *ptr, int value);
  35
  36static inline void atomic_add(int i, atomic_t *v)
  37{
  38        __raw_atomic_update_asm(&v->counter, i);
  39}
  40
  41static inline void atomic_sub(int i, atomic_t *v)
  42{
  43        __raw_atomic_update_asm(&v->counter, -i);
  44}
  45
  46static inline int atomic_add_return(int i, atomic_t *v)
  47{
  48        return __raw_atomic_update_asm(&v->counter, i);
  49}
  50
  51static inline int atomic_sub_return(int i, atomic_t *v)
  52{
  53        return __raw_atomic_update_asm(&v->counter, -i);
  54}
  55
  56static inline void atomic_inc(volatile atomic_t *v)
  57{
  58        __raw_atomic_update_asm(&v->counter, 1);
  59}
  60
  61static inline void atomic_dec(volatile atomic_t *v)
  62{
  63        __raw_atomic_update_asm(&v->counter, -1);
  64}
  65
  66static inline void atomic_clear_mask(int mask, atomic_t *v)
  67{
  68        __raw_atomic_clear_asm(&v->counter, mask);
  69}
  70
  71static inline void atomic_set_mask(int mask, atomic_t *v)
  72{
  73        __raw_atomic_set_asm(&v->counter, mask);
  74}
  75
  76static inline int atomic_test_mask(int mask, atomic_t *v)
  77{
  78        return __raw_atomic_test_asm(&v->counter, mask);
  79}
  80
  81/* Atomic operations are already serializing */
  82#define smp_mb__before_atomic_dec()    barrier()
  83#define smp_mb__after_atomic_dec() barrier()
  84#define smp_mb__before_atomic_inc()    barrier()
  85#define smp_mb__after_atomic_inc() barrier()
  86
  87#else /* !CONFIG_SMP */
  88
  89#define atomic_read(v)  ((v)->counter)
  90
  91static inline void atomic_add(int i, atomic_t *v)
  92{
  93        long flags;
  94
  95        local_irq_save_hw(flags);
  96        v->counter += i;
  97        local_irq_restore_hw(flags);
  98}
  99
 100static inline void atomic_sub(int i, atomic_t *v)
 101{
 102        long flags;
 103
 104        local_irq_save_hw(flags);
 105        v->counter -= i;
 106        local_irq_restore_hw(flags);
 107
 108}
 109
 110static inline int atomic_add_return(int i, atomic_t *v)
 111{
 112        int __temp = 0;
 113        long flags;
 114
 115        local_irq_save_hw(flags);
 116        v->counter += i;
 117        __temp = v->counter;
 118        local_irq_restore_hw(flags);
 119
 120
 121        return __temp;
 122}
 123
 124static inline int atomic_sub_return(int i, atomic_t *v)
 125{
 126        int __temp = 0;
 127        long flags;
 128
 129        local_irq_save_hw(flags);
 130        v->counter -= i;
 131        __temp = v->counter;
 132        local_irq_restore_hw(flags);
 133
 134        return __temp;
 135}
 136
 137static inline void atomic_inc(volatile atomic_t *v)
 138{
 139        long flags;
 140
 141        local_irq_save_hw(flags);
 142        v->counter++;
 143        local_irq_restore_hw(flags);
 144}
 145
 146static inline void atomic_dec(volatile atomic_t *v)
 147{
 148        long flags;
 149
 150        local_irq_save_hw(flags);
 151        v->counter--;
 152        local_irq_restore_hw(flags);
 153}
 154
 155static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
 156{
 157        long flags;
 158
 159        local_irq_save_hw(flags);
 160        v->counter &= ~mask;
 161        local_irq_restore_hw(flags);
 162}
 163
 164static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
 165{
 166        long flags;
 167
 168        local_irq_save_hw(flags);
 169        v->counter |= mask;
 170        local_irq_restore_hw(flags);
 171}
 172
 173/* Atomic operations are already serializing */
 174#define smp_mb__before_atomic_dec()    barrier()
 175#define smp_mb__after_atomic_dec() barrier()
 176#define smp_mb__before_atomic_inc()    barrier()
 177#define smp_mb__after_atomic_inc() barrier()
 178
 179#endif /* !CONFIG_SMP */
 180
 181#define atomic_add_negative(a, v)       (atomic_add_return((a), (v)) < 0)
 182#define atomic_dec_return(v) atomic_sub_return(1,(v))
 183#define atomic_inc_return(v) atomic_add_return(1,(v))
 184
 185#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
 186#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 187
 188#define atomic_add_unless(v, a, u)                              \
 189({                                                              \
 190        int c, old;                                             \
 191        c = atomic_read(v);                                     \
 192        while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
 193                c = old;                                        \
 194        c != (u);                                               \
 195})
 196#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
 197
 198/*
 199 * atomic_inc_and_test - increment and test
 200 * @v: pointer of type atomic_t
 201 *
 202 * Atomically increments @v by 1
 203 * and returns true if the result is zero, or false for all
 204 * other cases.
 205 */
 206#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
 207
 208#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
 209#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
 210
 211#include <asm-generic/atomic.h>
 212
 213#endif                          /* __ARCH_BLACKFIN_ATOMIC __ */
 214
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.