uboot/arch/arm/include/asm/atomic.h
<<
>>
Prefs
   1/*
   2 *  linux/include/asm-arm/atomic.h
   3 *
   4 *  Copyright (c) 1996 Russell King.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 *  Changelog:
  11 *   27-06-1996 RMK     Created
  12 *   13-04-1997 RMK     Made functions atomic!
  13 *   07-12-1997 RMK     Upgraded for v2.1.
  14 *   26-08-1998 PJB     Added #ifdef __KERNEL__
  15 */
  16#ifndef __ASM_ARM_ATOMIC_H
  17#define __ASM_ARM_ATOMIC_H
  18
  19#include <linux/config.h>
  20
  21#ifdef CONFIG_SMP
  22#error SMP not supported
  23#endif
  24
  25typedef struct { volatile int counter; } atomic_t;
  26
  27#define ATOMIC_INIT(i)  { (i) }
  28
  29#ifdef __KERNEL__
  30#include <asm/proc/system.h>
  31
  32#define atomic_read(v)  ((v)->counter)
  33#define atomic_set(v,i) (((v)->counter) = (i))
  34
  35static inline void atomic_add(int i, volatile atomic_t *v)
  36{
  37        unsigned long flags;
  38
  39        local_irq_save(flags);
  40        v->counter += i;
  41        local_irq_restore(flags);
  42}
  43
  44static inline void atomic_sub(int i, volatile atomic_t *v)
  45{
  46        unsigned long flags;
  47
  48        local_irq_save(flags);
  49        v->counter -= i;
  50        local_irq_restore(flags);
  51}
  52
  53static inline void atomic_inc(volatile atomic_t *v)
  54{
  55        unsigned long flags;
  56
  57        local_irq_save(flags);
  58        v->counter += 1;
  59        local_irq_restore(flags);
  60}
  61
  62static inline void atomic_dec(volatile atomic_t *v)
  63{
  64        unsigned long flags;
  65
  66        local_irq_save(flags);
  67        v->counter -= 1;
  68        local_irq_restore(flags);
  69}
  70
  71static inline int atomic_dec_and_test(volatile atomic_t *v)
  72{
  73        unsigned long flags;
  74        int val;
  75
  76        local_irq_save(flags);
  77        val = v->counter;
  78        v->counter = val -= 1;
  79        local_irq_restore(flags);
  80
  81        return val == 0;
  82}
  83
  84static inline int atomic_add_negative(int i, volatile atomic_t *v)
  85{
  86        unsigned long flags;
  87        int val;
  88
  89        local_irq_save(flags);
  90        val = v->counter;
  91        v->counter = val += i;
  92        local_irq_restore(flags);
  93
  94        return val < 0;
  95}
  96
  97static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
  98{
  99        unsigned long flags;
 100
 101        local_irq_save(flags);
 102        *addr &= ~mask;
 103        local_irq_restore(flags);
 104}
 105
 106/* Atomic operations are already serializing on ARM */
 107#define smp_mb__before_atomic_dec()     barrier()
 108#define smp_mb__after_atomic_dec()      barrier()
 109#define smp_mb__before_atomic_inc()     barrier()
 110#define smp_mb__after_atomic_inc()      barrier()
 111
 112#endif
 113#endif
 114