1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright 2024 Kalray, Inc. All Rights Reserved. 4 */ 5 6 #include <linux/align.h> 7 #include <linux/export.h> 8 #include <linux/io.h> 9 #include <linux/types.h> 10 #include <linux/unaligned.h> 11 12 #ifndef memset_io 13 /** 14 * memset_io() - Set a range of I/O memory to a constant value 15 * @addr: The beginning of the I/O-memory range to set 16 * @val: The value to set the memory to 17 * @count: The number of bytes to set 18 * 19 * Set a range of I/O memory to a given value. 20 */ 21 void memset_io(volatile void __iomem *addr, int val, size_t count) 22 { 23 long qc = (u8)val; 24 25 qc *= ~0UL / 0xff; 26 27 while (count && !IS_ALIGNED((long)addr, sizeof(long))) { 28 __raw_writeb(val, addr); 29 addr++; 30 count--; 31 } 32 33 while (count >= sizeof(long)) { 34 #ifdef CONFIG_64BIT 35 __raw_writeq(qc, addr); 36 #else 37 __raw_writel(qc, addr); 38 #endif 39 40 addr += sizeof(long); 41 count -= sizeof(long); 42 } 43 44 while (count) { 45 __raw_writeb(val, addr); 46 addr++; 47 count--; 48 } 49 } 50 EXPORT_SYMBOL(memset_io); 51 #endif 52 53 #ifndef memcpy_fromio 54 /** 55 * memcpy_fromio() - Copy a block of data from I/O memory 56 * @dst: The (RAM) destination for the copy 57 * @src: The (I/O memory) source for the data 58 * @count: The number of bytes to copy 59 * 60 * Copy a block of data from I/O memory. 61 */ 62 void memcpy_fromio(void *dst, const volatile void __iomem *src, size_t count) 63 { 64 while (count && !IS_ALIGNED((long)src, sizeof(long))) { 65 *(u8 *)dst = __raw_readb(src); 66 src++; 67 dst++; 68 count--; 69 } 70 71 while (count >= sizeof(long)) { 72 #ifdef CONFIG_64BIT 73 long val = __raw_readq(src); 74 #else 75 long val = __raw_readl(src); 76 #endif 77 put_unaligned(val, (long *)dst); 78 79 80 src += sizeof(long); 81 dst += sizeof(long); 82 count -= sizeof(long); 83 } 84 85 while (count) { 86 *(u8 *)dst = __raw_readb(src); 87 src++; 88 dst++; 89 count--; 90 } 91 } 92 EXPORT_SYMBOL(memcpy_fromio); 93 #endif 94 95 #ifndef memcpy_toio 96 /** 97 * memcpy_toio() -Copy a block of data into I/O memory 98 * @dst: The (I/O memory) destination for the copy 99 * @src: The (RAM) source for the data 100 * @count: The number of bytes to copy 101 * 102 * Copy a block of data to I/O memory. 103 */ 104 void memcpy_toio(volatile void __iomem *dst, const void *src, size_t count) 105 { 106 while (count && !IS_ALIGNED((long)dst, sizeof(long))) { 107 __raw_writeb(*(u8 *)src, dst); 108 src++; 109 dst++; 110 count--; 111 } 112 113 while (count >= sizeof(long)) { 114 long val = get_unaligned((long *)src); 115 #ifdef CONFIG_64BIT 116 __raw_writeq(val, dst); 117 #else 118 __raw_writel(val, dst); 119 #endif 120 121 src += sizeof(long); 122 dst += sizeof(long); 123 count -= sizeof(long); 124 } 125 126 while (count) { 127 __raw_writeb(*(u8 *)src, dst); 128 src++; 129 dst++; 130 count--; 131 } 132 } 133 EXPORT_SYMBOL(memcpy_toio); 134 #endif 135 136 137