aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/nand_base.c44
-rw-r--r--include/linux/mtd/nand.h11
2 files changed, 32 insertions, 23 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index e1e81a9543e8..baece61169f4 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -990,7 +990,10 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
990 } 990 }
991 991
992 /* Now read the page into the buffer */ 992 /* Now read the page into the buffer */
993 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);
994 if (ret < 0) 997 if (ret < 0)
995 break; 998 break;
996 999
@@ -1323,8 +1326,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1323static int nand_read_oob(struct mtd_info *mtd, loff_t from, 1326static int nand_read_oob(struct mtd_info *mtd, loff_t from,
1324 struct mtd_oob_ops *ops) 1327 struct mtd_oob_ops *ops)
1325{ 1328{
1326 int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
1327 uint8_t *buf) = NULL;
1328 struct nand_chip *chip = mtd->priv; 1329 struct nand_chip *chip = mtd->priv;
1329 int ret = -ENOTSUPP; 1330 int ret = -ENOTSUPP;
1330 1331
@@ -1342,12 +1343,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
1342 switch(ops->mode) { 1343 switch(ops->mode) {
1343 case MTD_OOB_PLACE: 1344 case MTD_OOB_PLACE:
1344 case MTD_OOB_AUTO: 1345 case MTD_OOB_AUTO:
1345 break;
1346
1347 case MTD_OOB_RAW: 1346 case MTD_OOB_RAW:
1348 /* Replace the read_page algorithm temporary */
1349 read_page = chip->ecc.read_page;
1350 chip->ecc.read_page = nand_read_page_raw;
1351 break; 1347 break;
1352 1348
1353 default: 1349 default:
@@ -1359,8 +1355,6 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
1359 else 1355 else
1360 ret = nand_do_read_ops(mtd, from, ops); 1356 ret = nand_do_read_ops(mtd, from, ops);
1361 1357
1362 if (unlikely(ops->mode == MTD_OOB_RAW))
1363 chip->ecc.read_page = read_page;
1364 out: 1358 out:
1365 nand_release_device(mtd); 1359 nand_release_device(mtd);
1366 return ret; 1360 return ret;
@@ -1479,7 +1473,7 @@ static void nand_write_page_syndrome(struct mtd_info *mtd,
1479} 1473}
1480 1474
1481/** 1475/**
1482 * nand_write_page - [INTERNAL] write one page 1476 * nand_write_page - [REPLACEABLE] write one page
1483 * @mtd: MTD device structure 1477 * @mtd: MTD device structure
1484 * @chip: NAND chip descriptor 1478 * @chip: NAND chip descriptor
1485 * @buf: the data to write 1479 * @buf: the data to write
@@ -1487,13 +1481,16 @@ static void nand_write_page_syndrome(struct mtd_info *mtd,
1487 * @cached: cached programming 1481 * @cached: cached programming
1488 */ 1482 */
1489static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, 1483static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
1490 const uint8_t *buf, int page, int cached) 1484 const uint8_t *buf, int page, int cached, int raw)
1491{ 1485{
1492 int status; 1486 int status;
1493 1487
1494 chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); 1488 chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
1495 1489
1496 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);
1497 1494
1498 /* 1495 /*
1499 * Cached progamming disabled for now, Not sure if its worth the 1496 * Cached progamming disabled for now, Not sure if its worth the
@@ -1636,7 +1633,8 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
1636 if (unlikely(oob)) 1633 if (unlikely(oob))
1637 oob = nand_fill_oob(chip, oob, ops); 1634 oob = nand_fill_oob(chip, oob, ops);
1638 1635
1639 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));
1640 if (ret) 1638 if (ret)
1641 break; 1639 break;
1642 1640
@@ -1769,8 +1767,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
1769static int nand_write_oob(struct mtd_info *mtd, loff_t to, 1767static int nand_write_oob(struct mtd_info *mtd, loff_t to,
1770 struct mtd_oob_ops *ops) 1768 struct mtd_oob_ops *ops)
1771{ 1769{
1772 void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
1773 const uint8_t *buf) = NULL;
1774 struct nand_chip *chip = mtd->priv; 1770 struct nand_chip *chip = mtd->priv;
1775 int ret = -ENOTSUPP; 1771 int ret = -ENOTSUPP;
1776 1772
@@ -1788,12 +1784,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
1788 switch(ops->mode) { 1784 switch(ops->mode) {
1789 case MTD_OOB_PLACE: 1785 case MTD_OOB_PLACE:
1790 case MTD_OOB_AUTO: 1786 case MTD_OOB_AUTO:
1791 break;
1792
1793 case MTD_OOB_RAW: 1787 case MTD_OOB_RAW:
1794 /* Replace the write_page algorithm temporary */
1795 write_page = chip->ecc.write_page;
1796 chip->ecc.write_page = nand_write_page_raw;
1797 break; 1788 break;
1798 1789
1799 default: 1790 default:
@@ -1805,8 +1796,6 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
1805 else 1796 else
1806 ret = nand_do_write_ops(mtd, to, ops); 1797 ret = nand_do_write_ops(mtd, to, ops);
1807 1798
1808 if (unlikely(ops->mode == MTD_OOB_RAW))
1809 chip->ecc.write_page = write_page;
1810 out: 1799 out:
1811 nand_release_device(mtd); 1800 nand_release_device(mtd);
1812 return ret; 1801 return ret;
@@ -2383,10 +2372,18 @@ int nand_scan_tail(struct mtd_info *mtd)
2383 } 2372 }
2384 } 2373 }
2385 2374
2375 if (!chip->write_page)
2376 chip->write_page = nand_write_page;
2377
2386 /* 2378 /*
2387 * 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
2388 * selected and we have 256 byte pagesize fallback to software ECC 2380 * selected and we have 256 byte pagesize fallback to software ECC
2389 */ 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
2390 switch (chip->ecc.mode) { 2387 switch (chip->ecc.mode) {
2391 case NAND_ECC_HW: 2388 case NAND_ECC_HW:
2392 /* Use standard hwecc read page function ? */ 2389 /* Use standard hwecc read page function ? */
@@ -2444,6 +2441,7 @@ int nand_scan_tail(struct mtd_info *mtd)
2444 chip->ecc.size = mtd->writesize; 2441 chip->ecc.size = mtd->writesize;
2445 chip->ecc.bytes = 0; 2442 chip->ecc.bytes = 0;
2446 break; 2443 break;
2444
2447 default: 2445 default:
2448 printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n", 2446 printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n",
2449 chip->ecc.mode); 2447 chip->ecc.mode);
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index cd4fe9ae8622..2bcbcc896835 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -235,6 +235,8 @@ struct nand_hw_control {
235 * be provided if an hardware ECC is available 235 * be provided if an hardware ECC is available
236 * @calculate: function for ecc calculation or readback from ecc hardware 236 * @calculate: function for ecc calculation or readback from ecc hardware
237 * @correct: function for ecc correction, matching to ecc generator (sw/hw) 237 * @correct: function for ecc correction, matching to ecc generator (sw/hw)
238 * @read_page_raw: function to read a raw page without ECC
239 * @write_page_raw: function to write a raw page without ECC
238 * @read_page: function to read a page according to the ecc generator requirements 240 * @read_page: function to read a page according to the ecc generator requirements
239 * @write_page: function to write a page according to the ecc generator requirements 241 * @write_page: function to write a page according to the ecc generator requirements
240 * @read_oob: function to read chip OOB data 242 * @read_oob: function to read chip OOB data
@@ -256,6 +258,12 @@ struct nand_ecc_ctrl {
256 int (*correct)(struct mtd_info *mtd, uint8_t *dat, 258 int (*correct)(struct mtd_info *mtd, uint8_t *dat,
257 uint8_t *read_ecc, 259 uint8_t *read_ecc,
258 uint8_t *calc_ecc); 260 uint8_t *calc_ecc);
261 int (*read_page_raw)(struct mtd_info *mtd,
262 struct nand_chip *chip,
263 uint8_t *buf);
264 void (*write_page_raw)(struct mtd_info *mtd,
265 struct nand_chip *chip,
266 const uint8_t *buf);
259 int (*read_page)(struct mtd_info *mtd, 267 int (*read_page)(struct mtd_info *mtd,
260 struct nand_chip *chip, 268 struct nand_chip *chip,
261 uint8_t *buf); 269 uint8_t *buf);
@@ -344,6 +352,7 @@ struct nand_buffers {
344 * @priv: [OPTIONAL] pointer to private chip date 352 * @priv: [OPTIONAL] pointer to private chip date
345 * @errstat: [OPTIONAL] hardware specific function to perform additional error status checks 353 * @errstat: [OPTIONAL] hardware specific function to perform additional error status checks
346 * (determine if errors are correctable) 354 * (determine if errors are correctable)
355 * @write_page [REPLACEABLE] High-level page write function
347 */ 356 */
348 357
349struct nand_chip { 358struct nand_chip {
@@ -366,6 +375,8 @@ struct nand_chip {
366 void (*erase_cmd)(struct mtd_info *mtd, int page); 375 void (*erase_cmd)(struct mtd_info *mtd, int page);
367 int (*scan_bbt)(struct mtd_info *mtd); 376 int (*scan_bbt)(struct mtd_info *mtd);
368 int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page); 377 int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
378 int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
379 const uint8_t *buf, int page, int cached, int raw);
369 380
370 int chip_delay; 381 int chip_delay;
371 unsigned int options; 382 unsigned int options;