mtd: nand: Sync with Linux v4.6
[oweals/u-boot.git] / drivers / mtd / nand / nand_base.c
index 9e8fc1ffe24f8fc0ec5e6e5e651e78f060d2b041..74c563c49556f4483b0bcdabf88cabe87006edc9 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  drivers/mtd/nand.c
- *
  *  Overview:
  *   This is the generic MTD driver for NAND flash devices. It should be
  *   capable of working with almost all NAND chips currently available.
@@ -45,8 +43,6 @@
 #include <asm/io.h>
 #include <asm/errno.h>
 
-static bool is_module_text_address(unsigned long addr) {return 0;}
-
 /* Define default oob placement schemes for large and small page devices */
 static struct nand_ecclayout nand_oob_8 = {
        .eccbytes = 3,
@@ -105,7 +101,7 @@ DEFINE_LED_TRIGGER(nand_led_trigger);
 static int check_offs_len(struct mtd_info *mtd,
                                        loff_t ofs, uint64_t len)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        int ret = 0;
 
        /* Start address must align on block boundary */
@@ -131,7 +127,7 @@ static int check_offs_len(struct mtd_info *mtd,
  */
 static void nand_release_device(struct mtd_info *mtd)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
 
        /* De-select the NAND device */
        chip->select_chip(mtd, -1);
@@ -145,7 +141,7 @@ static void nand_release_device(struct mtd_info *mtd)
  */
 uint8_t nand_read_byte(struct mtd_info *mtd)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        return readb(chip->IO_ADDR_R);
 }
 
@@ -158,7 +154,7 @@ uint8_t nand_read_byte(struct mtd_info *mtd)
  */
 static uint8_t nand_read_byte16(struct mtd_info *mtd)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R));
 }
 
@@ -170,7 +166,7 @@ static uint8_t nand_read_byte16(struct mtd_info *mtd)
  */
 static u16 nand_read_word(struct mtd_info *mtd)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        return readw(chip->IO_ADDR_R);
 }
 
@@ -183,7 +179,7 @@ static u16 nand_read_word(struct mtd_info *mtd)
  */
 static void nand_select_chip(struct mtd_info *mtd, int chipnr)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
 
        switch (chipnr) {
        case -1:
@@ -206,7 +202,7 @@ static void nand_select_chip(struct mtd_info *mtd, int chipnr)
  */
 static void nand_write_byte(struct mtd_info *mtd, uint8_t byte)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
 
        chip->write_buf(mtd, &byte, 1);
 }
@@ -220,7 +216,7 @@ static void nand_write_byte(struct mtd_info *mtd, uint8_t byte)
  */
 static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        uint16_t word = byte;
 
        /*
@@ -287,7 +283,7 @@ static void iowrite16_rep(void *addr, void *buf, int len)
  */
 void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
 
        iowrite8_rep(chip->IO_ADDR_W, buf, len);
 }
@@ -302,7 +298,7 @@ void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
  */
 void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
 
        ioread8_rep(chip->IO_ADDR_R, buf, len);
 }
@@ -317,7 +313,7 @@ void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
  */
 void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        u16 *p = (u16 *) buf;
 
        iowrite16_rep(chip->IO_ADDR_W, p, len >> 1);
@@ -333,7 +329,7 @@ void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
  */
 void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        u16 *p = (u16 *) buf;
 
        ioread16_rep(chip->IO_ADDR_R, p, len >> 1);
@@ -343,14 +339,13 @@ void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
  * nand_block_bad - [DEFAULT] Read bad block marker from the chip
  * @mtd: MTD device structure
  * @ofs: offset from device start
- * @getchip: 0, if the chip is already selected
  *
  * Check, if the block is bad.
  */
