All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Vrabel <dvrabel@arcom.com>
To: jbowler@acm.org
Cc: 'Alessandro Zummo' <azummo-lists@towertech.it>,
	linux-mtd@lists.infradead.org
Subject: Re: [PATCH] [MTD] MAPS/ixp4xx.c: fix BE system break in 2.6.15-rc1, enable LE operation in 2.6.15
Date: Wed, 16 Nov 2005 16:35:36 +0000	[thread overview]
Message-ID: <437B5FD8.9060900@arcom.com> (raw)
In-Reply-To: <007301c5e961$3083a300$1001a8c0@kalmiopsis>

[-- Attachment #1: Type: text/plain, Size: 239 bytes --]

Commited with some cleanups.

FYI, I've attached what was committed.

David Vrabel
-- 
David Vrabel, Design Engineer

Arcom, Clifton Road           Tel: +44 (0)1223 411200 ext. 3233
Cambridge CB1 7EA, UK         Web: http://www.arcom.com/

[-- Attachment #2: mtd-ixp4xx-updates --]
[-- Type: text/plain, Size: 3572 bytes --]

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 <jbowler@acm.org>
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: David Vrabel <dvrabel@arcom.com>

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 <linux/reboot.h>
 
+/*
+ * 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 {

  reply	other threads:[~2005-11-16 16:35 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <436F94D0.5070509@arcom.com>
2005-11-14  6:50 ` ixp4xx stuff John Bowler
2005-11-14 10:14   ` David Vrabel
2005-11-14 16:37     ` John Bowler
2005-11-14 17:49       ` David Vrabel
2005-11-14 18:32         ` John Bowler
2005-11-14 21:20         ` [PATCH] [MTD] MAPS/ixp4xx.c: fix BE system break in 2.6.15-rc1, enable LE operation in 2.6.15 John Bowler
2005-11-16 16:35           ` David Vrabel [this message]
2005-11-19 18:17             ` John Bowler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=437B5FD8.9060900@arcom.com \
    --to=dvrabel@arcom.com \
    --cc=azummo-lists@towertech.it \
    --cc=jbowler@acm.org \
    --cc=linux-mtd@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.