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