From ce446b4b2d803cf62de2e74b1fbda8758e4835bd Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Sat, 18 Apr 2020 21:42:17 +0200 Subject: [PATCH] mtd: rawnand: Take check_only into account ->exec_op() is passed a check_only argument that encodes when the controller should just check whether the operation is supported or not without executing it. Some controllers simply ignore this arguments, others don't but keep modifying some of the registers before returning. Let's fix all those drivers. Signed-off-by: Boris Brezillon Signed-off-by: Miquel Raynal Link: https://lore.kernel.org/linux-mtd/20200418194217.1016060-1-boris.brezillon@collabora.com --- drivers/mtd/nand/raw/cadence-nand-controller.c | 8 +++++--- drivers/mtd/nand/raw/fsmc_nand.c | 3 +++ drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 3 +++ drivers/mtd/nand/raw/marvell_nand.c | 3 ++- drivers/mtd/nand/raw/meson_nand.c | 3 +++ drivers/mtd/nand/raw/mxic_nand.c | 3 +++ drivers/mtd/nand/raw/nandsim.c | 3 +++ drivers/mtd/nand/raw/stm32_fmc2_nand.c | 6 +++--- drivers/mtd/nand/raw/sunxi_nand.c | 3 ++- drivers/mtd/nand/raw/tegra_nand.c | 4 +++- drivers/mtd/nand/raw/vf610_nfc.c | 4 +++- 11 files changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/mtd/nand/raw/cadence-nand-controller.c b/drivers/mtd/nand/raw/cadence-nand-controller.c index acc0a24e5816..e7abb15c7253 100644 --- a/drivers/mtd/nand/raw/cadence-nand-controller.c +++ b/drivers/mtd/nand/raw/cadence-nand-controller.c @@ -2223,10 +2223,12 @@ static int cadence_nand_exec_op(struct nand_chip *chip, const struct nand_operation *op, bool check_only) { - int status = cadence_nand_select_target(chip); + if (!check_only) { + int status = cadence_nand_select_target(chip); - if (status) - return status; + if (status) + return status; + } return nand_op_parser_exec_op(chip, &cadence_nand_op_parser, op, check_only); diff --git a/drivers/mtd/nand/raw/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c index 7e28311dffcb..31dc9fd0a94d 100644 --- a/drivers/mtd/nand/raw/fsmc_nand.c +++ b/drivers/mtd/nand/raw/fsmc_nand.c @@ -608,6 +608,9 @@ static int fsmc_exec_op(struct nand_chip *chip, const struct nand_operation *op, unsigned int op_id; int i; + if (check_only) + return 0; + pr_debug("Executing operation [%d instructions]:\n", op->ninstrs); for (op_id = 0; op_id < op->ninstrs; op_id++) { diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c index 53b00c841aec..cc4cb190968e 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c @@ -2408,6 +2408,9 @@ static int gpmi_nfc_exec_op(struct nand_chip *chip, struct completion *completion; unsigned long to; + if (check_only) + return 0; + this->ntransfers = 0; for (i = 0; i < GPMI_MAX_TRANSFERS; i++) this->transfers[i].direction = DMA_NONE; diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index 179f0ca585f8..343001250ccc 100644 --- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c @@ -2107,7 +2107,8 @@ static int marvell_nfc_exec_op(struct nand_chip *chip, { struct marvell_nfc *nfc = to_marvell_nfc(chip->controller); - marvell_nfc_select_target(chip, op->cs); + if (!check_only) + marvell_nfc_select_target(chip, op->cs); if (nfc->caps->is_nfcv2) return nand_op_parser_exec_op(chip, &marvell_nfcv2_op_parser, diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c index f6fb5c0e6255..e961f7bebf0a 100644 --- a/drivers/mtd/nand/raw/meson_nand.c +++ b/drivers/mtd/nand/raw/meson_nand.c @@ -899,6 +899,9 @@ static int meson_nfc_exec_op(struct nand_chip *nand, u32 op_id, delay_idle, cmd; int i; + if (check_only) + return 0; + meson_nfc_select_chip(nand, op->cs); for (op_id = 0; op_id < op->ninstrs; op_id++) { instr = &op->instrs[op_id]; diff --git a/drivers/mtd/nand/raw/mxic_nand.c b/drivers/mtd/nand/raw/mxic_nand.c index ed7a4e021bf5..5a5a5b3b546d 100644 --- a/drivers/mtd/nand/raw/mxic_nand.c +++ b/drivers/mtd/nand/raw/mxic_nand.c @@ -393,6 +393,9 @@ static int mxic_nfc_exec_op(struct nand_chip *chip, int ret = 0; unsigned int op_id; + if (check_only) + return 0; + mxic_nfc_cs_enable(nfc); init_completion(&nfc->complete); for (op_id = 0; op_id < op->ninstrs; op_id++) { diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c index 1de03bb34e84..23cda67a3f53 100644 --- a/drivers/mtd/nand/raw/nandsim.c +++ b/drivers/mtd/nand/raw/nandsim.c @@ -2144,6 +2144,9 @@ static int ns_exec_op(struct nand_chip *chip, const struct nand_operation *op, const struct nand_op_instr *instr = NULL; struct nandsim *ns = nand_get_controller_data(chip); + if (check_only) + return 0; + ns->lines.ce = 1; for (op_id = 0; op_id < op->ninstrs; op_id++) { diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c index b6d45cd911ae..46b7d04e2c87 100644 --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c @@ -1365,13 +1365,13 @@ static int stm32_fmc2_exec_op(struct nand_chip *chip, unsigned int op_id, i; int ret; + if (check_only) + return 0; + ret = stm32_fmc2_select_chip(chip, op->cs); if (ret) return ret; - if (check_only) - return ret; - for (op_id = 0; op_id < op->ninstrs; op_id++) { instr = &op->instrs[op_id]; diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 5f3e40b79fb1..18ac0b36abfa 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1907,7 +1907,8 @@ static int sunxi_nfc_exec_op(struct nand_chip *nand, struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); const struct nand_op_parser *parser; - sunxi_nfc_select_chip(nand, op->cs); + if (!check_only) + sunxi_nfc_select_chip(nand, op->cs); if (sunxi_nand->sels[op->cs].rb >= 0) parser = &sunxi_nfc_op_parser; diff --git a/drivers/mtd/nand/raw/tegra_nand.c b/drivers/mtd/nand/raw/tegra_nand.c index 3cc9a4c41443..6a255ba0f288 100644 --- a/drivers/mtd/nand/raw/tegra_nand.c +++ b/drivers/mtd/nand/raw/tegra_nand.c @@ -467,7 +467,9 @@ static int tegra_nand_exec_op(struct nand_chip *chip, const struct nand_operation *op, bool check_only) { - tegra_nand_select_target(chip, op->cs); + if (!check_only) + tegra_nand_select_target(chip, op->cs); + return nand_op_parser_exec_op(chip, &tegra_nand_op_parser, op, check_only); } diff --git a/drivers/mtd/nand/raw/vf610_nfc.c b/drivers/mtd/nand/raw/vf610_nfc.c index 6b399a75f9ae..bd9e16de78a2 100644 --- a/drivers/mtd/nand/raw/vf610_nfc.c +++ b/drivers/mtd/nand/raw/vf610_nfc.c @@ -502,7 +502,9 @@ static int vf610_nfc_exec_op(struct nand_chip *chip, const struct nand_operation *op, bool check_only) { - vf610_nfc_select_target(chip, op->cs); + if (!check_only) + vf610_nfc_select_target(chip, op->cs); + return nand_op_parser_exec_op(chip, &vf610_nfc_op_parser, op, check_only); }