#include <asm/octeon/octeon.h>
 #include <asm/octeon/pci-octeon.h>
-#include <asm/octeon/cvmx-mio-defs.h>
 #include <asm/octeon/cvmx-rst-defs.h>
 
+/*
+ * TRUE for devices having registers with little-endian byte
+ * order, FALSE for registers with native-endian byte order.
+ * PCI mandates little-endian, USB and SATA are configuraable,
+ * but we chose little-endian for these.
+ */
+const bool octeon_should_swizzle_table[256] = {
+       [0x00] = true,  /* bootbus/CF */
+       [0x1b] = true,  /* PCI mmio window */
+       [0x1c] = true,  /* PCI mmio window */
+       [0x1d] = true,  /* PCI mmio window */
+       [0x1e] = true,  /* PCI mmio window */
+       [0x68] = true,  /* OCTEON III USB */
+       [0x69] = true,  /* OCTEON III USB */
+       [0x6c] = true,  /* OCTEON III SATA */
+       [0x6f] = true,  /* OCTEON II USB */
+};
+EXPORT_SYMBOL(octeon_should_swizzle_table);
+
 #ifdef CONFIG_PCI
 extern void pci_console_init(const char *arg);
 #endif
 
 
 #ifdef __BIG_ENDIAN
 
+static inline bool __should_swizzle_bits(volatile void *a)
+{
+       extern const bool octeon_should_swizzle_table[];
+
+       unsigned long did = ((unsigned long)a >> 40) & 0xff;
+       return octeon_should_swizzle_table[did];
+}
+
 # define __swizzle_addr_b(port)        (port)
 # define __swizzle_addr_w(port)        (port)
 # define __swizzle_addr_l(port)        (port)
 
 #else /* __LITTLE_ENDIAN */
 
+#define __should_swizzle_bits(a)       false
+
 static inline bool __should_swizzle_addr(unsigned long p)
 {
        /* boot bus? */
 
 #endif /* __BIG_ENDIAN */
 
-/*
- * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
- * less sane hardware forces software to fiddle with this...
- *
- * Regardless, if the host bus endianness mismatches that of PCI/ISA, then
- * you can't have the numerical value of data and byte addresses within
- * multibyte quantities both preserved at the same time.  Hence two
- * variations of functions: non-prefixed ones that preserve the value
- * and prefixed ones that preserve byte addresses.  The latters are
- * typically used for moving raw data between a peripheral and memory (cf.
- * string I/O functions), hence the "__mem_" prefix.
- */
-#if defined(CONFIG_SWAP_IO_SPACE)
 
 # define ioswabb(a, x)         (x)
 # define __mem_ioswabb(a, x)   (x)
-# define ioswabw(a, x)         le16_to_cpu(x)
+# define ioswabw(a, x)         (__should_swizzle_bits(a) ? le16_to_cpu(x) : x)
 # define __mem_ioswabw(a, x)   (x)
-# define ioswabl(a, x)         le32_to_cpu(x)
+# define ioswabl(a, x)         (__should_swizzle_bits(a) ? le32_to_cpu(x) : x)
 # define __mem_ioswabl(a, x)   (x)
-# define ioswabq(a, x)         le64_to_cpu(x)
+# define ioswabq(a, x)         (__should_swizzle_bits(a) ? le64_to_cpu(x) : x)
 # define __mem_ioswabq(a, x)   (x)
 
-#else
-
-# define ioswabb(a, x)         (x)
-# define __mem_ioswabb(a, x)   (x)
-# define ioswabw(a, x)         (x)
-# define __mem_ioswabw(a, x)   cpu_to_le16(x)
-# define ioswabl(a, x)         (x)
-# define __mem_ioswabl(a, x)   cpu_to_le32(x)
-# define ioswabq(a, x)         (x)
-# define __mem_ioswabq(a, x)   cpu_to_le32(x)
-
-#endif
-
 #endif /* __ASM_MACH_GENERIC_MANGLE_PORT_H */