]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
b00dc837 | 2 | /* |
1da177e4 LT |
3 | * PeeCeeI.c: The emerging standard... |
4 | * | |
5 | * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) | |
6 | */ | |
7 | ||
917c3660 SR |
8 | #include <linux/module.h> |
9 | ||
1da177e4 LT |
10 | #include <asm/io.h> |
11 | #include <asm/byteorder.h> | |
12 | ||
8a36895c | 13 | void outsb(unsigned long __addr, const void *src, unsigned long count) |
1da177e4 | 14 | { |
8a36895c | 15 | void __iomem *addr = (void __iomem *) __addr; |
1da177e4 LT |
16 | const u8 *p = src; |
17 | ||
8a36895c | 18 | while (count--) |
6b8b5507 | 19 | __raw_writeb(*p++, addr); |
1da177e4 | 20 | } |
917c3660 | 21 | EXPORT_SYMBOL(outsb); |
1da177e4 | 22 | |
8a36895c | 23 | void outsw(unsigned long __addr, const void *src, unsigned long count) |
1da177e4 | 24 | { |
8a36895c DM |
25 | void __iomem *addr = (void __iomem *) __addr; |
26 | ||
1758ef68 HH |
27 | while (count--) { |
28 | __raw_writew(*(u16 *)src, addr); | |
29 | src += sizeof(u16); | |
1da177e4 LT |
30 | } |
31 | } | |
917c3660 | 32 | EXPORT_SYMBOL(outsw); |
1da177e4 | 33 | |
8a36895c | 34 | void outsl(unsigned long __addr, const void *src, unsigned long count) |
1da177e4 | 35 | { |
8a36895c | 36 | void __iomem *addr = (void __iomem *) __addr; |
1758ef68 | 37 | u32 l, l2; |
8a36895c | 38 | |
1758ef68 HH |
39 | if (!count) |
40 | return; | |
1da177e4 | 41 | |
1758ef68 HH |
42 | switch (((unsigned long)src) & 0x3) { |
43 | case 0x0: | |
44 | /* src is naturally aligned */ | |
45 | while (count--) { | |
46 | __raw_writel(*(u32 *)src, addr); | |
47 | src += sizeof(u32); | |
48 | } | |
49 | break; | |
50 | case 0x2: | |
51 | /* 2-byte alignment */ | |
52 | while (count--) { | |
53 | l = (*(u16 *)src) << 16; | |
54 | l |= *(u16 *)(src + sizeof(u16)); | |
55 | __raw_writel(l, addr); | |
56 | src += sizeof(u32); | |
57 | } | |
58 | break; | |
59 | case 0x1: | |
60 | /* Hold three bytes in l each time, grab a byte from l2 */ | |
61 | l = (*(u8 *)src) << 24; | |
62 | l |= (*(u16 *)(src + sizeof(u8))) << 8; | |
63 | src += sizeof(u8) + sizeof(u16); | |
64 | while (count--) { | |
65 | l2 = *(u32 *)src; | |
66 | l |= (l2 >> 24); | |
67 | __raw_writel(l, addr); | |
68 | l = l2 << 8; | |
69 | src += sizeof(u32); | |
70 | } | |
71 | break; | |
72 | case 0x3: | |
73 | /* Hold a byte in l each time, grab 3 bytes from l2 */ | |
74 | l = (*(u8 *)src) << 24; | |
75 | src += sizeof(u8); | |
76 | while (count--) { | |
77 | l2 = *(u32 *)src; | |
78 | l |= (l2 >> 8); | |
79 | __raw_writel(l, addr); | |
80 | l = l2 << 24; | |
81 | src += sizeof(u32); | |
1da177e4 | 82 | } |
1758ef68 | 83 | break; |
1da177e4 LT |
84 | } |
85 | } | |
917c3660 | 86 | EXPORT_SYMBOL(outsl); |
1da177e4 | 87 | |
8a36895c | 88 | void insb(unsigned long __addr, void *dst, unsigned long count) |
1da177e4 | 89 | { |
8a36895c DM |
90 | void __iomem *addr = (void __iomem *) __addr; |
91 | ||
92 | if (count) { | |
1da177e4 LT |
93 | u32 *pi; |
94 | u8 *pb = dst; | |
95 | ||
8a36895c | 96 | while ((((unsigned long)pb) & 0x3) && count--) |
6b8b5507 | 97 | *pb++ = __raw_readb(addr); |
1da177e4 | 98 | pi = (u32 *)pb; |
8a36895c | 99 | while (count >= 4) { |
1da177e4 LT |
100 | u32 w; |
101 | ||
6b8b5507 SR |
102 | w = (__raw_readb(addr) << 24); |
103 | w |= (__raw_readb(addr) << 16); | |
104 | w |= (__raw_readb(addr) << 8); | |
105 | w |= (__raw_readb(addr) << 0); | |
1da177e4 LT |
106 | *pi++ = w; |
107 | count -= 4; | |
108 | } | |
109 | pb = (u8 *)pi; | |
8a36895c | 110 | while (count--) |
6b8b5507 | 111 | *pb++ = __raw_readb(addr); |
1da177e4 LT |
112 | } |
113 | } | |
917c3660 | 114 | EXPORT_SYMBOL(insb); |
1da177e4 | 115 | |
8a36895c | 116 | void insw(unsigned long __addr, void *dst, unsigned long count) |
1da177e4 | 117 | { |
8a36895c DM |
118 | void __iomem *addr = (void __iomem *) __addr; |
119 | ||
120 | if (count) { | |
1da177e4 LT |
121 | u16 *ps = dst; |
122 | u32 *pi; | |
123 | ||
8a36895c | 124 | if (((unsigned long)ps) & 0x2) { |
6b8b5507 | 125 | *ps++ = __raw_readw(addr); |
1da177e4 LT |
126 | count--; |
127 | } | |
128 | pi = (u32 *)ps; | |
8a36895c | 129 | while (count >= 2) { |
1da177e4 LT |
130 | u32 w; |
131 | ||
6b8b5507 SR |
132 | w = __raw_readw(addr) << 16; |
133 | w |= __raw_readw(addr) << 0; | |
1da177e4 LT |
134 | *pi++ = w; |
135 | count -= 2; | |
136 | } | |
137 | ps = (u16 *)pi; | |
8a36895c | 138 | if (count) |
6b8b5507 | 139 | *ps = __raw_readw(addr); |
1da177e4 LT |
140 | } |
141 | } | |
917c3660 | 142 | EXPORT_SYMBOL(insw); |
1da177e4 | 143 | |
8a36895c | 144 | void insl(unsigned long __addr, void *dst, unsigned long count) |
1da177e4 | 145 | { |
8a36895c DM |
146 | void __iomem *addr = (void __iomem *) __addr; |
147 | ||
148 | if (count) { | |
149 | if ((((unsigned long)dst) & 0x3) == 0) { | |
1da177e4 | 150 | u32 *pi = dst; |
8a36895c | 151 | while (count--) |
6b8b5507 | 152 | *pi++ = __raw_readl(addr); |
1da177e4 LT |
153 | } else { |
154 | u32 l = 0, l2, *pi; | |
155 | u16 *ps; | |
156 | u8 *pb; | |
157 | ||
8a36895c | 158 | switch (((unsigned long)dst) & 3) { |
1da177e4 LT |
159 | case 0x2: |
160 | ps = dst; | |
161 | count -= 1; | |
6b8b5507 | 162 | l = __raw_readl(addr); |
1da177e4 LT |
163 | *ps++ = l; |
164 | pi = (u32 *)ps; | |
8a36895c | 165 | while (count--) { |
6b8b5507 | 166 | l2 = __raw_readl(addr); |
1da177e4 LT |
167 | *pi++ = (l << 16) | (l2 >> 16); |
168 | l = l2; | |
169 | } | |
170 | ps = (u16 *)pi; | |
171 | *ps = l; | |
172 | break; | |
173 | ||
174 | case 0x1: | |
175 | pb = dst; | |
176 | count -= 1; | |
6b8b5507 | 177 | l = __raw_readl(addr); |
1da177e4 LT |
178 | *pb++ = l >> 24; |
179 | ps = (u16 *)pb; | |
180 | *ps++ = ((l >> 8) & 0xffff); | |
181 | pi = (u32 *)ps; | |
8a36895c | 182 | while (count--) { |
6b8b5507 | 183 | l2 = __raw_readl(addr); |
1da177e4 LT |
184 | *pi++ = (l << 24) | (l2 >> 8); |
185 | l = l2; | |
186 | } | |
187 | pb = (u8 *)pi; | |
188 | *pb = l; | |
189 | break; | |
190 | ||
191 | case 0x3: | |
192 | pb = (u8 *)dst; | |
193 | count -= 1; | |
6b8b5507 | 194 | l = __raw_readl(addr); |
1da177e4 LT |
195 | *pb++ = l >> 24; |
196 | pi = (u32 *)pb; | |
8a36895c | 197 | while (count--) { |
6b8b5507 | 198 | l2 = __raw_readl(addr); |
1da177e4 LT |
199 | *pi++ = (l << 8) | (l2 >> 24); |
200 | l = l2; | |
201 | } | |
202 | ps = (u16 *)pi; | |
203 | *ps++ = ((l >> 8) & 0xffff); | |
204 | pb = (u8 *)ps; | |
205 | *pb = l; | |
206 | break; | |
207 | } | |
208 | } | |
209 | } | |
210 | } | |
917c3660 | 211 | EXPORT_SYMBOL(insl); |
1da177e4 | 212 |