linux/arch/sh/include/asm/cmpxchg.h
<<
>>
Prefs
   1#ifndef __ASM_SH_CMPXCHG_H
   2#define __ASM_SH_CMPXCHG_H
   3
   4/*
   5 * Atomic operations that C can't guarantee us.  Useful for
   6 * resource counting etc..
   7 */
   8
   9#include <linux/compiler.h>
  10#include <linux/types.h>
  11
  12#if defined(CONFIG_GUSA_RB)
  13#include <asm/cmpxchg-grb.h>
  14#elif defined(CONFIG_CPU_SH4A)
  15#include <asm/cmpxchg-llsc.h>
  16#else
  17#include <asm/cmpxchg-irq.h>
  18#endif
  19
  20extern void __xchg_called_with_bad_pointer(void);
  21
  22#define __xchg(ptr, x, size)                            \
  23({                                                      \
  24        unsigned long __xchg__res;                      \
  25        volatile void *__xchg_ptr = (ptr);              \
  26        switch (size) {                                 \
  27        case 4:                                         \
  28                __xchg__res = xchg_u32(__xchg_ptr, x);  \
  29                break;                                  \
  30        case 1:                                         \
  31                __xchg__res = xchg_u8(__xchg_ptr, x);   \
  32                break;                                  \
  33        default:                                        \
  34                __xchg_called_with_bad_pointer();       \
  35                __xchg__res = x;                        \
  36                break;                                  \
  37        }                                               \
  38                                                        \
  39        __xchg__res;                                    \
  40})
  41
  42#define xchg(ptr,x)     \
  43        ((__typeof__(*(ptr)))__xchg((ptr),(unsigned long)(x), sizeof(*(ptr))))
  44
  45/* This function doesn't exist, so you'll get a linker error
  46 * if something tries to do an invalid cmpxchg(). */
  47extern void __cmpxchg_called_with_bad_pointer(void);
  48
  49static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
  50                unsigned long new, int size)
  51{
  52        switch (size) {
  53        case 4:
  54                return __cmpxchg_u32(ptr, old, new);
  55        }
  56        __cmpxchg_called_with_bad_pointer();
  57        return old;
  58}
  59
  60#define cmpxchg(ptr,o,n)                                                 \
  61  ({                                                                     \
  62     __typeof__(*(ptr)) _o_ = (o);                                       \
  63     __typeof__(*(ptr)) _n_ = (n);                                       \
  64     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,           \
  65                                    (unsigned long)_n_, sizeof(*(ptr))); \
  66  })
  67
  68#endif /* __ASM_SH_CMPXCHG_H */
  69