linux/arch/openrisc/include/asm/bitops/atomic.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2014 Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
   3 *
   4 * This file is licensed under the terms of the GNU General Public License
   5 * version 2.  This program is licensed "as is" without any warranty of any
   6 * kind, whether express or implied.
   7 */
   8
   9#ifndef __ASM_OPENRISC_BITOPS_ATOMIC_H
  10#define __ASM_OPENRISC_BITOPS_ATOMIC_H
  11
  12static inline void set_bit(int nr, volatile unsigned long *addr)
  13{
  14        unsigned long mask = BIT_MASK(nr);
  15        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  16        unsigned long tmp;
  17
  18        __asm__ __volatile__(
  19                "1:     l.lwa   %0,0(%1)        \n"
  20                "       l.or    %0,%0,%2        \n"
  21                "       l.swa   0(%1),%0        \n"
  22                "       l.bnf   1b              \n"
  23                "        l.nop                  \n"
  24                : "=&r"(tmp)
  25                : "r"(p), "r"(mask)
  26                : "cc", "memory");
  27}
  28
  29static inline void clear_bit(int nr, volatile unsigned long *addr)
  30{
  31        unsigned long mask = BIT_MASK(nr);
  32        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  33        unsigned long tmp;
  34
  35        __asm__ __volatile__(
  36                "1:     l.lwa   %0,0(%1)        \n"
  37                "       l.and   %0,%0,%2        \n"
  38                "       l.swa   0(%1),%0        \n"
  39                "       l.bnf   1b              \n"
  40                "        l.nop                  \n"
  41                : "=&r"(tmp)
  42                : "r"(p), "r"(~mask)
  43                : "cc", "memory");
  44}
  45
  46static inline void change_bit(int nr, volatile unsigned long *addr)
  47{
  48        unsigned long mask = BIT_MASK(nr);
  49        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  50        unsigned long tmp;
  51
  52        __asm__ __volatile__(
  53                "1:     l.lwa   %0,0(%1)        \n"
  54                "       l.xor   %0,%0,%2        \n"
  55                "       l.swa   0(%1),%0        \n"
  56                "       l.bnf   1b              \n"
  57                "        l.nop                  \n"
  58                : "=&r"(tmp)
  59                : "r"(p), "r"(mask)
  60                : "cc", "memory");
  61}
  62
  63static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
  64{
  65        unsigned long mask = BIT_MASK(nr);
  66        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  67        unsigned long old;
  68        unsigned long tmp;
  69
  70        __asm__ __volatile__(
  71                "1:     l.lwa   %0,0(%2)        \n"
  72                "       l.or    %1,%0,%3        \n"
  73                "       l.swa   0(%2),%1        \n"
  74                "       l.bnf   1b              \n"
  75                "        l.nop                  \n"
  76                : "=&r"(old), "=&r"(tmp)
  77                : "r"(p), "r"(mask)
  78                : "cc", "memory");
  79
  80        return (old & mask) != 0;
  81}
  82
  83static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
  84{
  85        unsigned long mask = BIT_MASK(nr);
  86        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  87        unsigned long old;
  88        unsigned long tmp;
  89
  90        __asm__ __volatile__(
  91                "1:     l.lwa   %0,0(%2)        \n"
  92                "       l.and   %1,%0,%3        \n"
  93                "       l.swa   0(%2),%1        \n"
  94                "       l.bnf   1b              \n"
  95                "        l.nop                  \n"
  96                : "=&r"(old), "=&r"(tmp)
  97                : "r"(p), "r"(~mask)
  98                : "cc", "memory");
  99
 100        return (old & mask) != 0;
 101}
 102
 103static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
 104{
 105        unsigned long mask = BIT_MASK(nr);
 106        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
 107        unsigned long old;
 108        unsigned long tmp;
 109
 110        __asm__ __volatile__(
 111                "1:     l.lwa   %0,0(%2)        \n"
 112                "       l.xor   %1,%0,%3        \n"
 113                "       l.swa   0(%2),%1        \n"
 114                "       l.bnf   1b              \n"
 115                "        l.nop                  \n"
 116                : "=&r"(old), "=&r"(tmp)
 117                : "r"(p), "r"(mask)
 118                : "cc", "memory");
 119
 120        return (old & mask) != 0;
 121}
 122
 123#endif /* __ASM_OPENRISC_BITOPS_ATOMIC_H */
 124