--- /dev/null
+diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
+index 97a48c3..aaba655 100644
+--- a/drivers/mtd/nand/nand_base.c
++++ b/drivers/mtd/nand/nand_base.c
+@@ -2934,246 +2934,6 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
+ }
+
+ /*
+- * nand_id_has_period - Check if an ID string has a given wraparound period
+- * @id_data: the ID string
+- * @arrlen: the length of the @id_data array
+- * @period: the period of repitition
+- *
+- * Check if an ID string is repeated within a given sequence of bytes at
+- * specific repetition interval period (e.g., {0x20,0x01,0x7F,0x20} has a
+- * period of 2). This is a helper function for nand_id_len(). Returns non-zero
+- * if the repetition has a period of @period; otherwise, returns zero.
+- */
+-static int nand_id_has_period(u8 *id_data, int arrlen, int period)
+-{
+- int i, j;
+- for (i = 0; i < period; i++)
+- for (j = i + period; j < arrlen; j += period)
+- if (id_data[i] != id_data[j])
+- return 0;
+- return 1;
+-}
+-
+-/*
+- * nand_id_len - Get the length of an ID string returned by CMD_READID
+- * @id_data: the ID string
+- * @arrlen: the length of the @id_data array
+-
+- * Returns the length of the ID string, according to known wraparound/trailing
+- * zero patterns. If no pattern exists, returns the length of the array.
+- */
+-static int nand_id_len(u8 *id_data, int arrlen)
+-{
+- int last_nonzero, period;
+-
+- /* Find last non-zero byte */
+- for (last_nonzero = arrlen - 1; last_nonzero >= 0; last_nonzero--)
+- if (id_data[last_nonzero])
+- break;
+-
+- /* All zeros */
+- if (last_nonzero < 0)
+- return 0;
+-
+- /* Calculate wraparound period */
+- for (period = 1; period < arrlen; period++)
+- if (nand_id_has_period(id_data, arrlen, period))
+- break;
+-
+- /* There's a repeated pattern */
+- if (period < arrlen)
+- return period;
+-
+- /* There are trailing zeros */
+- if (last_nonzero < arrlen - 1)
+- return last_nonzero + 1;
+-
+- /* No pattern detected */
+- return arrlen;
+-}
+-
+-/*
+- * Many new NAND share similar device ID codes, which represent the size of the
+- * chip. The rest of the parameters must be decoded according to generic or
+- * manufacturer-specific "extended ID" decoding patterns.
+- */
+-static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
+- u8 id_data[8], int *busw)
+-{
+- int extid, id_len;
+- /* The 3rd id byte holds MLC / multichip data */
+- chip->cellinfo = id_data[2];
+- /* The 4th id byte is the important one */
+- extid = id_data[3];
+-
+- id_len = nand_id_len(id_data, 8);
+-
+- /*
+- * Field definitions are in the following datasheets:
+- * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
+- * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44)
+- * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22)
+- *
+- * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung
+- * ID to decide what to do.
+- */
+- if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
+- id_data[5] != 0x00) {
+- /* Calc pagesize */
+- mtd->writesize = 2048 << (extid & 0x03);
+- extid >>= 2;
+- /* Calc oobsize */
+- switch (((extid >> 2) & 0x04) | (extid & 0x03)) {
+- case 1:
+- mtd->oobsize = 128;
+- break;
+- case 2:
+- mtd->oobsize = 218;
+- break;
+- case 3:
+- mtd->oobsize = 400;
+- break;
+- case 4:
+- mtd->oobsize = 436;
+- break;
+- case 5:
+- mtd->oobsize = 512;
+- break;
+- case 6:
+- default: /* Other cases are "reserved" (unknown) */
+- mtd->oobsize = 640;
+- break;
+- }
+- extid >>= 2;
+- /* Calc blocksize */
+- mtd->erasesize = (128 * 1024) <<
+- (((extid >> 1) & 0x04) | (extid & 0x03));
+- *busw = 0;
+- } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX &&
+- (chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
+- unsigned int tmp;
+-
+- /* Calc pagesize */
+- mtd->writesize = 2048 << (extid & 0x03);
+- extid >>= 2;
+- /* Calc oobsize */
+- switch (((extid >> 2) & 0x04) | (extid & 0x03)) {
+- case 0:
+- mtd->oobsize = 128;
+- break;
+- case 1:
+- mtd->oobsize = 224;
+- break;
+- case 2:
+- mtd->oobsize = 448;
+- break;
+- case 3:
+- mtd->oobsize = 64;
+- break;
+- case 4:
+- mtd->oobsize = 32;
+- break;
+- case 5:
+- mtd->oobsize = 16;
+- break;
+- default:
+- mtd->oobsize = 640;
+- break;
+- }
+- extid >>= 2;
+- /* Calc blocksize */
+- tmp = ((extid >> 1) & 0x04) | (extid & 0x03);
+- if (tmp < 0x03)
+- mtd->erasesize = (128 * 1024) << tmp;
+- else if (tmp == 0x03)
+- mtd->erasesize = 768 * 1024;
+- else
+- mtd->erasesize = (64 * 1024) << tmp;
+- *busw = 0;
+- } else {
+- /* Calc pagesize */
+- mtd->writesize = 1024 << (extid & 0x03);
+- extid >>= 2;
+- /* Calc oobsize */
+- mtd->oobsize = (8 << (extid & 0x01)) *
+- (mtd->writesize >> 9);
+- extid >>= 2;
+- /* Calc blocksize. Blocksize is multiples of 64KiB */
+- mtd->erasesize = (64 * 1024) << (extid & 0x03);
+- extid >>= 2;
+- /* Get buswidth information */
+- *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+- }
+-}
+-
+-/*
+- * Old devices have chip data hardcoded in the device ID table. nand_decode_id
+- * decodes a matching ID table entry and assigns the MTD size parameters for
+- * the chip.
+- */
+-static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip,
+- struct nand_flash_dev *type, u8 id_data[8],
+- int *busw)
+-{
+- int maf_id = id_data[0];
+-
+- mtd->erasesize = type->erasesize;
+- mtd->writesize = type->pagesize;
+- mtd->oobsize = mtd->writesize / 32;
+- *busw = type->options & NAND_BUSWIDTH_16;
+-
+- /*
+- * Check for Spansion/AMD ID + repeating 5th, 6th byte since
+- * some Spansion chips have erasesize that conflicts with size
+- * listed in nand_ids table.
+- * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
+- */
+- if (maf_id == NAND_MFR_AMD && id_data[4] != 0x00 && id_data[5] == 0x00
+- && id_data[6] == 0x00 && id_data[7] == 0x00
+- && mtd->writesize == 512) {
+- mtd->erasesize = 128 * 1024;
+- mtd->erasesize <<= ((id_data[3] & 0x03) << 1);
+- }
+-}
+-
+-/*
+- * Set the bad block marker/indicator (BBM/BBI) patterns according to some
+- * heuristic patterns using various detected parameters (e.g., manufacturer,
+- * page size, cell-type information).
+- */
+-static void nand_decode_bbm_options(struct mtd_info *mtd,
+- struct nand_chip *chip, u8 id_data[8])
+-{
+- int maf_id = id_data[0];
+-
+- /* Set the bad block position */
+- if (mtd->writesize > 512 || (chip->options & NAND_BUSWIDTH_16))
+- chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
+- else
+- chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
+-
+- /*
+- * Bad block marker is stored in the last page of each block on Samsung
+- * and Hynix MLC devices; stored in first two pages of each block on
+- * Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba,
+- * AMD/Spansion, and Macronix. All others scan only the first page.
+- */
+- if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+- (maf_id == NAND_MFR_SAMSUNG ||
+- maf_id == NAND_MFR_HYNIX))
+- chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
+- else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+- (maf_id == NAND_MFR_SAMSUNG ||
+- maf_id == NAND_MFR_HYNIX ||
+- maf_id == NAND_MFR_TOSHIBA ||
+- maf_id == NAND_MFR_AMD ||
+- maf_id == NAND_MFR_MACRONIX)) ||
+- (mtd->writesize == 2048 &&
+- maf_id == NAND_MFR_MICRON))
+- chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
+-}
+-
+-/*
+ * Get the flash and manufacturer id and lookup if the type is supported.
+ */
+ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
+@@ -3184,6 +2944,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
+ {
+ int i, maf_idx;
+ u8 id_data[8];
++ int ret;
+
+ /* Select the device */
+ chip->select_chip(mtd, 0);
+@@ -3210,8 +2971,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
+
+ chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
+
+- /* Read entire ID string */
+- for (i = 0; i < 8; i++)
++ for (i = 0; i < 2; i++)
+ id_data[i] = chip->read_byte(mtd);
+
+ if (id_data[0] != *maf_id || id_data[1] != *dev_id) {
+@@ -3231,10 +2991,18 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
+ chip->onfi_version = 0;
+ if (!type->name || !type->pagesize) {
+ /* Check is chip is ONFI compliant */
+- if (nand_flash_detect_onfi(mtd, chip, &busw))
++ ret = nand_flash_detect_onfi(mtd, chip, &busw);
++ if (ret)
+ goto ident_done;
+ }
+
++ chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
++
++ /* Read entire ID string */
++
++ for (i = 0; i < 8; i++)
++ id_data[i] = chip->read_byte(mtd);
++
+ if (!type->name)
+ return ERR_PTR(-ENODEV);
+
+@@ -3247,10 +3015,82 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
+ /* Set the pagesize, oobsize, erasesize by the driver */
+ busw = chip->init_size(mtd, chip, id_data);
+ } else if (!type->pagesize) {
+- /* Decode parameters from extended ID */
+- nand_decode_ext_id(mtd, chip, id_data, &busw);
++ int extid;
++ /* The 3rd id byte holds MLC / multichip data */
++ chip->cellinfo = id_data[2];
++ /* The 4th id byte is the important one */
++ extid = id_data[3];
++
++ /*
++ * Field definitions are in the following datasheets:
++ * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
++ * New style (6 byte ID): Samsung K9GBG08U0M (p.40)
++ *
++ * Check for wraparound + Samsung ID + nonzero 6th byte
++ * to decide what to do.
++ */
++ if (id_data[0] == id_data[6] && id_data[1] == id_data[7] &&
++ id_data[0] == NAND_MFR_SAMSUNG &&
++ (chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
++ id_data[5] != 0x00) {
++ /* Calc pagesize */
++ mtd->writesize = 2048 << (extid & 0x03);
++ extid >>= 2;
++ /* Calc oobsize */
++ switch (extid & 0x03) {
++ case 1:
++ mtd->oobsize = 128;
++ break;
++ case 2:
++ mtd->oobsize = 218;
++ break;
++ case 3:
++ mtd->oobsize = 400;
++ break;
++ default:
++ mtd->oobsize = 436;
++ break;
++ }
++ extid >>= 2;
++ /* Calc blocksize */
++ mtd->erasesize = (128 * 1024) <<
++ (((extid >> 1) & 0x04) | (extid & 0x03));
++ busw = 0;
++ } else {
++ /* Calc pagesize */
++ mtd->writesize = 1024 << (extid & 0x03);
++ extid >>= 2;
++ /* Calc oobsize */
++ mtd->oobsize = (8 << (extid & 0x01)) *
++ (mtd->writesize >> 9);
++ extid >>= 2;
++ /* Calc blocksize. Blocksize is multiples of 64KiB */
++ mtd->erasesize = (64 * 1024) << (extid & 0x03);
++ extid >>= 2;
++ /* Get buswidth information */
++ busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
++ }
+ } else {
+- nand_decode_id(mtd, chip, type, id_data, &busw);
++ /*
++ * Old devices have chip data hardcoded in the device id table.
++ */
++ mtd->erasesize = type->erasesize;
++ mtd->writesize = type->pagesize;
++ mtd->oobsize = mtd->writesize / 32;
++ busw = type->options & NAND_BUSWIDTH_16;
++
++ /*
++ * Check for Spansion/AMD ID + repeating 5th, 6th byte since
++ * some Spansion chips have erasesize that conflicts with size
++ * listed in nand_ids table.
++ * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
++ */
++ if (*maf_id == NAND_MFR_AMD && id_data[4] != 0x00 &&
++ id_data[5] == 0x00 && id_data[6] == 0x00 &&
++ id_data[7] == 0x00 && mtd->writesize == 512) {
++ mtd->erasesize = 128 * 1024;
++ mtd->erasesize <<= ((id_data[3] & 0x03) << 1);
++ }
+ }
+ /* Get chip options, preserve non chip based options */
+ chip->options &= ~NAND_CHIPOPTIONS_MSK;
+@@ -3284,8 +3124,6 @@ ident_done:
+ return ERR_PTR(-EINVAL);
+ }
+
+- nand_decode_bbm_options(mtd, chip, id_data);
+-
+ /* Calculate the address shift from the page size */
+ chip->page_shift = ffs(mtd->writesize) - 1;
+ /* Convert chipsize to number of pages per chip -1 */
+@@ -3302,6 +3140,33 @@ ident_done:
+
+ chip->badblockbits = 8;
+
++ /* Set the bad block position */
++ if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16))
++ chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
++ else
++ chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
++
++ /*
++ * Bad block marker is stored in the last page of each block
++ * on Samsung and Hynix MLC devices; stored in first two pages
++ * of each block on Micron devices with 2KiB pages and on
++ * SLC Samsung, Hynix, Toshiba, AMD/Spansion, and Macronix.
++ * All others scan only the first page.
++ */
++ if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
++ (*maf_id == NAND_MFR_SAMSUNG ||
++ *maf_id == NAND_MFR_HYNIX))
++ chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
++ else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
++ (*maf_id == NAND_MFR_SAMSUNG ||
++ *maf_id == NAND_MFR_HYNIX ||
++ *maf_id == NAND_MFR_TOSHIBA ||
++ *maf_id == NAND_MFR_AMD ||
++ *maf_id == NAND_MFR_MACRONIX)) ||
++ (mtd->writesize == 2048 &&
++ *maf_id == NAND_MFR_MICRON))
++ chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
++
+ /* Check for AND chips with 4 page planes */
+ if (chip->options & NAND_4PAGE_ARRAY)
+ chip->erase_cmd = multi_erase_cmd;