From 0d2d69ed39038ada1a07216ec9f39670619edd7b Mon Sep 17 00:00:00 2001 From: Rod Whitby Date: Sun, 20 Nov 2005 20:39:10 +0000 Subject: nas100d-kernel: Latest 2.6.15-rc1 patches added. --- .../nas100d-kernel/2.6.15/90-ixp4xx-nslu2.patch | 132 +++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 packages/linux/nas100d-kernel/2.6.15/90-ixp4xx-nslu2.patch (limited to 'packages/linux/nas100d-kernel/2.6.15/90-ixp4xx-nslu2.patch') diff --git a/packages/linux/nas100d-kernel/2.6.15/90-ixp4xx-nslu2.patch b/packages/linux/nas100d-kernel/2.6.15/90-ixp4xx-nslu2.patch new file mode 100644 index 0000000000..c106f7c957 --- /dev/null +++ b/packages/linux/nas100d-kernel/2.6.15/90-ixp4xx-nslu2.patch @@ -0,0 +1,132 @@ +ixp4xx updates: + - Handle reads that don't start on a half-word boundary. + - Make it work when CPU is in little-endian mode. + +Signed-off-by: John Bowler +Signed-off-by: Alessandro Zummo +Signed-off-by: David Vrabel + +Index: linux-2.6-working/drivers/mtd/maps/ixp4xx.c +=================================================================== +--- linux-2.6-working.orig/drivers/mtd/maps/ixp4xx.c 2005-11-16 15:19:34.000000000 +0000 ++++ linux-2.6-working/drivers/mtd/maps/ixp4xx.c 2005-11-16 16:06:54.000000000 +0000 +@@ -34,10 +34,55 @@ + + #include + ++/* ++ * 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. ++ * ++ * To further complicate matters, due to the way the expansion bus controller ++ * handles 32 bit reads, the byte stream ABCD is stored on the flash as: ++ * D15 D0 ++ * +---+---+ ++ * | A | B | 0 ++ * +---+---+ ++ * | C | D | 2 ++ * +---+---+ ++ * This means that on LE systems each 16 bit word must be swapped. Note that ++ * this requires CONFIG_MTD_CFI_BE_BYTE_SWAP to be enabled to 'unswap' the CFI ++ * data and other flash commands which are always in D7-D0. ++ */ + #ifndef __ARMEB__ ++#ifndef CONFIG_MTD_CFI_BE_BYTE_SWAP ++# error CONFIG_MTD_CFI_BE_BYTE_SWAP required ++#endif ++ ++static inline u16 flash_read16(void __iomem *addr) ++{ ++ return be16_to_cpu(__raw_readw((void __iomem *)((unsigned long)addr ^ 0x2))); ++} ++ ++static inline void flash_write16(u16 d, void __iomem *addr) ++{ ++ __raw_writew(cpu_to_be16(d), (void __iomem *)((unsigned long)addr ^ 0x2)); ++} ++ + #define BYTE0(h) ((h) & 0xFF) + #define BYTE1(h) (((h) >> 8) & 0xFF) ++ + #else ++ ++static inline u16 flash_read16(const void __iomem *addr) ++{ ++ return __raw_readw(addr); ++} ++ ++static inline void flash_write16(u16 d, void __iomem *addr) ++{ ++ __raw_writew(d, addr); ++} ++ + #define BYTE0(h) (((h) >> 8) & 0xFF) + #define BYTE1(h) ((h) & 0xFF) + #endif +@@ -45,7 +90,7 @@ + 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; + } + +@@ -57,19 +102,28 @@ + static void ixp4xx_copy_from(struct map_info *map, void *to, + unsigned long from, ssize_t len) + { +- int i; + u8 *dest = (u8 *) to; + void __iomem *src = map->virt + from; +- u16 data; + +- for (i = 0; i < (len / 2); i++) { +- data = le16_to_cpu(readw(src + 2*i)); +- dest[i * 2] = BYTE0(data); +- dest[i * 2 + 1] = BYTE1(data); ++ if (len <= 0) ++ return; ++ ++ if (from & 1) { ++ *dest++ = BYTE1(flash_read16(src)); ++ src++; ++ --len; + } + +- if (len & 1) +- dest[len - 1] = BYTE0(le16_to_cpu(readw(src + 2*i))); ++ while (len >= 2) { ++ u16 data = flash_read16(src); ++ *dest++ = BYTE0(data); ++ *dest++ = BYTE1(data); ++ src += 2; ++ len -= 2; ++ } ++ ++ if (len > 0) ++ *dest++ = BYTE0(flash_read16(src)); + } + + /* +@@ -79,7 +133,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); + } + + /* +@@ -87,7 +141,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 { -- cgit v1.2.3