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