]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
mtd: rawnand: get rid of the JEDEC parameter page in nand_chip
authorMiquel Raynal <miquel.raynal@bootlin.com>
Mon, 19 Mar 2018 13:47:30 +0000 (14:47 +0100)
committerBoris Brezillon <boris.brezillon@bootlin.com>
Tue, 20 Mar 2018 10:59:59 +0000 (11:59 +0100)
The NAND chip parameter page is statically allocated within the
nand_chip structure, which reserves a lot of space. Even not ONFI nor
JEDEC chips have it embedded. Also, only a few parameters are actually
read from the parameter page after the detection.

Now that there is a small nand_parameters structure that can held
generic parameters, remove the JEDEC page from the nand_chip structure
by just allocating it during the identification phase and removing it
right after.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
drivers/mtd/nand/raw/nand_base.c
include/linux/mtd/rawnand.h

index 0bd9f22973e96389dd2341c4b054ca8f9f1b98da..79348165e4a3040ef79ef747454437d99f05947f 100644 (file)
@@ -5226,8 +5226,9 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
 static int nand_flash_detect_jedec(struct nand_chip *chip)
 {
        struct mtd_info *mtd = nand_to_mtd(chip);
-       struct nand_jedec_params *p = &chip->jedec_params;
+       struct nand_jedec_params *p;
        struct jedec_ecc_info *ecc;
+       int jedec_version = 0;
        char id[5];
        int i, val, ret;
 
@@ -5236,14 +5237,23 @@ static int nand_flash_detect_jedec(struct nand_chip *chip)
        if (ret || strncmp(id, "JEDEC", sizeof(id)))
                return 0;
 
+       /* JEDEC chip: allocate a buffer to hold its parameter page */
+       p = kzalloc(sizeof(*p), GFP_KERNEL);
+       if (!p)
+               return -ENOMEM;
+
        ret = nand_read_param_page_op(chip, 0x40, NULL, 0);
-       if (ret)
-               return 0;
+       if (ret) {
+               ret = 0;
+               goto free_jedec_param_page;
+       }
 
        for (i = 0; i < 3; i++) {
                ret = nand_read_data_op(chip, p, sizeof(*p), true);
-               if (ret)
-                       return 0;
+               if (ret) {
+                       ret = 0;
+                       goto free_jedec_param_page;
+               }
 
                if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 510) ==
                                le16_to_cpu(p->crc))
@@ -5252,19 +5262,19 @@ static int nand_flash_detect_jedec(struct nand_chip *chip)
 
        if (i == 3) {
                pr_err("Could not find valid JEDEC parameter page; aborting\n");
-               return 0;
+               goto free_jedec_param_page;
        }
 
        /* Check version */
        val = le16_to_cpu(p->revision);
        if (val & (1 << 2))
-               chip->jedec_version = 10;
+               jedec_version = 10;
        else if (val & (1 << 1))
-               chip->jedec_version = 1; /* vendor specific version */
+               jedec_version = 1; /* vendor specific version */
 
-       if (!chip->jedec_version) {
+       if (!jedec_version) {
                pr_info("unsupported JEDEC version: %d\n", val);
-               return 0;
+               goto free_jedec_param_page;
        }
 
        sanitize_string(p->manufacturer, sizeof(p->manufacturer));
@@ -5285,7 +5295,7 @@ static int nand_flash_detect_jedec(struct nand_chip *chip)
        chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
        chip->bits_per_cell = p->bits_per_cell;
 
-       if (jedec_feature(chip) & JEDEC_FEATURE_16_BIT_BUS)
+       if (le16_to_cpu(p->features) & JEDEC_FEATURE_16_BIT_BUS)
                chip->options |= NAND_BUSWIDTH_16;
 
        /* ECC info */
@@ -5298,7 +5308,9 @@ static int nand_flash_detect_jedec(struct nand_chip *chip)
                pr_warn("Invalid codeword size\n");
        }
 
-       return 1;
+free_jedec_param_page:
+       kfree(p);
+       return ret;
 }
 
 /*
@@ -5604,7 +5616,10 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
                        goto ident_done;
 
                /* Check if the chip is JEDEC compliant */
-               if (nand_flash_detect_jedec(chip))
+               ret = nand_flash_detect_jedec(chip);
+               if (ret < 0)
+                       return ret;
+               else if (ret)
                        goto ident_done;
        }
 
index d9f417719d36ee0f35c5a153c3e931730a86637e..cf82a959b0f3699292cb3984412d297fb3ab409c 100644 (file)
@@ -1200,12 +1200,8 @@ int nand_op_parser_exec_op(struct nand_chip *chip,
  *                     currently in data_buf.
  * @subpagesize:       [INTERN] holds the subpagesize
  * @id:                        [INTERN] holds NAND ID
- * @jedec_version:     [INTERN] holds the chip JEDEC version (BCD encoded),
- *                     non 0 if JEDEC supported.
  * @onfi_params:       [INTERN] holds the ONFI page parameter when ONFI is
  *                     supported, 0 otherwise.
- * @jedec_params:      [INTERN] holds the JEDEC parameter page when JEDEC is
- *                     supported, 0 otherwise.
  * @parameters:                [INTERN] holds generic parameters under an easily
  *                     readable form.
  * @max_bb_per_die:    [INTERN] the max number of bad blocks each die of a
@@ -1286,11 +1282,7 @@ struct nand_chip {
        int badblockbits;
 
        struct nand_id id;
-       int jedec_version;
-       union {
-               struct nand_onfi_params onfi_params;
-               struct nand_jedec_params jedec_params;
-       };
+       struct nand_onfi_params onfi_params;
        struct nand_parameters parameters;
        u16 max_bb_per_die;
        u32 blocks_per_die;
@@ -1621,13 +1613,6 @@ static inline int nand_opcode_8bits(unsigned int command)
        return 0;
 }
 
-/* return the supported JEDEC features. */
-static inline int jedec_feature(struct nand_chip *chip)
-{
-       return chip->jedec_version ? le16_to_cpu(chip->jedec_params.features)
-               : 0;
-}
-
 /* get timing characteristics from ONFI timing mode. */
 const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode);