mtd: rawnand: Always store info about bad block markers in chip struct
authorFrieder Schrempf <frieder.schrempf@kontron.de>
Wed, 17 Apr 2019 12:36:34 +0000 (12:36 +0000)
committerMiquel Raynal <miquel.raynal@bootlin.com>
Thu, 18 Apr 2019 06:54:07 +0000 (08:54 +0200)
The information about where the manufacturer puts the bad block
markers inside the bad block and in the OOB data is stored in
different places. Let's move this information to nand_chip.options
and nand_chip.badblockpos.

As this chip-specific information is not directly related to the
bad block table (BBT), we also rename the flags to NAND_BBM_*.

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
drivers/mtd/nand/raw/nand_amd.c
drivers/mtd/nand/raw/nand_base.c
drivers/mtd/nand/raw/nand_bbt.c
drivers/mtd/nand/raw/nand_esmt.c
drivers/mtd/nand/raw/nand_hynix.c
drivers/mtd/nand/raw/nand_macronix.c
drivers/mtd/nand/raw/nand_micron.c
drivers/mtd/nand/raw/nand_samsung.c
drivers/mtd/nand/raw/nand_toshiba.c
drivers/mtd/nand/raw/sh_flctl.c
include/linux/mtd/rawnand.h

index e008fd662ee69cb9c375e85520f2e47381f3e05e..9051e4e41eee2b0f30e298f5fcc219f23c46c8f6 100644 (file)
@@ -45,7 +45,7 @@ static void amd_nand_decode_id(struct nand_chip *chip)
 static int amd_nand_init(struct nand_chip *chip)
 {
        if (nand_is_slc(chip))
-               chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
+               chip->options |= NAND_BBM_SECONDPAGE;
 
        return 0;
 }
index fd7ce5b929c05be22a01bf98e4cff84128f69467..e1111291389aa7b64c01b20cd23725f63c41186e 100644 (file)
@@ -295,11 +295,11 @@ static int nand_block_bad(struct nand_chip *chip, loff_t ofs)
        int page, page_end, res;
        u8 bad;
 
-       if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
+       if (chip->options & NAND_BBM_LASTPAGE)
                ofs += mtd->erasesize - mtd->writesize;
 
        page = (int)(ofs >> chip->page_shift) & chip->pagemask;
-       page_end = page + (chip->bbt_options & NAND_BBT_SCAN2NDPAGE ? 2 : 1);
+       page_end = page + ((chip->options & NAND_BBM_SECONDPAGE) ? 2 : 1);
 
        for (; page < page_end; page++) {
                res = chip->ecc.read_oob(chip, page);
@@ -507,7 +507,7 @@ static int nand_default_block_markbad(struct nand_chip *chip, loff_t ofs)
        ops.mode = MTD_OPS_PLACE_OOB;
 
        /* Write to first/last page(s) if necessary */
-       if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
+       if (chip->options & NAND_BBM_LASTPAGE)
                ofs += mtd->erasesize - mtd->writesize;
        do {
                res = nand_do_write_oob(chip, ofs, &ops);
@@ -516,7 +516,7 @@ static int nand_default_block_markbad(struct nand_chip *chip, loff_t ofs)
 
                i++;
                ofs += mtd->writesize;
-       } while ((chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2);
+       } while ((chip->options & NAND_BBM_SECONDPAGE) && i < 2);
 
        return ret;
 }
@@ -4513,9 +4513,9 @@ static void nand_decode_bbm_options(struct nand_chip *chip)
 
        /* Set the bad block position */
        if (mtd->writesize > 512 || (chip->options & NAND_BUSWIDTH_16))
-               chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
+               chip->badblockpos = NAND_BBM_POS_LARGE;
        else
-               chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
+               chip->badblockpos = NAND_BBM_POS_SMALL;
 }
 
 static inline bool is_full_id_nand(struct nand_flash_dev *type)
index 9a7855839f81d1e59531d65838ffb3f346b847ac..4915dd7283bb07a4669998bd5f3b2db22b88648e 100644 (file)
@@ -468,7 +468,7 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf,
 
        pr_info("Scanning device for bad blocks\n");
 
-       if (bd->options & NAND_BBT_SCAN2NDPAGE)
+       if (this->options & NAND_BBM_SECONDPAGE)
                numpages = 2;
        else
                numpages = 1;
@@ -489,7 +489,7 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf,
                from = (loff_t)startblock << this->bbt_erase_shift;
        }
 
