[PATCH 16/17] mtd: rawnand: cafe: Handle non-32bit aligned reads/writes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The spec says the write/read buffers should be filled/read 32bits at a
time. While most of the time the reads/writes are aligned on 4 bytes,
we should make the implementation more robust to non-usual NAND
operations.

Signed-off-by: Boris Brezillon <boris.brezillon@xxxxxxxxxxxxx>
---
 drivers/mtd/nand/raw/cafe_nand.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c
index 26495085f285..955dc78c57be 100644
--- a/drivers/mtd/nand/raw/cafe_nand.c
+++ b/drivers/mtd/nand/raw/cafe_nand.c
@@ -184,10 +184,18 @@ static void cafe_write_buf(struct nand_chip *chip, const void *buf,
 {
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 
-	if (cafe->usedma)
+	if (cafe->usedma) {
 		memcpy(cafe->dmabuf, buf, len);
-	else
-		memcpy_toio(cafe->mmio + CAFE_NAND_WRITE_DATA, buf, len);
+	} else {
+		memcpy_toio(cafe->mmio + CAFE_NAND_WRITE_DATA, buf,
+			    len & ~0x3);
+		if (len & 0x3) {
+			u32 tmp = 0;
+
+			memcpy(&tmp, buf + (len & ~0x3), len & 0x3);
+			cafe_writel(cafe, tmp, NAND_WRITE_DATA);
+		}
+	}
 
 	dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes to write buffer.\n",	len);
 }
@@ -196,10 +204,17 @@ static void cafe_read_buf(struct nand_chip *chip, void *buf, unsigned int len)
 {
 	struct cafe_priv *cafe = nand_get_controller_data(chip);
 
-	if (cafe->usedma)
+	if (cafe->usedma) {
 		memcpy(buf, cafe->dmabuf, len);
-	else
-		memcpy_fromio(buf, cafe->mmio + CAFE_NAND_READ_DATA, len);
+	} else {
+		memcpy_fromio(buf, cafe->mmio + CAFE_NAND_READ_DATA,
+			      len & ~0x3);
+		if (len & 0x3) {
+			u32 tmp = cafe_readl(cafe, NAND_READ_DATA);
+
+			memcpy(buf + (len & ~0x3), &tmp, len & 0x3);
+		}
+	}
 
 	dev_dbg(&cafe->pdev->dev, "Copy 0x%x bytes from read buffer.\n", len);
 }
-- 
2.25.3


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/



[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux