diff options
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-support | 94 |
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 { |