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