diff options
author | Paul Mundt <lethal@linux-sh.org> | 2012-03-29 03:05:10 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2012-03-29 03:05:10 -0400 |
commit | b7e68d6876dfbab087bc3859211a9efc74cbe30c (patch) | |
tree | 25186c33a579a88116fbef38ba4849cc59c2d498 | |
parent | 5e047fa159cf40733c627002d0443fddff3183c7 (diff) |
sh: Support I/O space swapping where needed.
This adopts a trimmed down version of the MIPS port mangling interface
limited to the I/O swabbing for platforms that can't use little endian
accessors. For platforms with mixed I/O spaces involving PCI it will
still be necessary to enable byte swapping at the host controller level.
Attention needs to be paid to all of host controller endianness, CPU
endianness, and whether I/O accesses are explicitly swapped or not via
SWAP_IO_SPACE. Fortunately the platforms that need this are in the
minority.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | arch/sh/Kconfig | 3 | ||||
-rw-r--r-- | arch/sh/include/asm/io.h | 25 | ||||
-rw-r--r-- | arch/sh/include/mach-common/mach/mangle-port.h | 49 |
3 files changed, 62 insertions, 15 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 5d1ae854bfda..2d9cd1327a06 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -162,6 +162,9 @@ config NO_IOPORT | |||
162 | config IO_TRAPPED | 162 | config IO_TRAPPED |
163 | bool | 163 | bool |
164 | 164 | ||
165 | config SWAP_IO_SPACE | ||
166 | bool | ||
167 | |||
165 | config DMA_COHERENT | 168 | config DMA_COHERENT |
166 | bool | 169 | bool |
167 | 170 | ||
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 28c5aa58bb45..eb76cb32f49f 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define __IO_PREFIX generic | 24 | #define __IO_PREFIX generic |
25 | #include <asm/io_generic.h> | 25 | #include <asm/io_generic.h> |
26 | #include <asm/io_trapped.h> | 26 | #include <asm/io_trapped.h> |
27 | #include <mach/mangle-port.h> | ||
27 | 28 | ||
28 | #define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile u8 __force *)(a) = (v)) | 29 | #define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile u8 __force *)(a) = (v)) |
29 | #define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile u16 __force *)(a) = (v)) | 30 | #define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile u16 __force *)(a) = (v)) |
@@ -35,21 +36,15 @@ | |||
35 | #define __raw_readl(a) (__chk_io_ptr(a), *(volatile u32 __force *)(a)) | 36 | #define __raw_readl(a) (__chk_io_ptr(a), *(volatile u32 __force *)(a)) |
36 | #define __raw_readq(a) (__chk_io_ptr(a), *(volatile u64 __force *)(a)) | 37 | #define __raw_readq(a) (__chk_io_ptr(a), *(volatile u64 __force *)(a)) |
37 | 38 | ||
38 | #define readb_relaxed(c) ({ u8 __v = __raw_readb(c); __v; }) | 39 | #define readb_relaxed(c) ({ u8 __v = ioswabb(__raw_readb(c)); __v; }) |
39 | #define readw_relaxed(c) ({ u16 __v = le16_to_cpu((__force __le16) \ | 40 | #define readw_relaxed(c) ({ u16 __v = ioswabw(__raw_readw(c)); __v; }) |
40 | __raw_readw(c)); __v; }) | 41 | #define readl_relaxed(c) ({ u32 __v = ioswabl(__raw_readl(c)); __v; }) |
41 | #define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32) \ | 42 | #define readq_relaxed(c) ({ u64 __v = ioswabq(__raw_readq(c)); __v; }) |
42 | __raw_readl(c)); __v; }) | 43 | |
43 | #define readq_relaxed(c) ({ u64 __v = le64_to_cpu((__force __le64) \ | 44 | #define writeb_relaxed(v,c) ((void)__raw_writeb((__force u8)ioswabb(v),c)) |
44 | __raw_readq(c)); __v; }) | 45 | #define writew_relaxed(v,c) ((void)__raw_writew((__force u16)ioswabw(v),c)) |
45 | 46 | #define writel_relaxed(v,c) ((void)__raw_writel((__force u32)ioswabl(v),c)) | |
46 | #define writeb_relaxed(v,c) ((void)__raw_writeb(v,c)) | 47 | #define writeq_relaxed(v,c) ((void)__raw_writeq((__force u64)ioswabq(v),c)) |
47 | #define writew_relaxed(v,c) ((void)__raw_writew((__force u16) \ | ||
48 | cpu_to_le16(v),c)) | ||
49 | #define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \ | ||
50 | cpu_to_le32(v),c)) | ||
51 | #define writeq_relaxed(v,c) ((void)__raw_writeq((__force u64) \ | ||
52 | cpu_to_le64(v),c)) | ||
53 | 48 | ||
54 | #define readb(a) ({ u8 r_ = readb_relaxed(a); rmb(); r_; }) | 49 | #define readb(a) ({ u8 r_ = readb_relaxed(a); rmb(); r_; }) |
55 | #define readw(a) ({ u16 r_ = readw_relaxed(a); rmb(); r_; }) | 50 | #define readw(a) ({ u16 r_ = readw_relaxed(a); rmb(); r_; }) |
diff --git a/arch/sh/include/mach-common/mach/mangle-port.h b/arch/sh/include/mach-common/mach/mangle-port.h new file mode 100644 index 000000000000..4ca1769a0f12 --- /dev/null +++ b/arch/sh/include/mach-common/mach/mangle-port.h | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * SH version cribbed from the MIPS copy: | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2003, 2004 Ralf Baechle | ||
9 | */ | ||
10 | #ifndef __MACH_COMMON_MANGLE_PORT_H | ||
11 | #define __MACH_COMMON_MANGLE_PORT_H | ||
12 | |||
13 | /* | ||
14 | * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware; | ||
15 | * less sane hardware forces software to fiddle with this... | ||
16 | * | ||
17 | * Regardless, if the host bus endianness mismatches that of PCI/ISA, then | ||
18 | * you can't have the numerical value of data and byte addresses within | ||
19 | * multibyte quantities both preserved at the same time. Hence two | ||
20 | * variations of functions: non-prefixed ones that preserve the value | ||
21 | * and prefixed ones that preserve byte addresses. The latters are | ||
22 | * typically used for moving raw data between a peripheral and memory (cf. | ||
23 | * string I/O functions), hence the "__mem_" prefix. | ||
24 | */ | ||
25 | #if defined(CONFIG_SWAP_IO_SPACE) | ||
26 | |||
27 | # define ioswabb(x) (x) | ||
28 | # define __mem_ioswabb(x) (x) | ||
29 | # define ioswabw(x) le16_to_cpu(x) | ||
30 | # define __mem_ioswabw(x) (x) | ||
31 | # define ioswabl(x) le32_to_cpu(x) | ||
32 | # define __mem_ioswabl(x) (x) | ||
33 | # define ioswabq(x) le64_to_cpu(x) | ||
34 | # define __mem_ioswabq(x) (x) | ||
35 | |||
36 | #else | ||
37 | |||
38 | # define ioswabb(x) (x) | ||
39 | # define __mem_ioswabb(x) (x) | ||
40 | # define ioswabw(x) (x) | ||
41 | # define __mem_ioswabw(x) cpu_to_le16(x) | ||
42 | # define ioswabl(x) (x) | ||
43 | # define __mem_ioswabl(x) cpu_to_le32(x) | ||
44 | # define ioswabq(x) (x) | ||
45 | # define __mem_ioswabq(x) cpu_to_le32(x) | ||
46 | |||
47 | #endif | ||
48 | |||
49 | #endif /* __MACH_COMMON_MANGLE_PORT_H */ | ||