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); 98