|
@@ -0,0 +1,77 @@
|
|
|
+#ifndef _M68K_BITOPS_H
|
|
|
+#define _M68K_BITOPS_H
|
|
|
+/*
|
|
|
+ * Copyright 1992, Linus Torvalds.
|
|
|
+ *
|
|
|
+ * This file is subject to the terms and conditions of the GNU General Public
|
|
|
+ * License. See the file COPYING in the main directory of this archive
|
|
|
+ * for more details.
|
|
|
+ */
|
|
|
+
|
|
|
+#ifndef _LINUX_BITOPS_H
|
|
|
+#error only <linux/bitops.h> can be included directly
|
|
|
+#endif
|
|
|
+
|
|
|
+#include <linux/compiler.h>
|
|
|
+
|
|
|
+/*
|
|
|
+ * Bit access functions vary across the ColdFire and 68k families.
|
|
|
+ * So we will break them out here, and then macro in the ones we want.
|
|
|
+ *
|
|
|
+ * ColdFire - supports standard bset/bclr/bchg with register operand only
|
|
|
+ * 68000 - supports standard bset/bclr/bchg with memory operand
|
|
|
+ * >= 68020 - also supports the bfset/bfclr/bfchg instructions
|
|
|
+ *
|
|
|
+ * Although it is possible to use only the bset/bclr/bchg with register
|
|
|
+ * operands on all platforms you end up with larger generated code.
|
|
|
+ * So we use the best form possible on a given platform.
|
|
|
+ */
|
|
|
+
|
|
|
+static inline void bset_reg_set_bit(int nr, volatile unsigned long *vaddr)
|
|
|
+{
|
|
|
+ char *p = (char *)vaddr + (nr ^ 31) / 8;
|
|
|
+
|
|
|
+ __asm__ __volatile__ ("bset %1,(%0)"
|
|
|
+ :
|
|
|
+ : "a" (p), "di" (nr & 7)
|
|
|
+ : "memory");
|
|
|
+}
|
|
|
+
|
|
|
+static inline void bset_mem_set_bit(int nr, volatile unsigned long *vaddr)
|
|
|
+{
|
|
|
+ char *p = (char *)vaddr + (nr ^ 31) / 8;
|
|
|
+
|
|
|
+ __asm__ __volatile__ ("bset %1,%0"
|
|
|
+ : "+m" (*p)
|
|
|
+ : "di" (nr & 7));
|
|
|
+}
|
|
|
+
|
|
|
+static inline void bfset_mem_set_bit(int nr, volatile unsigned long *vaddr)
|
|
|
+{
|
|
|
+ __asm__ __volatile__ ("bfset %1{%0:#1}"
|
|
|
+ :
|
|
|
+ : "d" (nr ^ 31), "o" (*vaddr)
|
|
|
+ : "memory");
|
|
|
+}
|
|
|
+
|
|
|
+#if defined(CONFIG_COLDFIRE)
|
|
|
+#define set_bit(nr, vaddr) bset_reg_set_bit(nr, vaddr)
|
|
|
+#elif defined(CONFIG_CPU_HAS_NO_BITFIELDS)
|
|
|
+#define set_bit(nr, vaddr) bset_mem_set_bit(nr, vaddr)
|
|
|
+#else
|
|
|
+#define set_bit(nr, vaddr) (__builtin_constant_p(nr) ? \
|
|
|
+ bset_mem_set_bit(nr, vaddr) : \
|
|
|
+ bfset_mem_set_bit(nr, vaddr))
|
|
|
+#endif
|
|
|
+
|
|
|
+#define __set_bit(nr, vaddr) set_bit(nr, vaddr)
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ * clear_bit() doesn't provide any barrier for the compiler.
|
|
|
+ */
|
|
|
+#define smp_mb__before_clear_bit() barrier()
|
|
|
+#define smp_mb__after_clear_bit() barrier()
|
|
|
+
|
|
|
+static inline void bclr_reg_clear_bit(int nr, volatile unsigned long *vaddr)
|
|
|
+{
|