aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Norris <computersforpeace@gmail.com>2012-05-02 13:14:55 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-05-14 00:20:00 -0400
commit1fbb938dff5b6bb4514a4e7600276b03c7f08e25 (patch)
tree49ab8089580041bcbd767ff7a57aa7188ee6b6c0
parentb4f7aa84d6ff44327ab91a2973ebf0c2a7797d24 (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.c5
-rw-r--r--drivers/mtd/nand/bcm_umi_bch.c10
-rw-r--r--drivers/mtd/nand/bcm_umi_nand.c2
-rw-r--r--drivers/mtd/nand/bf5xx_nand.c4
-rw-r--r--drivers/mtd/nand/cafe_nand.c13
-rw-r--r--drivers/mtd/nand/denali.c8
-rw-r--r--drivers/mtd/nand/docg4.c12
-rw-r--r--drivers/mtd/nand/fsl_elbc_nand.c11
-rw-r--r--drivers/mtd/nand/fsl_ifc_nand.c10
-rw-r--r--drivers/mtd/nand/fsmc_nand.c3
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c8
-rw-r--r--drivers/mtd/nand/nand_base.c56
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c5
-rw-r--r--drivers/mtd/nand/sh_flctl.c4
-rw-r--r--include/linux/mtd/nand.h11
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 */
328static int atmel_nand_read_page(struct mtd_info *mtd, 329static 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 -------------------------------------- */
24static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd, 24static 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);
26static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd, 26static 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***************************************************************************/
108static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd, 109static 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***************************************************************************/
195static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd, 197static 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
560static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, 560static 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
569static void bf5xx_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, 569static 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 */
382static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, 383static 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
522static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd, 523static 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
534static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, 536static 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