aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/nand_base.c15
-rw-r--r--drivers/mtd/nand/nand_bbt.c3
-rw-r--r--include/linux/mtd/nand.h2
3 files changed, 20 insertions, 0 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 85891dcc27ad..4a7b86423ee9 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -347,6 +347,9 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
347 struct nand_chip *chip = mtd->priv; 347 struct nand_chip *chip = mtd->priv;
348 u16 bad; 348 u16 bad;
349 349
350 if (chip->options & NAND_BB_LAST_PAGE)
351 ofs += mtd->erasesize - mtd->writesize;
352
350 page = (int)(ofs >> chip->page_shift) & chip->pagemask; 353 page = (int)(ofs >> chip->page_shift) & chip->pagemask;
351 354
352 if (getchip) { 355 if (getchip) {
@@ -396,6 +399,9 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
396 uint8_t buf[2] = { 0, 0 }; 399 uint8_t buf[2] = { 0, 0 };
397 int block, ret; 400 int block, ret;
398 401
402 if (chip->options & NAND_BB_LAST_PAGE)
403 ofs += mtd->erasesize - mtd->writesize;
404
399 /* Get block number */ 405 /* Get block number */
400 block = (int)(ofs >> chip->bbt_erase_shift); 406 block = (int)(ofs >> chip->bbt_erase_shift);
401 if (chip->bbt) 407 if (chip->bbt)
@@ -2933,6 +2939,15 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
2933 if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize) 2939 if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize)
2934 chip->options &= ~NAND_SAMSUNG_LP_OPTIONS; 2940 chip->options &= ~NAND_SAMSUNG_LP_OPTIONS;
2935 2941
2942 /*
2943 * Bad block marker is stored in the last page of each block
2944 * on Samsung and Hynix MLC devices
2945 */
2946 if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
2947 (*maf_id == NAND_MFR_SAMSUNG ||
2948 *maf_id == NAND_MFR_HYNIX))
2949 chip->options |= NAND_BB_LAST_PAGE;
2950
2936 /* Check for AND chips with 4 page planes */ 2951 /* Check for AND chips with 4 page planes */
2937 if (chip->options & NAND_4PAGE_ARRAY) 2952 if (chip->options & NAND_4PAGE_ARRAY)
2938 chip->erase_cmd = multi_erase_cmd; 2953 chip->erase_cmd = multi_erase_cmd;
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 387c45c366fe..ad97c0ce73b2 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -432,6 +432,9 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
432 from = (loff_t)startblock << (this->bbt_erase_shift - 1); 432 from = (loff_t)startblock << (this->bbt_erase_shift - 1);
433 } 433 }
434 434
435 if (this->options & NAND_BB_LAST_PAGE)
436 from += mtd->erasesize - (mtd->writesize * len);
437
435 for (i = startblock; i < numblocks;) { 438 for (i = startblock; i < numblocks;) {
436 int ret; 439 int ret;
437 440
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 50f3aa00a452..a81b185e23a7 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -181,6 +181,8 @@ typedef enum {
181#define NAND_NO_READRDY 0x00000100 181#define NAND_NO_READRDY 0x00000100
182/* Chip does not allow subpage writes */ 182/* Chip does not allow subpage writes */
183#define NAND_NO_SUBPAGE_WRITE 0x00000200 183#define NAND_NO_SUBPAGE_WRITE 0x00000200
184/* Chip stores bad block marker on the last page of the eraseblock */
185#define NAND_BB_LAST_PAGE 0x00000400
184 186
185/* Device is one of 'new' xD cards that expose fake nand command set */ 187/* Device is one of 'new' xD cards that expose fake nand command set */
186#define NAND_BROKEN_XD 0x00000400 188#define NAND_BROKEN_XD 0x00000400