nand, gpmc: fix reading after switching ecc
[platform/kernel/u-boot.git] / drivers / mtd / nand / omap_gpmc.c
index 2067969..389c4de 100644 (file)
@@ -763,7 +763,7 @@ static void __maybe_unused omap_free_bch(struct mtd_info *mtd)
 static int omap_select_ecc_scheme(struct nand_chip *nand,
        enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) {
        struct nand_bch_priv    *bch            = nand->priv;
-       struct nand_ecclayout   *ecclayout      = nand->ecc.layout;
+       struct nand_ecclayout   *ecclayout      = &omap_ecclayout;
        int eccsteps = pagesize / SECTOR_BYTES;
        int i;
 
@@ -776,7 +776,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
                bch_priv.type           = 0;
                nand->ecc.mode          = NAND_ECC_SOFT;
                nand->ecc.layout        = NULL;
-               nand->ecc.size          = pagesize;
+               nand->ecc.size          = 0;
                bch->ecc_scheme         = OMAP_ECC_HAM1_CODE_SW;
                break;
 
@@ -791,6 +791,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
                bch_priv.control        = NULL;
                bch_priv.type           = 0;
                /* populate ecc specific fields */
+               memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
                nand->ecc.mode          = NAND_ECC_HW;
                nand->ecc.strength      = 1;
                nand->ecc.size          = SECTOR_BYTES;
@@ -829,6 +830,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
                }
                bch_priv.type = ECC_BCH8;
                /* populate ecc specific fields */
+               memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
                nand->ecc.mode          = NAND_ECC_HW;
                nand->ecc.strength      = 8;
                nand->ecc.size          = SECTOR_BYTES;
@@ -871,6 +873,7 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
                elm_init();
                bch_priv.type           = ECC_BCH8;
                /* populate ecc specific fields */
+               memset(&nand->ecc, 0, sizeof(struct nand_ecc_ctrl));
                nand->ecc.mode          = NAND_ECC_HW;
                nand->ecc.strength      = 8;
                nand->ecc.size          = SECTOR_BYTES;
@@ -897,6 +900,11 @@ static int omap_select_ecc_scheme(struct nand_chip *nand,
                debug("nand: error: ecc scheme not enabled or supported\n");
                return -EINVAL;
        }
+
+       /* nand_scan_tail() sets ham1 sw ecc; hw ecc layout is set by driver */
+       if (ecc_scheme != OMAP_ECC_HAM1_CODE_SW)
+               nand->ecc.layout = ecclayout;
+
        return 0;
 }
 
@@ -925,6 +933,7 @@ int __maybe_unused omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
        mtd = &nand_info[nand_curr_device];
        nand = mtd->priv;
        nand->options |= NAND_OWN_BUFFERS;
+       nand->options &= ~NAND_SUBPAGE_READ;
        /* Setup the ecc configurations again */
        if (hardware) {
                if (eccstrength == 1) {