summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHuang Shijie <b32955@freescale.com>2013-09-25 14:58:10 +0800
committerBrian Norris <computersforpeace@gmail.com>2013-10-27 16:27:04 -0700
commit1d0ed69ddd714b6e2a974f42896463366923ded6 (patch)
tree958946ae1a2823cea55b6a1a4d4e4417faa6896b
parent4ae7d228d6048d25a16bee209ebea24c5ecde825 (diff)
mtd: nand: add a helper to check the SLC/MLC nand chip
Add a helper to check if a nand chip is SLC or MLC. This helper makes the code more readable. Signed-off-by: Huang Shijie <b32955@freescale.com> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
-rw-r--r--drivers/mtd/nand/denali.c2
-rw-r--r--drivers/mtd/nand/nand_base.c14
-rw-r--r--include/linux/mtd/nand.h9
3 files changed, 16 insertions, 9 deletions
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 154b033b4e8e..370b9dd7a278 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -1520,7 +1520,7 @@ int denali_init(struct denali_nand_info *denali)
* so just let controller do 15bit ECC for MLC and 8bit ECC for
* SLC if possible.
* */
- if (denali->nand.cellinfo & NAND_CI_CELLTYPE_MSK &&
+ if (!nand_is_slc(&denali->nand) &&
(denali->mtd.oobsize > (denali->bbtskipbytes +
ECC_15BITS * (denali->mtd.writesize /
ECC_SECTOR_SIZE)))) {
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 0b39d0c03f1e..6ea66270dbf5 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3108,8 +3108,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
* ID to decide what to do.
*/
if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
- (chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
- id_data[5] != 0x00) {
+ !nand_is_slc(chip) && id_data[5] != 0x00) {
/* Calc pagesize */
mtd->writesize = 2048 << (extid & 0x03);
extid >>= 2;
@@ -3141,7 +3140,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
(((extid >> 1) & 0x04) | (extid & 0x03));
*busw = 0;
} else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX &&
- (chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
+ !nand_is_slc(chip)) {
unsigned int tmp;
/* Calc pagesize */
@@ -3204,7 +3203,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
* - ID byte 5, bit[7]: 1 -> BENAND, 0 -> raw SLC
*/
if (id_len >= 6 && id_data[0] == NAND_MFR_TOSHIBA &&
- !(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+ nand_is_slc(chip) &&
(id_data[5] & 0x7) == 0x6 /* 24nm */ &&
!(id_data[4] & 0x80) /* !BENAND */) {
mtd->oobsize = 32 * mtd->writesize >> 9;
@@ -3265,11 +3264,11 @@ static void nand_decode_bbm_options(struct mtd_info *mtd,
* 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) &&
+ if (!nand_is_slc(chip) &&
(maf_id == NAND_MFR_SAMSUNG ||
maf_id == NAND_MFR_HYNIX))
chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
- else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+ else if ((nand_is_slc(chip) &&
(maf_id == NAND_MFR_SAMSUNG ||
maf_id == NAND_MFR_HYNIX ||
maf_id == NAND_MFR_TOSHIBA ||
@@ -3745,8 +3744,7 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
/* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
- if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&
- !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
+ if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && nand_is_slc(chip)) {
switch (chip->ecc.steps) {
case 2:
mtd->subpage_sft = 1;
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 129548169400..5c05bab0ad89 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -795,4 +795,13 @@ static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
return le16_to_cpu(chip->onfi_params.src_sync_timing_mode);
}
+/*
+ * Check if it is a SLC nand.
+ * The !nand_is_slc() can be used to check the MLC/TLC nand chips.
+ * We do not distinguish the MLC and TLC now.
+ */
+static inline bool nand_is_slc(struct nand_chip *chip)
+{
+ return !(chip->cellinfo & NAND_CI_CELLTYPE_MSK);
+}
#endif /* __LINUX_MTD_NAND_H */