aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorMiquel Raynal <miquel.raynal@bootlin.com>2018-03-19 14:47:31 +0100
committerBoris Brezillon <boris.brezillon@bootlin.com>2018-03-20 11:59:59 +0100
commitbd0b64340c2d66c0fe1aa99b0b23159d7e0c21f2 (patch)
tree78e94afb6d8a63ee1f68907a68c0d806a3e7706d /drivers/mtd
parentmtd: rawnand: get rid of the JEDEC parameter page in nand_chip (diff)
downloadlinux-dev-bd0b64340c2d66c0fe1aa99b0b23159d7e0c21f2.tar.xz
linux-dev-bd0b64340c2d66c0fe1aa99b0b23159d7e0c21f2.zip
mtd: rawnand: get rid of the ONFI parameter page in nand_chip
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 hold all needed ONFI parameters, remove the ONFI 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>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/raw/nand_base.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 79348165e4a3..d0b993fcf3a5 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -5101,7 +5101,7 @@ ext_out:
static int nand_flash_detect_onfi(struct nand_chip *chip)
{
struct mtd_info *mtd = nand_to_mtd(chip);
- struct nand_onfi_params *p = &chip->onfi_params;
+ struct nand_onfi_params *p;
char id[4];
int i, ret, val;
@@ -5110,14 +5110,23 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
if (ret || strncmp(id, "ONFI", 4))
return 0;
+ /* ONFI 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, 0, NULL, 0);
- if (ret)
- return 0;
+ if (ret) {
+ ret = 0;
+ goto free_onfi_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_onfi_param_page;
+ }
if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) ==
le16_to_cpu(p->crc)) {
@@ -5127,7 +5136,7 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
if (i == 3) {
pr_err("Could not find valid ONFI parameter page; aborting\n");
- return 0;
+ goto free_onfi_param_page;
}
/* Check version */
@@ -5145,7 +5154,9 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
if (!chip->parameters.onfi.version) {
pr_info("unsupported ONFI version: %d\n", val);
- return 0;
+ goto free_onfi_param_page;
+ } else {
+ ret = 1;
}
sanitize_string(p->manufacturer, sizeof(p->manufacturer));
@@ -5217,7 +5228,9 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
memcpy(chip->parameters.onfi.vendor, p->vendor,
sizeof(p->vendor));
- return 1;
+free_onfi_param_page:
+ kfree(p);
+ return ret;
}
/*
@@ -5612,7 +5625,10 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
chip->parameters.onfi.version = 0;
if (!type->name || !type->pagesize) {
/* Check if the chip is ONFI compliant */
- if (nand_flash_detect_onfi(chip))
+ ret = nand_flash_detect_onfi(chip);
+ if (ret < 0)
+ return ret;
+ else if (ret)
goto ident_done;
/* Check if the chip is JEDEC compliant */