Merge tag 'nand/for-4.15' of git://git.infradead.org/l2-mtd
[linux-2.6-block.git] / drivers / mtd / nand / nand_base.c
index 12edaae17d81f2228eefcc50b9d5de7433119987..6135d007a0686193d557ce831553ed53c9dd58c6 100644 (file)
@@ -115,7 +115,7 @@ static int nand_ooblayout_ecc_lp(struct mtd_info *mtd, int section,
        struct nand_chip *chip = mtd_to_nand(mtd);
        struct nand_ecc_ctrl *ecc = &chip->ecc;
 
-       if (section)
+       if (section || !ecc->total)
                return -ERANGE;
 
        oobregion->length = ecc->total;
@@ -727,8 +727,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
                chip->cmd_ctrl(mtd, page_addr, ctrl);
                ctrl &= ~NAND_CTRL_CHANGE;
                chip->cmd_ctrl(mtd, page_addr >> 8, ctrl);
-               /* One more address cycle for devices > 32MiB */
-               if (chip->chipsize > (32 << 20))
+               if (chip->options & NAND_ROW_ADDR_3)
                        chip->cmd_ctrl(mtd, page_addr >> 16, ctrl);
        }
        chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
@@ -854,8 +853,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
                        chip->cmd_ctrl(mtd, page_addr, ctrl);
                        chip->cmd_ctrl(mtd, page_addr >> 8,
                                       NAND_NCE | NAND_ALE);
-                       /* One more address cycle for devices > 128MiB */
-                       if (chip->chipsize > (128 << 20))
+                       if (chip->options & NAND_ROW_ADDR_3)
                                chip->cmd_ctrl(mtd, page_addr >> 16,
                                               NAND_NCE | NAND_ALE);
                }
@@ -1246,6 +1244,7 @@ int nand_reset(struct nand_chip *chip, int chipnr)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(nand_reset);
 
 /**
  * nand_check_erased_buf - check if a buffer contains (almost) only 0xff data
@@ -2799,15 +2798,18 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
                            size_t *retlen, const uint8_t *buf)
 {
        struct nand_chip *chip = mtd_to_nand(mtd);
+       int chipnr = (int)(to >> chip->chip_shift);
        struct mtd_oob_ops ops;
        int ret;
 
-       /* Wait for the device to get ready */
-       panic_nand_wait(mtd, chip, 400);
-
        /* Grab the device */
        panic_nand_get_device(chip, mtd, FL_WRITING);
 
+       chip->select_chip(mtd, chipnr);
+
+       /* Wait for the device to get ready */
+       panic_nand_wait(mtd, chip, 400);
+
        memset(&ops, 0, sizeof(ops));
        ops.len = len;
        ops.datbuf = (uint8_t *)buf;
@@ -3999,6 +4001,9 @@ ident_done:
                chip->chip_shift += 32 - 1;
        }
 
+       if (chip->chip_shift - chip->page_shift > 16)
+               chip->options |= NAND_ROW_ADDR_3;
+
        chip->badblockbits = 8;
        chip->erase = single_erase;
 
@@ -4700,6 +4705,19 @@ int nand_scan_tail(struct mtd_info *mtd)
                        mtd_set_ooblayout(mtd, &nand_ooblayout_lp_hamming_ops);
                        break;
                default:
+                       /*
+                        * Expose the whole OOB area to users if ECC_NONE
+                        * is passed. We could do that for all kind of
+                        * ->oobsize, but we must keep the old large/small
+                        * page with ECC layout when ->oobsize <= 128 for
+                        * compatibility reasons.
+                        */
+                       if (ecc->mode == NAND_ECC_NONE) {
+                               mtd_set_ooblayout(mtd,
+                                               &nand_ooblayout_lp_ops);
+                               break;
+                       }
+
                        WARN(1, "No oob scheme defined for oobsize %d\n",
                                mtd->oobsize);
                        ret = -EINVAL;