xref: /openbmc/linux/sound/core/memory.c (revision 561b4fa9)
11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
3c1017a4cSJaroslav Kysela  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
41da177e4SLinus Torvalds  *
5e38e0cfaSTakashi Iwai  *  Misc memory accessors
61da177e4SLinus Torvalds  */
71da177e4SLinus Torvalds 
8d81a6d71SPaul Gortmaker #include <linux/export.h>
96cbbfe1cSTakashi Iwai #include <linux/io.h>
10976412fbSTakashi Iwai #include <linux/uaccess.h>
119004acc7STakashi Iwai #include <sound/core.h>
12*561b4fa9STakashi Iwai #include <sound/pcm.h>
131da177e4SLinus Torvalds 
141da177e4SLinus Torvalds /**
151da177e4SLinus Torvalds  * copy_to_user_fromio - copy data from mmio-space to user-space
161da177e4SLinus Torvalds  * @dst: the destination pointer on user-space
171da177e4SLinus Torvalds  * @src: the source pointer on mmio
181da177e4SLinus Torvalds  * @count: the data size to copy in bytes
191da177e4SLinus Torvalds  *
201da177e4SLinus Torvalds  * Copies the data from mmio-space to user-space.
211da177e4SLinus Torvalds  *
22eb7c06e8SYacine Belkadi  * Return: Zero if successful, or non-zero on failure.
231da177e4SLinus Torvalds  */
copy_to_user_fromio(void __user * dst,const volatile void __iomem * src,size_t count)241da177e4SLinus Torvalds int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count)
251da177e4SLinus Torvalds {
26*561b4fa9STakashi Iwai 	struct iov_iter iter;
27*561b4fa9STakashi Iwai 
28*561b4fa9STakashi Iwai 	if (import_ubuf(ITER_DEST, dst, count, &iter))
29*561b4fa9STakashi Iwai 		return -EFAULT;
30*561b4fa9STakashi Iwai 	return copy_to_iter_fromio(&iter, (const void __iomem *)src, count);
31*561b4fa9STakashi Iwai }
32*561b4fa9STakashi Iwai EXPORT_SYMBOL(copy_to_user_fromio);
33*561b4fa9STakashi Iwai 
34*561b4fa9STakashi Iwai /**
35*561b4fa9STakashi Iwai  * copy_to_iter_fromio - copy data from mmio-space to iov_iter
36*561b4fa9STakashi Iwai  * @dst: the destination iov_iter
37*561b4fa9STakashi Iwai  * @src: the source pointer on mmio
38*561b4fa9STakashi Iwai  * @count: the data size to copy in bytes
39*561b4fa9STakashi Iwai  *
40*561b4fa9STakashi Iwai  * Copies the data from mmio-space to iov_iter.
41*561b4fa9STakashi Iwai  *
42*561b4fa9STakashi Iwai  * Return: Zero if successful, or non-zero on failure.
43*561b4fa9STakashi Iwai  */
copy_to_iter_fromio(struct iov_iter * dst,const void __iomem * src,size_t count)44*561b4fa9STakashi Iwai int copy_to_iter_fromio(struct iov_iter *dst, const void __iomem *src,
45*561b4fa9STakashi Iwai 			size_t count)
46*561b4fa9STakashi Iwai {
471da177e4SLinus Torvalds #if defined(__i386__) || defined(CONFIG_SPARC32)
48*561b4fa9STakashi Iwai 	return copy_to_iter((const void __force *)src, count, dst) == count ? 0 : -EFAULT;
491da177e4SLinus Torvalds #else
501da177e4SLinus Torvalds 	char buf[256];
511da177e4SLinus Torvalds 	while (count) {
521da177e4SLinus Torvalds 		size_t c = count;
531da177e4SLinus Torvalds 		if (c > sizeof(buf))
541da177e4SLinus Torvalds 			c = sizeof(buf);
551da177e4SLinus Torvalds 		memcpy_fromio(buf, (void __iomem *)src, c);
56*561b4fa9STakashi Iwai 		if (copy_to_iter(buf, c, dst) != c)
571da177e4SLinus Torvalds 			return -EFAULT;
581da177e4SLinus Torvalds 		count -= c;
591da177e4SLinus Torvalds 		src += c;
601da177e4SLinus Torvalds 	}
611da177e4SLinus Torvalds 	return 0;
621da177e4SLinus Torvalds #endif
631da177e4SLinus Torvalds }
64*561b4fa9STakashi Iwai EXPORT_SYMBOL(copy_to_iter_fromio);
65c0d3fb39STakashi Iwai 
661da177e4SLinus Torvalds /**
671da177e4SLinus Torvalds  * copy_from_user_toio - copy data from user-space to mmio-space
681da177e4SLinus Torvalds  * @dst: the destination pointer on mmio-space
691da177e4SLinus Torvalds  * @src: the source pointer on user-space
701da177e4SLinus Torvalds  * @count: the data size to copy in bytes
711da177e4SLinus Torvalds  *
721da177e4SLinus Torvalds  * Copies the data from user-space to mmio-space.
731da177e4SLinus Torvalds  *
74eb7c06e8SYacine Belkadi  * Return: Zero if successful, or non-zero on failure.
751da177e4SLinus Torvalds  */
copy_from_user_toio(volatile void __iomem * dst,const void __user * src,size_t count)761da177e4SLinus Torvalds int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count)
771da177e4SLinus Torvalds {
78*561b4fa9STakashi Iwai 	struct iov_iter iter;
79*561b4fa9STakashi Iwai 
80*561b4fa9STakashi Iwai 	if (import_ubuf(ITER_SOURCE, (void __user *)src, count, &iter))
81*561b4fa9STakashi Iwai 		return -EFAULT;
82*561b4fa9STakashi Iwai 	return copy_from_iter_toio((void __iomem *)dst, &iter, count);
83*561b4fa9STakashi Iwai }
84*561b4fa9STakashi Iwai EXPORT_SYMBOL(copy_from_user_toio);
85*561b4fa9STakashi Iwai 
86*561b4fa9STakashi Iwai /**
87*561b4fa9STakashi Iwai  * copy_from_iter_toio - copy data from iov_iter to mmio-space
88*561b4fa9STakashi Iwai  * @dst: the destination pointer on mmio-space
89*561b4fa9STakashi Iwai  * @src: the source iov_iter
90*561b4fa9STakashi Iwai  * @count: the data size to copy in bytes
91*561b4fa9STakashi Iwai  *
92*561b4fa9STakashi Iwai  * Copies the data from iov_iter to mmio-space.
93*561b4fa9STakashi Iwai  *
94*561b4fa9STakashi Iwai  * Return: Zero if successful, or non-zero on failure.
95*561b4fa9STakashi Iwai  */
copy_from_iter_toio(void __iomem * dst,struct iov_iter * src,size_t count)96*561b4fa9STakashi Iwai int copy_from_iter_toio(void __iomem *dst, struct iov_iter *src, size_t count)
97*561b4fa9STakashi Iwai {
981da177e4SLinus Torvalds #if defined(__i386__) || defined(CONFIG_SPARC32)
99*561b4fa9STakashi Iwai 	return copy_from_iter((void __force *)dst, count, src) == count ? 0 : -EFAULT;
1001da177e4SLinus Torvalds #else
1011da177e4SLinus Torvalds 	char buf[256];
1021da177e4SLinus Torvalds 	while (count) {
1031da177e4SLinus Torvalds 		size_t c = count;
1041da177e4SLinus Torvalds 		if (c > sizeof(buf))
1051da177e4SLinus Torvalds 			c = sizeof(buf);
106*561b4fa9STakashi Iwai 		if (copy_from_iter(buf, c, src) != c)
1071da177e4SLinus Torvalds 			return -EFAULT;
1081da177e4SLinus Torvalds 		memcpy_toio(dst, buf, c);
1091da177e4SLinus Torvalds 		count -= c;
1101da177e4SLinus Torvalds 		dst += c;
1111da177e4SLinus Torvalds 	}
1121da177e4SLinus Torvalds 	return 0;
1131da177e4SLinus Torvalds #endif
1141da177e4SLinus Torvalds }
115*561b4fa9STakashi Iwai EXPORT_SYMBOL(copy_from_iter_toio);
116