From 52cde35b9645e60a0c8e4040136476c4f9804110 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 22 Nov 2017 02:38:28 +0900 Subject: [PATCH] mtd: nand: Pass the CS line to ->setup_data_interface() Some NAND controllers can assign different NAND timings to different CS lines. Pass the CS line information to ->setup_data_interface() so that the NAND controller driver knows which CS line is concerned by the setup_data_interface() request. Signed-off-by: Boris Brezillon [Linux commit: 104e442a67cfba4d0cc982384761befb917fb6a1] Signed-off-by: Masahiro Yamada --- drivers/mtd/nand/nand_base.c | 22 +++++++++++++--------- include/linux/mtd/nand.h | 12 ++++++++---- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index f3c515b6df..e490c84e84 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -904,12 +904,13 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip) /** * nand_reset_data_interface - Reset data interface and timings * @chip: The NAND chip + * @chipnr: Internal die id * * Reset the Data interface and timings to ONFI mode 0. * * Returns 0 for success or negative error code otherwise. */ -static int nand_reset_data_interface(struct nand_chip *chip) +static int nand_reset_data_interface(struct nand_chip *chip, int chipnr) { struct mtd_info *mtd = nand_to_mtd(chip); const struct nand_data_interface *conf; @@ -933,7 +934,7 @@ static int nand_reset_data_interface(struct nand_chip *chip) */ conf = nand_get_default_data_interface(); - ret = chip->setup_data_interface(mtd, conf, false); + ret = chip->setup_data_interface(mtd, chipnr, conf); if (ret) pr_err("Failed to configure data interface to SDR timing mode 0\n"); @@ -943,6 +944,7 @@ static int nand_reset_data_interface(struct nand_chip *chip) /** * nand_setup_data_interface - Setup the best data interface and timings * @chip: The NAND chip + * @chipnr: Internal die id * * Find and configure the best data interface and NAND timings supported by * the chip and the driver. @@ -952,7 +954,7 @@ static int nand_reset_data_interface(struct nand_chip *chip) * * Returns 0 for success or negative error code otherwise. */ -static int nand_setup_data_interface(struct nand_chip *chip) +static int nand_setup_data_interface(struct nand_chip *chip, int chipnr) { struct mtd_info *mtd = nand_to_mtd(chip); int ret; @@ -976,7 +978,7 @@ static int nand_setup_data_interface(struct nand_chip *chip) goto err; } - ret = chip->setup_data_interface(mtd, chip->data_interface, false); + ret = chip->setup_data_interface(mtd, chipnr, chip->data_interface); err: return ret; } @@ -1027,8 +1029,10 @@ static int nand_init_data_interface(struct nand_chip *chip) if (ret) continue; - ret = chip->setup_data_interface(mtd, chip->data_interface, - true); + /* Pass -1 to only */ + ret = chip->setup_data_interface(mtd, + NAND_DATA_IFACE_CHECK_ONLY, + chip->data_interface); if (!ret) { chip->onfi_timing_mode_default = mode; break; @@ -1055,7 +1059,7 @@ int nand_reset(struct nand_chip *chip, int chipnr) struct mtd_info *mtd = nand_to_mtd(chip); int ret; - ret = nand_reset_data_interface(chip); + ret = nand_reset_data_interface(chip, chipnr); if (ret) return ret; @@ -1068,7 +1072,7 @@ int nand_reset(struct nand_chip *chip, int chipnr) chip->select_chip(mtd, -1); chip->select_chip(mtd, chipnr); - ret = nand_setup_data_interface(chip); + ret = nand_setup_data_interface(chip, chipnr); chip->select_chip(mtd, -1); if (ret) return ret; @@ -4037,7 +4041,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, * For the other dies, nand_reset() will automatically switch to the * best mode for us. */ - ret = nand_setup_data_interface(chip); + ret = nand_setup_data_interface(chip, 0); if (ret) return ret; diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 90c6010105..b1a664815d 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -124,6 +124,8 @@ void nand_wait_ready(struct mtd_info *mtd); #define NAND_STATUS_READY 0x40 #define NAND_STATUS_WP 0x80 +#define NAND_DATA_IFACE_CHECK_ONLY -1 + /* * Constants for ECC_MODES */ @@ -807,7 +809,10 @@ nand_get_sdr_timings(const struct nand_data_interface *conf) * @read_retries: [INTERN] the number of read retry modes supported * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand - * @setup_data_interface: [OPTIONAL] setup the data interface and timing + * @setup_data_interface: [OPTIONAL] setup the data interface and timing. If + * chipnr is set to %NAND_DATA_IFACE_CHECK_ONLY this + * means the configuration should not be applied but + * only checked. * @bbt: [INTERN] bad block table pointer * @bbt_td: [REPLACEABLE] bad block table descriptor for flash * lookup. @@ -851,9 +856,8 @@ struct nand_chip { int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip, int feature_addr, uint8_t *subfeature_para); int (*setup_read_retry)(struct mtd_info *mtd, int retry_mode); - int (*setup_data_interface)(struct mtd_info *mtd, - const struct nand_data_interface *conf, - bool check_only); + int (*setup_data_interface)(struct mtd_info *mtd, int chipnr, + const struct nand_data_interface *conf); int chip_delay; -- 2.25.1