blob: aa7a4ec6a3ae6f44b9168f849376587578ae0a44 [file] [log] [blame]
Thomas Gleixnercaab2772019-06-03 07:44:50 +02001// SPDX-License-Identifier: GPL-2.0-only
Catalin Marinasfc478972012-03-05 11:49:29 +00002/*
3 * Based on arch/arm/kernel/io.c
4 *
5 * Copyright (C) 2012 ARM Ltd.
Catalin Marinasfc478972012-03-05 11:49:29 +00006 */
7
8#include <linux/export.h>
9#include <linux/types.h>
10#include <linux/io.h>
11
12/*
13 * Copy data from IO memory space to "real" memory space.
14 */
15void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
16{
Mark Salyzyn9ca255b2017-10-24 07:47:14 -070017 while (count && !IS_ALIGNED((unsigned long)from, 8)) {
Joonwoo Park70ddb632014-10-21 01:59:03 +010018 *(u8 *)to = __raw_readb(from);
Catalin Marinasfc478972012-03-05 11:49:29 +000019 from++;
Joonwoo Park70ddb632014-10-21 01:59:03 +010020 to++;
21 count--;
22 }
23
24 while (count >= 8) {
25 *(u64 *)to = __raw_readq(from);
26 from += 8;
27 to += 8;
28 count -= 8;
29 }
30
31 while (count) {
32 *(u8 *)to = __raw_readb(from);
33 from++;
34 to++;
35 count--;
Catalin Marinasfc478972012-03-05 11:49:29 +000036 }
37}
38EXPORT_SYMBOL(__memcpy_fromio);
39
40/*
41 * Copy data from "real" memory space to IO memory space.
42 */
43void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
44{
Mark Salyzyn9ca255b2017-10-24 07:47:14 -070045 while (count && !IS_ALIGNED((unsigned long)to, 8)) {
46 __raw_writeb(*(u8 *)from, to);
Joonwoo Park70ddb632014-10-21 01:59:03 +010047 from++;
Catalin Marinasfc478972012-03-05 11:49:29 +000048 to++;
Joonwoo Park70ddb632014-10-21 01:59:03 +010049 count--;
50 }
51
52 while (count >= 8) {
Mark Salyzyn9ca255b2017-10-24 07:47:14 -070053 __raw_writeq(*(u64 *)from, to);
Joonwoo Park70ddb632014-10-21 01:59:03 +010054 from += 8;
55 to += 8;
56 count -= 8;
57 }
58
59 while (count) {
Mark Salyzyn9ca255b2017-10-24 07:47:14 -070060 __raw_writeb(*(u8 *)from, to);
Joonwoo Park70ddb632014-10-21 01:59:03 +010061 from++;
62 to++;
63 count--;
Catalin Marinasfc478972012-03-05 11:49:29 +000064 }
65}
66EXPORT_SYMBOL(__memcpy_toio);
67
68/*
69 * "memset" on IO memory space.
70 */
71void __memset_io(volatile void __iomem *dst, int c, size_t count)
72{
Joonwoo Park70ddb632014-10-21 01:59:03 +010073 u64 qc = (u8)c;
74
75 qc |= qc << 8;
76 qc |= qc << 16;
77 qc |= qc << 32;
78
79 while (count && !IS_ALIGNED((unsigned long)dst, 8)) {
80 __raw_writeb(c, dst);
Catalin Marinasfc478972012-03-05 11:49:29 +000081 dst++;
Joonwoo Park70ddb632014-10-21 01:59:03 +010082 count--;
83 }
84
85 while (count >= 8) {
86 __raw_writeq(qc, dst);
87 dst += 8;
88 count -= 8;
89 }
90
91 while (count) {
92 __raw_writeb(c, dst);
93 dst++;
94 count--;
Catalin Marinasfc478972012-03-05 11:49:29 +000095 }
96}
97EXPORT_SYMBOL(__memset_io);