diff options
author | Brian Norris <computersforpeace@gmail.com> | 2012-05-02 13:14:55 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-05-14 00:20:00 -0400 |
commit | 1fbb938dff5b6bb4514a4e7600276b03c7f08e25 (patch) | |
tree | 49ab8089580041bcbd767ff7a57aa7188ee6b6c0 | |
parent | b4f7aa84d6ff44327ab91a2973ebf0c2a7797d24 (diff) |
mtd: nand: add 'oob_required' argument to NAND {read,write}_page interfaces
New NAND controllers can perform read/write via HW engines which don't expose
OOB data in their DMA mode. To reflect this, we should rework the nand_chip /
nand_ecc_ctrl interfaces that assume that drivers will always read/write OOB
data in the nand_chip.oob_poi buffer. A better interface includes a boolean
argument that explicitly tells the callee when OOB data is requested by the
calling layer (for reading/writing to/from nand_chip.oob_poi).
This patch adds the 'oob_required' parameter to each relevant {read,write}_page
interface; all 'oob_required' parameters are left unused for now. The next
patch will set the parameter properly in the nand_base.c callers, and follow-up
patches will make use of 'oob_required' in some of the callee functions.
Note that currently, there is no harm in ignoring the 'oob_required' parameter
and *always* utilizing nand_chip.oob_poi, but there can be
performance/complexity/design benefits from avoiding filling oob_poi in the
common case. I will try to implement this for some drivers which can be ported
easily.
Note: I couldn't compile-test all of these easily, as some had ARCH
dependencies.
[dwmw2: Merge later 1/0 vs. true/false cleanup]
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Reviewed-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
Acked-by: Jiandong Zheng <jdzheng@broadcom.com>
Acked-by: Mike Dunn <mikedunn@newsguy.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r-- | drivers/mtd/nand/atmel_nand.c | 5 | ||||
-rw-r--r-- | drivers/mtd/nand/bcm_umi_bch.c | 10 | ||||
-rw-r--r-- | drivers/mtd/nand/bcm_umi_nand.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/bf5xx_nand.c | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/cafe_nand.c | 13 | ||||
-rw-r--r-- | drivers/mtd/nand/denali.c | 8 | ||||
-rw-r--r-- | drivers/mtd/nand/docg4.c | 12 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_elbc_nand.c | 11 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_ifc_nand.c | 10 | ||||
-rw-r--r-- | drivers/mtd/nand/fsmc_nand.c | 3 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 8 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 56 | ||||
-rw-r--r-- | drivers/mtd/nand/pxa3xx_nand.c | 5 | ||||
-rw-r--r-- | drivers/mtd/nand/sh_flctl.c | 4 | ||||
-rw-r--r-- | include/linux/mtd/nand.h | 11 |
15 files changed, 90 insertions, 72 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 9a7876e8de42..97ac6712bb19 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -324,9 +324,10 @@ static int atmel_nand_calculate(struct mtd_info *mtd, | |||
324 | * mtd: mtd info structure | 324 | * mtd: mtd info structure |
325 | * chip: nand chip info structure | 325 | * chip: nand chip info structure |
326 | * buf: buffer to store read data | 326 | * buf: buffer to store read data |
327 | * oob_required: caller expects OOB data read to chip->oob_poi | ||
327 | */ | 328 | */ |
328 | static int atmel_nand_read_page(struct mtd_info *mtd, | 329 | static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
329 | struct nand_chip *chip, uint8_t *buf, int page) | 330 | uint8_t *buf, int oob_required, int page) |
330 | { | 331 | { |
331 | int eccsize = chip->ecc.size; | 332 | int eccsize = chip->ecc.size; |
332 | int eccbytes = chip->ecc.bytes; | 333 | int eccbytes = chip->ecc.bytes; |
diff --git a/drivers/mtd/nand/bcm_umi_bch.c b/drivers/mtd/nand/bcm_umi_bch.c index f8472b49567a..5914bb32e001 100644 --- a/drivers/mtd/nand/bcm_umi_bch.c +++ b/drivers/mtd/nand/bcm_umi_bch.c | |||
@@ -22,9 +22,9 @@ | |||
22 | 22 | ||
23 | /* ---- Private Function Prototypes -------------------------------------- */ | 23 | /* ---- Private Function Prototypes -------------------------------------- */ |
24 | static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd, | 24 | static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd, |
25 | struct nand_chip *chip, uint8_t *buf, int page); | 25 | struct nand_chip *chip, uint8_t *buf, int oob_required, int page); |
26 | static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd, | 26 | static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd, |
27 | struct nand_chip *chip, const uint8_t *buf); | 27 | struct nand_chip *chip, const uint8_t *buf, int oob_required); |
28 | 28 | ||
29 | /* ---- Private Variables ------------------------------------------------ */ | 29 | /* ---- Private Variables ------------------------------------------------ */ |
30 | 30 | ||
@@ -103,11 +103,12 @@ static struct nand_ecclayout nand_hw_eccoob_4096 = { | |||
103 | * @mtd: mtd info structure | 103 | * @mtd: mtd info structure |
104 | * @chip: nand chip info structure | 104 | * @chip: nand chip info structure |
105 | * @buf: buffer to store read data | 105 | * @buf: buffer to store read data |
106 | * @oob_required: caller expects OOB data read to chip->oob_poi | ||
106 | * | 107 | * |
107 | ***************************************************************************/ | 108 | ***************************************************************************/ |
108 | static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd, | 109 | static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd, |
109 | struct nand_chip *chip, uint8_t * buf, | 110 | struct nand_chip *chip, uint8_t * buf, |
110 | int page) | 111 | int oob_required, int page) |
111 | { | 112 | { |
112 | int sectorIdx = 0; | 113 | int sectorIdx = 0; |
113 | int eccsize = chip->ecc.size; | 114 | int eccsize = chip->ecc.size; |
@@ -190,10 +191,11 @@ static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd, | |||
190 | * @mtd: mtd info structure | 191 | * @mtd: mtd info structure |
191 | * @chip: nand chip info structure | 192 | * @chip: nand chip info structure |
192 | * @buf: data buffer | 193 | * @buf: data buffer |
194 | * @oob_required: must write chip->oob_poi to OOB | ||
193 | * | 195 | * |
194 | ***************************************************************************/ | 196 | ***************************************************************************/ |
195 | static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd, | 197 | static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd, |
196 | struct nand_chip *chip, const uint8_t *buf) | 198 | struct nand_chip *chip, const uint8_t *buf, int oob_required) |
197 | { | 199 | { |
198 | int sectorIdx = 0; | 200 | int sectorIdx = 0; |
199 | int eccsize = chip->ecc.size; | 201 | int eccsize = chip->ecc.size; |
diff --git a/drivers/mtd/nand/bcm_umi_nand.c b/drivers/mtd/nand/bcm_umi_nand.c index 7134adfa1089..c855e7cd337b 100644 --- a/drivers/mtd/nand/bcm_umi_nand.c +++ b/drivers/mtd/nand/bcm_umi_nand.c | |||
@@ -341,7 +341,7 @@ static int bcm_umi_nand_verify_buf(struct mtd_info *mtd, const u_char * buf, | |||
341 | * for MLC parts which may have permanently stuck bits. | 341 | * for MLC parts which may have permanently stuck bits. |
342 | */ | 342 | */ |
343 | struct nand_chip *chip = mtd->priv; | 343 | struct nand_chip *chip = mtd->priv; |
344 | int ret = chip->ecc.read_page(mtd, chip, readbackbuf, 0); | 344 | int ret = chip->ecc.read_page(mtd, chip, readbackbuf, 0, 0); |
345 | if (ret < 0) | 345 | if (ret < 0) |
346 | return -EFAULT; | 346 | return -EFAULT; |
347 | else { | 347 | else { |
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index d7b86b925de5..3f1c18599cbd 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c | |||
@@ -558,7 +558,7 @@ static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd, | |||
558 | } | 558 | } |
559 | 559 | ||
560 | static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | 560 | static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, |
561 | uint8_t *buf, int page) | 561 | uint8_t *buf, int oob_required, int page) |
562 | { | 562 | { |
563 | bf5xx_nand_read_buf(mtd, buf, mtd->writesize); | 563 | bf5xx_nand_read_buf(mtd, buf, mtd->writesize); |
564 | bf5xx_nand_read_buf(mtd, chip->oob_poi, mtd->oobsize); | 564 | bf5xx_nand_read_buf(mtd, chip->oob_poi, mtd->oobsize); |
@@ -567,7 +567,7 @@ static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip | |||
567 | } | 567 | } |
568 | 568 | ||
569 | static void bf5xx_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | 569 | static void bf5xx_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, |
570 | const uint8_t *buf) | 570 | const uint8_t *buf, int oob_required) |
571 | { | 571 | { |
572 | bf5xx_nand_write_buf(mtd, buf, mtd->writesize); | 572 | bf5xx_nand_write_buf(mtd, buf, mtd->writesize); |
573 | bf5xx_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize); | 573 | bf5xx_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize); |
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 75fb77b96efb..3a6c88d69bc7 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c | |||
@@ -375,12 +375,13 @@ static int cafe_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, | |||
375 | * @mtd: mtd info structure | 375 | * @mtd: mtd info structure |
376 | * @chip: nand chip info structure | 376 | * @chip: nand chip info structure |
377 | * @buf: buffer to store read data | 377 | * @buf: buffer to store read data |
378 | * @oob_required: caller expects OOB data read to chip->oob_poi | ||
378 | * | 379 | * |
379 | * The hw generator calculates the error syndrome automatically. Therefor | 380 | * The hw generator calculates the error syndrome automatically. Therefor |
380 | * we need a special oob layout and handling. | 381 | * we need a special oob layout and handling. |
381 | */ | 382 | */ |
382 | static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, | 383 | static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
383 | uint8_t *buf, int page) | 384 | uint8_t *buf, int oob_required, int page) |
384 | { | 385 | { |
385 | struct cafe_priv *cafe = mtd->priv; | 386 | struct cafe_priv *cafe = mtd->priv; |
386 | unsigned int max_bitflips = 0; | 387 | unsigned int max_bitflips = 0; |
@@ -520,7 +521,8 @@ static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = { | |||
520 | 521 | ||
521 | 522 | ||
522 | static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd, | 523 | static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd, |
523 | struct nand_chip *chip, const uint8_t *buf) | 524 | struct nand_chip *chip, |
525 | const uint8_t *buf, int oob_required) | ||
524 | { | 526 | { |
525 | struct cafe_priv *cafe = mtd->priv; | 527 | struct cafe_priv *cafe = mtd->priv; |
526 | 528 | ||
@@ -532,16 +534,17 @@ static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd, | |||
532 | } | 534 | } |
533 | 535 | ||
534 | static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, | 536 | static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
535 | const uint8_t *buf, int page, int cached, int raw) | 537 | const uint8_t *buf, int oob_required, int page, |
538 | int cached, int raw) | ||
536 | { | 539 | { |
537 | int status; | 540 | int status; |
538 | 541 | ||
539 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); | 542 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); |
540 | 543 | ||
541 | if (unlikely(raw)) | 544 | if (unlikely(raw)) |
542 | chip->ecc.write_page_raw(mtd, chip, buf); | 545 | chip->ecc.write_page_raw(mtd, chip, buf, oob_required); |
543 | else | 546 | else |
544 | chip->ecc.write_page(mtd, chip, buf); | 547 | chip->ecc.write_page(mtd, chip, buf, oob_required); |
545 | 548 | ||
546 | /* | 549 | /* |
547 | * Cached progamming disabled for now, Not sure if its worth the | 550 | * Cached progamming disabled for now, Not sure if its worth the |
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 1b346474dba8..a54c18611945 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c | |||
@@ -1087,7 +1087,7 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1087 | * by write_page above. | 1087 | * by write_page above. |
1088 | * */ | 1088 | * */ |
1089 | static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip, | 1089 | static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
1090 | const uint8_t *buf) | 1090 | const uint8_t *buf, int oob_required) |
1091 | { | 1091 | { |
1092 | /* for regular page writes, we let HW handle all the ECC | 1092 | /* for regular page writes, we let HW handle all the ECC |
1093 | * data written to the device. */ | 1093 | * data written to the device. */ |
@@ -1099,7 +1099,7 @@ static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1099 | * write_page() function above. | 1099 | * write_page() function above. |
1100 | */ | 1100 | */ |
1101 | static void denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | 1101 | static void denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, |
1102 | const uint8_t *buf) | 1102 | const uint8_t *buf, int oob_required) |
1103 | { | 1103 | { |
1104 | /* for raw page writes, we want to disable ECC and simply write | 1104 | /* for raw page writes, we want to disable ECC and simply write |
1105 | whatever data is in the buffer. */ | 1105 | whatever data is in the buffer. */ |
@@ -1122,7 +1122,7 @@ static int denali_read_oob(struct mtd_info *mtd, struct nand_chip *chip, | |||
1122 | } | 1122 | } |
1123 | 1123 | ||
1124 | static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, | 1124 | static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
1125 | uint8_t *buf, int page) | 1125 | uint8_t *buf, int oob_required, int page) |
1126 | { | 1126 | { |
1127 | unsigned int max_bitflips; | 1127 | unsigned int max_bitflips; |
1128 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 1128 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
@@ -1175,7 +1175,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1175 | } | 1175 | } |
1176 | 1176 | ||
1177 | static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | 1177 | static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, |
1178 | uint8_t *buf, int page) | 1178 | uint8_t *buf, int oob_required, int page) |
1179 | { | 1179 | { |
1180 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 1180 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
1181 | 1181 | ||
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c index 1540de2ad39a..1f8485d7500c 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c | |||
@@ -787,13 +787,13 @@ static int read_page(struct mtd_info *mtd, struct nand_chip *nand, | |||
787 | 787 | ||
788 | 788 | ||
789 | static int docg4_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand, | 789 | static int docg4_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand, |
790 | uint8_t *buf, int page) | 790 | uint8_t *buf, int oob_required, int page) |
791 | { | 791 | { |
792 | return read_page(mtd, nand, buf, page, false); | 792 | return read_page(mtd, nand, buf, page, false); |
793 | } | 793 | } |
794 | 794 | ||
795 | static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand, | 795 | static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand, |
796 | uint8_t *buf, int page) | 796 | uint8_t *buf, int oob_required, int page) |
797 | { | 797 | { |
798 | return read_page(mtd, nand, buf, page, true); | 798 | return read_page(mtd, nand, buf, page, true); |
799 | } | 799 | } |
@@ -953,13 +953,13 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *nand, | |||
953 | } | 953 | } |
954 | 954 | ||
955 | static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand, | 955 | static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand, |
956 | const uint8_t *buf) | 956 | const uint8_t *buf, int oob_required) |
957 | { | 957 | { |
958 | return write_page(mtd, nand, buf, false); | 958 | return write_page(mtd, nand, buf, false); |
959 | } | 959 | } |
960 | 960 | ||
961 | static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand, | 961 | static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand, |
962 | const uint8_t *buf) | 962 | const uint8_t *buf, int oob_required) |
963 | { | 963 | { |
964 | return write_page(mtd, nand, buf, true); | 964 | return write_page(mtd, nand, buf, true); |
965 | } | 965 | } |
@@ -1003,7 +1003,7 @@ static int __init read_factory_bbt(struct mtd_info *mtd) | |||
1003 | return -ENOMEM; | 1003 | return -ENOMEM; |
1004 | 1004 | ||
1005 | read_page_prologue(mtd, g4_addr); | 1005 | read_page_prologue(mtd, g4_addr); |
1006 | status = docg4_read_page(mtd, nand, buf, DOCG4_FACTORY_BBT_PAGE); | 1006 | status = docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE); |
1007 | if (status) | 1007 | if (status) |
1008 | goto exit; | 1008 | goto exit; |
1009 | 1009 | ||
@@ -1080,7 +1080,7 @@ static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs) | |||
1080 | 1080 | ||
1081 | /* write first page of block */ | 1081 | /* write first page of block */ |
1082 | write_page_prologue(mtd, g4_addr); | 1082 | write_page_prologue(mtd, g4_addr); |
1083 | docg4_write_page(mtd, nand, buf); | 1083 | docg4_write_page(mtd, nand, buf, 1); |
1084 | ret = pageprog(mtd); | 1084 | ret = pageprog(mtd); |
1085 | if (!ret) | 1085 | if (!ret) |
1086 | mtd->ecc_stats.badblocks++; | 1086 | mtd->ecc_stats.badblocks++; |
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 4d995875d366..11e34010272f 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c | |||
@@ -746,10 +746,8 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) | |||
746 | return 0; | 746 | return 0; |
747 | } | 747 | } |
748 | 748 | ||
749 | static int fsl_elbc_read_page(struct mtd_info *mtd, | 749 | static int fsl_elbc_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
750 | struct nand_chip *chip, | 750 | uint8_t *buf, int oob_required, int page) |
751 | uint8_t *buf, | ||
752 | int page) | ||
753 | { | 751 | { |
754 | struct fsl_elbc_mtd *priv = chip->priv; | 752 | struct fsl_elbc_mtd *priv = chip->priv; |
755 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; | 753 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; |
@@ -767,9 +765,8 @@ static int fsl_elbc_read_page(struct mtd_info *mtd, | |||
767 | /* ECC will be calculated automatically, and errors will be detected in | 765 | /* ECC will be calculated automatically, and errors will be detected in |
768 | * waitfunc. | 766 | * waitfunc. |
769 | */ | 767 | */ |
770 | static void fsl_elbc_write_page(struct mtd_info *mtd, | 768 | static void fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
771 | struct nand_chip *chip, | 769 | const uint8_t *buf, int oob_required) |
772 | const uint8_t *buf) | ||
773 | { | 770 | { |
774 | fsl_elbc_write_buf(mtd, buf, mtd->writesize); | 771 | fsl_elbc_write_buf(mtd, buf, mtd->writesize); |
775 | fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize); | 772 | fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize); |
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index dffd2fa353ae..c085df3d816a 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c | |||
@@ -698,9 +698,8 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) | |||
698 | return nand_fsr | NAND_STATUS_WP; | 698 | return nand_fsr | NAND_STATUS_WP; |
699 | } | 699 | } |
700 | 700 | ||
701 | static int fsl_ifc_read_page(struct mtd_info *mtd, | 701 | static int fsl_ifc_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
702 | struct nand_chip *chip, | 702 | uint8_t *buf, int oob_required, int page) |
703 | uint8_t *buf, int page) | ||
704 | { | 703 | { |
705 | struct fsl_ifc_mtd *priv = chip->priv; | 704 | struct fsl_ifc_mtd *priv = chip->priv; |
706 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | 705 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; |
@@ -721,9 +720,8 @@ static int fsl_ifc_read_page(struct mtd_info *mtd, | |||
721 | /* ECC will be calculated automatically, and errors will be detected in | 720 | /* ECC will be calculated automatically, and errors will be detected in |
722 | * waitfunc. | 721 | * waitfunc. |
723 | */ | 722 | */ |
724 | static void fsl_ifc_write_page(struct mtd_info *mtd, | 723 | static void fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
725 | struct nand_chip *chip, | 724 | const uint8_t *buf, int oob_required) |
726 | const uint8_t *buf) | ||
727 | { | 725 | { |
728 | fsl_ifc_write_buf(mtd, buf, mtd->writesize); | 726 | fsl_ifc_write_buf(mtd, buf, mtd->writesize); |
729 | fsl_ifc_write_buf(mtd, chip->oob_poi, mtd->oobsize); | 727 | fsl_ifc_write_buf(mtd, chip->oob_poi, mtd->oobsize); |
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 6bf59fdde263..38d26240d8b1 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c | |||
@@ -692,6 +692,7 @@ static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf, | |||
692 | * @mtd: mtd info structure | 692 | * @mtd: mtd info structure |
693 | * @chip: nand chip info structure | 693 | * @chip: nand chip info structure |
694 | * @buf: buffer to store read data | 694 | * @buf: buffer to store read data |
695 | * @oob_required: caller expects OOB data read to chip->oob_poi | ||
695 | * @page: page number to read | 696 | * @page: page number to read |
696 | * | 697 | * |
697 | * This routine is needed for fsmc version 8 as reading from NAND chip has to be | 698 | * This routine is needed for fsmc version 8 as reading from NAND chip has to be |
@@ -701,7 +702,7 @@ static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf, | |||
701 | * max of 8 bits) | 702 | * max of 8 bits) |
702 | */ | 703 | */ |
703 | static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | 704 | static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, |
704 | uint8_t *buf, int page) | 705 | uint8_t *buf, int oob_required, int page) |
705 | { | 706 | { |
706 | struct fsmc_nand_data *host = container_of(mtd, | 707 | struct fsmc_nand_data *host = container_of(mtd, |
707 | struct fsmc_nand_data, mtd); | 708 | struct fsmc_nand_data, mtd); |
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 9ec51cec2e14..d85a2c1fad54 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c | |||
@@ -842,7 +842,7 @@ static void block_mark_swapping(struct gpmi_nand_data *this, | |||
842 | } | 842 | } |
843 | 843 | ||
844 | static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, | 844 | static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
845 | uint8_t *buf, int page) | 845 | uint8_t *buf, int oob_required, int page) |
846 | { | 846 | { |
847 | struct gpmi_nand_data *this = chip->priv; | 847 | struct gpmi_nand_data *this = chip->priv; |
848 | struct bch_geometry *nfc_geo = &this->bch_geometry; | 848 | struct bch_geometry *nfc_geo = &this->bch_geometry; |
@@ -928,8 +928,8 @@ exit_nfc: | |||
928 | return ret; | 928 | return ret; |
929 | } | 929 | } |
930 | 930 | ||
931 | static void gpmi_ecc_write_page(struct mtd_info *mtd, | 931 | static void gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
932 | struct nand_chip *chip, const uint8_t *buf) | 932 | const uint8_t *buf, int oob_required) |
933 | { | 933 | { |
934 | struct gpmi_nand_data *this = chip->priv; | 934 | struct gpmi_nand_data *this = chip->priv; |
935 | struct bch_geometry *nfc_geo = &this->bch_geometry; | 935 | struct bch_geometry *nfc_geo = &this->bch_geometry; |
@@ -1309,7 +1309,7 @@ static int mx23_write_transcription_stamp(struct gpmi_nand_data *this) | |||
1309 | /* Write the first page of the current stride. */ | 1309 | /* Write the first page of the current stride. */ |
1310 | dev_dbg(dev, "Writing an NCB fingerprint in page 0x%x\n", page); | 1310 | dev_dbg(dev, "Writing an NCB fingerprint in page 0x%x\n", page); |
1311 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); | 1311 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); |
1312 | chip->ecc.write_page_raw(mtd, chip, buffer); | 1312 | chip->ecc.write_page_raw(mtd, chip, buffer, 0); |
1313 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); | 1313 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); |
1314 | 1314 | ||
1315 | /* Wait for the write to finish. */ | 1315 | /* Wait for the write to finish. */ |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 5ec4d2c01b87..6d4894acb567 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -1066,12 +1066,13 @@ EXPORT_SYMBOL(nand_lock); | |||
1066 | * @mtd: mtd info structure | 1066 | * @mtd: mtd info structure |
1067 | * @chip: nand chip info structure | 1067 | * @chip: nand chip info structure |
1068 | * @buf: buffer to store read data | 1068 | * @buf: buffer to store read data |
1069 | * @oob_required: caller requires OOB data read to chip->oob_poi | ||
1069 | * @page: page number to read | 1070 | * @page: page number to read |
1070 | * | 1071 | * |
1071 | * Not for syndrome calculating ECC controllers, which use a special oob layout. | 1072 | * Not for syndrome calculating ECC controllers, which use a special oob layout. |
1072 | */ | 1073 | */ |
1073 | static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | 1074 | static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, |
1074 | uint8_t *buf, int page) | 1075 | uint8_t *buf, int oob_required, int page) |
1075 | { | 1076 | { |
1076 | chip->read_buf(mtd, buf, mtd->writesize); | 1077 | chip->read_buf(mtd, buf, mtd->writesize); |
1077 | chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); | 1078 | chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); |
@@ -1083,13 +1084,14 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | |||
1083 | * @mtd: mtd info structure | 1084 | * @mtd: mtd info structure |
1084 | * @chip: nand chip info structure | 1085 | * @chip: nand chip info structure |
1085 | * @buf: buffer to store read data | 1086 | * @buf: buffer to store read data |
1087 | * @oob_required: caller requires OOB data read to chip->oob_poi | ||
1086 | * @page: page number to read | 1088 | * @page: page number to read |
1087 | * | 1089 | * |
1088 | * We need a special oob layout and handling even when OOB isn't used. | 1090 | * We need a special oob layout and handling even when OOB isn't used. |
1089 | */ | 1091 | */ |
1090 | static int nand_read_page_raw_syndrome(struct mtd_info *mtd, | 1092 | static int nand_read_page_raw_syndrome(struct mtd_info *mtd, |
1091 | struct nand_chip *chip, | 1093 | struct nand_chip *chip, uint8_t *buf, |
1092 | uint8_t *buf, int page) | 1094 | int oob_required, int page) |
1093 | { | 1095 | { |
1094 | int eccsize = chip->ecc.size; | 1096 | int eccsize = chip->ecc.size; |
1095 | int eccbytes = chip->ecc.bytes; | 1097 | int eccbytes = chip->ecc.bytes; |
@@ -1126,10 +1128,11 @@ static int nand_read_page_raw_syndrome(struct mtd_info *mtd, | |||
1126 | * @mtd: mtd info structure | 1128 | * @mtd: mtd info structure |
1127 | * @chip: nand chip info structure | 1129 | * @chip: nand chip info structure |
1128 | * @buf: buffer to store read data | 1130 | * @buf: buffer to store read data |
1131 | * @oob_required: caller requires OOB data read to chip->oob_poi | ||
1129 | * @page: page number to read | 1132 | * @page: page number to read |
1130 | */ | 1133 | */ |
1131 | static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | 1134 | static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, |
1132 | uint8_t *buf, int page) | 1135 | uint8_t *buf, int oob_required, int page) |
1133 | { | 1136 | { |
1134 | int i, eccsize = chip->ecc.size; | 1137 | int i, eccsize = chip->ecc.size; |
1135 | int eccbytes = chip->ecc.bytes; | 1138 | int eccbytes = chip->ecc.bytes; |
@@ -1140,7 +1143,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1140 | uint32_t *eccpos = chip->ecc.layout->eccpos; | 1143 | uint32_t *eccpos = chip->ecc.layout->eccpos; |
1141 | unsigned int max_bitflips = 0; | 1144 | unsigned int max_bitflips = 0; |
1142 | 1145 | ||
1143 | chip->ecc.read_page_raw(mtd, chip, buf, page); | 1146 | chip->ecc.read_page_raw(mtd, chip, buf, 1, page); |
1144 | 1147 | ||
1145 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) | 1148 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) |
1146 | chip->ecc.calculate(mtd, p, &ecc_calc[i]); | 1149 | chip->ecc.calculate(mtd, p, &ecc_calc[i]); |
@@ -1263,12 +1266,13 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, | |||
1263 | * @mtd: mtd info structure | 1266 | * @mtd: mtd info structure |
1264 | * @chip: nand chip info structure | 1267 | * @chip: nand chip info structure |
1265 | * @buf: buffer to store read data | 1268 | * @buf: buffer to store read data |
1269 | * @oob_required: caller requires OOB data read to chip->oob_poi | ||
1266 | * @page: page number to read | 1270 | * @page: page number to read |
1267 | * | 1271 | * |
1268 | * Not for syndrome calculating ECC controllers which need a special oob layout. | 1272 | * Not for syndrome calculating ECC controllers which need a special oob layout. |
1269 | */ | 1273 | */ |
1270 | static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | 1274 | static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, |
1271 | uint8_t *buf, int page) | 1275 | uint8_t *buf, int oob_required, int page) |
1272 | { | 1276 | { |
1273 | int i, eccsize = chip->ecc.size; | 1277 | int i, eccsize = chip->ecc.size; |
1274 | int eccbytes = chip->ecc.bytes; | 1278 | int eccbytes = chip->ecc.bytes; |
@@ -1311,6 +1315,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1311 | * @mtd: mtd info structure | 1315 | * @mtd: mtd info structure |
1312 | * @chip: nand chip info structure | 1316 | * @chip: nand chip info structure |
1313 | * @buf: buffer to store read data | 1317 | * @buf: buffer to store read data |
1318 | * @oob_required: caller requires OOB data read to chip->oob_poi | ||
1314 | * @page: page number to read | 1319 | * @page: page number to read |
1315 | * | 1320 | * |
1316 | * Hardware ECC for large page chips, require OOB to be read first. For this | 1321 | * Hardware ECC for large page chips, require OOB to be read first. For this |
@@ -1320,7 +1325,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1320 | * the data area, by overwriting the NAND manufacturer bad block markings. | 1325 | * the data area, by overwriting the NAND manufacturer bad block markings. |
1321 | */ | 1326 | */ |
1322 | static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd, | 1327 | static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd, |
1323 | struct nand_chip *chip, uint8_t *buf, int page) | 1328 | struct nand_chip *chip, uint8_t *buf, int oob_required, int page) |
1324 | { | 1329 | { |
1325 | int i, eccsize = chip->ecc.size; | 1330 | int i, eccsize = chip->ecc.size; |
1326 | int eccbytes = chip->ecc.bytes; | 1331 | int eccbytes = chip->ecc.bytes; |
@@ -1362,13 +1367,14 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd, | |||
1362 | * @mtd: mtd info structure | 1367 | * @mtd: mtd info structure |
1363 | * @chip: nand chip info structure | 1368 | * @chip: nand chip info structure |
1364 | * @buf: buffer to store read data | 1369 | * @buf: buffer to store read data |
1370 | * @oob_required: caller requires OOB data read to chip->oob_poi | ||
1365 | * @page: page number to read | 1371 | * @page: page number to read |
1366 | * | 1372 | * |
1367 | * The hw generator calculates the error syndrome automatically. Therefore we | 1373 | * The hw generator calculates the error syndrome automatically. Therefore we |
1368 | * need a special oob layout and handling. | 1374 | * need a special oob layout and handling. |
1369 | */ | 1375 | */ |
1370 | static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, | 1376 | static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, |
1371 | uint8_t *buf, int page) | 1377 | uint8_t *buf, int oob_required, int page) |
1372 | { | 1378 | { |
1373 | int i, eccsize = chip->ecc.size; | 1379 | int i, eccsize = chip->ecc.size; |
1374 | int eccbytes = chip->ecc.bytes; | 1380 | int eccbytes = chip->ecc.bytes; |
@@ -1514,14 +1520,14 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
1514 | * the read methods return max bitflips per ecc step. | 1520 | * the read methods return max bitflips per ecc step. |
1515 | */ | 1521 | */ |
1516 | if (unlikely(ops->mode == MTD_OPS_RAW)) | 1522 | if (unlikely(ops->mode == MTD_OPS_RAW)) |
1517 | ret = chip->ecc.read_page_raw(mtd, chip, | 1523 | ret = chip->ecc.read_page_raw(mtd, chip, bufpoi, |
1518 | bufpoi, page); | 1524 | 1, page); |
1519 | else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob) | 1525 | else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob) |
1520 | ret = chip->ecc.read_subpage(mtd, chip, | 1526 | ret = chip->ecc.read_subpage(mtd, chip, |
1521 | col, bytes, bufpoi); | 1527 | col, bytes, bufpoi); |
1522 | else | 1528 | else |
1523 | ret = chip->ecc.read_page(mtd, chip, bufpoi, | 1529 | ret = chip->ecc.read_page(mtd, chip, bufpoi, |
1524 | page); | 1530 | 1, page); |
1525 | if (ret < 0) { | 1531 | if (ret < 0) { |
1526 | if (!aligned) | 1532 | if (!aligned) |
1527 | /* Invalidate page cache */ | 1533 | /* Invalidate page cache */ |
@@ -1913,11 +1919,12 @@ out: | |||
1913 | * @mtd: mtd info structure | 1919 | * @mtd: mtd info structure |
1914 | * @chip: nand chip info structure | 1920 | * @chip: nand chip info structure |
1915 | * @buf: data buffer | 1921 | * @buf: data buffer |
1922 | * @oob_required: must write chip->oob_poi to OOB | ||
1916 | * | 1923 | * |
1917 | * Not for syndrome calculating ECC controllers, which use a special oob layout. | 1924 | * Not for syndrome calculating ECC controllers, which use a special oob layout. |
1918 | */ | 1925 | */ |
1919 | static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | 1926 | static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, |
1920 | const uint8_t *buf) | 1927 | const uint8_t *buf, int oob_required) |
1921 | { | 1928 | { |
1922 | chip->write_buf(mtd, buf, mtd->writesize); | 1929 | chip->write_buf(mtd, buf, mtd->writesize); |
1923 | chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); | 1930 | chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); |
@@ -1928,12 +1935,13 @@ static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | |||
1928 | * @mtd: mtd info structure | 1935 | * @mtd: mtd info structure |
1929 | * @chip: nand chip info structure | 1936 | * @chip: nand chip info structure |
1930 | * @buf: data buffer | 1937 | * @buf: data buffer |
1938 | * @oob_required: must write chip->oob_poi to OOB | ||
1931 | * | 1939 | * |
1932 | * We need a special oob layout and handling even when ECC isn't checked. | 1940 | * We need a special oob layout and handling even when ECC isn't checked. |
1933 | */ | 1941 | */ |
1934 | static void nand_write_page_raw_syndrome(struct mtd_info *mtd, | 1942 | static void nand_write_page_raw_syndrome(struct mtd_info *mtd, |
1935 | struct nand_chip *chip, | 1943 | struct nand_chip *chip, |
1936 | const uint8_t *buf) | 1944 | const uint8_t *buf, int oob_required) |
1937 | { | 1945 | { |
1938 | int eccsize = chip->ecc.size; | 1946 | int eccsize = chip->ecc.size; |
1939 | int eccbytes = chip->ecc.bytes; | 1947 | int eccbytes = chip->ecc.bytes; |
@@ -1967,9 +1975,10 @@ static void nand_write_page_raw_syndrome(struct mtd_info *mtd, | |||
1967 | * @mtd: mtd info structure | 1975 | * @mtd: mtd info structure |
1968 | * @chip: nand chip info structure | 1976 | * @chip: nand chip info structure |
1969 | * @buf: data buffer | 1977 | * @buf: data buffer |
1978 | * @oob_required: must write chip->oob_poi to OOB | ||
1970 | */ | 1979 | */ |
1971 | static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | 1980 | static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, |
1972 | const uint8_t *buf) | 1981 | const uint8_t *buf, int oob_required) |
1973 | { | 1982 | { |
1974 | int i, eccsize = chip->ecc.size; | 1983 | int i, eccsize = chip->ecc.size; |
1975 | int eccbytes = chip->ecc.bytes; | 1984 | int eccbytes = chip->ecc.bytes; |
@@ -1985,7 +1994,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1985 | for (i = 0; i < chip->ecc.total; i++) | 1994 | for (i = 0; i < chip->ecc.total; i++) |
1986 | chip->oob_poi[eccpos[i]] = ecc_calc[i]; | 1995 | chip->oob_poi[eccpos[i]] = ecc_calc[i]; |
1987 | 1996 | ||
1988 | chip->ecc.write_page_raw(mtd, chip, buf); | 1997 | chip->ecc.write_page_raw(mtd, chip, buf, 1); |
1989 | } | 1998 | } |
1990 | 1999 | ||
1991 | /** | 2000 | /** |
@@ -1993,9 +2002,10 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1993 | * @mtd: mtd info structure | 2002 | * @mtd: mtd info structure |
1994 | * @chip: nand chip info structure | 2003 | * @chip: nand chip info structure |
1995 | * @buf: data buffer | 2004 | * @buf: data buffer |
2005 | * @oob_required: must write chip->oob_poi to OOB | ||
1996 | */ | 2006 | */ |
1997 | static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | 2007 | static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, |
1998 | const uint8_t *buf) | 2008 | const uint8_t *buf, int oob_required) |
1999 | { | 2009 | { |
2000 | int i, eccsize = chip->ecc.size; | 2010 | int i, eccsize = chip->ecc.size; |
2001 | int eccbytes = chip->ecc.bytes; | 2011 | int eccbytes = chip->ecc.bytes; |
@@ -2021,12 +2031,14 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
2021 | * @mtd: mtd info structure | 2031 | * @mtd: mtd info structure |
2022 | * @chip: nand chip info structure | 2032 | * @chip: nand chip info structure |
2023 | * @buf: data buffer | 2033 | * @buf: data buffer |
2034 | * @oob_required: must write chip->oob_poi to OOB | ||
2024 | * | 2035 | * |
2025 | * The hw generator calculates the error syndrome automatically. Therefore we | 2036 | * The hw generator calculates the error syndrome automatically. Therefore we |
2026 | * need a special oob layout and handling. | 2037 | * need a special oob layout and handling. |
2027 | */ | 2038 | */ |
2028 | static void nand_write_page_syndrome(struct mtd_info *mtd, | 2039 | static void nand_write_page_syndrome(struct mtd_info *mtd, |
2029 | struct nand_chip *chip, const uint8_t *buf) | 2040 | struct nand_chip *chip, |
2041 | const uint8_t *buf, int oob_required) | ||
2030 | { | 2042 | { |
2031 | int i, eccsize = chip->ecc.size; | 2043 | int i, eccsize = chip->ecc.size; |
2032 | int eccbytes = chip->ecc.bytes; | 2044 | int eccbytes = chip->ecc.bytes; |
@@ -2065,21 +2077,23 @@ static void nand_write_page_syndrome(struct mtd_info *mtd, | |||
2065 | * @mtd: MTD device structure | 2077 | * @mtd: MTD device structure |
2066 | * @chip: NAND chip descriptor | 2078 | * @chip: NAND chip descriptor |
2067 | * @buf: the data to write | 2079 | * @buf: the data to write |
2080 | * @oob_required: must write chip->oob_poi to OOB | ||
2068 | * @page: page number to write | 2081 | * @page: page number to write |
2069 | * @cached: cached programming | 2082 | * @cached: cached programming |
2070 | * @raw: use _raw version of write_page | 2083 | * @raw: use _raw version of write_page |
2071 | */ | 2084 | */ |
2072 | static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, | 2085 | static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
2073 | const uint8_t *buf, int page, int cached, int raw) | 2086 | const uint8_t *buf, int oob_required, int page, |
2087 | int cached, int raw) | ||
2074 | { | 2088 | { |
2075 | int status; | 2089 | int status; |
2076 | 2090 | ||
2077 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); | 2091 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); |
2078 | 2092 | ||
2079 | if (unlikely(raw)) | 2093 | if (unlikely(raw)) |
2080 | chip->ecc.write_page_raw(mtd, chip, buf); | 2094 | chip->ecc.write_page_raw(mtd, chip, buf, oob_required); |
2081 | else | 2095 | else |
2082 | chip->ecc.write_page(mtd, chip, buf); | 2096 | chip->ecc.write_page(mtd, chip, buf, oob_required); |
2083 | 2097 | ||
2084 | /* | 2098 | /* |
2085 | * Cached progamming disabled for now. Not sure if it's worth the | 2099 | * Cached progamming disabled for now. Not sure if it's worth the |
@@ -2261,7 +2275,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
2261 | memset(chip->oob_poi, 0xff, mtd->oobsize); | 2275 | memset(chip->oob_poi, 0xff, mtd->oobsize); |
2262 | } | 2276 | } |
2263 | 2277 | ||
2264 | ret = chip->write_page(mtd, chip, wbuf, page, cached, | 2278 | ret = chip->write_page(mtd, chip, wbuf, 1, page, cached, |
2265 | (ops->mode == MTD_OPS_RAW)); | 2279 | (ops->mode == MTD_OPS_RAW)); |
2266 | if (ret) | 2280 | if (ret) |
2267 | break; | 2281 | break; |
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 36a32a0d3b9f..252aaefcacfa 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -682,14 +682,15 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command, | |||
682 | } | 682 | } |
683 | 683 | ||
684 | static void pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd, | 684 | static void pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd, |
685 | struct nand_chip *chip, const uint8_t *buf) | 685 | struct nand_chip *chip, const uint8_t *buf, int oob_required) |
686 | { | 686 | { |
687 | chip->write_buf(mtd, buf, mtd->writesize); | 687 | chip->write_buf(mtd, buf, mtd->writesize); |
688 | chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); | 688 | chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); |
689 | } | 689 | } |
690 | 690 | ||
691 | static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, | 691 | static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, |
692 | struct nand_chip *chip, uint8_t *buf, int page) | 692 | struct nand_chip *chip, uint8_t *buf, int oob_required, |
693 | int page) | ||
693 | { | 694 | { |
694 | struct pxa3xx_nand_host *host = mtd->priv; | 695 | struct pxa3xx_nand_host *host = mtd->priv; |
695 | struct pxa3xx_nand_info *info = host->info_data; | 696 | struct pxa3xx_nand_info *info = host->info_data; |
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index 3f0788fad66f..aa9b8a5e0b8f 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c | |||
@@ -344,7 +344,7 @@ static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_va | |||
344 | } | 344 | } |
345 | 345 | ||
346 | static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | 346 | static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, |
347 | uint8_t *buf, int page) | 347 | uint8_t *buf, int oob_required, int page) |
348 | { | 348 | { |
349 | int i, eccsize = chip->ecc.size; | 349 | int i, eccsize = chip->ecc.size; |
350 | int eccbytes = chip->ecc.bytes; | 350 | int eccbytes = chip->ecc.bytes; |
@@ -366,7 +366,7 @@ static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
366 | } | 366 | } |
367 | 367 | ||
368 | static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | 368 | static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, |
369 | const uint8_t *buf) | 369 | const uint8_t *buf, int oob_required) |
370 | { | 370 | { |
371 | int i, eccsize = chip->ecc.size; | 371 | int i, eccsize = chip->ecc.size; |
372 | int eccbytes = chip->ecc.bytes; | 372 | int eccbytes = chip->ecc.bytes; |
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 94a6679bfc2e..c7755f455c81 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
@@ -360,15 +360,15 @@ struct nand_ecc_ctrl { | |||
360 | int (*correct)(struct mtd_info *mtd, uint8_t *dat, uint8_t *read_ecc, | 360 | int (*correct)(struct mtd_info *mtd, uint8_t *dat, uint8_t *read_ecc, |
361 | uint8_t *calc_ecc); | 361 | uint8_t *calc_ecc); |
362 | int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip, | 362 | int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip, |
363 | uint8_t *buf, int page); | 363 | uint8_t *buf, int oob_required, int page); |
364 | void (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip, | 364 | void (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip, |
365 | const uint8_t *buf); | 365 | const uint8_t *buf, int oob_required); |
366 | int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip, | 366 | int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip, |
367 | uint8_t *buf, int page); | 367 | uint8_t *buf, int oob_required, int page); |
368 | int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip, | 368 | int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip, |
369 | uint32_t offs, uint32_t len, uint8_t *buf); | 369 | uint32_t offs, uint32_t len, uint8_t *buf); |
370 | void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, | 370 | void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, |
371 | const uint8_t *buf); | 371 | const uint8_t *buf, int oob_required); |
372 | int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip, | 372 | int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip, |
373 | int page); | 373 | int page); |
374 | int (*read_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip, | 374 | int (*read_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip, |
@@ -504,7 +504,8 @@ struct nand_chip { | |||
504 | int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, | 504 | int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, |
505 | int status, int page); | 505 | int status, int page); |
506 | int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, | 506 | int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, |
507 | const uint8_t *buf, int page, int cached, int raw); | 507 | const uint8_t *buf, int oob_required, int page, |
508 | int cached, int raw); | ||
508 | 509 | ||
509 | int chip_delay; | 510 | int chip_delay; |
510 | unsigned int options; | 511 | unsigned int options; |