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