-       if (this->bbt_options & NAND_BBT_SCANLASTPAGE)
+       if (this->options & NAND_BBM_LASTPAGE)
                from += mtd->erasesize - (mtd->writesize * numpages);
 
        for (i = startblock; i < numblocks; i++) {
index 3de5e89482f5c2b357a645f30e46bb54fe4ca277..4320d4c6a7cdcd4b2bb9bcf2ac2aded521162f2a 100644 (file)
@@ -36,7 +36,7 @@ static void esmt_nand_decode_id(struct nand_chip *chip)
 static int esmt_nand_init(struct nand_chip *chip)
 {
        if (nand_is_slc(chip))
-               chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
+               chip->options |= NAND_BBM_SECONDPAGE;
 
        return 0;
 }
index 821d221b83eb17e553cc749314305a32276e8975..33cb10df65b8069b21ce7dcf83f0f8014d471a87 100644 (file)
@@ -688,9 +688,9 @@ static int hynix_nand_init(struct nand_chip *chip)
        int ret;
 
        if (!nand_is_slc(chip))
-               chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
+               chip->options |= NAND_BBM_LASTPAGE;
        else
-               chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
+               chip->options |= NAND_BBM_SECONDPAGE;
 
        hynix = kzalloc(sizeof(*hynix), GFP_KERNEL);
        if (!hynix)
index 47d8cda547cfe10c87852f5d855ab9157bc6fe73..6db7ced4b96bc538ea7a7d506203b81656730fcd 100644 (file)
@@ -62,7 +62,7 @@ static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip)
 static int macronix_nand_init(struct nand_chip *chip)
 {
        if (nand_is_slc(chip))
-               chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
+               chip->options |= NAND_BBM_SECONDPAGE;
 
        macronix_nand_fix_broken_get_timings(chip);
 
index 7a2cef02eacd563e4beb1c478ee5199f70bba5a4..d43e15772f735d80d01137483c87a97199568e93 100644 (file)
@@ -448,7 +448,7 @@ static int micron_nand_init(struct nand_chip *chip)
                goto err_free_manuf_data;
 
        if (mtd->writesize == 2048)
-               chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
+               chip->options |= NAND_BBM_SECONDPAGE;
 
        ondie = micron_supports_on_die_ecc(chip);
 
index f7d7041b621344eaed76f00075a331d170e46792..f4db72329b7bf22b2db2ff85379e2ac7661b46b1 100644 (file)
@@ -131,9 +131,9 @@ static int samsung_nand_init(struct nand_chip *chip)
                chip->options |= NAND_SAMSUNG_LP_OPTIONS;
 
        if (!nand_is_slc(chip))
-               chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
+               chip->options |= NAND_BBM_LASTPAGE;
        else
-               chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
+               chip->options |= NAND_BBM_SECONDPAGE;
 
        return 0;
 }
index 13f9632f1cb4a7e79946e21b191e971b8d771f58..67f01cef56510942ccf5327066921e3537b102c9 100644 (file)
@@ -152,7 +152,7 @@ static void toshiba_nand_decode_id(struct nand_chip *chip)
 static int toshiba_nand_init(struct nand_chip *chip)
 {
        if (nand_is_slc(chip))
-               chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
+               chip->options |=  NAND_BBM_SECONDPAGE;
 
        /* Check that chip is BENAND and ECC mode is on-die */
        if (nand_is_slc(chip) && chip->ecc.mode == NAND_ECC_ON_DIE &&
index 3f610040f0c33dce2926b8ebb1c26d6d906648cb..02a6768ab13f248520a6480ca19e24db76ecd850 100644 (file)
@@ -101,14 +101,12 @@ static const struct mtd_ooblayout_ops flctl_4secc_oob_largepage_ops = {
 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
 
 static struct nand_bbt_descr flctl_4secc_smallpage = {
-       .options = NAND_BBT_SCAN2NDPAGE,
        .offs = 11,
        .len = 1,
        .pattern = scan_ff_pattern,
 };
 
 static struct nand_bbt_descr flctl_4secc_largepage = {
-       .options = NAND_BBT_SCAN2NDPAGE,
        .offs = 0,
        .len = 2,
        .pattern = scan_ff_pattern,
@@ -1179,6 +1177,8 @@ static int flctl_probe(struct platform_device *pdev)
        if (pdata->flcmncr_val & SEL_16BIT)
                nand->options |= NAND_BUSWIDTH_16;
 
+       nand->options |= NAND_BBM_SECONDPAGE;
+
        pm_runtime_enable(&pdev->dev);
        pm_runtime_resume(&pdev->dev);
 
index 39f6c62b0edefe7cd693fbd8a79f7500ab714185..8b3e28ef75ceaa327e652558efdf7d28acf5cbae 100644 (file)
@@ -169,6 +169,20 @@ enum nand_ecc_algo {
 /* Macros to identify the above */
 #define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ))
 
+/*
+ * There are different places where the manufacturer stores the factory bad
+ * block markers.
+ *
+ * Position within the block: Each of these pages needs to be checked for a
+ * bad block marking pattern.
+ */
+#define NAND_BBM_SECONDPAGE            0x02000000
+#define NAND_BBM_LASTPAGE              0x04000000
+
+/* Position within the OOB data of the page */
+#define NAND_BBM_POS_SMALL             5
+#define NAND_BBM_POS_LARGE             0
+
 /* Non chip related options */
 /* This option skips the bbt scan during initialization. */
 #define NAND_SKIP_BBTSCAN      0x00010000
@@ -1055,7 +1069,7 @@ struct nand_chip {
 
        int subpagesize;
        int onfi_timing_mode_default;
-       int badblockpos;
+       unsigned int badblockpos;
        int badblockbits;
 
        struct nand_id id;