diff options
| -rw-r--r-- | drivers/mtd/nand/nand_base.c | 15 | ||||
| -rw-r--r-- | drivers/mtd/nand/nand_bbt.c | 3 | ||||
| -rw-r--r-- | include/linux/mtd/nand.h | 2 |
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 |
