summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Zhang <william.zhang@broadcom.com>2023-07-06 11:29:06 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-09-19 12:20:28 +0200
commitd68f639ddec4f634739cb92c457715f7ecdd1df9 (patch)
tree3cc59e70caa77d548840b40277d725328b305322
parentd00b031266514a9395124704630b056a5185ec17 (diff)
downloadlinux-d68f639ddec4f634739cb92c457715f7ecdd1df9.tar.gz
linux-d68f639ddec4f634739cb92c457715f7ecdd1df9.tar.bz2
linux-d68f639ddec4f634739cb92c457715f7ecdd1df9.zip
mtd: rawnand: brcmnand: Fix potential false time out warning
commit 9cc0a598b944816f2968baf2631757f22721b996 upstream. If system is busy during the command status polling function, the driver may not get the chance to poll the status register till the end of time out and return the premature status. Do a final check after time out happens to ensure reading the correct status. Fixes: 9d2ee0a60b8b ("mtd: nand: brcmnand: Check flash #WP pin status before nand erase/program") Signed-off-by: William Zhang <william.zhang@broadcom.com> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com> Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-3-william.zhang@broadcom.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/mtd/nand/raw/brcmnand/brcmnand.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 844558ac9db5..e170c545fec5 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -1040,6 +1040,14 @@ static int bcmnand_ctrl_poll_status(struct brcmnand_controller *ctrl,
cpu_relax();
} while (time_after(limit, jiffies));
+ /*
+ * do a final check after time out in case the CPU was busy and the driver
+ * did not get enough time to perform the polling to avoid false alarms
+ */
+ val = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS);
+ if ((val & mask) == expected_val)
+ return 0;
+
dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
expected_val, val & mask);