diff options
Diffstat (limited to 'include/asm-mips/io.h')
-rw-r--r-- | include/asm-mips/io.h | 164 |
1 files changed, 109 insertions, 55 deletions
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index 039845f2e6b0..3061870b7f6c 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h | |||
@@ -25,7 +25,9 @@ | |||
25 | #include <asm/page.h> | 25 | #include <asm/page.h> |
26 | #include <asm/pgtable-bits.h> | 26 | #include <asm/pgtable-bits.h> |
27 | #include <asm/processor.h> | 27 | #include <asm/processor.h> |
28 | #include <asm/string.h> | ||
28 | 29 | ||
30 | #include <ioremap.h> | ||
29 | #include <mangle-port.h> | 31 | #include <mangle-port.h> |
30 | 32 | ||
31 | /* | 33 | /* |
@@ -34,7 +36,7 @@ | |||
34 | #undef CONF_SLOWDOWN_IO | 36 | #undef CONF_SLOWDOWN_IO |
35 | 37 | ||
36 | /* | 38 | /* |
37 | * Raw operations are never swapped in software. Otoh values that raw | 39 | * Raw operations are never swapped in software. OTOH values that raw |
38 | * operations are working on may or may not have been swapped by the bus | 40 | * operations are working on may or may not have been swapped by the bus |
39 | * hardware. An example use would be for flash memory that's used for | 41 | * hardware. An example use would be for flash memory that's used for |
40 | * execute in place. | 42 | * execute in place. |
@@ -43,45 +45,53 @@ | |||
43 | # define __raw_ioswabw(x) (x) | 45 | # define __raw_ioswabw(x) (x) |
44 | # define __raw_ioswabl(x) (x) | 46 | # define __raw_ioswabl(x) (x) |
45 | # define __raw_ioswabq(x) (x) | 47 | # define __raw_ioswabq(x) (x) |
48 | # define ____raw_ioswabq(x) (x) | ||
46 | 49 | ||
47 | /* | 50 | /* |
48 | * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware; | 51 | * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware; |
49 | * less sane hardware forces software to fiddle with this... | 52 | * less sane hardware forces software to fiddle with this... |
53 | * | ||
54 | * Regardless, if the host bus endianness mismatches that of PCI/ISA, then | ||
55 | * you can't have the numerical value of data and byte addresses within | ||
56 | * multibyte quantities both preserved at the same time. Hence two | ||
57 | * variations of functions: non-prefixed ones that preserve the value | ||
58 | * and prefixed ones that preserve byte addresses. The latters are | ||
59 | * typically used for moving raw data between a peripheral and memory (cf. | ||
60 | * string I/O functions), hence the "mem_" prefix. | ||
50 | */ | 61 | */ |
51 | #if defined(CONFIG_SWAP_IO_SPACE) | 62 | #if defined(CONFIG_SWAP_IO_SPACE) |
52 | 63 | ||
53 | # define ioswabb(x) (x) | 64 | # define ioswabb(x) (x) |
65 | # define mem_ioswabb(x) (x) | ||
54 | # ifdef CONFIG_SGI_IP22 | 66 | # ifdef CONFIG_SGI_IP22 |
55 | /* | 67 | /* |
56 | * IP22 seems braindead enough to swap 16bits values in hardware, but | 68 | * IP22 seems braindead enough to swap 16bits values in hardware, but |
57 | * not 32bits. Go figure... Can't tell without documentation. | 69 | * not 32bits. Go figure... Can't tell without documentation. |
58 | */ | 70 | */ |
59 | # define ioswabw(x) (x) | 71 | # define ioswabw(x) (x) |
72 | # define mem_ioswabw(x) le16_to_cpu(x) | ||
60 | # else | 73 | # else |
61 | # define ioswabw(x) le16_to_cpu(x) | 74 | # define ioswabw(x) le16_to_cpu(x) |
75 | # define mem_ioswabw(x) (x) | ||
62 | # endif | 76 | # endif |
63 | # define ioswabl(x) le32_to_cpu(x) | 77 | # define ioswabl(x) le32_to_cpu(x) |
78 | # define mem_ioswabl(x) (x) | ||
64 | # define ioswabq(x) le64_to_cpu(x) | 79 | # define ioswabq(x) le64_to_cpu(x) |
80 | # define mem_ioswabq(x) (x) | ||
65 | 81 | ||
66 | #else | 82 | #else |
67 | 83 | ||
68 | # define ioswabb(x) (x) | 84 | # define ioswabb(x) (x) |
85 | # define mem_ioswabb(x) (x) | ||
69 | # define ioswabw(x) (x) | 86 | # define ioswabw(x) (x) |
87 | # define mem_ioswabw(x) cpu_to_le16(x) | ||
70 | # define ioswabl(x) (x) | 88 | # define ioswabl(x) (x) |
89 | # define mem_ioswabl(x) cpu_to_le32(x) | ||
71 | # define ioswabq(x) (x) | 90 | # define ioswabq(x) (x) |
91 | # define mem_ioswabq(x) cpu_to_le32(x) | ||
72 | 92 | ||
73 | #endif | 93 | #endif |
74 | 94 | ||
75 | /* | ||
76 | * Native bus accesses never swapped. | ||
77 | */ | ||
78 | #define bus_ioswabb(x) (x) | ||
79 | #define bus_ioswabw(x) (x) | ||
80 | #define bus_ioswabl(x) (x) | ||
81 | #define bus_ioswabq(x) (x) | ||
82 | |||
83 | #define __bus_ioswabq bus_ioswabq | ||
84 | |||
85 | #define IO_SPACE_LIMIT 0xffff | 95 | #define IO_SPACE_LIMIT 0xffff |
86 | 96 | ||
87 | /* | 97 | /* |
@@ -194,12 +204,14 @@ extern unsigned long isa_slot_offset; | |||
194 | */ | 204 | */ |
195 | #define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) | 205 | #define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) |
196 | 206 | ||
197 | extern void * __ioremap(phys_t offset, phys_t size, unsigned long flags); | 207 | extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags); |
198 | extern void __iounmap(volatile void __iomem *addr); | 208 | extern void __iounmap(volatile void __iomem *addr); |
199 | 209 | ||
200 | static inline void * __ioremap_mode(phys_t offset, unsigned long size, | 210 | static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, |
201 | unsigned long flags) | 211 | unsigned long flags) |
202 | { | 212 | { |
213 | #define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) | ||
214 | |||
203 | if (cpu_has_64bit_addresses) { | 215 | if (cpu_has_64bit_addresses) { |
204 | u64 base = UNCAC_BASE; | 216 | u64 base = UNCAC_BASE; |
205 | 217 | ||
@@ -209,10 +221,30 @@ static inline void * __ioremap_mode(phys_t offset, unsigned long size, | |||
209 | */ | 221 | */ |
210 | if (flags == _CACHE_UNCACHED) | 222 | if (flags == _CACHE_UNCACHED) |
211 | base = (u64) IO_BASE; | 223 | base = (u64) IO_BASE; |
212 | return (void *) (unsigned long) (base + offset); | 224 | return (void __iomem *) (unsigned long) (base + offset); |
225 | } else if (__builtin_constant_p(offset) && | ||
226 | __builtin_constant_p(size) && __builtin_constant_p(flags)) { | ||
227 | phys_t phys_addr, last_addr; | ||
228 | |||
229 | phys_addr = fixup_bigphys_addr(offset, size); | ||
230 | |||
231 | /* Don't allow wraparound or zero size. */ | ||
232 | last_addr = phys_addr + size - 1; | ||
233 | if (!size || last_addr < phys_addr) | ||
234 | return NULL; | ||
235 | |||
236 | /* | ||
237 | * Map uncached objects in the low 512MB of address | ||
238 | * space using KSEG1. | ||
239 | */ | ||
240 | if (__IS_LOW512(phys_addr) && __IS_LOW512(last_addr) && | ||
241 | flags == _CACHE_UNCACHED) | ||
242 | return (void __iomem *)CKSEG1ADDR(phys_addr); | ||
213 | } | 243 | } |
214 | 244 | ||
215 | return __ioremap(offset, size, flags); | 245 | return __ioremap(offset, size, flags); |
246 | |||
247 | #undef __IS_LOW512 | ||
216 | } | 248 | } |
217 | 249 | ||
218 | /* | 250 | /* |
@@ -264,12 +296,16 @@ static inline void * __ioremap_mode(phys_t offset, unsigned long size, | |||
264 | 296 | ||
265 | static inline void iounmap(volatile void __iomem *addr) | 297 | static inline void iounmap(volatile void __iomem *addr) |
266 | { | 298 | { |
267 | if (cpu_has_64bit_addresses) | 299 | #define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1) |
300 | |||
301 | if (cpu_has_64bit_addresses || | ||
302 | (__builtin_constant_p(addr) && __IS_KSEG1(addr))) | ||
268 | return; | 303 | return; |
269 | 304 | ||
270 | __iounmap(addr); | 305 | __iounmap(addr); |
271 | } | ||
272 | 306 | ||
307 | #undef __IS_KSEG1 | ||
308 | } | ||
273 | 309 | ||
274 | #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \ | 310 | #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \ |
275 | \ | 311 | \ |
@@ -319,7 +355,8 @@ static inline type pfx##read##bwlq(volatile void __iomem *mem) \ | |||
319 | else if (cpu_has_64bits) { \ | 355 | else if (cpu_has_64bits) { \ |
320 | unsigned long __flags; \ | 356 | unsigned long __flags; \ |
321 | \ | 357 | \ |
322 | local_irq_save(__flags); \ | 358 | if (irq) \ |
359 | local_irq_save(__flags); \ | ||
323 | __asm__ __volatile__( \ | 360 | __asm__ __volatile__( \ |
324 | ".set mips3" "\t\t# __readq" "\n\t" \ | 361 | ".set mips3" "\t\t# __readq" "\n\t" \ |
325 | "ld %L0, %1" "\n\t" \ | 362 | "ld %L0, %1" "\n\t" \ |
@@ -328,7 +365,8 @@ static inline type pfx##read##bwlq(volatile void __iomem *mem) \ | |||
328 | ".set mips0" "\n" \ | 365 | ".set mips0" "\n" \ |
329 | : "=r" (__val) \ | 366 | : "=r" (__val) \ |
330 | : "m" (*__mem)); \ | 367 | : "m" (*__mem)); \ |
331 | local_irq_restore(__flags); \ | 368 | if (irq) \ |
369 | local_irq_restore(__flags); \ | ||
332 | } else { \ | 370 | } else { \ |
333 | __val = 0; \ | 371 | __val = 0; \ |
334 | BUG(); \ | 372 | BUG(); \ |
@@ -349,11 +387,11 @@ static inline void pfx##out##bwlq##p(type val, unsigned long port) \ | |||
349 | \ | 387 | \ |
350 | __val = pfx##ioswab##bwlq(val); \ | 388 | __val = pfx##ioswab##bwlq(val); \ |
351 | \ | 389 | \ |
352 | if (sizeof(type) != sizeof(u64)) { \ | 390 | /* Really, we want this to be atomic */ \ |
353 | *__addr = __val; \ | 391 | BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \ |
354 | slow; \ | 392 | \ |
355 | } else \ | 393 | *__addr = __val; \ |
356 | BUILD_BUG(); \ | 394 | slow; \ |
357 | } \ | 395 | } \ |
358 | \ | 396 | \ |
359 | static inline type pfx##in##bwlq##p(unsigned long port) \ | 397 | static inline type pfx##in##bwlq##p(unsigned long port) \ |
@@ -364,13 +402,10 @@ static inline type pfx##in##bwlq##p(unsigned long port) \ | |||
364 | port = __swizzle_addr_##bwlq(port); \ | 402 | port = __swizzle_addr_##bwlq(port); \ |
365 | __addr = (void *)(mips_io_port_base + port); \ | 403 | __addr = (void *)(mips_io_port_base + port); \ |
366 | \ | 404 | \ |
367 | if (sizeof(type) != sizeof(u64)) { \ | 405 | BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \ |
368 | __val = *__addr; \ | 406 | \ |
369 | slow; \ | 407 | __val = *__addr; \ |
370 | } else { \ | 408 | slow; \ |
371 | __val = 0; \ | ||
372 | BUILD_BUG(); \ | ||
373 | } \ | ||
374 | \ | 409 | \ |
375 | return pfx##ioswab##bwlq(__val); \ | 410 | return pfx##ioswab##bwlq(__val); \ |
376 | } | 411 | } |
@@ -379,27 +414,35 @@ static inline type pfx##in##bwlq##p(unsigned long port) \ | |||
379 | \ | 414 | \ |
380 | __BUILD_MEMORY_SINGLE(bus, bwlq, type, 1) | 415 | __BUILD_MEMORY_SINGLE(bus, bwlq, type, 1) |
381 | 416 | ||
382 | #define __BUILD_IOPORT_PFX(bus, bwlq, type) \ | 417 | #define BUILDIO_MEM(bwlq, type) \ |
383 | \ | ||
384 | __BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \ | ||
385 | __BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO) | ||
386 | |||
387 | #define BUILDIO(bwlq, type) \ | ||
388 | \ | 418 | \ |
389 | __BUILD_MEMORY_PFX(, bwlq, type) \ | ||
390 | __BUILD_MEMORY_PFX(__raw_, bwlq, type) \ | 419 | __BUILD_MEMORY_PFX(__raw_, bwlq, type) \ |
391 | __BUILD_MEMORY_PFX(bus_, bwlq, type) \ | 420 | __BUILD_MEMORY_PFX(, bwlq, type) \ |
392 | __BUILD_IOPORT_PFX(, bwlq, type) \ | 421 | __BUILD_MEMORY_PFX(mem_, bwlq, type) \ |
393 | __BUILD_IOPORT_PFX(__raw_, bwlq, type) | 422 | |
423 | BUILDIO_MEM(b, u8) | ||
424 | BUILDIO_MEM(w, u16) | ||
425 | BUILDIO_MEM(l, u32) | ||
426 | BUILDIO_MEM(q, u64) | ||
427 | |||
428 | #define __BUILD_IOPORT_PFX(bus, bwlq, type) \ | ||
429 | __BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \ | ||
430 | __BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO) | ||
431 | |||
432 | #define BUILDIO_IOPORT(bwlq, type) \ | ||
433 | __BUILD_IOPORT_PFX(, bwlq, type) \ | ||
434 | __BUILD_IOPORT_PFX(mem_, bwlq, type) | ||
435 | |||
436 | BUILDIO_IOPORT(b, u8) | ||
437 | BUILDIO_IOPORT(w, u16) | ||
438 | BUILDIO_IOPORT(l, u32) | ||
439 | #ifdef CONFIG_64BIT | ||
440 | BUILDIO_IOPORT(q, u64) | ||
441 | #endif | ||
394 | 442 | ||
395 | #define __BUILDIO(bwlq, type) \ | 443 | #define __BUILDIO(bwlq, type) \ |
396 | \ | 444 | \ |
397 | __BUILD_MEMORY_SINGLE(__bus_, bwlq, type, 0) | 445 | __BUILD_MEMORY_SINGLE(____raw_, bwlq, type, 0) |
398 | |||
399 | BUILDIO(b, u8) | ||
400 | BUILDIO(w, u16) | ||
401 | BUILDIO(l, u32) | ||
402 | BUILDIO(q, u64) | ||
403 | 446 | ||
404 | __BUILDIO(q, u64) | 447 | __BUILDIO(q, u64) |
405 | 448 | ||
@@ -422,7 +465,7 @@ static inline void writes##bwlq(volatile void __iomem *mem, void *addr, \ | |||
422 | volatile type *__addr = addr; \ | 465 | volatile type *__addr = addr; \ |
423 | \ | 466 | \ |
424 | while (count--) { \ | 467 | while (count--) { \ |
425 | __raw_write##bwlq(*__addr, mem); \ | 468 | mem_write##bwlq(*__addr, mem); \ |
426 | __addr++; \ | 469 | __addr++; \ |
427 | } \ | 470 | } \ |
428 | } \ | 471 | } \ |
@@ -433,20 +476,20 @@ static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \ | |||
433 | volatile type *__addr = addr; \ | 476 | volatile type *__addr = addr; \ |
434 | \ | 477 | \ |
435 | while (count--) { \ | 478 | while (count--) { \ |
436 | *__addr = __raw_read##bwlq(mem); \ | 479 | *__addr = mem_read##bwlq(mem); \ |
437 | __addr++; \ | 480 | __addr++; \ |
438 | } \ | 481 | } \ |
439 | } | 482 | } |
440 | 483 | ||
441 | #define __BUILD_IOPORT_STRING(bwlq, type) \ | 484 | #define __BUILD_IOPORT_STRING(bwlq, type) \ |
442 | \ | 485 | \ |
443 | static inline void outs##bwlq(unsigned long port, void *addr, \ | 486 | static inline void outs##bwlq(unsigned long port, const void *addr, \ |
444 | unsigned int count) \ | 487 | unsigned int count) \ |
445 | { \ | 488 | { \ |
446 | volatile type *__addr = addr; \ | 489 | const volatile type *__addr = addr; \ |
447 | \ | 490 | \ |
448 | while (count--) { \ | 491 | while (count--) { \ |
449 | __raw_out##bwlq(*__addr, port); \ | 492 | mem_out##bwlq(*__addr, port); \ |
450 | __addr++; \ | 493 | __addr++; \ |
451 | } \ | 494 | } \ |
452 | } \ | 495 | } \ |
@@ -457,7 +500,7 @@ static inline void ins##bwlq(unsigned long port, void *addr, \ | |||
457 | volatile type *__addr = addr; \ | 500 | volatile type *__addr = addr; \ |
458 | \ | 501 | \ |
459 | while (count--) { \ | 502 | while (count--) { \ |
460 | *__addr = __raw_in##bwlq(port); \ | 503 | *__addr = mem_in##bwlq(port); \ |
461 | __addr++; \ | 504 | __addr++; \ |
462 | } \ | 505 | } \ |
463 | } | 506 | } |
@@ -470,15 +513,26 @@ __BUILD_IOPORT_STRING(bwlq, type) | |||
470 | BUILDSTRING(b, u8) | 513 | BUILDSTRING(b, u8) |
471 | BUILDSTRING(w, u16) | 514 | BUILDSTRING(w, u16) |
472 | BUILDSTRING(l, u32) | 515 | BUILDSTRING(l, u32) |
516 | #ifdef CONFIG_64BIT | ||
473 | BUILDSTRING(q, u64) | 517 | BUILDSTRING(q, u64) |
518 | #endif | ||
474 | 519 | ||
475 | 520 | ||
476 | /* Depends on MIPS II instruction set */ | 521 | /* Depends on MIPS II instruction set */ |
477 | #define mmiowb() asm volatile ("sync" ::: "memory") | 522 | #define mmiowb() asm volatile ("sync" ::: "memory") |
478 | 523 | ||
479 | #define memset_io(a,b,c) memset((void *)(a),(b),(c)) | 524 | static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count) |
480 | #define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) | 525 | { |
481 | #define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) | 526 | memset((void __force *) addr, val, count); |
527 | } | ||
528 | static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count) | ||
529 | { | ||
530 | memcpy(dst, (void __force *) src, count); | ||
531 | } | ||
532 | static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count) | ||
533 | { | ||
534 | memcpy((void __force *) dst, src, count); | ||
535 | } | ||
482 | 536 | ||
483 | /* | 537 | /* |
484 | * Memory Mapped I/O | 538 | * Memory Mapped I/O |