diff options
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 172 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_bbt.c | 2 | ||||
-rw-r--r-- | drivers/mtd/onenand/Kconfig | 6 | ||||
-rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 154 |
4 files changed, 242 insertions, 92 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 975b2ef61121..baece61169f4 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -415,7 +415,7 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, | |||
415 | * Wait for the ready pin, after a command | 415 | * Wait for the ready pin, after a command |
416 | * The timeout is catched later. | 416 | * The timeout is catched later. |
417 | */ | 417 | */ |
418 | static void nand_wait_ready(struct mtd_info *mtd) | 418 | void nand_wait_ready(struct mtd_info *mtd) |
419 | { | 419 | { |
420 | struct nand_chip *chip = mtd->priv; | 420 | struct nand_chip *chip = mtd->priv; |
421 | unsigned long timeo = jiffies + 2; | 421 | unsigned long timeo = jiffies + 2; |
@@ -429,6 +429,7 @@ static void nand_wait_ready(struct mtd_info *mtd) | |||
429 | } while (time_before(jiffies, timeo)); | 429 | } while (time_before(jiffies, timeo)); |
430 | led_trigger_event(nand_led_trigger, LED_OFF); | 430 | led_trigger_event(nand_led_trigger, LED_OFF); |
431 | } | 431 | } |
432 | EXPORT_SYMBOL_GPL(nand_wait_ready); | ||
432 | 433 | ||
433 | /** | 434 | /** |
434 | * nand_command - [DEFAULT] Send command to NAND device | 435 | * nand_command - [DEFAULT] Send command to NAND device |
@@ -766,8 +767,8 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
766 | int eccbytes = chip->ecc.bytes; | 767 | int eccbytes = chip->ecc.bytes; |
767 | int eccsteps = chip->ecc.steps; | 768 | int eccsteps = chip->ecc.steps; |
768 | uint8_t *p = buf; | 769 | uint8_t *p = buf; |
769 | uint8_t *ecc_calc = chip->buffers.ecccalc; | 770 | uint8_t *ecc_calc = chip->buffers->ecccalc; |
770 | uint8_t *ecc_code = chip->buffers.ecccode; | 771 | uint8_t *ecc_code = chip->buffers->ecccode; |
771 | int *eccpos = chip->ecc.layout->eccpos; | 772 | int *eccpos = chip->ecc.layout->eccpos; |
772 | 773 | ||
773 | nand_read_page_raw(mtd, chip, buf); | 774 | nand_read_page_raw(mtd, chip, buf); |
@@ -808,8 +809,8 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
808 | int eccbytes = chip->ecc.bytes; | 809 | int eccbytes = chip->ecc.bytes; |
809 | int eccsteps = chip->ecc.steps; | 810 | int eccsteps = chip->ecc.steps; |
810 | uint8_t *p = buf; | 811 | uint8_t *p = buf; |
811 | uint8_t *ecc_calc = chip->buffers.ecccalc; | 812 | uint8_t *ecc_calc = chip->buffers->ecccalc; |
812 | uint8_t *ecc_code = chip->buffers.ecccode; | 813 | uint8_t *ecc_code = chip->buffers->ecccode; |
813 | int *eccpos = chip->ecc.layout->eccpos; | 814 | int *eccpos = chip->ecc.layout->eccpos; |
814 | 815 | ||
815 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { | 816 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { |
@@ -970,7 +971,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
970 | page = realpage & chip->pagemask; | 971 | page = realpage & chip->pagemask; |
971 | 972 | ||
972 | col = (int)(from & (mtd->writesize - 1)); | 973 | col = (int)(from & (mtd->writesize - 1)); |
973 | chip->oob_poi = chip->buffers.oobrbuf; | 974 | chip->oob_poi = chip->buffers->oobrbuf; |
974 | 975 | ||
975 | buf = ops->datbuf; | 976 | buf = ops->datbuf; |
976 | oob = ops->oobbuf; | 977 | oob = ops->oobbuf; |
@@ -981,7 +982,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
981 | 982 | ||
982 | /* Is the current page in the buffer ? */ | 983 | /* Is the current page in the buffer ? */ |
983 | if (realpage != chip->pagebuf || oob) { | 984 | if (realpage != chip->pagebuf || oob) { |
984 | bufpoi = aligned ? buf : chip->buffers.databuf; | 985 | bufpoi = aligned ? buf : chip->buffers->databuf; |
985 | 986 | ||
986 | if (likely(sndcmd)) { | 987 | if (likely(sndcmd)) { |
987 | chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); | 988 | chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); |
@@ -989,14 +990,17 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
989 | } | 990 | } |
990 | 991 | ||
991 | /* Now read the page into the buffer */ | 992 | /* Now read the page into the buffer */ |
992 | ret = chip->ecc.read_page(mtd, chip, bufpoi); | 993 | if (unlikely(ops->mode == MTD_OOB_RAW)) |
994 | ret = chip->ecc.read_page_raw(mtd, chip, bufpoi); | ||
995 | else | ||
996 | ret = chip->ecc.read_page(mtd, chip, bufpoi); | ||
993 | if (ret < 0) | 997 | if (ret < 0) |
994 | break; | 998 | break; |
995 | 999 | ||
996 | /* Transfer not aligned data */ | 1000 | /* Transfer not aligned data */ |
997 | if (!aligned) { | 1001 | if (!aligned) { |
998 | chip->pagebuf = realpage; | 1002 | chip->pagebuf = realpage; |
999 | memcpy(buf, chip->buffers.databuf + col, bytes); | 1003 | memcpy(buf, chip->buffers->databuf + col, bytes); |
1000 | } | 1004 | } |
1001 | 1005 | ||
1002 | buf += bytes; | 1006 | buf += bytes; |
@@ -1023,7 +1027,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
1023 | nand_wait_ready(mtd); | 1027 | nand_wait_ready(mtd); |
1024 | } | 1028 | } |
1025 | } else { | 1029 | } else { |
1026 | memcpy(buf, chip->buffers.databuf + col, bytes); | 1030 | memcpy(buf, chip->buffers->databuf + col, bytes); |
1027 | buf += bytes; | 1031 | buf += bytes; |
1028 | } | 1032 | } |
1029 | 1033 | ||
@@ -1266,7 +1270,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, | |||
1266 | realpage = (int)(from >> chip->page_shift); | 1270 | realpage = (int)(from >> chip->page_shift); |
1267 | page = realpage & chip->pagemask; | 1271 | page = realpage & chip->pagemask; |
1268 | 1272 | ||
1269 | chip->oob_poi = chip->buffers.oobrbuf; | 1273 | chip->oob_poi = chip->buffers->oobrbuf; |
1270 | 1274 | ||
1271 | while(1) { | 1275 | while(1) { |
1272 | sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); | 1276 | sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); |
@@ -1322,8 +1326,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, | |||
1322 | static int nand_read_oob(struct mtd_info *mtd, loff_t from, | 1326 | static int nand_read_oob(struct mtd_info *mtd, loff_t from, |
1323 | struct mtd_oob_ops *ops) | 1327 | struct mtd_oob_ops *ops) |
1324 | { | 1328 | { |
1325 | int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip, | ||
1326 | uint8_t *buf) = NULL; | ||
1327 | struct nand_chip *chip = mtd->priv; | 1329 | struct nand_chip *chip = mtd->priv; |
1328 | int ret = -ENOTSUPP; | 1330 | int ret = -ENOTSUPP; |
1329 | 1331 | ||
@@ -1341,12 +1343,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from, | |||
1341 | switch(ops->mode) { | 1343 | switch(ops->mode) { |
1342 | case MTD_OOB_PLACE: | 1344 | case MTD_OOB_PLACE: |
1343 | case MTD_OOB_AUTO: | 1345 | case MTD_OOB_AUTO: |
1344 | break; | ||
1345 | |||
1346 | case MTD_OOB_RAW: | 1346 | case MTD_OOB_RAW: |
1347 | /* Replace the read_page algorithm temporary */ | ||
1348 | read_page = chip->ecc.read_page; | ||
1349 | chip->ecc.read_page = nand_read_page_raw; | ||
1350 | break; | 1347 | break; |
1351 | 1348 | ||
1352 | default: | 1349 | default: |
@@ -1358,8 +1355,6 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from, | |||
1358 | else | 1355 | else |
1359 | ret = nand_do_read_ops(mtd, from, ops); | 1356 | ret = nand_do_read_ops(mtd, from, ops); |
1360 | 1357 | ||
1361 | if (unlikely(ops->mode == MTD_OOB_RAW)) | ||
1362 | chip->ecc.read_page = read_page; | ||
1363 | out: | 1358 | out: |
1364 | nand_release_device(mtd); | 1359 | nand_release_device(mtd); |
1365 | return ret; | 1360 | return ret; |
@@ -1391,7 +1386,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1391 | int i, eccsize = chip->ecc.size; | 1386 | int i, eccsize = chip->ecc.size; |
1392 | int eccbytes = chip->ecc.bytes; | 1387 | int eccbytes = chip->ecc.bytes; |
1393 | int eccsteps = chip->ecc.steps; | 1388 | int eccsteps = chip->ecc.steps; |
1394 | uint8_t *ecc_calc = chip->buffers.ecccalc; | 1389 | uint8_t *ecc_calc = chip->buffers->ecccalc; |
1395 | const uint8_t *p = buf; | 1390 | const uint8_t *p = buf; |
1396 | int *eccpos = chip->ecc.layout->eccpos; | 1391 | int *eccpos = chip->ecc.layout->eccpos; |
1397 | 1392 | ||
@@ -1417,7 +1412,7 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1417 | int i, eccsize = chip->ecc.size; | 1412 | int i, eccsize = chip->ecc.size; |
1418 | int eccbytes = chip->ecc.bytes; | 1413 | int eccbytes = chip->ecc.bytes; |
1419 | int eccsteps = chip->ecc.steps; | 1414 | int eccsteps = chip->ecc.steps; |
1420 | uint8_t *ecc_calc = chip->buffers.ecccalc; | 1415 | uint8_t *ecc_calc = chip->buffers->ecccalc; |
1421 | const uint8_t *p = buf; | 1416 | const uint8_t *p = buf; |
1422 | int *eccpos = chip->ecc.layout->eccpos; | 1417 | int *eccpos = chip->ecc.layout->eccpos; |
1423 | 1418 | ||
@@ -1478,7 +1473,7 @@ static void nand_write_page_syndrome(struct mtd_info *mtd, | |||
1478 | } | 1473 | } |
1479 | 1474 | ||
1480 | /** | 1475 | /** |
1481 | * nand_write_page - [INTERNAL] write one page | 1476 | * nand_write_page - [REPLACEABLE] write one page |
1482 | * @mtd: MTD device structure | 1477 | * @mtd: MTD device structure |
1483 | * @chip: NAND chip descriptor | 1478 | * @chip: NAND chip descriptor |
1484 | * @buf: the data to write | 1479 | * @buf: the data to write |
@@ -1486,13 +1481,16 @@ static void nand_write_page_syndrome(struct mtd_info *mtd, | |||
1486 | * @cached: cached programming | 1481 | * @cached: cached programming |
1487 | */ | 1482 | */ |
1488 | static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, | 1483 | static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
1489 | const uint8_t *buf, int page, int cached) | 1484 | const uint8_t *buf, int page, int cached, int raw) |
1490 | { | 1485 | { |
1491 | int status; | 1486 | int status; |
1492 | 1487 | ||
1493 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); | 1488 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); |
1494 | 1489 | ||
1495 | chip->ecc.write_page(mtd, chip, buf); | 1490 | if (unlikely(raw)) |
1491 | chip->ecc.write_page_raw(mtd, chip, buf); | ||
1492 | else | ||
1493 | chip->ecc.write_page(mtd, chip, buf); | ||
1496 | 1494 | ||
1497 | /* | 1495 | /* |
1498 | * Cached progamming disabled for now, Not sure if its worth the | 1496 | * Cached progamming disabled for now, Not sure if its worth the |
@@ -1627,7 +1625,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
1627 | (chip->pagebuf << chip->page_shift) < (to + ops->len)) | 1625 | (chip->pagebuf << chip->page_shift) < (to + ops->len)) |
1628 | chip->pagebuf = -1; | 1626 | chip->pagebuf = -1; |
1629 | 1627 | ||
1630 | chip->oob_poi = chip->buffers.oobwbuf; | 1628 | chip->oob_poi = chip->buffers->oobwbuf; |
1631 | 1629 | ||
1632 | while(1) { | 1630 | while(1) { |
1633 | int cached = writelen > bytes && page != blockmask; | 1631 | int cached = writelen > bytes && page != blockmask; |
@@ -1635,7 +1633,8 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
1635 | if (unlikely(oob)) | 1633 | if (unlikely(oob)) |
1636 | oob = nand_fill_oob(chip, oob, ops); | 1634 | oob = nand_fill_oob(chip, oob, ops); |
1637 | 1635 | ||
1638 | ret = nand_write_page(mtd, chip, buf, page, cached); | 1636 | ret = chip->write_page(mtd, chip, buf, page, cached, |
1637 | (ops->mode == MTD_OOB_RAW)); | ||
1639 | if (ret) | 1638 | if (ret) |
1640 | break; | 1639 | break; |
1641 | 1640 | ||
@@ -1745,7 +1744,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, | |||
1745 | if (page == chip->pagebuf) | 1744 | if (page == chip->pagebuf) |
1746 | chip->pagebuf = -1; | 1745 | chip->pagebuf = -1; |
1747 | 1746 | ||
1748 | chip->oob_poi = chip->buffers.oobwbuf; | 1747 | chip->oob_poi = chip->buffers->oobwbuf; |
1749 | memset(chip->oob_poi, 0xff, mtd->oobsize); | 1748 | memset(chip->oob_poi, 0xff, mtd->oobsize); |
1750 | nand_fill_oob(chip, ops->oobbuf, ops); | 1749 | nand_fill_oob(chip, ops->oobbuf, ops); |
1751 | status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); | 1750 | status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); |
@@ -1768,8 +1767,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, | |||
1768 | static int nand_write_oob(struct mtd_info *mtd, loff_t to, | 1767 | static int nand_write_oob(struct mtd_info *mtd, loff_t to, |
1769 | struct mtd_oob_ops *ops) | 1768 | struct mtd_oob_ops *ops) |
1770 | { | 1769 | { |
1771 | void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, | ||
1772 | const uint8_t *buf) = NULL; | ||
1773 | struct nand_chip *chip = mtd->priv; | 1770 | struct nand_chip *chip = mtd->priv; |
1774 | int ret = -ENOTSUPP; | 1771 | int ret = -ENOTSUPP; |
1775 | 1772 | ||
@@ -1787,12 +1784,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, | |||
1787 | switch(ops->mode) { | 1784 | switch(ops->mode) { |
1788 | case MTD_OOB_PLACE: | 1785 | case MTD_OOB_PLACE: |
1789 | case MTD_OOB_AUTO: | 1786 | case MTD_OOB_AUTO: |
1790 | break; | ||
1791 | |||
1792 | case MTD_OOB_RAW: | 1787 | case MTD_OOB_RAW: |
1793 | /* Replace the write_page algorithm temporary */ | ||
1794 | write_page = chip->ecc.write_page; | ||
1795 | chip->ecc.write_page = nand_write_page_raw; | ||
1796 | break; | 1788 | break; |
1797 | 1789 | ||
1798 | default: | 1790 | default: |
@@ -1804,8 +1796,6 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, | |||
1804 | else | 1796 | else |
1805 | ret = nand_do_write_ops(mtd, to, ops); | 1797 | ret = nand_do_write_ops(mtd, to, ops); |
1806 | 1798 | ||
1807 | if (unlikely(ops->mode == MTD_OOB_RAW)) | ||
1808 | chip->ecc.write_page = write_page; | ||
1809 | out: | 1799 | out: |
1810 | nand_release_device(mtd); | 1800 | nand_release_device(mtd); |
1811 | return ret; | 1801 | return ret; |
@@ -2288,40 +2278,22 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2288 | return type; | 2278 | return type; |
2289 | } | 2279 | } |
2290 | 2280 | ||
2291 | /* module_text_address() isn't exported, and it's mostly a pointless | ||
2292 | test if this is a module _anyway_ -- they'd have to try _really_ hard | ||
2293 | to call us from in-kernel code if the core NAND support is modular. */ | ||
2294 | #ifdef MODULE | ||
2295 | #define caller_is_module() (1) | ||
2296 | #else | ||
2297 | #define caller_is_module() \ | ||
2298 | module_text_address((unsigned long)__builtin_return_address(0)) | ||
2299 | #endif | ||
2300 | |||
2301 | /** | 2281 | /** |
2302 | * nand_scan - [NAND Interface] Scan for the NAND device | 2282 | * nand_scan_ident - [NAND Interface] Scan for the NAND device |
2303 | * @mtd: MTD device structure | 2283 | * @mtd: MTD device structure |
2304 | * @maxchips: Number of chips to scan for | 2284 | * @maxchips: Number of chips to scan for |
2305 | * | 2285 | * |
2306 | * This fills out all the uninitialized function pointers | 2286 | * This is the first phase of the normal nand_scan() function. It |
2307 | * with the defaults. | 2287 | * reads the flash ID and sets up MTD fields accordingly. |
2308 | * The flash ID is read and the mtd/chip structures are | ||
2309 | * filled with the appropriate values. | ||
2310 | * The mtd->owner field must be set to the module of the caller | ||
2311 | * | 2288 | * |
2289 | * The mtd->owner field must be set to the module of the caller. | ||
2312 | */ | 2290 | */ |
2313 | int nand_scan(struct mtd_info *mtd, int maxchips) | 2291 | int nand_scan_ident(struct mtd_info *mtd, int maxchips) |
2314 | { | 2292 | { |
2315 | int i, busw, nand_maf_id; | 2293 | int i, busw, nand_maf_id; |
2316 | struct nand_chip *chip = mtd->priv; | 2294 | struct nand_chip *chip = mtd->priv; |
2317 | struct nand_flash_dev *type; | 2295 | struct nand_flash_dev *type; |
2318 | 2296 | ||
2319 | /* Many callers got this wrong, so check for it for a while... */ | ||
2320 | if (!mtd->owner && caller_is_module()) { | ||
2321 | printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n"); | ||
2322 | BUG(); | ||
2323 | } | ||
2324 | |||
2325 | /* Get buswidth to select the correct functions */ | 2297 | /* Get buswidth to select the correct functions */ |
2326 | busw = chip->options & NAND_BUSWIDTH_16; | 2298 | busw = chip->options & NAND_BUSWIDTH_16; |
2327 | /* Set the default functions */ | 2299 | /* Set the default functions */ |
@@ -2353,8 +2325,31 @@ int nand_scan(struct mtd_info *mtd, int maxchips) | |||
2353 | chip->numchips = i; | 2325 | chip->numchips = i; |
2354 | mtd->size = i * chip->chipsize; | 2326 | mtd->size = i * chip->chipsize; |
2355 | 2327 | ||
2328 | return 0; | ||
2329 | } | ||
2330 | |||
2331 | |||
2332 | /** | ||
2333 | * nand_scan_tail - [NAND Interface] Scan for the NAND device | ||
2334 | * @mtd: MTD device structure | ||
2335 | * @maxchips: Number of chips to scan for | ||
2336 | * | ||
2337 | * This is the second phase of the normal nand_scan() function. It | ||
2338 | * fills out all the uninitialized function pointers with the defaults | ||
2339 | * and scans for a bad block table if appropriate. | ||
2340 | */ | ||
2341 | int nand_scan_tail(struct mtd_info *mtd) | ||
2342 | { | ||
2343 | int i; | ||
2344 | struct nand_chip *chip = mtd->priv; | ||
2345 | |||
2346 | if (!(chip->options & NAND_OWN_BUFFERS)) | ||
2347 | chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL); | ||
2348 | if (!chip->buffers) | ||
2349 | return -ENOMEM; | ||
2350 | |||
2356 | /* Preset the internal oob write buffer */ | 2351 | /* Preset the internal oob write buffer */ |
2357 | memset(chip->buffers.oobwbuf, 0xff, mtd->oobsize); | 2352 | memset(chip->buffers->oobwbuf, 0xff, mtd->oobsize); |
2358 | 2353 | ||
2359 | /* | 2354 | /* |
2360 | * If no default placement scheme is given, select an appropriate one | 2355 | * If no default placement scheme is given, select an appropriate one |
@@ -2377,10 +2372,18 @@ int nand_scan(struct mtd_info *mtd, int maxchips) | |||
2377 | } | 2372 | } |
2378 | } | 2373 | } |
2379 | 2374 | ||
2375 | if (!chip->write_page) | ||
2376 | chip->write_page = nand_write_page; | ||
2377 | |||
2380 | /* | 2378 | /* |
2381 | * check ECC mode, default to software if 3byte/512byte hardware ECC is | 2379 | * check ECC mode, default to software if 3byte/512byte hardware ECC is |
2382 | * selected and we have 256 byte pagesize fallback to software ECC | 2380 | * selected and we have 256 byte pagesize fallback to software ECC |
2383 | */ | 2381 | */ |
2382 | if (!chip->ecc.read_page_raw) | ||
2383 | chip->ecc.read_page_raw = nand_read_page_raw; | ||
2384 | if (!chip->ecc.write_page_raw) | ||
2385 | chip->ecc.write_page_raw = nand_write_page_raw; | ||
2386 | |||
2384 | switch (chip->ecc.mode) { | 2387 | switch (chip->ecc.mode) { |
2385 | case NAND_ECC_HW: | 2388 | case NAND_ECC_HW: |
2386 | /* Use standard hwecc read page function ? */ | 2389 | /* Use standard hwecc read page function ? */ |
@@ -2438,6 +2441,7 @@ int nand_scan(struct mtd_info *mtd, int maxchips) | |||
2438 | chip->ecc.size = mtd->writesize; | 2441 | chip->ecc.size = mtd->writesize; |
2439 | chip->ecc.bytes = 0; | 2442 | chip->ecc.bytes = 0; |
2440 | break; | 2443 | break; |
2444 | |||
2441 | default: | 2445 | default: |
2442 | printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n", | 2446 | printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n", |
2443 | chip->ecc.mode); | 2447 | chip->ecc.mode); |
@@ -2503,6 +2507,44 @@ int nand_scan(struct mtd_info *mtd, int maxchips) | |||
2503 | return chip->scan_bbt(mtd); | 2507 | return chip->scan_bbt(mtd); |
2504 | } | 2508 | } |
2505 | 2509 | ||
2510 | /* module_text_address() isn't exported, and it's mostly a pointless | ||
2511 | test if this is a module _anyway_ -- they'd have to try _really_ hard | ||
2512 | to call us from in-kernel code if the core NAND support is modular. */ | ||
2513 | #ifdef MODULE | ||
2514 | #define caller_is_module() (1) | ||
2515 | #else | ||
2516 | #define caller_is_module() \ | ||
2517 | module_text_address((unsigned long)__builtin_return_address(0)) | ||
2518 | #endif | ||
2519 | |||
2520 | /** | ||
2521 | * nand_scan - [NAND Interface] Scan for the NAND device | ||
2522 | * @mtd: MTD device structure | ||
2523 | * @maxchips: Number of chips to scan for | ||
2524 | * | ||
2525 | * This fills out all the uninitialized function pointers | ||
2526 | * with the defaults. | ||
2527 | * The flash ID is read and the mtd/chip structures are | ||
2528 | * filled with the appropriate values. | ||
2529 | * The mtd->owner field must be set to the module of the caller | ||
2530 | * | ||
2531 | */ | ||
2532 | int nand_scan(struct mtd_info *mtd, int maxchips) | ||
2533 | { | ||
2534 | int ret; | ||
2535 | |||
2536 | /* Many callers got this wrong, so check for it for a while... */ | ||
2537 | if (!mtd->owner && caller_is_module()) { | ||
2538 | printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n"); | ||
2539 | BUG(); | ||
2540 | } | ||
2541 | |||
2542 | ret = nand_scan_ident(mtd, maxchips); | ||
2543 | if (!ret) | ||
2544 | ret = nand_scan_tail(mtd); | ||
2545 | return ret; | ||
2546 | } | ||
2547 | |||
2506 | /** | 2548 | /** |
2507 | * nand_release - [NAND Interface] Free resources held by the NAND device | 2549 | * nand_release - [NAND Interface] Free resources held by the NAND device |
2508 | * @mtd: MTD device structure | 2550 | * @mtd: MTD device structure |
@@ -2520,9 +2562,13 @@ void nand_release(struct mtd_info *mtd) | |||
2520 | 2562 | ||
2521 | /* Free bad block table memory */ | 2563 | /* Free bad block table memory */ |
2522 | kfree(chip->bbt); | 2564 | kfree(chip->bbt); |
2565 | if (!(chip->options & NAND_OWN_BUFFERS)) | ||
2566 | kfree(chip->buffers); | ||
2523 | } | 2567 | } |
2524 | 2568 | ||
2525 | EXPORT_SYMBOL_GPL(nand_scan); | 2569 | EXPORT_SYMBOL_GPL(nand_scan); |
2570 | EXPORT_SYMBOL_GPL(nand_scan_ident); | ||
2571 | EXPORT_SYMBOL_GPL(nand_scan_tail); | ||
2526 | EXPORT_SYMBOL_GPL(nand_release); | 2572 | EXPORT_SYMBOL_GPL(nand_release); |
2527 | 2573 | ||
2528 | static int __init nand_base_init(void) | 2574 | static int __init nand_base_init(void) |
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index a612c4ea8194..9402653eb09b 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c | |||
@@ -759,7 +759,7 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b | |||
759 | struct nand_chip *this = mtd->priv; | 759 | struct nand_chip *this = mtd->priv; |
760 | 760 | ||
761 | bd->options &= ~NAND_BBT_SCANEMPTY; | 761 | bd->options &= ~NAND_BBT_SCANEMPTY; |
762 | return create_bbt(mtd, this->buffers.databuf, bd, -1); | 762 | return create_bbt(mtd, this->buffers->databuf, bd, -1); |
763 | } | 763 | } |
764 | 764 | ||
765 | /** | 765 | /** |
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig index 5930a03736d7..465961b8bcd1 100644 --- a/drivers/mtd/onenand/Kconfig +++ b/drivers/mtd/onenand/Kconfig | |||
@@ -43,10 +43,4 @@ config MTD_ONENAND_OTP | |||
43 | 43 | ||
44 | OTP block is fully-guaranteed to be a valid block. | 44 | OTP block is fully-guaranteed to be a valid block. |
45 | 45 | ||
46 | config MTD_ONENAND_SYNC_READ | ||
47 | bool "OneNAND Sync. Burst Read Support" | ||
48 | depends on ARCH_OMAP | ||
49 | help | ||
50 | This enables support for Sync. Burst Read. | ||
51 | |||
52 | endmenu | 46 | endmenu |
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 84ec40d25438..8ed68b28afe3 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mtd/onenand/onenand_base.c | 2 | * linux/drivers/mtd/onenand/onenand_base.c |
3 | * | 3 | * |
4 | * Copyright (C) 2005 Samsung Electronics | 4 | * Copyright (C) 2005-2006 Samsung Electronics |
5 | * Kyungmin Park <kyungmin.park@samsung.com> | 5 | * Kyungmin Park <kyungmin.park@samsung.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -199,6 +199,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le | |||
199 | case ONENAND_CMD_UNLOCK: | 199 | case ONENAND_CMD_UNLOCK: |
200 | case ONENAND_CMD_LOCK: | 200 | case ONENAND_CMD_LOCK: |
201 | case ONENAND_CMD_LOCK_TIGHT: | 201 | case ONENAND_CMD_LOCK_TIGHT: |
202 | case ONENAND_CMD_UNLOCK_ALL: | ||
202 | block = -1; | 203 | block = -1; |
203 | page = -1; | 204 | page = -1; |
204 | break; | 205 | break; |
@@ -1211,11 +1212,11 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1211 | end = len >> this->erase_shift; | 1212 | end = len >> this->erase_shift; |
1212 | 1213 | ||
1213 | /* Continuous lock scheme */ | 1214 | /* Continuous lock scheme */ |
1214 | if (this->options & ONENAND_CONT_LOCK) { | 1215 | if (this->options & ONENAND_HAS_CONT_LOCK) { |
1215 | /* Set start block address */ | 1216 | /* Set start block address */ |
1216 | this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS); | 1217 | this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS); |
1217 | /* Set end block address */ | 1218 | /* Set end block address */ |
1218 | this->write_word(end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS); | 1219 | this->write_word(start + end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS); |
1219 | /* Write unlock command */ | 1220 | /* Write unlock command */ |
1220 | this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0); | 1221 | this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0); |
1221 | 1222 | ||
@@ -1236,7 +1237,7 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1236 | } | 1237 | } |
1237 | 1238 | ||
1238 | /* Block lock scheme */ | 1239 | /* Block lock scheme */ |
1239 | for (block = start; block < end; block++) { | 1240 | for (block = start; block < start + end; block++) { |
1240 | /* Set block address */ | 1241 | /* Set block address */ |
1241 | value = onenand_block_address(this, block); | 1242 | value = onenand_block_address(this, block); |
1242 | this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); | 1243 | this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); |
@@ -1265,6 +1266,79 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1265 | return 0; | 1266 | return 0; |
1266 | } | 1267 | } |
1267 | 1268 | ||
1269 | /** | ||
1270 | * onenand_check_lock_status - [OneNAND Interface] Check lock status | ||
1271 | * @param this onenand chip data structure | ||
1272 | * | ||
1273 | * Check lock status | ||
1274 | */ | ||
1275 | static void onenand_check_lock_status(struct onenand_chip *this) | ||
1276 | { | ||
1277 | unsigned int value, block, status; | ||
1278 | unsigned int end; | ||
1279 | |||
1280 | end = this->chipsize >> this->erase_shift; | ||
1281 | for (block = 0; block < end; block++) { | ||
1282 | /* Set block address */ | ||
1283 | value = onenand_block_address(this, block); | ||
1284 | this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1); | ||
1285 | /* Select DataRAM for DDP */ | ||
1286 | value = onenand_bufferram_address(this, block); | ||
1287 | this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); | ||
1288 | /* Set start block address */ | ||
1289 | this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS); | ||
1290 | |||
1291 | /* Check lock status */ | ||
1292 | status = this->read_word(this->base + ONENAND_REG_WP_STATUS); | ||
1293 | if (!(status & ONENAND_WP_US)) | ||
1294 | printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status); | ||
1295 | } | ||
1296 | } | ||
1297 | |||
1298 | /** | ||
1299 | * onenand_unlock_all - [OneNAND Interface] unlock all blocks | ||
1300 | * @param mtd MTD device structure | ||
1301 | * | ||
1302 | * Unlock all blocks | ||
1303 | */ | ||
1304 | static int onenand_unlock_all(struct mtd_info *mtd) | ||
1305 | { | ||
1306 | struct onenand_chip *this = mtd->priv; | ||
1307 | |||
1308 | if (this->options & ONENAND_HAS_UNLOCK_ALL) { | ||
1309 | /* Write unlock command */ | ||
1310 | this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0); | ||
1311 | |||
1312 | /* There's no return value */ | ||
1313 | this->wait(mtd, FL_UNLOCKING); | ||
1314 | |||
1315 | /* Sanity check */ | ||
1316 | while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS) | ||
1317 | & ONENAND_CTRL_ONGO) | ||
1318 | continue; | ||
1319 | |||
1320 | /* Workaround for all block unlock in DDP */ | ||
1321 | if (this->device_id & ONENAND_DEVICE_IS_DDP) { | ||
1322 | loff_t ofs; | ||
1323 | size_t len; | ||
1324 | |||
1325 | /* 1st block on another chip */ | ||
1326 | ofs = this->chipsize >> 1; | ||
1327 | len = 1 << this->erase_shift; | ||
1328 | |||
1329 | onenand_unlock(mtd, ofs, len); | ||
1330 | } | ||
1331 | |||
1332 | onenand_check_lock_status(this); | ||
1333 | |||
1334 | return 0; | ||
1335 | } | ||
1336 | |||
1337 | mtd->unlock(mtd, 0x0, this->chipsize); | ||
1338 | |||
1339 | return 0; | ||
1340 | } | ||
1341 | |||
1268 | #ifdef CONFIG_MTD_ONENAND_OTP | 1342 | #ifdef CONFIG_MTD_ONENAND_OTP |
1269 | 1343 | ||
1270 | /* Interal OTP operation */ | 1344 | /* Interal OTP operation */ |
@@ -1564,12 +1638,43 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, | |||
1564 | #endif /* CONFIG_MTD_ONENAND_OTP */ | 1638 | #endif /* CONFIG_MTD_ONENAND_OTP */ |
1565 | 1639 | ||
1566 | /** | 1640 | /** |
1641 | * onenand_lock_scheme - Check and set OneNAND lock scheme | ||
1642 | * @param mtd MTD data structure | ||
1643 | * | ||
1644 | * Check and set OneNAND lock scheme | ||
1645 | */ | ||
1646 | static void onenand_lock_scheme(struct mtd_info *mtd) | ||
1647 | { | ||
1648 | struct onenand_chip *this = mtd->priv; | ||
1649 | unsigned int density, process; | ||
1650 | |||
1651 | /* Lock scheme depends on density and process */ | ||
1652 | density = this->device_id >> ONENAND_DEVICE_DENSITY_SHIFT; | ||
1653 | process = this->version_id >> ONENAND_VERSION_PROCESS_SHIFT; | ||
1654 | |||
1655 | /* Lock scheme */ | ||
1656 | if (density >= ONENAND_DEVICE_DENSITY_1Gb) { | ||
1657 | /* A-Die has all block unlock */ | ||
1658 | if (process) { | ||
1659 | printk(KERN_DEBUG "Chip support all block unlock\n"); | ||
1660 | this->options |= ONENAND_HAS_UNLOCK_ALL; | ||
1661 | } | ||
1662 | } else { | ||
1663 | /* Some OneNAND has continues lock scheme */ | ||
1664 | if (!process) { | ||
1665 | printk(KERN_DEBUG "Lock scheme is Continues Lock\n"); | ||
1666 | this->options |= ONENAND_HAS_CONT_LOCK; | ||
1667 | } | ||
1668 | } | ||
1669 | } | ||
1670 | |||
1671 | /** | ||
1567 | * onenand_print_device_info - Print device ID | 1672 | * onenand_print_device_info - Print device ID |
1568 | * @param device device ID | 1673 | * @param device device ID |
1569 | * | 1674 | * |
1570 | * Print device ID | 1675 | * Print device ID |
1571 | */ | 1676 | */ |
1572 | static void onenand_print_device_info(int device) | 1677 | static void onenand_print_device_info(int device, int version) |
1573 | { | 1678 | { |
1574 | int vcc, demuxed, ddp, density; | 1679 | int vcc, demuxed, ddp, density; |
1575 | 1680 | ||
@@ -1583,6 +1688,7 @@ static void onenand_print_device_info(int device) | |||
1583 | (16 << density), | 1688 | (16 << density), |
1584 | vcc ? "2.65/3.3" : "1.8", | 1689 | vcc ? "2.65/3.3" : "1.8", |
1585 | device); | 1690 | device); |
1691 | printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version); | ||
1586 | } | 1692 | } |
1587 | 1693 | ||
1588 | static const struct onenand_manufacturers onenand_manuf_ids[] = { | 1694 | static const struct onenand_manufacturers onenand_manuf_ids[] = { |
@@ -1625,9 +1731,14 @@ static int onenand_check_maf(int manuf) | |||
1625 | static int onenand_probe(struct mtd_info *mtd) | 1731 | static int onenand_probe(struct mtd_info *mtd) |
1626 | { | 1732 | { |
1627 | struct onenand_chip *this = mtd->priv; | 1733 | struct onenand_chip *this = mtd->priv; |
1628 | int bram_maf_id, bram_dev_id, maf_id, dev_id; | 1734 | int bram_maf_id, bram_dev_id, maf_id, dev_id, ver_id; |
1629 | int version_id; | ||
1630 | int density; | 1735 | int density; |
1736 | int syscfg; | ||
1737 | |||
1738 | /* Save system configuration 1 */ | ||
1739 | syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1); | ||
1740 | /* Clear Sync. Burst Read mode to read BootRAM */ | ||
1741 | this->write_word((syscfg & ~ONENAND_SYS_CFG1_SYNC_READ), this->base + ONENAND_REG_SYS_CFG1); | ||
1631 | 1742 | ||
1632 | /* Send the command for reading device ID from BootRAM */ | 1743 | /* Send the command for reading device ID from BootRAM */ |
1633 | this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM); | 1744 | this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM); |
@@ -1636,24 +1747,31 @@ static int onenand_probe(struct mtd_info *mtd) | |||
1636 | bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0); | 1747 | bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0); |
1637 | bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2); | 1748 | bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2); |
1638 | 1749 | ||
1750 | /* Reset OneNAND to read default register values */ | ||
1751 | this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM); | ||
1752 | /* Wait reset */ | ||
1753 | this->wait(mtd, FL_RESETING); | ||
1754 | |||
1755 | /* Restore system configuration 1 */ | ||
1756 | this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1); | ||
1757 | |||
1639 | /* Check manufacturer ID */ | 1758 | /* Check manufacturer ID */ |
1640 | if (onenand_check_maf(bram_maf_id)) | 1759 | if (onenand_check_maf(bram_maf_id)) |
1641 | return -ENXIO; | 1760 | return -ENXIO; |
1642 | 1761 | ||
1643 | /* Reset OneNAND to read default register values */ | ||
1644 | this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM); | ||
1645 | |||
1646 | /* Read manufacturer and device IDs from Register */ | 1762 | /* Read manufacturer and device IDs from Register */ |
1647 | maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID); | 1763 | maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID); |
1648 | dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID); | 1764 | dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID); |
1765 | ver_id= this->read_word(this->base + ONENAND_REG_VERSION_ID); | ||
1649 | 1766 | ||
1650 | /* Check OneNAND device */ | 1767 | /* Check OneNAND device */ |
1651 | if (maf_id != bram_maf_id || dev_id != bram_dev_id) | 1768 | if (maf_id != bram_maf_id || dev_id != bram_dev_id) |
1652 | return -ENXIO; | 1769 | return -ENXIO; |
1653 | 1770 | ||
1654 | /* Flash device information */ | 1771 | /* Flash device information */ |
1655 | onenand_print_device_info(dev_id); | 1772 | onenand_print_device_info(dev_id, ver_id); |
1656 | this->device_id = dev_id; | 1773 | this->device_id = dev_id; |
1774 | this->version_id = ver_id; | ||
1657 | 1775 | ||
1658 | density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT; | 1776 | density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT; |
1659 | this->chipsize = (16 << density) << 20; | 1777 | this->chipsize = (16 << density) << 20; |
@@ -1676,16 +1794,8 @@ static int onenand_probe(struct mtd_info *mtd) | |||
1676 | 1794 | ||
1677 | mtd->size = this->chipsize; | 1795 | mtd->size = this->chipsize; |
1678 | 1796 | ||
1679 | /* Version ID */ | 1797 | /* Check OneNAND lock scheme */ |
1680 | version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID); | 1798 | onenand_lock_scheme(mtd); |
1681 | printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version_id); | ||
1682 | |||
1683 | /* Lock scheme */ | ||
1684 | if (density <= ONENAND_DEVICE_DENSITY_512Mb && | ||
1685 | !(version_id >> ONENAND_VERSION_PROCESS_SHIFT)) { | ||
1686 | printk(KERN_INFO "Lock scheme is Continues Lock\n"); | ||
1687 | this->options |= ONENAND_CONT_LOCK; | ||
1688 | } | ||
1689 | 1799 | ||
1690 | return 0; | 1800 | return 0; |
1691 | } | 1801 | } |
@@ -1821,7 +1931,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) | |||
1821 | mtd->owner = THIS_MODULE; | 1931 | mtd->owner = THIS_MODULE; |
1822 | 1932 | ||
1823 | /* Unlock whole block */ | 1933 | /* Unlock whole block */ |
1824 | mtd->unlock(mtd, 0x0, this->chipsize); | 1934 | onenand_unlock_all(mtd); |
1825 | 1935 | ||
1826 | return this->scan_bbt(mtd); | 1936 | return this->scan_bbt(mtd); |
1827 | } | 1937 | } |