[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240930132321.2785718-2-jvetter@kalrayinc.com>
Date: Mon, 30 Sep 2024 15:23:12 +0200
From: Julian Vetter <jvetter@...rayinc.com>
To: Arnd Bergmann <arnd@...db.de>, Russell King <linux@...linux.org.uk>,
Catalin Marinas <catalin.marinas@....com>, Will Deacon <will@...nel.org>,
Guo Ren <guoren@...nel.org>, Huacai Chen <chenhuacai@...nel.org>, WANG
Xuerui <kernel@...0n.name>, Andrew Morton <akpm@...ux-foundation.org>, Geert
Uytterhoeven <geert@...ux-m68k.org>, Richard Henderson
<richard.henderson@...aro.org>, Ivan Kokshaysky <ink@...assic.park.msu.ru>,
Matt Turner <mattst88@...il.com>, "James E . J . Bottomley"
<James.Bottomley@...senpartnership.com>, Helge Deller <deller@....de>,
Yoshinori Sato <ysato@...rs.sourceforge.jp>, Rich Felker <dalias@...c.org>,
John Paul Adrian Glaubitz <glaubitz@...sik.fu-berlin.de>, Richard Weinberger
<richard@....at>, Anton Ivanov <anton.ivanov@...bridgegreys.com>, Johannes
Berg <johannes@...solutions.net>
Cc: linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org,
linux-csky@...r.kernel.org, loongarch@...ts.linux.dev,
linux-m68k@...ts.linux-m68k.org, linux-alpha@...r.kernel.org,
linux-parisc@...r.kernel.org, linux-sh@...r.kernel.org,
linux-um@...ts.infradead.org, linux-arch@...r.kernel.org, Yann Sionneau
<ysionneau@...rayinc.com>, Julian Vetter <jvetter@...rayinc.com>
Subject: [PATCH v7 01/10] Consolidate IO memcpy/memset into iomap_copy.c
Various architectures have almost the same implementations for
memcpy_{to,from}io and memset_io functions. So, consolidate them
into the existing lib/iomap_copy.c.
Reviewed-by: Yann Sionneau <ysionneau@...rayinc.com>
Signed-off-by: Julian Vetter <jvetter@...rayinc.com>
---
Changes for v7:
- Addressed reviewer comments from David:
- Replaced NATIVE_STORE_TYPE and uintptr_t by long
- Split the read/write and the {get,put}_unaligned into two different
lines for readability
- Addressed reviewer comments from Arnd:
- Placed "extern" definitions in asm-generic/io.h
- Renamed functions from __memcpy_{to,from}io and __memset_io
to memcpy_{to,from}io and memset_io
- Removed the guarding '#ifndef __memcpy_fromio', etc.
---
include/asm-generic/io.h | 58 ++---------------
lib/iomap_copy.c | 133 +++++++++++++++++++++++++++++++++++++++
2 files changed, 139 insertions(+), 52 deletions(-)
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index 80de699bf6af..f14655ed4d9d 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -102,6 +102,12 @@ static inline void log_post_read_mmio(u64 val, u8 width, const volatile void __i
#endif /* CONFIG_TRACE_MMIO_ACCESS */
+extern void memcpy_fromio(void *to, const volatile void __iomem *from,
+ size_t count);
+extern void memcpy_toio(volatile void __iomem *to, const void *from,
+ size_t count);
+extern void memset_io(volatile void __iomem *dst, int c, size_t count);
+
/*
* __raw_{read,write}{b,w,l,q}() access memory in native endianness.
*
@@ -1150,58 +1156,6 @@ static inline void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr)
}
#endif
-#ifndef memset_io
-#define memset_io memset_io
-/**
- * memset_io Set a range of I/O memory to a constant value
- * @addr: The beginning of the I/O-memory range to set
- * @val: The value to set the memory to
- * @count: The number of bytes to set
- *
- * Set a range of I/O memory to a given value.
- */
-static inline void memset_io(volatile void __iomem *addr, int value,
- size_t size)
-{
- memset(__io_virt(addr), value, size);
-}
-#endif
-
-#ifndef memcpy_fromio
-#define memcpy_fromio memcpy_fromio
-/**
- * memcpy_fromio Copy a block of data from I/O memory
- * @dst: The (RAM) destination for the copy
- * @src: The (I/O memory) source for the data
- * @count: The number of bytes to copy
- *
- * Copy a block of data from I/O memory.
- */
-static inline void memcpy_fromio(void *buffer,
- const volatile void __iomem *addr,
- size_t size)
-{
- memcpy(buffer, __io_virt(addr), size);
-}
-#endif
-
-#ifndef memcpy_toio
-#define memcpy_toio memcpy_toio
-/**
- * memcpy_toio Copy a block of data into I/O memory
- * @dst: The (I/O memory) destination for the copy
- * @src: The (RAM) source for the data
- * @count: The number of bytes to copy
- *
- * Copy a block of data to I/O memory.
- */
-static inline void memcpy_toio(volatile void __iomem *addr, const void *buffer,
- size_t size)
-{
- memcpy(__io_virt(addr), buffer, size);
-}
-#endif
-
extern int devmem_is_allowed(unsigned long pfn);
#endif /* __KERNEL__ */
diff --git a/lib/iomap_copy.c b/lib/iomap_copy.c
index 2fd5712fb7c0..5567bf8db8bc 100644
--- a/lib/iomap_copy.c
+++ b/lib/iomap_copy.c
@@ -3,7 +3,11 @@
* Copyright 2006 PathScale, Inc. All Rights Reserved.
*/
+#include <asm/unaligned.h>
+
+#include <linux/align.h>
#include <linux/export.h>
+#include <linux/types.h>
#include <linux/io.h>
/**
@@ -76,3 +80,132 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count)
}
EXPORT_SYMBOL_GPL(__iowrite64_copy);
#endif
+
+#ifndef memcpy_fromio
+/**
+ * memcpy_fromio Copy a block of data from I/O memory
+ * @to: The (RAM) destination for the copy
+ * @from: The (I/O memory) source for the data
+ * @count: The number of bytes to copy
+ *
+ * Copy a block of data from I/O memory.
+ */
+void memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
+{
+ while (count && !IS_ALIGNED((long)from, sizeof(long))) {
+ *(u8 *)to = __raw_readb(from);
+ from++;
+ to++;
+ count--;
+ }
+
+ while (count >= sizeof(long)) {
+#ifdef CONFIG_64BIT
+ long val = __raw_readq(from);
+#else
+ long val = __raw_readl(from);
+#endif
+ put_unaligned(val, (long *)to);
+
+
+ from += sizeof(long);
+ to += sizeof(long);
+ count -= sizeof(long);
+ }
+
+ while (count) {
+ *(u8 *)to = __raw_readb(from);
+ from++;
+ to++;
+ count--;
+ }
+}
+EXPORT_SYMBOL(memcpy_fromio);
+#endif
+
+#ifndef memcpy_toio
+/**
+ * memcpy_toio Copy a block of data into I/O memory
+ * @to: The (I/O memory) destination for the copy
+ * @from: The (RAM) source for the data
+ * @count: The number of bytes to copy
+ *
+ * Copy a block of data to I/O memory.
+ */
+void memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
+{
+ while (count && !IS_ALIGNED((long)to, sizeof(long))) {
+ __raw_writeb(*(u8 *)from, to);
+ from++;
+ to++;
+ count--;
+ }
+
+ while (count >= sizeof(long)) {
+ long val = get_unaligned((long *)from);
+#ifdef CONFIG_64BIT
+ __raw_writeq(val, to);
+#else
+ __raw_writel(val, to);
+#endif
+
+ from += sizeof(long);
+ to += sizeof(long);
+ count -= sizeof(long);
+ }
+
+ while (count) {
+ __raw_writeb(*(u8 *)from, to);
+ from++;
+ to++;
+ count--;
+ }
+}
+EXPORT_SYMBOL(memcpy_toio);
+#endif
+
+#ifndef memset_io
+/**
+ * memset_io Set a range of I/O memory to a constant value
+ * @dst: The beginning of the I/O-memory range to set
+ * @c: The value to set the memory to
+ * @count: The number of bytes to set
+ *
+ * Set a range of I/O memory to a given value.
+ */
+void memset_io(volatile void __iomem *dst, int c, size_t count)
+{
+ uintptr_t qc = (u8)c;
+
+ qc |= qc << 8;
+ qc |= qc << 16;
+
+#ifdef CONFIG_64BIT
+ qc |= qc << 32;
+#endif
+
+ while (count && !IS_ALIGNED((long)dst, sizeof(long))) {
+ __raw_writeb(c, dst);
+ dst++;
+ count--;
+ }
+
+ while (count >= sizeof(long)) {
+#ifdef CONFIG_64BIT
+ __raw_writeq(qc, dst);
+#else
+ __raw_writel(qc, dst);
+#endif
+
+ dst += sizeof(long);
+ count -= sizeof(long);
+ }
+
+ while (count) {
+ __raw_writeb(c, dst);
+ dst++;
+ count--;
+ }
+}
+EXPORT_SYMBOL(memset_io);
+#endif
--
2.34.1
Powered by blists - more mailing lists