summaryrefslogtreecommitdiff
path: root/arch/sh/include/asm/bitops-cas.h
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2016-10-20 00:10:27 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2016-10-20 00:10:27 -0300
commitd0b2f91bede3bd5e3d24dd6803e56eee959c1797 (patch)
tree7fee4ab0509879c373c4f2cbd5b8a5be5b4041ee /arch/sh/include/asm/bitops-cas.h
parente914f8eb445e8f74b00303c19c2ffceaedd16a05 (diff)
Linux-libre 4.8.2-gnupck-4.8.2-gnu
Diffstat (limited to 'arch/sh/include/asm/bitops-cas.h')
-rw-r--r--arch/sh/include/asm/bitops-cas.h93
1 files changed, 93 insertions, 0 deletions
diff --git a/arch/sh/include/asm/bitops-cas.h b/arch/sh/include/asm/bitops-cas.h
new file mode 100644
index 000000000..88f793c04
--- /dev/null
+++ b/arch/sh/include/asm/bitops-cas.h
@@ -0,0 +1,93 @@
+#ifndef __ASM_SH_BITOPS_CAS_H
+#define __ASM_SH_BITOPS_CAS_H
+
+static inline unsigned __bo_cas(volatile unsigned *p, unsigned old, unsigned new)
+{
+ __asm__ __volatile__("cas.l %1,%0,@r0"
+ : "+r"(new)
+ : "r"(old), "z"(p)
+ : "t", "memory" );
+ return new;
+}
+
+static inline void set_bit(int nr, volatile void *addr)
+{
+ unsigned mask, old;
+ volatile unsigned *a = addr;
+
+ a += nr >> 5;
+ mask = 1U << (nr & 0x1f);
+
+ do old = *a;
+ while (__bo_cas(a, old, old|mask) != old);
+}
+
+static inline void clear_bit(int nr, volatile void *addr)
+{
+ unsigned mask, old;
+ volatile unsigned *a = addr;
+
+ a += nr >> 5;
+ mask = 1U << (nr & 0x1f);
+
+ do old = *a;
+ while (__bo_cas(a, old, old&~mask) != old);
+}
+
+static inline void change_bit(int nr, volatile void *addr)
+{
+ unsigned mask, old;
+ volatile unsigned *a = addr;
+
+ a += nr >> 5;
+ mask = 1U << (nr & 0x1f);
+
+ do old = *a;
+ while (__bo_cas(a, old, old^mask) != old);
+}
+
+static inline int test_and_set_bit(int nr, volatile void *addr)
+{
+ unsigned mask, old;
+ volatile unsigned *a = addr;
+
+ a += nr >> 5;
+ mask = 1U << (nr & 0x1f);
+
+ do old = *a;
+ while (__bo_cas(a, old, old|mask) != old);
+
+ return !!(old & mask);
+}
+
+static inline int test_and_clear_bit(int nr, volatile void *addr)
+{
+ unsigned mask, old;
+ volatile unsigned *a = addr;
+
+ a += nr >> 5;
+ mask = 1U << (nr & 0x1f);
+
+ do old = *a;
+ while (__bo_cas(a, old, old&~mask) != old);
+
+ return !!(old & mask);
+}
+
+static inline int test_and_change_bit(int nr, volatile void *addr)
+{
+ unsigned mask, old;
+ volatile unsigned *a = addr;
+
+ a += nr >> 5;
+ mask = 1U << (nr & 0x1f);
+
+ do old = *a;
+ while (__bo_cas(a, old, old^mask) != old);
+
+ return !!(old & mask);
+}
+
+#include <asm-generic/bitops/non-atomic.h>
+
+#endif /* __ASM_SH_BITOPS_CAS_H */