Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 892ca891 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "arm64: optimize memcpy_{from,to}io() and memset_io()"

parents 4d4d5a2b e7b447e5
Loading
Loading
Loading
Loading
+62 −10
Original line number Diff line number Diff line
@@ -20,18 +20,34 @@
#include <linux/types.h>
#include <linux/io.h>

#define IO_CHECK_ALIGN(v, a) ((((unsigned long)(v)) & ((a) - 1)) == 0)

/*
 * Copy data from IO memory space to "real" memory space.
 */
void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
{
	unsigned char *t = to;
	while (count) {
	while (count && (!IO_CHECK_ALIGN(from, 8) || !IO_CHECK_ALIGN(to, 8))) {
		*(u8 *)to = readb_relaxed(from);
		from++;
		to++;
		count--;
		*t = readb(from);
		t++;
	}

	while (count >= 8) {
		*(u64 *)to = readq_relaxed(from);
		from += 8;
		to += 8;
		count -= 8;
	}

	while (count) {
		*(u8 *)to = readb_relaxed(from);
		from++;
		to++;
		count--;
	}
	__iormb();
}
EXPORT_SYMBOL(__memcpy_fromio);

@@ -40,12 +56,28 @@ EXPORT_SYMBOL(__memcpy_fromio);
 */
void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
{
	const unsigned char *f = from;
	void *p = (void __force *)to;

	__iowmb();
	while (count && (!IO_CHECK_ALIGN(p, 8) || !IO_CHECK_ALIGN(from, 8))) {
		writeb_relaxed(*(volatile u8 *)from, p);
		from++;
		p++;
		count--;
	}

	while (count >= 8) {
		writeq_relaxed(*(volatile u64 *)from, p);
		from += 8;
		p += 8;
		count -= 8;
	}

	while (count) {
		writeb_relaxed(*(volatile u8 *)from, p);
		from++;
		p++;
		count--;
		writeb(*f, to);
		f++;
		to++;
	}
}
EXPORT_SYMBOL(__memcpy_toio);
@@ -55,10 +87,30 @@ EXPORT_SYMBOL(__memcpy_toio);
 */
void __memset_io(volatile void __iomem *dst, int c, size_t count)
{
	void *p = (void __force *)dst;
	u64 qc = c;

	qc |= qc << 8;
	qc |= qc << 16;
	qc |= qc << 32;

	__iowmb();
	while (count && !IO_CHECK_ALIGN(p, 8)) {
		writeb_relaxed(c, p);
		p++;
		count--;
	}

	while (count >= 8) {
		writeq_relaxed(c, p);
		p += 8;
		count -= 8;
	}

	while (count) {
		writeb_relaxed(c, p);
		p++;
		count--;
		writeb(c, dst);
		dst++;
	}
}
EXPORT_SYMBOL(__memset_io);