-static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
+static int nand_block_bad(struct mtd_info *mtd, loff_t ofs)
 {
-       int page, chipnr, res = 0, i = 0;
-       struct nand_chip *chip = mtd->priv;
+       int page, res = 0, i = 0;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        u16 bad;
 
        if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
@@ -358,15 +353,6 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
 
        page = (int)(ofs >> chip->page_shift) & chip->pagemask;
 
-       if (getchip) {
-               chipnr = (int)(ofs >> chip->chip_shift);
-
-               nand_get_device(mtd, FL_READING);
-
-               /* Select the NAND device */
-               chip->select_chip(mtd, chipnr);
-       }
-
        do {
                if (chip->options & NAND_BUSWIDTH_16) {
                        chip->cmdfunc(mtd, NAND_CMD_READOOB,
@@ -391,11 +377,6 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
                i++;
        } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE));
 
-       if (getchip) {
-               chip->select_chip(mtd, -1);
-               nand_release_device(mtd);
-       }
-
        return res;
 }
 
@@ -410,7 +391,7 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
  */
 static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        struct mtd_oob_ops ops;
        uint8_t buf[2] = { 0, 0 };
        int ret = 0, res, i = 0;
@@ -460,7 +441,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 */
 static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        int res, ret = 0;
 
        if (!(chip->bbt_options & NAND_BBT_NO_OOB_BBM)) {
@@ -501,7 +482,7 @@ static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs)
  */
 static int nand_check_wp(struct mtd_info *mtd)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
 
        /* Broken xD cards report WP despite being writable */
        if (chip->options & NAND_BROKEN_XD)
@@ -521,7 +502,7 @@ static int nand_check_wp(struct mtd_info *mtd)
  */
 static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
 
        if (!chip->bbt)
                return 0;
@@ -533,16 +514,14 @@ static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs)
  * nand_block_checkbad - [GENERIC] Check if a block is marked bad
  * @mtd: MTD device structure
  * @ofs: offset from device start
- * @getchip: 0, if the chip is already selected
  * @allowbbt: 1, if its allowed to access the bbt area
  *
  * Check, if the block is bad. Either by reading the bad block table or
  * calling of the scan function.
  */
-static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
-                              int allowbbt)
+static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int allowbbt)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
 
        if (!(chip->options & NAND_SKIP_BBTSCAN) &&
            !(chip->options & NAND_BBT_SCANNED)) {
@@ -551,17 +530,22 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip,
        }
 
        if (!chip->bbt)
-               return chip->block_bad(mtd, ofs, getchip);
+               return chip->block_bad(mtd, ofs);
 
        /* Return info from the table */
        return nand_isbad_bbt(mtd, ofs, allowbbt);
 }
 
-/* Wait for the ready pin, after a command. The timeout is caught later. */
+/**
+ * nand_wait_ready - [GENERIC] Wait for the ready pin after commands.
+ * @mtd: MTD device structure
+ *
+ * Wait for the ready pin after a command, and warn if a timeout occurs.
+ */
 void nand_wait_ready(struct mtd_info *mtd)
 {
-       struct nand_chip *chip = mtd->priv;
-       u32 timeo = (CONFIG_SYS_HZ * 20) / 1000;
+       struct nand_chip *chip = mtd_to_nand(mtd);
+       u32 timeo = (CONFIG_SYS_HZ * 400) / 1000;
        u32 time_start;
 
        time_start = get_timer(0);
@@ -571,6 +555,9 @@ void nand_wait_ready(struct mtd_info *mtd)
                        if (chip->dev_ready(mtd))
                                break;
        }
+
+       if (!chip->dev_ready(mtd))
+               pr_warn("timeout while waiting for chip to become ready\n");
 }
 EXPORT_SYMBOL_GPL(nand_wait_ready);
 
