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 |
