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 */
12void __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}
35EXPORT_SYMBOL(__memcpy_fromio);
36
37/*
38 * Copy data from "real" memory space to IO memory space.
39 */
40void __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}
63EXPORT_SYMBOL(__memcpy_toio);
64
65/*
66 * "memset" on IO memory space.
67 */
68void __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}
94EXPORT_SYMBOL(__memset_io);
95

source code of linux/arch/loongarch/kernel/io.c