Merge tag 'ieee802154-for-net-next-2022-06-09' of git://git.kernel.org/pub/scm/linux...
[linux-2.6-microblaze.git] / arch / loongarch / kernel / io.c
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(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  */
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  */
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);