@@ -583,7 +570,7 @@ EXPORT_SYMBOL_GPL(nand_wait_ready);
  */
 static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo)
 {
-       register struct nand_chip *chip = mtd->priv;
+       register struct nand_chip *chip = mtd_to_nand(mtd);
        u32 time_start;
 
        timeo = (CONFIG_SYS_HZ * timeo) / 1000;
@@ -608,7 +595,7 @@ static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo)
 static void nand_command(struct mtd_info *mtd, unsigned int command,
                         int column, int page_addr)
 {
-       register struct nand_chip *chip = mtd->priv;
+       register struct nand_chip *chip = mtd_to_nand(mtd);
        int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE;
 
        /* Write out the command to the device */
@@ -711,7 +698,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
 static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
                            int column, int page_addr)
 {
-       register struct nand_chip *chip = mtd->priv;
+       register struct nand_chip *chip = mtd_to_nand(mtd);
 
        /* Emulate NAND_CMD_READOOB */
        if (command == NAND_CMD_READOOB) {
@@ -835,7 +822,7 @@ static void panic_nand_get_device(struct nand_chip *chip,
 static int
 nand_get_device(struct mtd_info *mtd, int new_state)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        chip->state = new_state;
        return 0;
 }
@@ -871,15 +858,13 @@ static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip,
  * @mtd: MTD device structure
  * @chip: NAND chip structure
  *
- * Wait for command done. This applies to erase and program only. Erase can
- * take up to 400ms and program up to 20ms according to general NAND and
- * SmartMedia specs.
+ * Wait for command done. This applies to erase and program only.
  */
 static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
 {
 
-       int status, state = chip->state;
-       unsigned long timeo = (state == FL_ERASING ? 400 : 20);
+       int status;
+       unsigned long timeo = 400;
 
        led_trigger_event(nand_led_trigger, LED_FULL);
 
@@ -912,6 +897,135 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
        return status;
 }
 
+#define BITS_PER_BYTE 8
+
+/**
+ * nand_check_erased_buf - check if a buffer contains (almost) only 0xff data
+ * @buf: buffer to test
+ * @len: buffer length
+ * @bitflips_threshold: maximum number of bitflips
+ *
+ * Check if a buffer contains only 0xff, which means the underlying region
+ * has been erased and is ready to be programmed.
+ * The bitflips_threshold specify the maximum number of bitflips before
+ * considering the region is not erased.
+ * Note: The logic of this function has been extracted from the memweight
+ * implementation, except that nand_check_erased_buf function exit before
+ * testing the whole buffer if the number of bitflips exceed the
+ * bitflips_threshold value.
+ *
+ * Returns a positive number of bitflips less than or equal to
+ * bitflips_threshold, or -ERROR_CODE for bitflips in excess of the
+ * threshold.
+ */
+static int nand_check_erased_buf(void *buf, int len, int bitflips_threshold)
+{
+       const unsigned char *bitmap = buf;
+       int bitflips = 0;
+       int weight;
+
+       for (; len && ((uintptr_t)bitmap) % sizeof(long);
+            len--, bitmap++) {
+               weight = hweight8(*bitmap);
+               bitflips += BITS_PER_BYTE - weight;
+               if (unlikely(bitflips > bitflips_threshold))
+                       return -EBADMSG;
+       }
+
+       for (; len >= 4; len -= 4, bitmap += 4) {
+               weight = hweight32(*((u32 *)bitmap));
+               bitflips += 32 - weight;
+               if (unlikely(bitflips > bitflips_threshold))
+                       return -EBADMSG;
+       }
+
+       for (; len > 0; len--, bitmap++) {
+               weight = hweight8(*bitmap);
+               bitflips += BITS_PER_BYTE - weight;
+               if (unlikely(bitflips > bitflips_threshold))
+                       return -EBADMSG;
+       }
+
+       return bitflips;
+}
+
+/**
+ * nand_check_erased_ecc_chunk - check if an ECC chunk contains (almost) only
+ *                              0xff data
+ * @data: data buffer to test
+ * @datalen: data length
+ * @ecc: ECC buffer
+ * @ecclen: ECC length
+ * @extraoob: extra OOB buffer
+ * @extraooblen: extra OOB length
+ * @bitflips_threshold: maximum number of bitflips
+ *
+ * Check if a data buffer and its associated ECC and OOB data contains only
+ * 0xff pattern, which means the underlying region has been erased and is
+ * ready to be programmed.
+ * The bitflips_threshold specify the maximum number of bitflips before
+ * considering the region as not erased.
+ *
+ * Note:
+ * 1/ ECC algorithms are working on pre-defined block sizes which are usually
+ *    different from the NAND page size. When fixing bitflips, ECC engines will
+ *    report the number of errors per chunk, and the NAND core infrastructure
+ *    expect you to return the maximum number of bitflips for the whole page.
+ *    This is why you should always use this function on a single chunk and
+ *    not on the whole page. After checking each chunk you should update your
+ *    max_bitflips value accordingly.
+ * 2/ When checking for bitflips in erased pages you should not only check
+ *    the payload data but also their associated ECC data, because a user might
+ *    have programmed almost all bits to 1 but a few. In this case, we
+ *    shouldn't consider the chunk as erased, and checking ECC bytes prevent
+ *    this case.
+ * 3/ The extraoob argument is optional, and should be used if some of your OOB
+ *    data are protected by the ECC engine.
+ *    It could also be used if you support subpages and want to attach some
+ *    extra OOB data to an ECC chunk.
+ *
+ * Returns a positive number of bitflips less than or equal to
+ * bitflips_threshold, or -ERROR_CODE for bitflips in excess of the
+ * threshold. In case of success, the passed buffers are filled with 0xff.
+ */
+int nand_check_erased_ecc_chunk(void *data, int datalen,
+                               void *ecc, int ecclen,
+                               void *extraoob, int extraooblen,
+                               int bitflips_threshold)
+{
+       int data_bitflips = 0, ecc_bitflips = 0, extraoob_bitflips = 0;
+
+       data_bitflips = nand_check_erased_buf(data, datalen,
+                                             bitflips_threshold);
+       if (data_bitflips < 0)
+               return data_bitflips;
+
+       bitflips_threshold -= data_bitflips;
+
+       ecc_bitflips = nand_check_erased_buf(ecc, ecclen, bitflips_threshold);
+       if (ecc_bitflips < 0)
+               return ecc_bitflips;
+
+       bitflips_threshold -= ecc_bitflips;
+
+       extraoob_bitflips = nand_check_erased_buf(extraoob, extraooblen,
+                                                 bitflips_threshold);
+       if (extraoob_bitflips < 0)
+               return extraoob_bitflips;
+
+       if (data_bitflips)
+               memset(data, 0xff, datalen);
+
+       if (ecc_bitflips)
+               memset(ecc, 0xff, ecclen);
+
+       if (extraoob_bitflips)
+               memset(extraoob, 0xff, extraooblen);
+
+       return data_bitflips + ecc_bitflips + extraoob_bitflips;
+}
+EXPORT_SYMBOL(nand_check_erased_ecc_chunk);
+
 /**
  * nand_read_page_raw - [INTERN] read raw page data without ecc
  * @mtd: mtd info structure
@@ -1103,6 +1217,16 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 
                stat = chip->ecc.correct(mtd, p,
                        &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
+               if (stat == -EBADMSG &&
+                   (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
+                       /* check for empty pages with bitflips */
+                       stat = nand_check_erased_ecc_chunk(p, chip->ecc.size,
+                                               &chip->buffers->ecccode[i],
+                                               chip->ecc.bytes,
+                                               NULL, 0,
+                                               chip->ecc.strength);
+               }
+
                if (stat < 0) {
                        mtd->ecc_stats.failed++;
                } else {
@@ -1152,6 +1276,15 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
                int stat;
 
                stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
+               if (stat == -EBADMSG &&
+                   (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
+                       /* check for empty pages with bitflips */
+                       stat = nand_check_erased_ecc_chunk(p, eccsize,
+                                               &ecc_code[i], eccbytes,
+                                               NULL, 0,
+                                               chip->ecc.strength);
+               }
+
                if (stat < 0) {
                        mtd->ecc_stats.failed++;
                } else {
@@ -1204,6 +1337,15 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd,
                chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
                stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL);
+               if (stat == -EBADMSG &&
+                   (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
+                       /* check for empty pages with bitflips */
+                       stat = nand_check_erased_ecc_chunk(p, eccsize,
+                                               &ecc_code[i], eccbytes,
+                                               NULL, 0,
+                                               chip->ecc.strength);
+               }
+
                if (stat < 0) {
                        mtd->ecc_stats.failed++;
                } else {
@@ -1231,6 +1373,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
        int eccsteps = chip->ecc.steps;
+       int eccpadbytes = eccbytes + chip->ecc.prepad + chip->ecc.postpad;
        uint8_t *p = buf;
        uint8_t *oob = chip->oob_poi;
        unsigned int max_bitflips = 0;
@@ -1250,19 +1393,29 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
                chip->read_buf(mtd, oob, eccbytes);
                stat = chip->ecc.correct(mtd, p, oob, NULL);
 
-               if (stat < 0) {
-                       mtd->ecc_stats.failed++;
-               } else {
-                       mtd->ecc_stats.corrected += stat;
-                       max_bitflips = max_t(unsigned int, max_bitflips, stat);
-               }
-
                oob += eccbytes;
 
                if (chip->ecc.postpad) {
                        chip->read_buf(mtd, oob, chip->ecc.postpad);
                        oob += chip->ecc.postpad;
                }
+
+               if (stat == -EBADMSG &&
+                   (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) {
+                       /* check for empty pages with bitflips */
+                       stat = nand_check_erased_ecc_chunk(p, chip->ecc.size,
+                                                          oob - eccpadbytes,
+                                                          eccpadbytes,
+                                                          NULL, 0,
+                                                          chip->ecc.strength);
+               }
+
+               if (stat < 0) {
+                       mtd->ecc_stats.failed++;
+               } else {
+                       mtd->ecc_stats.corrected += stat;
+                       max_bitflips = max_t(unsigned int, max_bitflips, stat);
+               }
        }
 
        /* Calculate remaining oob bytes */
@@ -1332,7 +1485,7 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
  */
 static int nand_setup_read_retry(struct mtd_info *mtd, int retry_mode)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
 
        pr_debug("setting READ RETRY mode %d\n", retry_mode);
 
@@ -1357,12 +1510,11 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                            struct mtd_oob_ops *ops)
 {
        int chipnr, page, realpage, col, bytes, aligned, oob_required;
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        int ret = 0;
        uint32_t readlen = ops->len;
        uint32_t oobreadlen = ops->ooblen;
-       uint32_t max_oobsize = ops->mode == MTD_OPS_AUTO_OOB ?
-               mtd->oobavail : mtd->oobsize;
+       uint32_t max_oobsize = mtd_oobavail(mtd, ops);
 
        uint8_t *bufpoi, *oob, *buf;
        int use_bufpoi;
@@ -1700,7 +1852,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
                            struct mtd_oob_ops *ops)
 {
        int page, realpage, chipnr;
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        struct mtd_ecc_stats stats;
        int readlen = ops->ooblen;
        int len;
@@ -1712,10 +1864,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
 
        stats = mtd->ecc_stats;
 
-       if (ops->mode == MTD_OPS_AUTO_OOB)
-               len = chip->ecc.layout->oobavail;
-       else
-               len = mtd->oobsize;
+       len = mtd_oobavail(mtd, ops);
 
        if (unlikely(ops->ooboffs >= len)) {
                pr_debug("%s: attempt to start read outside oob\n",
@@ -1840,11 +1989,12 @@ out:
  * @chip: nand chip info structure
  * @buf: data buffer
  * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to write
  *
  * Not for syndrome calculating ECC controllers, which use a special oob layout.
  */
 static int nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
-                               const uint8_t *buf, int oob_required)
+                              const uint8_t *buf, int oob_required, int page)
 {
        chip->write_buf(mtd, buf, mtd->writesize);
        if (oob_required)
@@ -1859,12 +2009,14 @@ static int nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
  * @chip: nand chip info structure
  * @buf: data buffer
  * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to write
  *
  * We need a special oob layout and handling even when ECC isn't checked.
  */
 static int nand_write_page_raw_syndrome(struct mtd_info *mtd,
                                        struct nand_chip *chip,
-                                       const uint8_t *buf, int oob_required)
+                                       const uint8_t *buf, int oob_required,
+                                       int page)
 {
        int eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -1901,9 +2053,11 @@ static int nand_write_page_raw_syndrome(struct mtd_info *mtd,
  * @chip: nand chip info structure
  * @buf: data buffer
  * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to write
  */
 static int nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
-                                 const uint8_t *buf, int oob_required)
+                                const uint8_t *buf, int oob_required,
+                                int page)
 {
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -1919,7 +2073,7 @@ static int nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
        for (i = 0; i < chip->ecc.total; i++)
                chip->oob_poi[eccpos[i]] = ecc_calc[i];
 
-       return chip->ecc.write_page_raw(mtd, chip, buf, 1);
+       return chip->ecc.write_page_raw(mtd, chip, buf, 1, page);
 }
 
 /**
@@ -1928,9 +2082,11 @@ static int nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
  * @chip: nand chip info structure
  * @buf: data buffer
  * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to write
  */
 static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
-                                 const uint8_t *buf, int oob_required)
+                                 const uint8_t *buf, int oob_required,
+                                 int page)
 {
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -1962,11 +2118,12 @@ static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
  * @data_len:  data length
  * @buf:       data buffer
  * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to write
  */
 static int nand_write_subpage_hwecc(struct mtd_info *mtd,
                                struct nand_chip *chip, uint32_t offset,
                                uint32_t data_len, const uint8_t *buf,
-                               int oob_required)
+                               int oob_required, int page)
 {
        uint8_t *oob_buf  = chip->oob_poi;
        uint8_t *ecc_calc = chip->buffers->ecccalc;
@@ -2021,13 +2178,15 @@ static int nand_write_subpage_hwecc(struct mtd_info *mtd,
  * @chip: nand chip info structure
  * @buf: data buffer
  * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to write
  *
  * The hw generator calculates the error syndrome automatically. Therefore we
  * need a special oob layout and handling.
  */
 static int nand_write_page_syndrome(struct mtd_info *mtd,
                                    struct nand_chip *chip,
-                                   const uint8_t *buf, int oob_required)
+                                   const uint8_t *buf, int oob_required,
+                                   int page)
 {
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -2091,12 +2250,13 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 
        if (unlikely(raw))
                status = chip->ecc.write_page_raw(mtd, chip, buf,
-                                                       oob_required);
+                                                 oob_required, page);
        else if (subpage)
                status = chip->ecc.write_subpage(mtd, chip, offset, data_len,
-                                                        buf, oob_required);
+                                                buf, oob_required, page);
        else
-               status = chip->ecc.write_page(mtd, chip, buf, oob_required);
+               status = chip->ecc.write_page(mtd, chip, buf, oob_required,
+                                             page);
 
        if (status < 0)
                return status;
@@ -2139,7 +2299,7 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,
                              struct mtd_oob_ops *ops)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
 
        /*
         * Initialise to all 0xFF, to avoid the possibility of left over OOB
@@ -2199,12 +2359,11 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
                             struct mtd_oob_ops *ops)
 {
        int chipnr, realpage, page, blockmask, column;
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        uint32_t writelen = ops->len;
 
        uint32_t oobwritelen = ops->ooblen;
-       uint32_t oobmaxlen = ops->mode == MTD_OPS_AUTO_OOB ?
-                               mtd->oobavail : mtd->oobsize;
+       uint32_t oobmaxlen = mtd_oobavail(mtd, ops);
 
        uint8_t *oob = ops->oobbuf;
        uint8_t *buf = ops->datbuf;
@@ -2328,7 +2487,7 @@ err_out:
 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->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        struct mtd_oob_ops ops;
        int ret;
 
@@ -2388,15 +2547,12 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
                             struct mtd_oob_ops *ops)
 {
        int chipnr, page, status, len;
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
 
        pr_debug("%s: to = 0x%08x, len = %i\n",
                         __func__, (unsigned int)to, (int)ops->ooblen);
 
-       if (ops->mode == MTD_OPS_AUTO_OOB)
-               len = chip->ecc.layout->oobavail;
-       else
-               len = mtd->oobsize;
+       len = mtd_oobavail(mtd, ops);
 
        /* Do not allow write past end of page */
        if ((ops->ooboffs + ops->ooblen) > len) {
@@ -2513,7 +2669,7 @@ out:
  */
 static int single_erase(struct mtd_info *mtd, int page)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        /* Send commands to erase a block */
        chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page);
        chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1);
@@ -2545,7 +2701,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
                    int allowbbt)
 {
        int page, status, pages_per_block, ret, chipnr;
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        loff_t len;
 
        pr_debug("%s: start = 0x%012llx, len = %llu\n",
@@ -2586,7 +2742,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
 
                /* Check if we have a bad block, we do not erase bad blocks! */
                if (!instr->scrub && nand_block_checkbad(mtd, ((loff_t) page) <<
-                                       chip->page_shift, 0, allowbbt)) {
+                                       chip->page_shift, allowbbt)) {
                        pr_warn("%s: attempt to erase a bad block at page 0x%08x\n",
                                    __func__, page);
                        instr->state = MTD_ERASE_FAILED;
@@ -2673,7 +2829,20 @@ static void nand_sync(struct mtd_info *mtd)
  */
 static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
 {
-       return nand_block_checkbad(mtd, offs, 1, 0);
+       struct nand_chip *chip = mtd_to_nand(mtd);
+       int chipnr = (int)(offs >> chip->chip_shift);
+       int ret;
+
+       /* Select the NAND device */
+       nand_get_device(mtd, FL_READING);
+       chip->select_chip(mtd, chipnr);
+
+       ret = nand_block_checkbad(mtd, offs, 0);
+
+       chip->select_chip(mtd, -1);
+       nand_release_device(mtd);
+
+       return ret;
 }
 
 /**
@@ -2745,9 +2914,6 @@ static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
                return -EINVAL;
 #endif
 
-       /* clear the sub feature parameters */
-       memset(subfeature_param, 0, ONFI_SUBFEATURE_PARAM_LEN);
-
        chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, addr, -1);
        for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
                *subfeature_param++ = chip->read_byte(mtd);
@@ -2908,7 +3074,7 @@ ext_out:
 
 static int nand_setup_read_retry_micron(struct mtd_info *mtd, int retry_mode)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {retry_mode};
 
        return chip->onfi_set_features(mtd, chip, ONFI_FEATURE_ADDR_READ_RETRY,
@@ -3480,7 +3646,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
                        if (find_full_id_nand(mtd, chip, type, id_data, &busw))
                                goto ident_done;
                } else if (*dev_id == type->dev_id) {
-                               break;
+                       break;
                }
        }
 
