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 | */ |
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(addr: from); |
16 | from++; |
17 | to++; |
18 | count--; |
19 | } |
20 | |
21 | while (count >= 8) { |
22 | *(u64 *)to = __raw_readq(addr: from); |
23 | from += 8; |
24 | to += 8; |
25 | count -= 8; |
26 | } |
27 | |
28 | while (count) { |
29 | *(u8 *)to = __raw_readb(addr: 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 | */ |
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(val: *(u8 *)from, addr: to); |
44 | from++; |
45 | to++; |
46 | count--; |
47 | } |
48 | |
49 | while (count >= 8) { |
50 | __raw_writeq(val: *(u64 *)from, addr: to); |
51 | from += 8; |
52 | to += 8; |
53 | count -= 8; |
54 | } |
55 | |
56 | while (count) { |
57 | __raw_writeb(val: *(u8 *)from, addr: to); |
58 | from++; |
59 | to++; |
60 | count--; |
61 | } |
62 | } |
63 | EXPORT_SYMBOL(__memcpy_toio); |
64 | |
65 | /* |
66 | * "memset" on IO memory space. |
67 | */ |
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(val: c, addr: dst); |
78 | dst++; |
79 | count--; |
80 | } |
81 | |
82 | while (count >= 8) { |
83 | __raw_writeq(val: qc, addr: dst); |
84 | dst += 8; |
85 | count -= 8; |
86 | } |
87 | |
88 | while (count) { |
89 | __raw_writeb(val: c, addr: dst); |
90 | dst++; |
91 | count--; |
92 | } |
93 | } |
94 | EXPORT_SYMBOL(__memset_io); |
95 | |