aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiquel Raynal <miquel.raynal@bootlin.com>2018-07-25 09:31:51 -0400
committerMiquel Raynal <miquel.raynal@bootlin.com>2018-07-31 03:46:14 -0400
commit2023f1fa216f30b1877d65be2057fbaf0bbd49b3 (patch)
tree5d53702f9da4b77d8cfdd36e0bfb2b88aed18ea8
parent98732da1a08ebb666983d469981a8b994e77d556 (diff)
mtd: rawnand: allocate model parameter dynamically
Thanks to the migration of all drivers to use nand_scan() and the related nand_controller_ops, we can now allocate data during the detection phase. Let's do it first for the NAND model parameter which is allocated in nand_detect(). Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com>
-rw-r--r--drivers/mtd/nand/raw/nand_base.c52
-rw-r--r--include/linux/mtd/rawnand.h2
2 files changed, 42 insertions, 12 deletions
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 34ea44f90fd8..00e80781124a 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -5225,8 +5225,11 @@ static int nand_flash_detect_onfi(struct nand_chip *chip)
5225 5225
5226 sanitize_string(p->manufacturer, sizeof(p->manufacturer)); 5226 sanitize_string(p->manufacturer, sizeof(p->manufacturer));
5227 sanitize_string(p->model, sizeof(p->model)); 5227 sanitize_string(p->model, sizeof(p->model));
5228 strncpy(chip->parameters.model, p->model, 5228 chip->parameters.model = kstrdup(p->model, GFP_KERNEL);
5229 sizeof(chip->parameters.model) - 1); 5229 if (!chip->parameters.model) {
5230 ret = -ENOMEM;
5231 goto free_onfi_param_page;
5232 }
5230 5233
5231 mtd->writesize = le32_to_cpu(p->byte_per_page); 5234 mtd->writesize = le32_to_cpu(p->byte_per_page);
5232 5235
@@ -5356,8 +5359,11 @@ static int nand_flash_detect_jedec(struct nand_chip *chip)
5356 5359
5357 sanitize_string(p->manufacturer, sizeof(p->manufacturer)); 5360 sanitize_string(p->manufacturer, sizeof(p->manufacturer));
5358 sanitize_string(p->model, sizeof(p->model)); 5361 sanitize_string(p->model, sizeof(p->model));
5359 strncpy(chip->parameters.model, p->model, 5362 chip->parameters.model = kstrdup(p->model, GFP_KERNEL);
5360 sizeof(chip->parameters.model) - 1); 5363 if (!chip->parameters.model) {
5364 ret = -ENOMEM;
5365 goto free_jedec_param_page;
5366 }
5361 5367
5362 mtd->writesize = le32_to_cpu(p->byte_per_page); 5368 mtd->writesize = le32_to_cpu(p->byte_per_page);
5363 5369
@@ -5546,8 +5552,9 @@ static bool find_full_id_nand(struct nand_chip *chip,
5546 chip->onfi_timing_mode_default = 5552 chip->onfi_timing_mode_default =
5547 type->onfi_timing_mode_default; 5553 type->onfi_timing_mode_default;
5548 5554
5549 strncpy(chip->parameters.model, type->name, 5555 chip->parameters.model = kstrdup(type->name, GFP_KERNEL);
5550 sizeof(chip->parameters.model) - 1); 5556 if (!chip->parameters.model)
5557 return false;
5551 5558
5552 return true; 5559 return true;
5553 } 5560 }
@@ -5706,8 +5713,9 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
5706 if (!type->name) 5713 if (!type->name)
5707 return -ENODEV; 5714 return -ENODEV;
5708 5715
5709 strncpy(chip->parameters.model, type->name, 5716 chip->parameters.model = kstrdup(type->name, GFP_KERNEL);
5710 sizeof(chip->parameters.model) - 1); 5717 if (!chip->parameters.model)
5718 return -ENOMEM;
5711 5719
5712 chip->chipsize = (uint64_t)type->chipsize << 20; 5720 chip->chipsize = (uint64_t)type->chipsize << 20;
5713 5721
@@ -5737,7 +5745,9 @@ ident_done:
5737 mtd->name); 5745 mtd->name);
5738 pr_warn("bus width %d instead of %d bits\n", busw ? 16 : 8, 5746 pr_warn("bus width %d instead of %d bits\n", busw ? 16 : 8,
5739 (chip->options & NAND_BUSWIDTH_16) ? 16 : 8); 5747 (chip->options & NAND_BUSWIDTH_16) ? 16 : 8);
5740 return -EINVAL; 5748 ret = -EINVAL;
5749
5750 goto free_detect_allocation;
5741 } 5751 }
5742 5752
5743 nand_decode_bbm_options(chip); 5753 nand_decode_bbm_options(chip);
@@ -5774,6 +5784,11 @@ ident_done:
5774 (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", 5784 (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
5775 mtd->erasesize >> 10, mtd->writesize, mtd->oobsize); 5785 mtd->erasesize >> 10, mtd->writesize, mtd->oobsize);
5776 return 0; 5786 return 0;
5787
5788free_detect_allocation:
5789 kfree(chip->parameters.model);
5790
5791 return ret;
5777} 5792}
5778 5793
5779static const char * const nand_ecc_modes[] = { 5794static const char * const nand_ecc_modes[] = {
@@ -6013,6 +6028,11 @@ static int nand_scan_ident(struct mtd_info *mtd, int maxchips,
6013 return 0; 6028 return 0;
6014} 6029}
6015 6030
6031static void nand_scan_ident_cleanup(struct nand_chip *chip)
6032{
6033 kfree(chip->parameters.model);
6034}
6035
6016static int nand_set_ecc_soft_ops(struct mtd_info *mtd) 6036static int nand_set_ecc_soft_ops(struct mtd_info *mtd)
6017{ 6037{
6018 struct nand_chip *chip = mtd_to_nand(mtd); 6038 struct nand_chip *chip = mtd_to_nand(mtd);
@@ -6760,11 +6780,18 @@ int nand_scan_with_ids(struct mtd_info *mtd, int maxchips,
6760 6780
6761 ret = nand_attach(chip); 6781 ret = nand_attach(chip);
6762 if (ret) 6782 if (ret)
6763 return ret; 6783 goto cleanup_ident;
6764 6784
6765 ret = nand_scan_tail(mtd); 6785 ret = nand_scan_tail(mtd);
6766 if (ret) 6786 if (ret)
6767 nand_detach(chip); 6787 goto detach_chip;
6788
6789 return 0;
6790
6791detach_chip:
6792 nand_detach(chip);
6793cleanup_ident:
6794 nand_scan_ident_cleanup(chip);
6768 6795
6769 return ret; 6796 return ret;
6770} 6797}
@@ -6796,6 +6823,9 @@ void nand_cleanup(struct nand_chip *chip)
6796 6823
6797 /* Free controller specific allocations after chip identification */ 6824 /* Free controller specific allocations after chip identification */
6798 nand_detach(chip); 6825 nand_detach(chip);
6826
6827 /* Free identification phase allocations */
6828 nand_scan_ident_cleanup(chip);
6799} 6829}
6800 6830
6801EXPORT_SYMBOL_GPL(nand_cleanup); 6831EXPORT_SYMBOL_GPL(nand_cleanup);
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 71571ed23a20..099fa166569a 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -476,7 +476,7 @@ struct onfi_params {
476 */ 476 */
477struct nand_parameters { 477struct nand_parameters {
478 /* Generic parameters */ 478 /* Generic parameters */
479 char model[100]; 479 const char *model;
480 bool supports_set_get_features; 480 bool supports_set_get_features;
481 DECLARE_BITMAP(set_feature_list, ONFI_FEATURE_NUMBER); 481 DECLARE_BITMAP(set_feature_list, ONFI_FEATURE_NUMBER);
482 DECLARE_BITMAP(get_feature_list, ONFI_FEATURE_NUMBER); 482 DECLARE_BITMAP(get_feature_list, ONFI_FEATURE_NUMBER);