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/