summaryrefslogtreecommitdiff
path: root/packages/linux/nslu2-kernel/2.6.15/mtd-little-endian-support
diff options
context:
space:
mode:
Diffstat (limited to 'packages/linux/nslu2-kernel/2.6.15/mtd-little-endian-support')
-rw-r--r--packages/linux/nslu2-kernel/2.6.15/mtd-little-endian-support94
1 files changed, 94 insertions, 0 deletions
diff --git a/packages/linux/nslu2-kernel/2.6.15/mtd-little-endian-support b/packages/linux/nslu2-kernel/2.6.15/mtd-little-endian-support
new file mode 100644
index 0000000000..7dff4a2a77
--- /dev/null
+++ b/packages/linux/nslu2-kernel/2.6.15/mtd-little-endian-support
@@ -0,0 +1,94 @@
+diff -u linux-2.6-working/drivers/mtd/maps/ixp4xx.c linux-2.6-working/drivers/mtd/maps/ixp4xx.c
+--- linux-2.6.15/drivers/mtd/maps/ixp4xx.c 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.15/drivers/mtd/maps/ixp4xx.c 1970-01-01 00:00:00.000000000 +0000
+@@ -30,18 +30,42 @@
+
+ #include <linux/reboot.h>
+
+-#ifndef __ARMEB__
+-#define BYTE0(h) ((h) & 0xFF)
+-#define BYTE1(h) (((h) >> 8) & 0xFF)
+-#else
+ #define BYTE0(h) (((h) >> 8) & 0xFF)
+ #define BYTE1(h) ((h) & 0xFF)
++
++/*
++ * Read/write a 16 bit word from flash address 'addr'.
++ *
++ * When the cpu is in little-endian mode it swizzles the address lines
++ * ('address coherency') so we need to undo the swizzling to ensure commands
++ * and the like end up on the correct flash address.
++ */
++#ifndef __ARMEB__
++static inline u16 flash_read16(void __iomem *addr)
++{
++ return le16_to_cpu(readw((void __iomem *)((unsigned long)addr ^ 0x2)));
++}
++
++static inline void flash_write16(u16 d, void __iomem *addr)
++{
++ writew(cpu_to_le16(d), (void __iomem *)((unsigned long)addr ^ 0x2));
++}
++#else
++static inline u16 flash_read16(void __iomem *addr)
++{
++ return le16_to_cpu(readw(addr));
++}
++
++static inline void flash_write16(u16 d, void __iomem *addr)
++{
++ writew(cpu_to_le16(d), addr);
++}
+ #endif
+
+ static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs)
+ {
+ map_word val;
+- val.x[0] = le16_to_cpu(readw(map->virt + ofs));
++ val.x[0] = flash_read16(map->virt + ofs);
+ return val;
+ }
+
+@@ -60,13 +84,13 @@
+ return;
+
+ if (from & 1) {
+- *dest++ = BYTE1(le16_to_cpu(readw(src)));
++ *dest++ = BYTE1(flash_read16(src));
+ src++;
+ --len;
+ }
+
+ while (len >= 2) {
+- u16 data = le16_to_cpu(readw(src));
++ u16 data = flash_read16(src);
+ *dest++ = BYTE0(data);
+ *dest++ = BYTE1(data);
+ src += 2;
+@@ -74,7 +98,7 @@
+ }
+
+ if (len > 0)
+- *dest++ = BYTE0(le16_to_cpu(readw(src)));
++ *dest++ = BYTE0(flash_read16(src));
+ }
+
+ /*
+@@ -84,7 +108,7 @@
+ static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr)
+ {
+ if (!(adr & 1))
+- writew(cpu_to_le16(d.x[0]), map->virt + adr);
++ flash_write16(d.x[0], map->virt + adr);
+ }
+
+ /*
+@@ -92,7 +116,7 @@
+ */
+ static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr)
+ {
+- writew(cpu_to_le16(d.x[0]), map->virt + adr);
++ flash_write16(d.x[0], map->virt + adr);
+ }
+
+ struct ixp4xx_flash_info {