aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris BREZILLON <boris.brezillon@free-electrons.com>2015-09-14 04:41:03 -0400
committerBrian Norris <computersforpeace@gmail.com>2015-09-21 16:36:42 -0400
commit03a0e8a7c5ea29b5c4e72dfd64900b47a8fb6f2d (patch)
treee48836e5e4d1fb71522b52aa2d9f4df3d101334d
parent6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f (diff)
mtd: nand: sunxi: fix OOB handling in ->write_xxx() functions
The USER_DATA register cannot be accessed using byte accessors on A13 SoCs, thus triggering a bug when using memcpy_toio on this register. Declare an helper macros to convert an OOB buffer into a suitable USER_DATA value and vice-versa. This patch also fixes an error in the oob_required logic (some OOB data are not written even if the user required it) by removing the oob_required condition, which is perfectly valid since the core already fill ->oob_poi with FFs when oob_required is false. Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Cc: <stable@vger.kernel.org> # 3.19+ Fixes: 1fef62c1423b ("mtd: nand: add sunxi NAND flash controller support") Signed-off-by: Brian Norris <computersforpeace@gmail.com>
-rw-r--r--drivers/mtd/nand/sunxi_nand.c26
1 files changed, 9 insertions, 17 deletions
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index f97a58d6aae1..279cafd9d7f7 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -147,6 +147,10 @@
147#define NFC_ECC_MODE GENMASK(15, 12) 147#define NFC_ECC_MODE GENMASK(15, 12)
148#define NFC_RANDOM_SEED GENMASK(30, 16) 148#define NFC_RANDOM_SEED GENMASK(30, 16)
149 149
150/* NFC_USER_DATA helper macros */
151#define NFC_BUF_TO_USER_DATA(buf) ((buf)[0] | ((buf)[1] << 8) | \
152 ((buf)[2] << 16) | ((buf)[3] << 24))
153
150#define NFC_DEFAULT_TIMEOUT_MS 1000 154#define NFC_DEFAULT_TIMEOUT_MS 1000
151 155
152#define NFC_SRAM_SIZE 1024 156#define NFC_SRAM_SIZE 1024
@@ -646,15 +650,9 @@ static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
646 offset = layout->eccpos[i * ecc->bytes] - 4 + mtd->writesize; 650 offset = layout->eccpos[i * ecc->bytes] - 4 + mtd->writesize;
647 651
648 /* Fill OOB data in */ 652 /* Fill OOB data in */
649 if (oob_required) { 653 writel(NFC_BUF_TO_USER_DATA(chip->oob_poi +
650 tmp = 0xffffffff; 654 layout->oobfree[i].offset),
651 memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, &tmp, 655 nfc->regs + NFC_REG_USER_DATA_BASE);
652 4);
653 } else {
654 memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE,
655 chip->oob_poi + offset - mtd->writesize,
656 4);
657 }
658 656
659 chip->cmdfunc(mtd, NAND_CMD_RNDIN, offset, -1); 657 chip->cmdfunc(mtd, NAND_CMD_RNDIN, offset, -1);
660 658
@@ -784,14 +782,8 @@ static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
784 offset += ecc->size; 782 offset += ecc->size;
785 783
786 /* Fill OOB data in */ 784 /* Fill OOB data in */
787 if (oob_required) { 785 writel(NFC_BUF_TO_USER_DATA(oob),
788 tmp = 0xffffffff; 786 nfc->regs + NFC_REG_USER_DATA_BASE);
789 memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, &tmp,
790 4);
791 } else {
792 memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, oob,
793 4);
794 }
795 787
796 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ACCESS_DIR | 788 tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ACCESS_DIR |
797 (1 << 30); 789 (1 << 30);