Merge tag 'locking-urgent-2021-05-09' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / arch / arm64 / kernel / io.c
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(from);
19                 from++;
20                 to++;
21                 count--;
22         }
23
24         while (count >= 8) {
25                 *(u64 *)to = __raw_readq(from);
26                 from += 8;
27                 to += 8;
28                 count -= 8;
29         }
30
31         while (count) {
32                 *(u8 *)to = __raw_readb(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(*(u8 *)from, to);
47                 from++;
48                 to++;
49                 count--;
50         }
51
52         while (count >= 8) {
53                 __raw_writeq(*(u64 *)from, to);
54                 from += 8;
55                 to += 8;
56                 count -= 8;
57         }
58
59         while (count) {
60                 __raw_writeb(*(u8 *)from, 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(c, dst);
81                 dst++;
82                 count--;
83         }
84
85         while (count >= 8) {
86                 __raw_writeq(qc, dst);
87                 dst += 8;
88                 count -= 8;
89         }
90
91         while (count) {
92                 __raw_writeb(c, dst);
93                 dst++;
94                 count--;
95         }
96 }
97 EXPORT_SYMBOL(__memset_io);