From 7483096665161d2567c2717e001654ad653d944e Mon Sep 17 00:00:00 2001 From: Huang Shijie Date: Sun, 14 Oct 2012 23:47:24 -0400 Subject: mtd: use the NAND_STATUS_FAIL to replace the hardcode Use the NAND_STATUS_FAIL to replace the hardcode "0x01", which make the code more readable. Signed-off-by: Huang Shijie Acked-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/mtd/nand/nand_base.c') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 1a03b7f673ce..1d5c951ebcb0 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -899,7 +899,7 @@ static int __nand_unlock(struct mtd_info *mtd, loff_t ofs, /* Call wait ready function */ status = chip->waitfunc(mtd, chip); /* See if device thinks it succeeded */ - if (status & 0x01) { + if (status & NAND_STATUS_FAIL) { pr_debug("%s: error status = 0x%08x\n", __func__, status); ret = -EIO; @@ -1004,7 +1004,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) /* Call wait ready function */ status = chip->waitfunc(mtd, chip); /* See if device thinks it succeeded */ - if (status & 0x01) { + if (status & NAND_STATUS_FAIL) { pr_debug("%s: error status = 0x%08x\n", __func__, status); ret = -EIO; -- cgit v1.2.3 From f251b8dfdd0721255ea11751cdc282834e43b74e Mon Sep 17 00:00:00 2001 From: Matthieu CASTET Date: Mon, 5 Nov 2012 15:00:44 +0100 Subject: mtd: nand_wait: warn if the nand is busy on exit This patch allow to detect buggy driver/hardware with bad RnB (dev_ready) management or when timeout occurs in polling mode. This works when dev_ready is set or not set. There are 2 methods to wait for an erase/program command completion: 1. Wait until nand RnB pin goes high (that's what chip->dev_ready usually does) 2. Poll the device: send a status (0x70) command and read status byte in a loop until bit NAND_STATUS_READY is set In all cases, you should send a status command after completion, to check if the operation was successful. And if the operation completed, the status should have bit NAND_STATUS_READY set. Signed-off-by: Matthieu CASTET Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_base.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/mtd/nand/nand_base.c') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 1d5c951ebcb0..01505406ca7b 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -865,6 +865,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip) led_trigger_event(nand_led_trigger, LED_OFF); status = (int)chip->read_byte(mtd); + /* This can happen if in case of timeout or buggy dev_ready */ + WARN_ON(!(status & NAND_STATUS_READY)); return status; } -- cgit v1.2.3 From 07300164657526d8d26c626c43723c310fbf3616 Mon Sep 17 00:00:00 2001 From: Huang Shijie Date: Fri, 9 Nov 2012 16:23:45 +0800 Subject: mtd: de-select the chip when it is not used When we scan several nand chips with nand_scan(), such as ....................... nand_scan(*, 2); ....................... In nand_scan_ident(), the maxchips will become 2, so the current code will select chip 1 to read the device ID. But the chip 0 is still selected in this case. To make the logic clear, we'd better de-select the chip when it is not used. This patch de-select the nand chip if it is not used any more. Signed-off-by: Huang Shijie Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_base.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/mtd/nand/nand_base.c') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 01505406ca7b..95d56ed8500a 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3329,6 +3329,8 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, return PTR_ERR(type); } + chip->select_chip(mtd, -1); + /* Check for a chip array */ for (i = 1; i < maxchips; i++) { chip->select_chip(mtd, i); @@ -3338,8 +3340,11 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); /* Read manufacturer and device IDs */ if (nand_maf_id != chip->read_byte(mtd) || - nand_dev_id != chip->read_byte(mtd)) + nand_dev_id != chip->read_byte(mtd)) { + chip->select_chip(mtd, -1); break; + } + chip->select_chip(mtd, -1); } if (i > 1) pr_info("%d NAND chips detected\n", i); @@ -3598,9 +3603,6 @@ int nand_scan_tail(struct mtd_info *mtd) /* Initialize state */ chip->state = FL_READY; - /* De-select the device */ - chip->select_chip(mtd, -1); - /* Invalidate the pagebuffer reference */ chip->pagebuf = -1; -- cgit v1.2.3 From 064a7694b5347208febeb7aba7c90d38934ec8a1 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Fri, 9 Nov 2012 23:20:58 +0900 Subject: mtd: Fix typo mtd/tests Correct spelling typo in printk within drivers/mtd/tests. Signed-off-by: Masanari Iida Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_base.c | 2 +- drivers/mtd/tests/mtd_oobtest.c | 4 ++-- drivers/mtd/tests/mtd_pagetest.c | 2 +- drivers/mtd/tests/mtd_readtest.c | 2 +- drivers/mtd/tests/mtd_speedtest.c | 2 +- drivers/mtd/tests/mtd_stresstest.c | 2 +- drivers/mtd/tests/mtd_subpagetest.c | 2 +- drivers/mtd/tests/mtd_torturetest.c | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/mtd/nand/nand_base.c') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 95d56ed8500a..6eef7fbe8fdb 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -160,7 +160,7 @@ static uint8_t nand_read_byte(struct mtd_info *mtd) } /** - * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip + * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip * @mtd: MTD device structure * diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c index e86bb29419a2..e827fa8cd844 100644 --- a/drivers/mtd/tests/mtd_oobtest.c +++ b/drivers/mtd/tests/mtd_oobtest.c @@ -366,8 +366,8 @@ static int __init mtd_oobtest_init(void) printk(KERN_INFO "=================================================\n"); if (dev < 0) { - pr_info("Please specify a valid mtd-device via module paramter\n"); - pr_crit(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); + pr_info("Please specify a valid mtd-device via module parameter\n"); + pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } diff --git a/drivers/mtd/tests/mtd_pagetest.c b/drivers/mtd/tests/mtd_pagetest.c index 3ba2a77dbdaa..f93a76f88113 100644 --- a/drivers/mtd/tests/mtd_pagetest.c +++ b/drivers/mtd/tests/mtd_pagetest.c @@ -499,7 +499,7 @@ static int __init mtd_pagetest_init(void) printk(KERN_INFO "=================================================\n"); if (dev < 0) { - pr_info("Please specify a valid mtd-device via module paramter\n"); + pr_info("Please specify a valid mtd-device via module parameter\n"); pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } diff --git a/drivers/mtd/tests/mtd_readtest.c b/drivers/mtd/tests/mtd_readtest.c index ec3efb53826c..31f505cc942a 100644 --- a/drivers/mtd/tests/mtd_readtest.c +++ b/drivers/mtd/tests/mtd_readtest.c @@ -171,7 +171,7 @@ static int __init mtd_readtest_init(void) printk(KERN_INFO "=================================================\n"); if (dev < 0) { - pr_info("Please specify a valid mtd-device via module paramter\n"); + pr_info("Please specify a valid mtd-device via module parameter\n"); return -EINVAL; } diff --git a/drivers/mtd/tests/mtd_speedtest.c b/drivers/mtd/tests/mtd_speedtest.c index 8a5803b1724c..596cbea8df4c 100644 --- a/drivers/mtd/tests/mtd_speedtest.c +++ b/drivers/mtd/tests/mtd_speedtest.c @@ -351,7 +351,7 @@ static int __init mtd_speedtest_init(void) printk(KERN_INFO "=================================================\n"); if (dev < 0) { - pr_info("Please specify a valid mtd-device via module paramter\n"); + pr_info("Please specify a valid mtd-device via module parameter\n"); pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } diff --git a/drivers/mtd/tests/mtd_stresstest.c b/drivers/mtd/tests/mtd_stresstest.c index fea1dd78ccbe..3729f679ae5d 100644 --- a/drivers/mtd/tests/mtd_stresstest.c +++ b/drivers/mtd/tests/mtd_stresstest.c @@ -231,7 +231,7 @@ static int __init mtd_stresstest_init(void) printk(KERN_INFO "=================================================\n"); if (dev < 0) { - pr_info("Please specify a valid mtd-device via module paramter\n"); + pr_info("Please specify a valid mtd-device via module parameter\n"); pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } diff --git a/drivers/mtd/tests/mtd_subpagetest.c b/drivers/mtd/tests/mtd_subpagetest.c index 8813b0e86637..c880c2229c59 100644 --- a/drivers/mtd/tests/mtd_subpagetest.c +++ b/drivers/mtd/tests/mtd_subpagetest.c @@ -377,7 +377,7 @@ static int __init mtd_subpagetest_init(void) printk(KERN_INFO "=================================================\n"); if (dev < 0) { - pr_info("Please specify a valid mtd-device via module paramter\n"); + pr_info("Please specify a valid mtd-device via module parameter\n"); pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } diff --git a/drivers/mtd/tests/mtd_torturetest.c b/drivers/mtd/tests/mtd_torturetest.c index 98d2a820625f..c4cde1e9eddb 100644 --- a/drivers/mtd/tests/mtd_torturetest.c +++ b/drivers/mtd/tests/mtd_torturetest.c @@ -216,7 +216,7 @@ static int __init tort_init(void) "flash, stop it if this is not wanted.\n"); if (dev < 0) { - pr_info("Please specify a valid mtd-device via module paramter\n"); + pr_info("Please specify a valid mtd-device via module parameter\n"); pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } -- cgit v1.2.3 From b0bb6903c8fca2d5ebef1f8ae63d420eb931bb1e Mon Sep 17 00:00:00 2001 From: Huang Shijie Date: Mon, 19 Nov 2012 14:43:29 +0800 Subject: mtd: remove the de-select chip code in nand_release_device() The nand_get_device() does not select the chip, but nand_release_device() does de-select the chip. It is really strange. With the current code, nand_sync() will de-select the chip, even if the chip has never been selected. To make the balance of select/de-select chip, it's better to remove the de-select chip code in nand_release_device() which makes the code more clear. Signed-off-by: Huang Shijie Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_base.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'drivers/mtd/nand/nand_base.c') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 6eef7fbe8fdb..861a87d4d16b 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -130,15 +130,12 @@ static int check_offs_len(struct mtd_info *mtd, * nand_release_device - [GENERIC] release chip * @mtd: MTD device structure * - * Deselect, release chip lock and wake up anyone waiting on the device. + * Release chip lock and wake up anyone waiting on the device. */ static void nand_release_device(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; - /* De-select the NAND device */ - chip->select_chip(mtd, -1); - /* Release the controller and the chip */ spin_lock(&chip->controller->lock); chip->controller->active = NULL; @@ -333,8 +330,10 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) i++; } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE)); - if (getchip) + if (getchip) { + chip->select_chip(mtd, -1); nand_release_device(mtd); + } return res; } @@ -952,6 +951,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) ret = __nand_unlock(mtd, ofs, len, 0); out: + chip->select_chip(mtd, -1); nand_release_device(mtd); return ret; @@ -1016,6 +1016,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) ret = __nand_unlock(mtd, ofs, len, 0x1); out: + chip->select_chip(mtd, -1); nand_release_device(mtd); return ret; @@ -1552,6 +1553,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, chip->select_chip(mtd, chipnr); } } + chip->select_chip(mtd, -1); ops->retlen = ops->len - (size_t) readlen; if (oob) @@ -1806,6 +1808,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, chip->select_chip(mtd, chipnr); } } + chip->select_chip(mtd, -1); ops->oobretlen = ops->ooblen - readlen; @@ -2188,8 +2191,10 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, chip->select_chip(mtd, chipnr); /* Check, if it is write protected */ - if (nand_check_wp(mtd)) - return -EIO; + if (nand_check_wp(mtd)) { + ret = -EIO; + goto err_out; + } realpage = (int)(to >> chip->page_shift); page = realpage & chip->pagemask; @@ -2201,8 +2206,10 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, chip->pagebuf = -1; /* Don't allow multipage oob writes with offset */ - if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) - return -EINVAL; + if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) { + ret = -EINVAL; + goto err_out; + } while (1) { int bytes = mtd->writesize; @@ -2253,6 +2260,9 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, ops->retlen = ops->len - writelen; if (unlikely(oob)) ops->oobretlen = ops->ooblen; + +err_out: + chip->select_chip(mtd, -1); return ret; } @@ -2379,8 +2389,10 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); /* Check, if it is write protected */ - if (nand_check_wp(mtd)) + if (nand_check_wp(mtd)) { + chip->select_chip(mtd, -1); return -EROFS; + } /* Invalidate the page cache, if we write to the cached page */ if (page == chip->pagebuf) @@ -2393,6 +2405,8 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, else status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); + chip->select_chip(mtd, -1); + if (status) return status; @@ -2625,6 +2639,7 @@ erase_exit: ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; /* Deselect and wake up anyone waiting on the device */ + chip->select_chip(mtd, -1); nand_release_device(mtd); /* Do call back function */ -- cgit v1.2.3 From 6a8214aa3d323d2e185523ea112116759bc3c5ce Mon Sep 17 00:00:00 2001 From: Huang Shijie Date: Mon, 19 Nov 2012 14:43:30 +0800 Subject: mtd: remove the "chip" parameter in nand_get_device() There are two reasons to remove the "chip" parameter in nand_get_device(): [1] The nand_release_device() does not have the "chip" parameter. [2] We can get the nand_chip by the mtd->priv field. This patch removes the "chip" parameter in nand_get_device(). Signed-off-by: Huang Shijie Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_base.c | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) (limited to 'drivers/mtd/nand/nand_base.c') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 861a87d4d16b..55c2883af406 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -93,8 +93,7 @@ static struct nand_ecclayout nand_oob_128 = { .length = 78} } }; -static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, - int new_state); +static int nand_get_device(struct mtd_info *mtd, int new_state); static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops); @@ -300,7 +299,7 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) if (getchip) { chipnr = (int)(ofs >> chip->chip_shift); - nand_get_device(chip, mtd, FL_READING); + nand_get_device(mtd, FL_READING); /* Select the NAND device */ chip->select_chip(mtd, chipnr); @@ -382,7 +381,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) struct mtd_oob_ops ops; loff_t wr_ofs = ofs; - nand_get_device(chip, mtd, FL_WRITING); + nand_get_device(mtd, FL_WRITING); ops.datbuf = NULL; ops.oobbuf = buf; @@ -749,15 +748,15 @@ static void panic_nand_get_device(struct nand_chip *chip, /** * nand_get_device - [GENERIC] Get chip for selected access - * @chip: the nand chip descriptor * @mtd: MTD device structure * @new_state: the state which is requested * * Get the device and lock it for exclusive access */ static int -nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state) +nand_get_device(struct mtd_info *mtd, int new_state) { + struct nand_chip *chip = mtd->priv; spinlock_t *lock = &chip->controller->lock; wait_queue_head_t *wq = &chip->controller->wq; DECLARE_WAITQUEUE(wait, current); @@ -933,7 +932,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (ofs + len == mtd->size) len -= mtd->erasesize; - nand_get_device(chip, mtd, FL_UNLOCKING); + nand_get_device(mtd, FL_UNLOCKING); /* Shift to get chip number */ chipnr = ofs >> chip->chip_shift; @@ -983,7 +982,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (check_offs_len(mtd, ofs, len)) ret = -EINVAL; - nand_get_device(chip, mtd, FL_LOCKING); + nand_get_device(mtd, FL_LOCKING); /* Shift to get chip number */ chipnr = ofs >> chip->chip_shift; @@ -1581,11 +1580,10 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, uint8_t *buf) { - struct nand_chip *chip = mtd->priv; struct mtd_oob_ops ops; int ret; - nand_get_device(chip, mtd, FL_READING); + nand_get_device(mtd, FL_READING); ops.len = len; ops.datbuf = buf; ops.oobbuf = NULL; @@ -1832,7 +1830,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, static int nand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { - struct nand_chip *chip = mtd->priv; int ret = -ENOTSUPP; ops->retlen = 0; @@ -1844,7 +1841,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from, return -EINVAL; } - nand_get_device(chip, mtd, FL_READING); + nand_get_device(mtd, FL_READING); switch (ops->mode) { case MTD_OPS_PLACE_OOB: @@ -2314,11 +2311,10 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len, static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const uint8_t *buf) { - struct nand_chip *chip = mtd->priv; struct mtd_oob_ops ops; int ret; - nand_get_device(chip, mtd, FL_WRITING); + nand_get_device(mtd, FL_WRITING); ops.len = len; ops.datbuf = (uint8_t *)buf; ops.oobbuf = NULL; @@ -2424,7 +2420,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, static int nand_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) { - struct nand_chip *chip = mtd->priv; int ret = -ENOTSUPP; ops->retlen = 0; @@ -2436,7 +2431,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, return -EINVAL; } - nand_get_device(chip, mtd, FL_WRITING); + nand_get_device(mtd, FL_WRITING); switch (ops->mode) { case MTD_OPS_PLACE_OOB: @@ -2529,7 +2524,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, return -EINVAL; /* Grab the lock and see if the device is available */ - nand_get_device(chip, mtd, FL_ERASING); + nand_get_device(mtd, FL_ERASING); /* Shift to get first page */ page = (int)(instr->addr >> chip->page_shift); @@ -2675,12 +2670,10 @@ erase_exit: */ static void nand_sync(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; - pr_debug("%s: called\n", __func__); /* Grab the lock and see if the device is available */ - nand_get_device(chip, mtd, FL_SYNCING); + nand_get_device(mtd, FL_SYNCING); /* Release it and go back */ nand_release_device(mtd); } @@ -2766,9 +2759,7 @@ static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip, */ static int nand_suspend(struct mtd_info *mtd) { - struct nand_chip *chip = mtd->priv; - - return nand_get_device(chip, mtd, FL_PM_SUSPENDED); + return nand_get_device(mtd, FL_PM_SUSPENDED); } /** -- cgit v1.2.3 From ca6a24893073414c549920d93bac57d46d7f3e1e Mon Sep 17 00:00:00 2001 From: Matthieu CASTET Date: Thu, 22 Nov 2012 18:31:28 +0100 Subject: mted: nand_wait_ready timeout fix nand_wait_ready timeout should not assume HZ=100. Make it independent of HZ value by using msecs_to_jiffies. Signed-off-by: Matthieu CASTET Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd/nand/nand_base.c') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 55c2883af406..7738432c62dd 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -490,7 +490,7 @@ static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo) void nand_wait_ready(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; - unsigned long timeo = jiffies + 2; + unsigned long timeo = jiffies + msecs_to_jiffies(20); /* 400ms timeout */ if (in_interrupt() || oops_in_progress) -- cgit v1.2.3 From 2fd71a294a0aac407ec69e04916dc28eb39c8ac0 Mon Sep 17 00:00:00 2001 From: Matthieu CASTET Date: Thu, 22 Nov 2012 18:33:40 +0100 Subject: mtd: nand: print flash size during detection This help to detect bad flash identification in case the size is not present on the name (ONFI). Signed-off-by: Matthieu CASTET Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/mtd/nand/nand_base.c') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 7738432c62dd..6f58e1633e2f 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3293,10 +3293,10 @@ ident_done: chip->cmdfunc = nand_command_lp; pr_info("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s)," - " page size: %d, OOB size: %d\n", + " %dMiB, page size: %d, OOB size: %d\n", *maf_id, *dev_id, nand_manuf_ids[maf_idx].name, chip->onfi_version ? chip->onfi_params.model : type->name, - mtd->writesize, mtd->oobsize); + (int)(chip->chipsize >> 20), mtd->writesize, mtd->oobsize); return type; } -- cgit v1.2.3 From 64b37b2a63eb2f80b65c7185f0013f8ffc637ae3 Mon Sep 17 00:00:00 2001 From: Matthieu CASTET Date: Tue, 6 Nov 2012 11:51:44 +0100 Subject: mtd: nand: add NAND_BUSWIDTH_AUTO to autodetect bus width The driver call nand_scan_ident in 8 bit mode, then readid or onfi detection are done (and detect bus width). The driver should update its bus width before calling nand_scan_tail. This work because readid and onfi are read work 8 byte mode. Note that nand_scan_ident send command (NAND_CMD_RESET, NAND_CMD_READID, NAND_CMD_PARAM), address and read data The ONFI specificication is not very clear for x16 device if high byte of address should be driven to 0, but according to [1] it should be ok to not drive it during autodetection. [1] 3.3.2. Target Initialization [...] The Read ID and Read Parameter Page commands only use the lower 8-bits of the data bus. The host shall not issue commands that use a word data width on x16 devices until the host determines the device supports a 16-bit data bus width in the parameter page. Signed-off-by: Matthieu CASTET Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_base.c | 14 +++++++++----- include/linux/mtd/nand.h | 7 +++++++ 2 files changed, 16 insertions(+), 5 deletions(-) (limited to 'drivers/mtd/nand/nand_base.c') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 6f58e1633e2f..5851c51ac2df 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3250,11 +3250,15 @@ ident_done: break; } - /* - * Check, if buswidth is correct. Hardware drivers should set - * chip correct! - */ - if (busw != (chip->options & NAND_BUSWIDTH_16)) { + if (chip->options & NAND_BUSWIDTH_AUTO) { + WARN_ON(chip->options & NAND_BUSWIDTH_16); + chip->options |= busw; + nand_set_defaults(chip, busw); + } else if (busw != (chip->options & NAND_BUSWIDTH_16)) { + /* + * Check, if buswidth is correct. Hardware drivers should set + * chip correct! + */ pr_info("NAND device: Manufacturer ID:" " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id, nand_manuf_ids[maf_idx].name, mtd->name); diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 9d8a6048aacd..7ccb3c59ed60 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -219,6 +219,13 @@ typedef enum { #define NAND_OWN_BUFFERS 0x00020000 /* Chip may not exist, so silence any errors in scan */ #define NAND_SCAN_SILENT_NODEV 0x00040000 +/* + * Autodetect nand buswidth with readid/onfi. + * This suppose the driver will configure the hardware in 8 bits mode + * when calling nand_scan_ident, and update its configuration + * before calling nand_scan_tail. + */ +#define NAND_BUSWIDTH_AUTO 0x00080000 /* Options set by nand scan */ /* Nand scan has allocated controller struct */ -- cgit v1.2.3 From ff3206b2450499203532af2505a7f6f8413e92c0 Mon Sep 17 00:00:00 2001 From: Matthieu CASTET Date: Tue, 6 Nov 2012 11:51:43 +0100 Subject: mtd: nand: onfi need to be probed in 8 bits mode - NAND_CMD_READID want an address that it is not scaled on x16 device (it is always 0x20) - NAND_CMD_PARAM want 8 bits data Signed-off-by: Matthieu CASTET Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_base.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/mtd/nand/nand_base.c') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 5851c51ac2df..0ac49ca58524 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2857,6 +2857,8 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, int i; int val; + /* ONFI need to be probed in 8 bits mode */ + WARN_ON(chip->options & NAND_BUSWIDTH_16); /* Try ONFI for unknown chip or LP */ chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1); if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' || -- cgit v1.2.3 From d4d4f1bf6a343b25220fdcdf559fd593dd3e25a7 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 14 Nov 2012 21:54:20 -0800 Subject: mtd: nand: typo in nand_id_has_period() comments The simple example provided in the comments for nand_id_has_period() actually has a period of 3, not 2. Silly mistake... Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd/nand/nand_base.c') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 0ac49ca58524..8323ac991ad1 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2923,7 +2923,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, * * Check if an ID string is repeated within a given sequence of bytes at * specific repetition interval period (e.g., {0x20,0x01,0x7F,0x20} has a - * period of 2). This is a helper function for nand_id_len(). Returns non-zero + * period of 3). This is a helper function for nand_id_len(). Returns non-zero * if the repetition has a period of @period; otherwise, returns zero. */ static int nand_id_has_period(u8 *id_data, int arrlen, int period) -- cgit v1.2.3