summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/nand_base.c14
-rw-r--r--include/linux/mtd/nand.h7
2 files changed, 16 insertions, 5 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 6ea66270dbf5..5fb00957fd25 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3082,6 +3082,16 @@ static int nand_id_len(u8 *id_data, int arrlen)
return arrlen;
}
+/* Extract the bits of per cell from the 3rd byte of the extended ID */
+static int nand_get_bits_per_cell(u8 cellinfo)
+{
+ int bits;
+
+ bits = cellinfo & NAND_CI_CELLTYPE_MSK;
+ bits >>= NAND_CI_CELLTYPE_SHIFT;
+ return bits + 1;
+}
+
/*
* 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
@@ -3092,7 +3102,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
{
int extid, id_len;
/* The 3rd id byte holds MLC / multichip data */
- chip->cellinfo = id_data[2];
+ chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
/* The 4th id byte is the important one */
extid = id_data[3];
@@ -3292,7 +3302,7 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip,
mtd->erasesize = type->erasesize;
mtd->oobsize = type->oobsize;
- chip->cellinfo = id_data[2];
+ chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
chip->chipsize = (uint64_t)type->chipsize << 20;
chip->options |= type->options;
chip->ecc_strength_ds = NAND_ECC_STRENGTH(type);
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 5c05bab0ad89..9e6c8f9f306e 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -198,6 +198,7 @@ typedef enum {
/* Cell info constants */
#define NAND_CI_CHIPNR_MSK 0x03
#define NAND_CI_CELLTYPE_MSK 0x0C
+#define NAND_CI_CELLTYPE_SHIFT 2
/* Keep gcc happy */
struct nand_chip;
@@ -477,7 +478,7 @@ struct nand_buffers {
* @badblockbits: [INTERN] minimum number of set bits in a good block's
* bad block marker position; i.e., BBM == 11110111b is
* not bad when badblockbits == 7
- * @cellinfo: [INTERN] MLC/multichip data from chip ident
+ * @bits_per_cell: [INTERN] number of bits per cell. i.e., 1 means SLC.
* @ecc_strength_ds: [INTERN] ECC correctability from the datasheet.
* Minimum amount of bit errors per @ecc_step_ds guaranteed
* to be correctable. If unknown, set to zero.
@@ -558,7 +559,7 @@ struct nand_chip {
int pagebuf;
unsigned int pagebuf_bitflips;
int subpagesize;
- uint8_t cellinfo;
+ uint8_t bits_per_cell;
uint16_t ecc_strength_ds;
uint16_t ecc_step_ds;
int badblockpos;
@@ -802,6 +803,6 @@ static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
*/
static inline bool nand_is_slc(struct nand_chip *chip)
{
- return !(chip->cellinfo & NAND_CI_CELLTYPE_MSK);
+ return chip->bits_per_cell == 1;
}
#endif /* __LINUX_MTD_NAND_H */