diff options
author | Peter Tyser <ptyser@xes-inc.com> | 2009-02-04 13:47:22 -0600 |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2009-02-06 17:29:38 -0600 |
commit | 8da601280a8acbc3385784780ed35130e53812f1 (patch) | |
tree | 7314c3b39b39337cc53a061fd19168253d1e7dd3 /drivers | |
parent | 10dc6a9bef73d7d4cb25b3fde27ee91f8484b126 (diff) | |
download | u-boot-imx-8da601280a8acbc3385784780ed35130e53812f1.zip u-boot-imx-8da601280a8acbc3385784780ed35130e53812f1.tar.gz u-boot-imx-8da601280a8acbc3385784780ed35130e53812f1.tar.bz2 |
NAND: Add timeout for reset command
Without the timeout present an infinite loop can occur if the
NAND device is broken or not present.
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index bfa7874..d33fee2 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -75,6 +75,17 @@ #include <jffs2/jffs2.h> #endif +/* + * CONFIG_SYS_NAND_RESET_CNT is used as a timeout mechanism when resetting + * a flash. NAND flash is initialized prior to interrupts so standard timers + * can't be used. CONFIG_SYS_NAND_RESET_CNT should be set to a value + * which is greater than (max NAND reset time / NAND status read time). + * A conservative default of 200000 (500 us / 25 ns) is used as a default. + */ +#ifndef CONFIG_SYS_NAND_RESET_CNT +#define CONFIG_SYS_NAND_RESET_CNT 200000 +#endif + /* Define default oob placement schemes for large and small page devices */ static struct nand_ecclayout nand_oob_8 = { .eccbytes = 3, @@ -524,6 +535,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command, { register struct nand_chip *chip = mtd->priv; int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE; + uint32_t rst_sts_cnt = CONFIG_SYS_NAND_RESET_CNT; /* * Write out the command to the device. @@ -590,7 +602,8 @@ static void nand_command(struct mtd_info *mtd, unsigned int command, NAND_CTRL_CLE | NAND_CTRL_CHANGE); chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); - while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ; + while (!(chip->read_byte(mtd) & NAND_STATUS_READY) && + (rst_sts_cnt--)); return; /* This applies to read commands */ @@ -626,6 +639,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, int column, int page_addr) { register struct nand_chip *chip = mtd->priv; + uint32_t rst_sts_cnt = CONFIG_SYS_NAND_RESET_CNT; /* Emulate NAND_CMD_READOOB */ if (command == NAND_CMD_READOOB) { @@ -696,7 +710,8 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); - while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ; + while (!(chip->read_byte(mtd) & NAND_STATUS_READY) && + (rst_sts_cnt--)); return; case NAND_CMD_RNDOUT: |