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