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