[U-Boot] [RFC PATCH v1] mips: add atomic operations

Chris Packham judge.packham at gmail.com
Fri Sep 7 08:24:04 UTC 2018


Add mips version of atomic.h and basic atomic operations. These aren't
the optimised versions from the Linux kernel, just basic stubs that
satisfy users that need something to define atomic_inc() etc.

Signed-off-by: Chris Packham <judge.packham at gmail.com>

---
At $dayjob we have a mips target that we want to run UBIFS on. UBIFS
requires atomic.h. This is my naive attempt to supply enough of atomic.h
to satisfy UBIFS.

It's no coincidence that this looks like the arm version. I am
wondering if it's worth a asm-generic version leaving architectures that
actually need true atomic operations able to define them.

 arch/mips/include/asm/atomic.h | 151 +++++++++++++++++++++++++++++++++
 1 file changed, 151 insertions(+)
 create mode 100644 arch/mips/include/asm/atomic.h

diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
new file mode 100644
index 000000000000..3ab5684fdef4
--- /dev/null
+++ b/arch/mips/include/asm/atomic.h
@@ -0,0 +1,151 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+#ifndef _ASM_ATOMIC_H
+#define _ASM_ATOMIC_H
+
+#include <asm/system.h>
+
+typedef struct { volatile int counter; } atomic_t;
+#if BITS_PER_LONG == 32
+typedef struct { volatile long long counter; } atomic64_t;
+#else /* BIT_PER_LONG == 32 */
+typedef struct { volatile long counter; } atomic64_t;
+#endif
+
+#define ATOMIC_INIT(i)	  { (i) }
+
+#define atomic_read(v)	((v)->counter)
+#define atomic_set(v, i)	(((v)->counter) = (i))
+#define atomic64_read(v)	atomic_read(v)
+#define atomic64_set(v, i)	atomic_set(v, i)
+
+static inline void atomic_add(int i, volatile atomic_t *v)
+{
+	unsigned long flags = 0;
+
+	local_irq_save(flags);
+	v->counter += i;
+	local_irq_restore(flags);
+}
+
+static inline void atomic_sub(int i, volatile atomic_t *v)
+{
+	unsigned long flags = 0;
+
+	local_irq_save(flags);
+	v->counter -= i;
+	local_irq_restore(flags);
+}
+
+static inline void atomic_inc(volatile atomic_t *v)
+{
+	unsigned long flags = 0;
+
+	local_irq_save(flags);
+	v->counter += 1;
+	local_irq_restore(flags);
+}
+
+static inline void atomic_dec(volatile atomic_t *v)
+{
+	unsigned long flags = 0;
+
+	local_irq_save(flags);
+	v->counter -= 1;
+	local_irq_restore(flags);
+}
+
+static inline int atomic_dec_and_test(volatile atomic_t *v)
+{
+	unsigned long flags = 0;
+	int val;
+
+	local_irq_save(flags);
+	val = v->counter;
+	v->counter = val -= 1;
+	local_irq_restore(flags);
+
+	return val == 0;
+}
+
+static inline int atomic_add_negative(int i, volatile atomic_t *v)
+{
+	unsigned long flags = 0;
+	int val;
+
+	local_irq_save(flags);
+	val = v->counter;
+	v->counter = val += i;
+	local_irq_restore(flags);
+
+	return val < 0;
+}
+
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+{
+	unsigned long flags = 0;
+
+	local_irq_save(flags);
+	*addr &= ~mask;
+	local_irq_restore(flags);
+}
+
+#if BITS_PER_LONG == 32
+
+static inline void atomic64_add(long long i, volatile atomic64_t *v)
+{
+	unsigned long flags = 0;
+
+	local_irq_save(flags);
+	v->counter += i;
+	local_irq_restore(flags);
+}
+
+static inline void atomic64_sub(long long i, volatile atomic64_t *v)
+{
+	unsigned long flags = 0;
+
+	local_irq_save(flags);
+	v->counter -= i;
+	local_irq_restore(flags);
+}
+
+#else /* BIT_PER_LONG == 32 */
+
+static inline void atomic64_add(long i, volatile atomic64_t *v)
+{
+	unsigned long flags = 0;
+
+	local_irq_save(flags);
+	v->counter += i;
+	local_irq_restore(flags);
+}
+
+static inline void atomic64_sub(long i, volatile atomic64_t *v)
+{
+	unsigned long flags = 0;
+
+	local_irq_save(flags);
+	v->counter -= i;
+	local_irq_restore(flags);
+}
+#endif /* BIT_PER_LONG == 32 */
+
+static inline void atomic64_inc(volatile atomic64_t *v)
+{
+	unsigned long flags = 0;
+
+	local_irq_save(flags);
+	v->counter += 1;
+	local_irq_restore(flags);
+}
+
+static inline void atomic64_dec(volatile atomic64_t *v)
+{
+	unsigned long flags = 0;
+
+	local_irq_save(flags);
+	v->counter -= 1;
+	local_irq_restore(flags);
+}
+
+#endif
-- 
2.18.0



More information about the U-Boot mailing list