diff options
author | Ben Dooks <ben-linux@fluff.org> | 2008-04-14 15:58:58 +0200 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2008-04-22 22:43:06 +0200 |
commit | ed8165c75e3dd0b2e51b92a858cabe29ba00c9cb (patch) | |
tree | f024e77b2449f7308b6453f70ee293c7e633697a | |
parent | [MTD] [NAND] S3C2410 Allow ECC disable to be specified by the board (diff) | |
download | linux-ed8165c75e3dd0b2e51b92a858cabe29ba00c9cb.tar.xz linux-ed8165c75e3dd0b2e51b92a858cabe29ba00c9cb.zip |
[MTD] [NAND] Verify probe by retrying to checking the results match
With modern systems using bus-hold instead of bus pull-up, it can
often lead to erroneous reporting of NAND devices where there are
none. Do a double probe to ensure that the result we got the first
time is repeatable, and if it is not then return that there is no
chip there.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 7acb1a0e7409..ba1bdf787323 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2229,6 +2229,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, { struct nand_flash_dev *type = NULL; int i, dev_id, maf_idx; + int tmp_id, tmp_manf; /* Select the device */ chip->select_chip(mtd, 0); @@ -2240,6 +2241,26 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, *maf_id = chip->read_byte(mtd); dev_id = chip->read_byte(mtd); + /* Try again to make sure, as some systems the bus-hold or other + * interface concerns can cause random data which looks like a + * possibly credible NAND flash to appear. If the two results do + * not match, ignore the device completely. + */ + + chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); + + /* Read manufacturer and device IDs */ + + tmp_manf = chip->read_byte(mtd); + tmp_id = chip->read_byte(mtd); + + if (tmp_manf != *maf_id || tmp_id != dev_id) { + printk(KERN_INFO "%s: second ID read did not match " + "%02x,%02x against %02x,%02x\n", __func__, + *maf_id, dev_id, tmp_manf, tmp_id); + return ERR_PTR(-ENODEV); + } + /* Lookup the flash id */ for (i = 0; nand_flash_ids[i].name != NULL; i++) { if (dev_id == nand_flash_ids[i].id) { |