linux/arch/metag/include/asm/cmpxchg.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef __ASM_METAG_CMPXCHG_H
   3#define __ASM_METAG_CMPXCHG_H
   4
   5#include <asm/barrier.h>
   6
   7#if defined(CONFIG_METAG_ATOMICITY_IRQSOFF)
   8#include <asm/cmpxchg_irq.h>
   9#elif defined(CONFIG_METAG_ATOMICITY_LOCK1)
  10#include <asm/cmpxchg_lock1.h>
  11#elif defined(CONFIG_METAG_ATOMICITY_LNKGET)
  12#include <asm/cmpxchg_lnkget.h>
  13#endif
  14
  15extern void __xchg_called_with_bad_pointer(void);
  16
  17#define __xchg(ptr, x, size)                            \
  18({                                                      \
  19        unsigned long __xchg__res;                      \
  20        volatile void *__xchg_ptr = (ptr);              \
  21        switch (size) {                                 \
  22        case 4:                                         \
  23                __xchg__res = xchg_u32(__xchg_ptr, x);  \
  24                break;                                  \
  25        case 1:                                         \
  26                __xchg__res = xchg_u8(__xchg_ptr, x);   \
  27                break;                                  \
  28        default:                                        \
  29                __xchg_called_with_bad_pointer();       \
  30                __xchg__res = x;                        \
  31                break;                                  \
  32        }                                               \
  33                                                        \
  34        __xchg__res;                                    \
  35})
  36
  37#define xchg(ptr, x)    \
  38        ((__typeof__(*(ptr)))__xchg((ptr), (unsigned long)(x), sizeof(*(ptr))))
  39
  40/* This function doesn't exist, so you'll get a linker error
  41 * if something tries to do an invalid cmpxchg(). */
  42extern void __cmpxchg_called_with_bad_pointer(void);
  43
  44static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
  45                                      unsigned long new, int size)
  46{
  47        switch (size) {
  48        case 4:
  49                return __cmpxchg_u32(ptr, old, new);
  50        }
  51        __cmpxchg_called_with_bad_pointer();
  52        return old;
  53}
  54
  55#define cmpxchg(ptr, o, n)                                              \
  56        ({                                                              \
  57                __typeof__(*(ptr)) _o_ = (o);                           \
  58                __typeof__(*(ptr)) _n_ = (n);                           \
  59                (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
  60                                               (unsigned long)_n_,      \
  61                                               sizeof(*(ptr)));         \
  62        })
  63
  64#endif /* __ASM_METAG_CMPXCHG_H */
  65