1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * linux/include/asm-m68k/raw_io.h 4 * 5 * 10/20/00 RZ: - created from bits of io.h and ide.h to cleanup namespace 6 * 7 */ 8 9 #ifndef _RAW_IO_H 10 #define _RAW_IO_H 11 12 #ifdef __KERNEL__ 13 14 #include <asm/byteorder.h> 15 16 /* ++roman: The assignments to temp. vars avoid that gcc sometimes generates 17 * two accesses to memory, which may be undesirable for some devices. 18 */ 19 #define in_8(addr) \ 20 ({ u8 __v = (*(__force volatile u8 *) (addr)); __v; }) 21 #define in_be16(addr) \ 22 ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; }) 23 #define in_be32(addr) \ 24 ({ u32 __v = (*(__force volatile u32 *) (addr)); __v; }) 25 #define in_le16(addr) \ 26 ({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (addr)); __v; }) 27 #define in_le32(addr) \ 28 ({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (addr)); __v; }) 29 30 #define out_8(addr,b) (void)((*(__force volatile u8 *) (addr)) = (b)) 31 #define out_be16(addr,w) (void)((*(__force volatile u16 *) (addr)) = (w)) 32 #define out_be32(addr,l) (void)((*(__force volatile u32 *) (addr)) = (l)) 33 #define out_le16(addr,w) (void)((*(__force volatile __le16 *) (addr)) = cpu_to_le16(w)) 34 #define out_le32(addr,l) (void)((*(__force volatile __le32 *) (addr)) = cpu_to_le32(l)) 35 36 #define raw_inb in_8 37 #define raw_inw in_be16 38 #define raw_inl in_be32 39 #define __raw_readb in_8 40 #define __raw_readw in_be16 41 #define __raw_readl in_be32 42 43 #define raw_outb(val,port) out_8((port),(val)) 44 #define raw_outw(val,port) out_be16((port),(val)) 45 #define raw_outl(val,port) out_be32((port),(val)) 46 #define __raw_writeb(val,addr) out_8((addr),(val)) 47 #define __raw_writew(val,addr) out_be16((addr),(val)) 48 #define __raw_writel(val,addr) out_be32((addr),(val)) 49 50 /* 51 * Atari ROM port (cartridge port) ISA adapter, used for the EtherNEC NE2000 52 * network card driver. 53 * The ISA adapter connects address lines A9-A13 to ISA address lines A0-A4, 54 * and hardwires the rest of the ISA addresses for a base address of 0x300. 55 * 56 * Data lines D8-D15 are connected to ISA data lines D0-D7 for reading. 57 * For writes, address lines A1-A8 are latched to ISA data lines D0-D7 58 * (meaning the bit pattern on A1-A8 can be read back as byte). 59 * 60 * Read and write operations are distinguished by the base address used: 61 * reads are from the ROM A side range, writes are through the B side range 62 * addresses (A side base + 0x10000). 63 * 64 * Reads and writes are byte only. 65 * 66 * 16 bit reads and writes are necessary for the NetUSBee adapter's USB 67 * chipset - 16 bit words are read straight off the ROM port while 16 bit 68 * reads are split into two byte writes. The low byte is latched to the 69 * NetUSBee buffer by a read from the _read_ window (with the data pattern 70 * asserted as A1-A8 address pattern). The high byte is then written to the 71 * write range as usual, completing the write cycle. 72 */ 73 74 #if defined(CONFIG_ATARI_ROM_ISA) 75 #define rom_in_8(addr) \ 76 ({ u16 __v = (*(__force volatile u16 *) (addr)); __v >>= 8; __v; }) 77 #define rom_in_be16(addr) \ 78 ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; }) 79 #define rom_in_le16(addr) \ 80 ({ u16 __v = le16_to_cpu(*(__force volatile u16 *) (addr)); __v; }) 81 82 #define rom_out_8(addr, b) \ 83 ({u8 __w, __v = (b); u32 _addr = ((u32) (addr)); \ 84 __w = ((*(__force volatile u8 *) ((_addr | 0x10000) + (__v<<1)))); }) 85 #define rom_out_be16(addr, w) \ 86 ({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \ 87 __w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v & 0xFF)<<1)))); \ 88 __w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v >> 8)<<1)))); }) 89 #define rom_out_le16(addr, w) \ 90 ({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \ 91 __w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v >> 8)<<1)))); \ 92 __w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v & 0xFF)<<1)))); }) 93 94 #define raw_rom_inb rom_in_8 95 #define raw_rom_inw rom_in_be16 96 97 #define raw_rom_outb(val, port) rom_out_8((port), (val)) 98 #define raw_rom_outw(val, port) rom_out_be16((port), (val)) 99 #endif /* CONFIG_ATARI_ROM_ISA */ 100 101 static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len) 102 { 103 unsigned int i; 104 105 for (i = 0; i < len; i++) 106 *buf++ = in_8(port); 107 } 108 109 static inline void raw_outsb(volatile u8 __iomem *port, const u8 *buf, 110 unsigned int len) 111 { 112 unsigned int i; 113 114 for (i = 0; i < len; i++) 115 out_8(port, *buf++); 116 } 117 118 static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int nr) 119 { 120 unsigned int tmp; 121 122 if (nr & 15) { 123 tmp = (nr & 15) - 1; 124 asm volatile ( 125 "1: movew %2@,%0@+; dbra %1,1b" 126 : "=a" (buf), "=d" (tmp) 127 : "a" (port), "0" (buf), 128 "1" (tmp)); 129 } 130 if (nr >> 4) { 131 tmp = (nr >> 4) - 1; 132 asm volatile ( 133 "1: " 134 "movew %2@,%0@+; " 135 "movew %2@,%0@+; " 136 "movew %2@,%0@+; " 137 "movew %2@,%0@+; " 138 "movew %2@,%0@+; " 139 "movew %2@,%0@+; " 140 "movew %2@,%0@+; " 141 "movew %2@,%0@+; " 142 "movew %2@,%0@+; " 143 "movew %2@,%0@+; " 144 "movew %2@,%0@+; " 145 "movew %2@,%0@+; " 146 "movew %2@,%0@+; " 147 "movew %2@,%0@+; " 148 "movew %2@,%0@+; " 149 "movew %2@,%0@+; " 150 "dbra %1,1b" 151 : "=a" (buf), "=d" (tmp) 152 : "a" (port), "0" (buf), 153 "1" (tmp)); 154 } 155 } 156 157 static inline void raw_outsw(volatile u16 __iomem *port, const u16 *buf, 158 unsigned int nr) 159 { 160 unsigned int tmp; 161 162 if (nr & 15) { 163 tmp = (nr & 15) - 1; 164 asm volatile ( 165 "1: movew %0@+,%2@; dbra %1,1b" 166 : "=a" (buf), "=d" (tmp) 167 : "a" (port), "0" (buf), 168 "1" (tmp)); 169 } 170 if (nr >> 4) { 171 tmp = (nr >> 4) - 1; 172 asm volatile ( 173 "1: " 174 "movew %0@+,%2@; " 175 "movew %0@+,%2@; " 176 "movew %0@+,%2@; " 177 "movew %0@+,%2@; " 178 "movew %0@+,%2@; " 179 "movew %0@+,%2@; " 180 "movew %0@+,%2@; " 181 "movew %0@+,%2@; " 182 "movew %0@+,%2@; " 183 "movew %0@+,%2@; " 184 "movew %0@+,%2@; " 185 "movew %0@+,%2@; " 186 "movew %0@+,%2@; " 187 "movew %0@+,%2@; " 188 "movew %0@+,%2@; " 189 "movew %0@+,%2@; " 190 "dbra %1,1b" 191 : "=a" (buf), "=d" (tmp) 192 : "a" (port), "0" (buf), 193 "1" (tmp)); 194 } 195 } 196 197 static inline void raw_insl(volatile u32 __iomem *port, u32 *buf, unsigned int nr) 198 { 199 unsigned int tmp; 200 201 if (nr & 15) { 202 tmp = (nr & 15) - 1; 203 asm volatile ( 204 "1: movel %2@,%0@+; dbra %1,1b" 205 : "=a" (buf), "=d" (tmp) 206 : "a" (port), "0" (buf), 207 "1" (tmp)); 208 } 209 if (nr >> 4) { 210 tmp = (nr >> 4) - 1; 211 asm volatile ( 212 "1: " 213 "movel %2@,%0@+; " 214 "movel %2@,%0@+; " 215 "movel %2@,%0@+; " 216 "movel %2@,%0@+; " 217 "movel %2@,%0@+; " 218 "movel %2@,%0@+; " 219 "movel %2@,%0@+; " 220 "movel %2@,%0@+; " 221 "movel %2@,%0@+; " 222 "movel %2@,%0@+; " 223 "movel %2@,%0@+; " 224 "movel %2@,%0@+; " 225 "movel %2@,%0@+; " 226 "movel %2@,%0@+; " 227 "movel %2@,%0@+; " 228 "movel %2@,%0@+; " 229 "dbra %1,1b" 230 : "=a" (buf), "=d" (tmp) 231 : "a" (port), "0" (buf), 232 "1" (tmp)); 233 } 234 } 235 236 static inline void raw_outsl(volatile u32 __iomem *port, const u32 *buf, 237 unsigned int nr) 238 { 239 unsigned int tmp; 240 241 if (nr & 15) { 242 tmp = (nr & 15) - 1; 243 asm volatile ( 244 "1: movel %0@+,%2@; dbra %1,1b" 245 : "=a" (buf), "=d" (tmp) 246 : "a" (port), "0" (buf), 247 "1" (tmp)); 248 } 249 if (nr >> 4) { 250 tmp = (nr >> 4) - 1; 251 asm volatile ( 252 "1: " 253 "movel %0@+,%2@; " 254 "movel %0@+,%2@; " 255 "movel %0@+,%2@; " 256 "movel %0@+,%2@; " 257 "movel %0@+,%2@; " 258 "movel %0@+,%2@; " 259 "movel %0@+,%2@; " 260 "movel %0@+,%2@; " 261 "movel %0@+,%2@; " 262 "movel %0@+,%2@; " 263 "movel %0@+,%2@; " 264 "movel %0@+,%2@; " 265 "movel %0@+,%2@; " 266 "movel %0@+,%2@; " 267 "movel %0@+,%2@; " 268 "movel %0@+,%2@; " 269 "dbra %1,1b" 270 : "=a" (buf), "=d" (tmp) 271 : "a" (port), "0" (buf), 272 "1" (tmp)); 273 } 274 } 275 276 277 static inline void raw_insw_swapw(volatile u16 __iomem *port, u16 *buf, 278 unsigned int nr) 279 { 280 if ((nr) % 8) 281 __asm__ __volatile__ 282 ("\tmovel %0,%/a0\n\t" 283 "movel %1,%/a1\n\t" 284 "movel %2,%/d6\n\t" 285 "subql #1,%/d6\n" 286 "1:\tmovew %/a0@,%/d0\n\t" 287 "rolw #8,%/d0\n\t" 288 "movew %/d0,%/a1@+\n\t" 289 "dbra %/d6,1b" 290 : 291 : "g" (port), "g" (buf), "g" (nr) 292 : "d0", "a0", "a1", "d6"); 293 else 294 __asm__ __volatile__ 295 ("movel %0,%/a0\n\t" 296 "movel %1,%/a1\n\t" 297 "movel %2,%/d6\n\t" 298 "lsrl #3,%/d6\n\t" 299 "subql #1,%/d6\n" 300 "1:\tmovew %/a0@,%/d0\n\t" 301 "rolw #8,%/d0\n\t" 302 "movew %/d0,%/a1@+\n\t" 303 "movew %/a0@,%/d0\n\t" 304 "rolw #8,%/d0\n\t" 305 "movew %/d0,%/a1@+\n\t" 306 "movew %/a0@,%/d0\n\t" 307 "rolw #8,%/d0\n\t" 308 "movew %/d0,%/a1@+\n\t" 309 "movew %/a0@,%/d0\n\t" 310 "rolw #8,%/d0\n\t" 311 "movew %/d0,%/a1@+\n\t" 312 "movew %/a0@,%/d0\n\t" 313 "rolw #8,%/d0\n\t" 314 "movew %/d0,%/a1@+\n\t" 315 "movew %/a0@,%/d0\n\t" 316 "rolw #8,%/d0\n\t" 317 "movew %/d0,%/a1@+\n\t" 318 "movew %/a0@,%/d0\n\t" 319 "rolw #8,%/d0\n\t" 320 "movew %/d0,%/a1@+\n\t" 321 "movew %/a0@,%/d0\n\t" 322 "rolw #8,%/d0\n\t" 323 "movew %/d0,%/a1@+\n\t" 324 "dbra %/d6,1b" 325 : 326 : "g" (port), "g" (buf), "g" (nr) 327 : "d0", "a0", "a1", "d6"); 328 } 329 330 static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf, 331 unsigned int nr) 332 { 333 if ((nr) % 8) 334 __asm__ __volatile__ 335 ("movel %0,%/a0\n\t" 336 "movel %1,%/a1\n\t" 337 "movel %2,%/d6\n\t" 338 "subql #1,%/d6\n" 339 "1:\tmovew %/a1@+,%/d0\n\t" 340 "rolw #8,%/d0\n\t" 341 "movew %/d0,%/a0@\n\t" 342 "dbra %/d6,1b" 343 : 344 : "g" (port), "g" (buf), "g" (nr) 345 : "d0", "a0", "a1", "d6"); 346 else 347 __asm__ __volatile__ 348 ("movel %0,%/a0\n\t" 349 "movel %1,%/a1\n\t" 350 "movel %2,%/d6\n\t" 351 "lsrl #3,%/d6\n\t" 352 "subql #1,%/d6\n" 353 "1:\tmovew %/a1@+,%/d0\n\t" 354 "rolw #8,%/d0\n\t" 355 "movew %/d0,%/a0@\n\t" 356 "movew %/a1@+,%/d0\n\t" 357 "rolw #8,%/d0\n\t" 358 "movew %/d0,%/a0@\n\t" 359 "movew %/a1@+,%/d0\n\t" 360 "rolw #8,%/d0\n\t" 361 "movew %/d0,%/a0@\n\t" 362 "movew %/a1@+,%/d0\n\t" 363 "rolw #8,%/d0\n\t" 364 "movew %/d0,%/a0@\n\t" 365 "movew %/a1@+,%/d0\n\t" 366 "rolw #8,%/d0\n\t" 367 "movew %/d0,%/a0@\n\t" 368 "movew %/a1@+,%/d0\n\t" 369 "rolw #8,%/d0\n\t" 370 "movew %/d0,%/a0@\n\t" 371 "movew %/a1@+,%/d0\n\t" 372 "rolw #8,%/d0\n\t" 373 "movew %/d0,%/a0@\n\t" 374 "movew %/a1@+,%/d0\n\t" 375 "rolw #8,%/d0\n\t" 376 "movew %/d0,%/a0@\n\t" 377 "dbra %/d6,1b" 378 : 379 : "g" (port), "g" (buf), "g" (nr) 380 : "d0", "a0", "a1", "d6"); 381 } 382 383 384 #if defined(CONFIG_ATARI_ROM_ISA) 385 static inline void raw_rom_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len) 386 { 387 unsigned int i; 388 389 for (i = 0; i < len; i++) 390 *buf++ = rom_in_8(port); 391 } 392 393 static inline void raw_rom_outsb(volatile u8 __iomem *port, const u8 *buf, 394 unsigned int len) 395 { 396 unsigned int i; 397 398 for (i = 0; i < len; i++) 399 rom_out_8(port, *buf++); 400 } 401 402 static inline void raw_rom_insw(volatile u16 __iomem *port, u16 *buf, 403 unsigned int nr) 404 { 405 unsigned int i; 406 407 for (i = 0; i < nr; i++) 408 *buf++ = rom_in_be16(port); 409 } 410 411 static inline void raw_rom_outsw(volatile u16 __iomem *port, const u16 *buf, 412 unsigned int nr) 413 { 414 unsigned int i; 415 416 for (i = 0; i < nr; i++) 417 rom_out_be16(port, *buf++); 418 } 419 420 static inline void raw_rom_insw_swapw(volatile u16 __iomem *port, u16 *buf, 421 unsigned int nr) 422 { 423 unsigned int i; 424 425 for (i = 0; i < nr; i++) 426 *buf++ = rom_in_le16(port); 427 } 428 429 static inline void raw_rom_outsw_swapw(volatile u16 __iomem *port, const u16 *buf, 430 unsigned int nr) 431 { 432 unsigned int i; 433 434 for (i = 0; i < nr; i++) 435 rom_out_le16(port, *buf++); 436 } 437 #endif /* CONFIG_ATARI_ROM_ISA */ 438 439 #endif /* __KERNEL__ */ 440 441 #endif /* _RAW_IO_H */ 442