[Concept,12/19] linux: Add refcount.h header with refcount_t type

Message ID 20260117011448.3007171-13-sjg@u-boot.org
State New
Headers
Series ext4l: Reduce ext4_uboot.h size by moving code to include/linux |

Commit Message

Simon Glass Jan. 17, 2026, 1:14 a.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Move reference count type and operations to a dedicated header file
that mirrors the Linux kernel organisation.

refcount.h provides:
- refcount_t type (wrapper around atomic_t)
- REFCOUNT_INIT() macro for static initialisation
- refcount_set(), refcount_read() - set/get value
- refcount_inc(), refcount_dec() - increment/decrement
- refcount_dec_and_test() - decrement and test if zero
- refcount_inc_not_zero() - increment unless zero

These are simplified versions for single-threaded U-Boot, mapping
directly to atomic_t operations.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 fs/ext4l/ext4_uboot.h    | 10 ++----
 include/linux/refcount.h | 70 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+), 7 deletions(-)
 create mode 100644 include/linux/refcount.h
  

Patch

diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h
index 57d967965da..4fe7d40c37f 100644
--- a/fs/ext4l/ext4_uboot.h
+++ b/fs/ext4l/ext4_uboot.h
@@ -89,13 +89,12 @@ 
 #include <linux/dcache.h>
 #include <linux/uuid.h>
 #include <linux/smp.h>
+#include <linux/refcount.h>
 
 /* atomic_dec_if_positive, atomic_add_unless, etc. are now in asm-generic/atomic.h */
 /* cmpxchg is now in asm-generic/atomic.h */
 /* SMP stubs (raw_smp_processor_id, smp_*mb) are now in linux/smp.h */
-
-/* Reference count type */
-typedef struct { atomic_t refs; } refcount_t;
+/* refcount_t and operations are now in linux/refcount.h */
 
 /* rwlock_t and read_lock/read_unlock are now in linux/spinlock.h */
 #include <linux/spinlock.h>
@@ -1790,10 +1789,7 @@  static inline unsigned long ext4_find_next_bit_le(const void *addr,
  */
 #include <linux/bio.h>
 
-/* refcount operations - map to atomic */
-#define refcount_set(r, v)		atomic_set((atomic_t *)(r), v)
-#define refcount_dec_and_test(r)	atomic_dec_and_test((atomic_t *)(r))
-#define refcount_inc(r)			atomic_inc((atomic_t *)(r))
+/* refcount operations are now in linux/refcount.h */
 
 /* xchg - exchange value atomically */
 #define xchg(ptr, new)			({ typeof(*(ptr)) __old = *(ptr); *(ptr) = (new); __old; })
diff --git a/include/linux/refcount.h b/include/linux/refcount.h
new file mode 100644
index 00000000000..ce001b437bf
--- /dev/null
+++ b/include/linux/refcount.h
@@ -0,0 +1,70 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Reference count type stubs for U-Boot
+ *
+ * Based on Linux refcount.h - simplified for single-threaded U-Boot.
+ */
+#ifndef _LINUX_REFCOUNT_H
+#define _LINUX_REFCOUNT_H
+
+#include <asm-generic/atomic.h>
+
+/**
+ * typedef refcount_t - reference count type
+ *
+ * Variant of atomic_t for reference counting with saturation semantics.
+ * In U-Boot this is a simple wrapper around atomic_t.
+ */
+typedef struct {
+	atomic_t refs;
+} refcount_t;
+
+#define REFCOUNT_INIT(n)	{ .refs = ATOMIC_INIT(n), }
+
+/**
+ * refcount_set() - set a refcount's value
+ * @r: the refcount
+ * @n: value to set
+ */
+#define refcount_set(r, n)	atomic_set(&(r)->refs, (n))
+
+/**
+ * refcount_read() - get a refcount's value
+ * @r: the refcount
+ *
+ * Return: the refcount's value
+ */
+#define refcount_read(r)	atomic_read(&(r)->refs)
+
+/**
+ * refcount_inc() - increment a refcount
+ * @r: the refcount to increment
+ */
+#define refcount_inc(r)		atomic_inc(&(r)->refs)
+
+/**
+ * refcount_dec() - decrement a refcount
+ * @r: the refcount to decrement
+ */
+#define refcount_dec(r)		atomic_dec(&(r)->refs)
+
+/**
+ * refcount_dec_and_test() - decrement a refcount and test if it is 0
+ * @r: the refcount
+ *
+ * Return: true if the resulting refcount is 0, false otherwise
+ */
+#define refcount_dec_and_test(r) atomic_dec_and_test(&(r)->refs)
+
+/**
+ * refcount_inc_not_zero() - increment a refcount unless it is 0
+ * @r: the refcount to increment
+ *
+ * Return: true if the increment succeeded, false if refcount was 0
+ */
+static inline bool refcount_inc_not_zero(refcount_t *r)
+{
+	return atomic_add_unless(&r->refs, 1, 0);
+}
+
+#endif /* _LINUX_REFCOUNT_H */