1 // SPDX-License-Identifier: GPL-2.0
2
3 #include <linux/export.h>
4 #include <linux/types.h>
5 #include <linux/io.h>
6
7 /*
8 * Copy data from IO memory space to "real" memory space.
9 */
__memcpy_fromio(void * to,const volatile void __iomem * from,size_t count)10 void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
11 {
12 while (count && !IS_ALIGNED((unsigned long)from, 4)) {
13 *(u8 *)to = __raw_readb(from);
14 from++;
15 to++;
16 count--;
17 }
18
19 while (count >= 4) {
20 *(u32 *)to = __raw_readl(from);
21 from += 4;
22 to += 4;
23 count -= 4;
24 }
25
26 while (count) {
27 *(u8 *)to = __raw_readb(from);
28 from++;
29 to++;
30 count--;
31 }
32 }
33 EXPORT_SYMBOL(__memcpy_fromio);
34
35 /*
36 * Copy data from "real" memory space to IO memory space.
37 */
__memcpy_toio(volatile void __iomem * to,const void * from,size_t count)38 void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
39 {
40 while (count && !IS_ALIGNED((unsigned long)to, 4)) {
41 __raw_writeb(*(u8 *)from, to);
42 from++;
43 to++;
44 count--;
45 }
46
47 while (count >= 4) {
48 __raw_writel(*(u32 *)from, to);
49 from += 4;
50 to += 4;
51 count -= 4;
52 }
53
54 while (count) {
55 __raw_writeb(*(u8 *)from, to);
56 from++;
57 to++;
58 count--;
59 }
60 }
61 EXPORT_SYMBOL(__memcpy_toio);
62
63 /*
64 * "memset" on IO memory space.
65 */
__memset_io(volatile void __iomem * dst,int c,size_t count)66 void __memset_io(volatile void __iomem *dst, int c, size_t count)
67 {
68 u32 qc = (u8)c;
69
70 qc |= qc << 8;
71 qc |= qc << 16;
72
73 while (count && !IS_ALIGNED((unsigned long)dst, 4)) {
74 __raw_writeb(c, dst);
75 dst++;
76 count--;
77 }
78
79 while (count >= 4) {
80 __raw_writel(qc, dst);
81 dst += 4;
82 count -= 4;
83 }
84
85 while (count) {
86 __raw_writeb(c, dst);
87 dst++;
88 count--;
89 }
90 }
91 EXPORT_SYMBOL(__memset_io);
92