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#ifdef CONFIG_SMP
  20#error SMP not supported
  21#endif
  22
  23typedef struct { volatile int counter; } atomic_t;
  24
  25#define ATOMIC_INIT(i)  { (i) }
  26
  27#ifdef __KERNEL__
  28#include <asm/proc-armv/system.h>
  29
  30#define atomic_read(v)  ((v)->counter)
  31#define atomic_set(v,i) (((v)->counter) = (i))
  32
  33static inline void atomic_add(int i, volatile atomic_t *v)
  34{
  35        unsigned long flags = 0;
  36
  37        local_irq_save(flags);
  38        v->counter += i;
  39        local_irq_restore(flags);
  40}
  41
  42static inline void atomic_sub(int i, volatile atomic_t *v)
  43{
  44        unsigned long flags = 0;
  45
  46        local_irq_save(flags);
  47        v->counter -= i;
  48        local_irq_restore(flags);
  49}
  50
  51static inline void atomic_inc(volatile atomic_t *v)
  52{
  53        unsigned long flags = 0;
  54
  55        local_irq_save(flags);
  56        v->counter += 1;
  57        local_irq_restore(flags);
  58}
  59
  60static inline void atomic_dec(volatile atomic_t *v)
  61{
  62        unsigned long flags = 0;
  63
  64        local_irq_save(flags);
  65        v->counter -= 1;
  66        local_irq_restore(flags);
  67}
  68
  69static inline int atomic_dec_and_test(volatile atomic_t *v)
  70{
  71        unsigned long flags = 0;
  72        int val;
  73
  74        local_irq_save(flags);
  75        val = v->counter;
  76        v->counter = val -= 1;
  77        local_irq_restore(flags);
  78
  79        return val == 0;
  80}
  81
  82static inline int atomic_add_negative(int i, volatile atomic_t *v)
  83{
  84        unsigned long flags = 0;
  85        int val;
  86
  87        local_irq_save(flags);
  88        val = v->counter;
  89        v->counter = val += i;
  90        local_irq_restore(flags);
  91
  92        return val < 0;
  93}
  94
  95static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
  96{
  97        unsigned long flags = 0;
  98
  99        local_irq_save(flags);
 100        *addr &= ~mask;
 101        local_irq_restore(flags);
 102}
 103
 104/* Atomic operations are already serializing on ARM */
 105#define smp_mb__before_atomic_dec()     barrier()
 106#define smp_mb__after_atomic_dec()      barrier()
 107#define smp_mb__before_atomic_inc()     barrier()
 108#define smp_mb__after_atomic_inc()      barrier()
 109
 110#endif
 111#endif
 112