asm-generic: simplify unaligned.h
authorJens Wiklander <jens.wiklander@linaro.org>
Mon, 22 May 2023 12:22:38 +0000 (14:22 +0200)
committerTom Rini <trini@konsulko.com>
Wed, 31 May 2023 18:05:34 +0000 (14:05 -0400)
The get_unaligned()/put_unaligned() implementations are more
complex than necessary.

Move everything into one file and use a more compact implementation based
on packed struct access and byte swapping macros.

This patch is based on the Linux kernel commit 803f4e1eab7a
("asm-generic: simplify asm/unaligned.h") by Arnd Bergmann.

Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
include/asm-generic/unaligned.h

index 3d33a5a..9e5d93e 100644 (file)
@@ -1,24 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 #ifndef _GENERIC_UNALIGNED_H
 #define _GENERIC_UNALIGNED_H
 
 #include <asm/byteorder.h>
 
-#include <linux/unaligned/le_byteshift.h>
-#include <linux/unaligned/be_byteshift.h>
-#include <linux/unaligned/generic.h>
-
-/*
- * Select endianness
- */
-#if defined(__LITTLE_ENDIAN)
-#define get_unaligned  __get_unaligned_le
-#define put_unaligned  __put_unaligned_le
-#elif defined(__BIG_ENDIAN)
-#define get_unaligned  __get_unaligned_be
-#define put_unaligned  __put_unaligned_be
-#else
-#error invalid endian
-#endif
+#define __get_unaligned_t(type, ptr) ({                                                \
+       const struct { type x; } __packed * __pptr = (typeof(__pptr))(ptr);     \
+       __pptr->x;                                                              \
+})
+
+#define __put_unaligned_t(type, val, ptr) do {                                 \
+       struct { type x; } __packed * __pptr = (typeof(__pptr))(ptr);           \
+       __pptr->x = (val);                                                      \
+} while (0)
+
+#define get_unaligned(ptr)     __get_unaligned_t(typeof(*(ptr)), (ptr))
+#define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr))
+
+static inline u16 get_unaligned_le16(const void *p)
+{
+       return le16_to_cpu(__get_unaligned_t(__le16, p));
+}
+
+static inline u32 get_unaligned_le32(const void *p)
+{
+       return le32_to_cpu(__get_unaligned_t(__le32, p));
+}
+
+static inline u64 get_unaligned_le64(const void *p)
+{
+       return le64_to_cpu(__get_unaligned_t(__le64, p));
+}
+
+static inline void put_unaligned_le16(u16 val, void *p)
+{
+       __put_unaligned_t(__le16, cpu_to_le16(val), p);
+}
+
+static inline void put_unaligned_le32(u32 val, void *p)
+{
+       __put_unaligned_t(__le32, cpu_to_le32(val), p);
+}
+
+static inline void put_unaligned_le64(u64 val, void *p)
+{
+       __put_unaligned_t(__le64, cpu_to_le64(val), p);
+}
+
+static inline u16 get_unaligned_be16(const void *p)
+{
+       return be16_to_cpu(__get_unaligned_t(__be16, p));
+}
+
+static inline u32 get_unaligned_be32(const void *p)
+{
+       return be32_to_cpu(__get_unaligned_t(__be32, p));
+}
+
+static inline u64 get_unaligned_be64(const void *p)
+{
+       return be64_to_cpu(__get_unaligned_t(__be64, p));
+}
+
+static inline void put_unaligned_be16(u16 val, void *p)
+{
+       __put_unaligned_t(__be16, cpu_to_be16(val), p);
+}
+
+static inline void put_unaligned_be32(u32 val, void *p)
+{
+       __put_unaligned_t(__be32, cpu_to_be32(val), p);
+}
+
+static inline void put_unaligned_be64(u64 val, void *p)
+{
+       __put_unaligned_t(__be64, cpu_to_be64(val), p);
+}
 
 /* Allow unaligned memory access */
 void allow_unaligned(void);