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@kalrayinc.com>
Signed-off-by: Julian Vetter <jvetter@kalrayinc.com>
---
Changes for v5:
- Add function prototypes to asm-generic/io.h
- Instead of having yet another file, we add the functions to
iomap_copy.c as proposed by Arndt
---
include/asm-generic/io.h | 12 +++++
lib/iomap_copy.c | 107 +++++++++++++++++++++++++++++++++++++++
2 files changed, 119 insertions(+)
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index 80de699bf6af..9b8e0449da28 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -102,6 +102,18 @@ static inline void log_post_read_mmio(u64 val, u8 width, const volatile void __i
#endif /* CONFIG_TRACE_MMIO_ACCESS */
+#ifndef __memcpy_fromio
+void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count);
+#endif
+
+#ifndef __memcpy_toio
+void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count);
+#endif
+
+#ifndef __memset_io
+void __memset_io(volatile void __iomem *dst, int c, size_t count);
+#endif
+
/*
* __raw_{read,write}{b,w,l,q}() access memory in native endianness.
*
diff --git a/lib/iomap_copy.c b/lib/iomap_copy.c
index 2fd5712fb7c0..fabcc1e95668 100644
--- a/lib/iomap_copy.c
+++ b/lib/iomap_copy.c
@@ -3,9 +3,14 @@
* Copyright 2006 PathScale, Inc. All Rights Reserved.
*/
+#include <asm/unaligned.h>
+
#include <linux/export.h>
+#include <linux/types.h>
#include <linux/io.h>
+#define NATIVE_STORE_SIZE (BITS_PER_LONG/8)
+
/**
* __iowrite32_copy - copy data to MMIO space, in 32-bit units
* @to: destination, in MMIO space (must be 32-bit aligned)
@@ -76,3 +81,105 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count)
}
EXPORT_SYMBOL_GPL(__iowrite64_copy);
#endif
+
+
+#ifndef __memcpy_fromio
+void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
+{
+ while (count && !IS_ALIGNED((unsigned long)from, NATIVE_STORE_SIZE)) {
+ *(u8 *)to = __raw_readb(from);
+ from++;
+ to++;
+ count--;
+ }
+
+ while (count >= NATIVE_STORE_SIZE) {
+#ifdef CONFIG_64BIT
+ put_unaligned(__raw_readq(from), (uintptr_t *)to);
+#else
+ put_unaligned(__raw_readl(from), (uintptr_t *)to);
+#endif
+
+ from += NATIVE_STORE_SIZE;
+ to += NATIVE_STORE_SIZE;
+ count -= NATIVE_STORE_SIZE;
+ }
+
+ while (count) {
+ *(u8 *)to = __raw_readb(from);
+ from++;
+ to++;
+ count--;
+ }
+}
+EXPORT_SYMBOL(__memcpy_fromio);
+#endif
+
+#ifndef __memcpy_toio
+void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
+{
+ while (count && !IS_ALIGNED((unsigned long)to, NATIVE_STORE_SIZE)) {
+ __raw_writeb(*(u8 *)from, to);
+ from++;
+ to++;
+ count--;
+ }
+
+ while (count >= NATIVE_STORE_SIZE) {
+#ifdef CONFIG_64BIT
+ __raw_writeq(get_unaligned((uintptr_t *)from), to);
+#else
+ __raw_writel(get_unaligned((uintptr_t *)from), to);
+#endif
+
+ from += NATIVE_STORE_SIZE;
+ to += NATIVE_STORE_SIZE;
+ count -= NATIVE_STORE_SIZE;
+ }
+
+ while (count) {
+ __raw_writeb(*(u8 *)from, to);
+ from++;
+ to++;
+ count--;
+ }
+}
+EXPORT_SYMBOL(__memcpy_toio);
+#endif
+
+#ifndef __memset_io
+void __memset_io(volatile void __iomem *dst, int c, size_t count)
+{
+ uintptr_t qc = (u8)c;
+
+ qc |= qc << 8;
+ qc |= qc << 16;
+
+ if (IS_ENABLED(CONFIG_64BIT))
+ qc |= qc << 32;
+
+ while (count && !IS_ALIGNED((unsigned long)dst, NATIVE_STORE_SIZE)) {
+ __raw_writeb(c, dst);
+ dst++;
+ count--;
+ }
+
+ while (count >= NATIVE_STORE_SIZE) {
+#ifdef CONFIG_64BIT
+ __raw_writeq(qc, dst);
+#else
+ __raw_writel(qc, dst);
+#endif
+
+ dst += NATIVE_STORE_SIZE;
+ count -= NATIVE_STORE_SIZE;
+ }
+
+ while (count) {
+ __raw_writeb(c, dst);
+ dst++;
+ count--;
+ }
+}
+EXPORT_SYMBOL(__memset_io);
+#endif
--
2.34.1
Hi Julian,
kernel test robot noticed the following build errors:
[auto build test ERROR on arnd-asm-generic/master]
[also build test ERROR on soc/for-next akpm-mm/mm-nonmm-unstable arm64/for-next/core linus/master v6.11 next-20240924]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Julian-Vetter/Consolidate-__memcpy_-to-from-io-and-__memset_io-into-iomap_copy-c/20240924-202154
base: https://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git master
patch link: https://lore.kernel.org/r/20240924121432.798655-2-jvetter%40kalrayinc.com
patch subject: [PATCH v5 1/5] Consolidate __memcpy_{to,from}io and __memset_io into iomap_copy.c
config: arm-defconfig (https://download.01.org/0day-ci/archive/20240925/202409250806.Lq8C7QZr-lkp@intel.com/config)
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240925/202409250806.Lq8C7QZr-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409250806.Lq8C7QZr-lkp@intel.com/
All errors (new ones prefixed by >>):
>> lib/iomap_copy.c:89:19: error: implicit declaration of function 'IS_ALIGNED' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
while (count && !IS_ALIGNED((unsigned long)from, NATIVE_STORE_SIZE)) {
^
lib/iomap_copy.c:121:19: error: implicit declaration of function 'IS_ALIGNED' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
while (count && !IS_ALIGNED((unsigned long)to, NATIVE_STORE_SIZE)) {
^
lib/iomap_copy.c:161:19: error: implicit declaration of function 'IS_ALIGNED' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
while (count && !IS_ALIGNED((unsigned long)dst, NATIVE_STORE_SIZE)) {
^
3 errors generated.
vim +/IS_ALIGNED +89 lib/iomap_copy.c
84
85
86 #ifndef __memcpy_fromio
87 void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
88 {
> 89 while (count && !IS_ALIGNED((unsigned long)from, NATIVE_STORE_SIZE)) {
90 *(u8 *)to = __raw_readb(from);
91 from++;
92 to++;
93 count--;
94 }
95
96 while (count >= NATIVE_STORE_SIZE) {
97 #ifdef CONFIG_64BIT
98 put_unaligned(__raw_readq(from), (uintptr_t *)to);
99 #else
100 put_unaligned(__raw_readl(from), (uintptr_t *)to);
101 #endif
102
103 from += NATIVE_STORE_SIZE;
104 to += NATIVE_STORE_SIZE;
105 count -= NATIVE_STORE_SIZE;
106 }
107
108 while (count) {
109 *(u8 *)to = __raw_readb(from);
110 from++;
111 to++;
112 count--;
113 }
114 }
115 EXPORT_SYMBOL(__memcpy_fromio);
116 #endif
117
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Julian,
kernel test robot noticed the following build warnings:
[auto build test WARNING on arnd-asm-generic/master]
[also build test WARNING on soc/for-next akpm-mm/mm-nonmm-unstable arm64/for-next/core linus/master v6.11 next-20240924]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Julian-Vetter/Consolidate-__memcpy_-to-from-io-and-__memset_io-into-iomap_copy-c/20240924-202154
base: https://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git master
patch link: https://lore.kernel.org/r/20240924121432.798655-2-jvetter%40kalrayinc.com
patch subject: [PATCH v5 1/5] Consolidate __memcpy_{to,from}io and __memset_io into iomap_copy.c
config: arm-mxs_defconfig (https://download.01.org/0day-ci/archive/20240925/202409250603.okc57309-lkp@intel.com/config)
compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 7773243d9916f98ba0ffce0c3a960e4aa9f03e81)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240925/202409250603.okc57309-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409250603.okc57309-lkp@intel.com/
All warnings (new ones prefixed by >>):
lib/iomap_copy.c:89:19: error: call to undeclared function 'IS_ALIGNED'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
89 | while (count && !IS_ALIGNED((unsigned long)from, NATIVE_STORE_SIZE)) {
| ^
lib/iomap_copy.c:121:19: error: call to undeclared function 'IS_ALIGNED'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
121 | while (count && !IS_ALIGNED((unsigned long)to, NATIVE_STORE_SIZE)) {
| ^
lib/iomap_copy.c:161:19: error: call to undeclared function 'IS_ALIGNED'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
161 | while (count && !IS_ALIGNED((unsigned long)dst, NATIVE_STORE_SIZE)) {
| ^
>> lib/iomap_copy.c:159:12: warning: shift count >= width of type [-Wshift-count-overflow]
159 | qc |= qc << 32;
| ^ ~~
1 warning and 3 errors generated.
vim +159 lib/iomap_copy.c
84
85
86 #ifndef __memcpy_fromio
87 void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
88 {
> 89 while (count && !IS_ALIGNED((unsigned long)from, NATIVE_STORE_SIZE)) {
90 *(u8 *)to = __raw_readb(from);
91 from++;
92 to++;
93 count--;
94 }
95
96 while (count >= NATIVE_STORE_SIZE) {
97 #ifdef CONFIG_64BIT
98 put_unaligned(__raw_readq(from), (uintptr_t *)to);
99 #else
100 put_unaligned(__raw_readl(from), (uintptr_t *)to);
101 #endif
102
103 from += NATIVE_STORE_SIZE;
104 to += NATIVE_STORE_SIZE;
105 count -= NATIVE_STORE_SIZE;
106 }
107
108 while (count) {
109 *(u8 *)to = __raw_readb(from);
110 from++;
111 to++;
112 count--;
113 }
114 }
115 EXPORT_SYMBOL(__memcpy_fromio);
116 #endif
117
118 #ifndef __memcpy_toio
119 void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
120 {
121 while (count && !IS_ALIGNED((unsigned long)to, NATIVE_STORE_SIZE)) {
122 __raw_writeb(*(u8 *)from, to);
123 from++;
124 to++;
125 count--;
126 }
127
128 while (count >= NATIVE_STORE_SIZE) {
129 #ifdef CONFIG_64BIT
130 __raw_writeq(get_unaligned((uintptr_t *)from), to);
131 #else
132 __raw_writel(get_unaligned((uintptr_t *)from), to);
133 #endif
134
135 from += NATIVE_STORE_SIZE;
136 to += NATIVE_STORE_SIZE;
137 count -= NATIVE_STORE_SIZE;
138 }
139
140 while (count) {
141 __raw_writeb(*(u8 *)from, to);
142 from++;
143 to++;
144 count--;
145 }
146 }
147 EXPORT_SYMBOL(__memcpy_toio);
148 #endif
149
150 #ifndef __memset_io
151 void __memset_io(volatile void __iomem *dst, int c, size_t count)
152 {
153 uintptr_t qc = (u8)c;
154
155 qc |= qc << 8;
156 qc |= qc << 16;
157
158 if (IS_ENABLED(CONFIG_64BIT))
> 159 qc |= qc << 32;
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Julian,
kernel test robot noticed the following build errors:
[auto build test ERROR on arnd-asm-generic/master]
[also build test ERROR on soc/for-next akpm-mm/mm-nonmm-unstable arm64/for-next/core linus/master v6.11 next-20240924]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Julian-Vetter/Consolidate-__memcpy_-to-from-io-and-__memset_io-into-iomap_copy-c/20240924-202154
base: https://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git master
patch link: https://lore.kernel.org/r/20240924121432.798655-2-jvetter%40kalrayinc.com
patch subject: [PATCH v5 1/5] Consolidate __memcpy_{to,from}io and __memset_io into iomap_copy.c
config: arm-am200epdkit_defconfig (https://download.01.org/0day-ci/archive/20240925/202409250555.Ey0vV3Df-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 14.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240925/202409250555.Ey0vV3Df-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409250555.Ey0vV3Df-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
lib/iomap_copy.c: In function '__memcpy_fromio':
>> lib/iomap_copy.c:89:26: error: implicit declaration of function 'IS_ALIGNED' [-Wimplicit-function-declaration]
89 | while (count && !IS_ALIGNED((unsigned long)from, NATIVE_STORE_SIZE)) {
| ^~~~~~~~~~
lib/iomap_copy.c: In function '__memset_io':
>> lib/iomap_copy.c:159:26: warning: left shift count >= width of type [-Wshift-count-overflow]
159 | qc |= qc << 32;
| ^~
vim +/IS_ALIGNED +89 lib/iomap_copy.c
84
85
86 #ifndef __memcpy_fromio
87 void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
88 {
> 89 while (count && !IS_ALIGNED((unsigned long)from, NATIVE_STORE_SIZE)) {
90 *(u8 *)to = __raw_readb(from);
91 from++;
92 to++;
93 count--;
94 }
95
96 while (count >= NATIVE_STORE_SIZE) {
97 #ifdef CONFIG_64BIT
98 put_unaligned(__raw_readq(from), (uintptr_t *)to);
99 #else
100 put_unaligned(__raw_readl(from), (uintptr_t *)to);
101 #endif
102
103 from += NATIVE_STORE_SIZE;
104 to += NATIVE_STORE_SIZE;
105 count -= NATIVE_STORE_SIZE;
106 }
107
108 while (count) {
109 *(u8 *)to = __raw_readb(from);
110 from++;
111 to++;
112 count--;
113 }
114 }
115 EXPORT_SYMBOL(__memcpy_fromio);
116 #endif
117
118 #ifndef __memcpy_toio
119 void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
120 {
121 while (count && !IS_ALIGNED((unsigned long)to, NATIVE_STORE_SIZE)) {
122 __raw_writeb(*(u8 *)from, to);
123 from++;
124 to++;
125 count--;
126 }
127
128 while (count >= NATIVE_STORE_SIZE) {
129 #ifdef CONFIG_64BIT
130 __raw_writeq(get_unaligned((uintptr_t *)from), to);
131 #else
132 __raw_writel(get_unaligned((uintptr_t *)from), to);
133 #endif
134
135 from += NATIVE_STORE_SIZE;
136 to += NATIVE_STORE_SIZE;
137 count -= NATIVE_STORE_SIZE;
138 }
139
140 while (count) {
141 __raw_writeb(*(u8 *)from, to);
142 from++;
143 to++;
144 count--;
145 }
146 }
147 EXPORT_SYMBOL(__memcpy_toio);
148 #endif
149
150 #ifndef __memset_io
151 void __memset_io(volatile void __iomem *dst, int c, size_t count)
152 {
153 uintptr_t qc = (u8)c;
154
155 qc |= qc << 8;
156 qc |= qc << 16;
157
158 if (IS_ENABLED(CONFIG_64BIT))
> 159 qc |= qc << 32;
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
© 2016 - 2026 Red Hat, Inc.