From: Jiang Lu <lu.ji...@windriver.com>

On ACP34xx, remounting a jffs2 partition will fail after writing file
with following error:
mount:/dev/mtdblock6 can't read superblock

This is caused by involving EP501G1_NAND_BCH_STATUS to check HW ECC
result. This patch reads EP501G1_NAND_1BIT_ECC0_STATUS to check HW
ECC result. When EP501G1_NAND_BCH_STATUS returns non-zero value,
EP501G1_NAND_1BIT_ECC0_STATUS reads zero, it indicate no HW ECC error.

Extract from vendor drop patch lsi-patch 3.8.1.12.

Signed-off-by: Jiang Lu <lu.ji...@windriver.com>
---
 drivers/mtd/nand/lsi_acp_nand.c | 104 +++++++---------------------------------
 1 file changed, 16 insertions(+), 88 deletions(-)

diff --git a/drivers/mtd/nand/lsi_acp_nand.c b/drivers/mtd/nand/lsi_acp_nand.c
index 94b8e3c..eb9943a 100644
--- a/drivers/mtd/nand/lsi_acp_nand.c
+++ b/drivers/mtd/nand/lsi_acp_nand.c
@@ -2820,100 +2820,28 @@ static int
 report_ecc_errors_ep501g1(struct mtd_info *mtd, struct nand_chip *chip,
                          uint8_t *buffer, int page)
 {
-       unsigned long bch_status;
-       int rc = 0;
+       unsigned long ecc_status;
        int i;
-       int is_blank = 1;
-       uint8_t *data = buffer;
-       int section;
-       int syndrome;
-       unsigned long syndromes[8][8];
-
-       /* If there are no errors, return. */
-       bch_status = READL(chip->IO_ADDR_R + EP501G1_NAND_BCH_STATUS);
 
-       if (0 == bch_status)
-               goto report_ecc_errors_ep501g1_end;
+       for (i = 0; i < (mtd->writesize / 1024); ++i) {
+               ecc_status = readl(chip->IO_ADDR_R +
+                                  EP501G1_NAND_1BIT_ECC0_STATUS + (i * 4));
 
-       switch (mtd->writesize) {
-       case 512:
-               bch_status &= 0x1;
-               break;
-       case 2048:
-               bch_status &= 0xf;
-               break;
-       case 4096:
-               bch_status &= 0xff;
-               break;
-       default:
-               printk(KERN_ERR "Unexpected Page Size!\n");
-               rc = -1;
-               goto report_ecc_errors_ep501g1_end;
-               break;
-       }
-
-       /* Ignore fully erased blocks. */
-       if (NULL != data) {
-               for (i = 0; i < mtd->writesize; ++i) {
-                       if (0xff != *data++) {
-                               is_blank = 0;
-                               break;
-                       }
-               }
-       }
-
-       if (0 != is_blank)
-               goto report_ecc_errors_ep501g1_end;
-
-       /* Read the syndrome registers and split them into syndromes. */
-       for (section = 0; section < 8; ++section) {
-               unsigned long address;
-               unsigned long value;
-
-               address = EP501G1_NAND_SYN_R12_S0 + (section * 0x10);
-
-               for (syndrome = 0; syndrome < 8; syndrome += 2) {
-                       value = READL(chip->IO_ADDR_R + address +
-                                     (syndrome * 2));
-                       syndromes[section][syndrome] =
-                               (value & 0x1fff);
-                       syndromes[section][syndrome + 1] =
-                               ((value & 0x1fff0000) >> 16);
-               }
-       }
-
-#ifdef NOT_USED
-       /* Debug output (BCH status register and syndromes). */
-       printk(KERN_INFO "BCH Status Register: 0x%02lx\n", bch_status);
-
-       for (section = 0; section < 8; ++section) {
-               printk(KERN_INFO "Syndromes, Section %d: ", section);
-
-               for (syndrome = 0; syndrome < 8; ++syndrome) {
-                       printk(KERN_INFO "0x%04lx ",
-                              syndromes[section][syndrome]);
-               }
-
-               printk(KERN_INFO "\n");
-       }
-#endif
-
-       for (i = 0; i < 4; ++i) {
-               if ((1 << i) == (bch_status & (1 << i))) {
-                       rc = fix_section(((page * mtd->writesize) + (512 * i)),
-                                        (void *)(buffer + (512 * i)),
-                                        (int *)&syndromes[i]);
-
-                       if (-1 == rc)
-                               printk(KERN_ERR
-                                      "Uncorrectable ECC Error: Page %d\n",
-                                      page);
+               switch (ecc_status & (3 << 12)) {
+               case 01:
+                       printk(KERN_ERR
+                              "Correctable ECC Error: %d:0x%lx\n",
+                              i, ecc_status);
+                       break;
+               case 02:
+                       printk(KERN_ERR
+                              "Uncorrectable ECC Error: %d:0x%lx\n",
+                              i, ecc_status);
+                       break;
                }
        }
 
- report_ecc_errors_ep501g1_end:
-
-       return rc;
+       return 0;
 }
 
 /*
-- 
1.8.3

_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to