summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/env_nand.c6
-rw-r--r--drivers/mtd/nand/nand.c4
-rw-r--r--drivers/mtd/nand/nand_base.c21
3 files changed, 27 insertions, 4 deletions
diff --git a/common/env_nand.c b/common/env_nand.c
index 8af9e74aac..e490775ecf 100644
--- a/common/env_nand.c
+++ b/common/env_nand.c
@@ -304,9 +304,11 @@ void env_relocate_spec (void)
crc1_ok = (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc);
crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc);
- if(!crc1_ok && !crc2_ok)
+ if(!crc1_ok && !crc2_ok) {
+ free(tmp_env1);
+ free(tmp_env2);
return use_default();
- else if(crc1_ok && !crc2_ok)
+ } else if(crc1_ok && !crc2_ok)
gd->env_valid = 1;
else if(!crc1_ok && crc2_ok)
gd->env_valid = 2;
diff --git a/drivers/mtd/nand/nand.c b/drivers/mtd/nand/nand.c
index cf9261786d..70b605f9d2 100644
--- a/drivers/mtd/nand/nand.c
+++ b/drivers/mtd/nand/nand.c
@@ -28,6 +28,8 @@
#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
#endif
+DECLARE_GLOBAL_DATA_PTR;
+
int nand_curr_device = -1;
nand_info_t nand_info[CONFIG_SYS_MAX_NAND_DEVICE];
@@ -46,6 +48,8 @@ static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,
if (nand_scan(mtd, 1) == 0) {
if (!mtd->name)
mtd->name = (char *)default_nand_name;
+ else
+ mtd->name += gd->reloc_off;
} else
mtd->name = NULL;
} else {
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index ef37f97b33..d33fee242f 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:
@@ -2618,7 +2633,9 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips)
type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id);
if (IS_ERR(type)) {
+#ifndef CONFIG_SYS_NAND_QUIET_TEST
printk(KERN_WARNING "No NAND device found!!!\n");
+#endif
chip->select_chip(mtd, -1);
return PTR_ERR(type);
}
OpenPOWER on IntegriCloud