@@ -3503,10 +3669,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
 
        chip->chipsize = (uint64_t)type->chipsize << 20;
 
-       if (!type->pagesize && chip->init_size) {
-               /* Set the pagesize, oobsize, erasesize by the driver */
-               busw = chip->init_size(mtd, chip, id_data);
-       } else if (!type->pagesize) {
+       if (!type->pagesize) {
                /* Decode parameters from extended ID */
                nand_decode_ext_id(mtd, chip, id_data, &busw);
        } else {
@@ -3610,13 +3773,12 @@ ident_done:
  * This is the first phase of the normal nand_scan() function. It reads the
  * flash ID and sets up MTD fields accordingly.
  *
- * The mtd->owner field must be set to the module of the caller.
  */
 int nand_scan_ident(struct mtd_info *mtd, int maxchips,
                    struct nand_flash_dev *table)
 {
        int i, nand_maf_id, nand_dev_id;
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        struct nand_flash_dev *type;
 
        /* Set the default functions */
@@ -3680,7 +3842,7 @@ EXPORT_SYMBOL(nand_scan_ident);
  */
 static bool nand_ecc_strength_good(struct mtd_info *mtd)
 {
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        struct nand_ecc_ctrl *ecc = &chip->ecc;
        int corr, ds_corr;
 
@@ -3709,7 +3871,7 @@ static bool nand_ecc_strength_good(struct mtd_info *mtd)
 int nand_scan_tail(struct mtd_info *mtd)
 {
        int i;
-       struct nand_chip *chip = mtd->priv;
+       struct nand_chip *chip = mtd_to_nand(mtd);
        struct nand_ecc_ctrl *ecc = &chip->ecc;
        struct nand_buffers *nbuf;
 
@@ -3786,7 +3948,7 @@ int nand_scan_tail(struct mtd_info *mtd)
                        ecc->write_oob = nand_write_oob_std;
                if (!ecc->read_subpage)
                        ecc->read_subpage = nand_read_subpage;
-               if (!ecc->write_subpage)
+               if (!ecc->write_subpage && ecc->hwctl && ecc->calculate)
                        ecc->write_subpage = nand_write_subpage_hwecc;
 
        case NAND_ECC_HW_SYNDROME:
@@ -3864,10 +4026,8 @@ int nand_scan_tail(struct mtd_info *mtd)
                }
 
                /* See nand_bch_init() for details. */
-               ecc->bytes = DIV_ROUND_UP(
-                               ecc->strength * fls(8 * ecc->size), 8);
-               ecc->priv = nand_bch_init(mtd, ecc->size, ecc->bytes,
-                                              &ecc->layout);
+               ecc->bytes = 0;
+               ecc->priv = nand_bch_init(mtd);
                if (!ecc->priv) {
                        pr_warn("BCH ECC initialization failed!\n");
                        BUG();
@@ -3902,11 +4062,11 @@ int nand_scan_tail(struct mtd_info *mtd)
         * The number of bytes available for a client to place data into
         * the out of band area.
         */
-       ecc->layout->oobavail = 0;
-       for (i = 0; ecc->layout->oobfree[i].length
-                       && i < ARRAY_SIZE(ecc->layout->oobfree); i++)
-               ecc->layout->oobavail += ecc->layout->oobfree[i].length;
-       mtd->oobavail = ecc->layout->oobavail;
+       mtd->oobavail = 0;
+       if (ecc->layout) {
+               for (i = 0; ecc->layout->oobfree[i].length; i++)
+                       mtd->oobavail += ecc->layout->oobfree[i].length;
+       }
 
        /* ECC sanity check: warn if it's too weak */
        if (!nand_ecc_strength_good(mtd))
@@ -3991,18 +4151,6 @@ int nand_scan_tail(struct mtd_info *mtd)
 }
 EXPORT_SYMBOL(nand_scan_tail);
 
-/*
- * is_module_text_address() isn't exported, and it's mostly a pointless
- * test if this is a module _anyway_ -- they'd have to try _really_ hard
- * to call us from in-kernel code if the core NAND support is modular.
- */
-#ifdef MODULE
-#define caller_is_module() (1)
-#else
-#define caller_is_module() \
-       is_module_text_address((unsigned long)__builtin_return_address(0))
-#endif
-
 /**
  * nand_scan - [NAND Interface] Scan for the NAND device
  * @mtd: MTD device structure
@@ -4010,19 +4158,12 @@ EXPORT_SYMBOL(nand_scan_tail);
  *
  * This fills out all the uninitialized function pointers with the defaults.
  * The flash ID is read and the mtd/chip structures are filled with the
- * appropriate values. The mtd->owner field must be set to the module of the
- * caller.
+ * appropriate values.
  */
 int nand_scan(struct mtd_info *mtd, int maxchips)
 {
        int ret;
 
-       /* Many callers got this wrong, so check for it for a while... */
-       if (!mtd->owner && caller_is_module()) {
-               pr_crit("%s called with NULL mtd->owner!\n", __func__);
-               BUG();
-       }
-
        ret = nand_scan_ident(mtd, maxchips, NULL);
        if (!ret)
                ret = nand_scan_tail(mtd);
@@ -4030,9 +4171,6 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
 }
 EXPORT_SYMBOL(nand_scan);
 
-module_init(nand_base_init);
-module_exit(nand_base_exit);
-
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>");
 MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");