aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Westfahl <jeff.westfahl@ni.com>2012-08-13 17:35:30 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-09-29 10:28:33 -0400
commita5ff4f102937a3492bca4a9ff0c341d78813414c (patch)
treee2fb4a1b059243f92eec02cf5f0b41f869f48424
parent32098f6af02754b357ce303afd1bd00a470f906c (diff)
mtd: nand: Added a device flag for subpage read support
Added a NAND device flag for subpage read support. Previously this was hard coded based on large page and soft ECC. Updated base NAND driver to use the new subpage read flag if the NAND is large page and soft ECC. Signed-off-by: Jeff Westfahl <jeff.westfahl@ni.com> Reviewed-by: Brian Norris <computersforpeace@gmail.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/nand_base.c9
-rw-r--r--include/linux/mtd/nand.h7
2 files changed, 11 insertions, 5 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 6a8e15d6b402..88f671cb96c7 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1484,7 +1484,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1484 ret = chip->ecc.read_page_raw(mtd, chip, bufpoi, 1484 ret = chip->ecc.read_page_raw(mtd, chip, bufpoi,
1485 oob_required, 1485 oob_required,
1486 page); 1486 page);
1487 else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob) 1487 else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) &&
1488 !oob)
1488 ret = chip->ecc.read_subpage(mtd, chip, 1489 ret = chip->ecc.read_subpage(mtd, chip,
1489 col, bytes, bufpoi); 1490 col, bytes, bufpoi);
1490 else 1491 else
@@ -1501,7 +1502,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1501 1502
1502 /* Transfer not aligned data */ 1503 /* Transfer not aligned data */
1503 if (!aligned) { 1504 if (!aligned) {
1504 if (!NAND_SUBPAGE_READ(chip) && !oob && 1505 if (!NAND_HAS_SUBPAGE_READ(chip) && !oob &&
1505 !(mtd->ecc_stats.failed - stats.failed) && 1506 !(mtd->ecc_stats.failed - stats.failed) &&
1506 (ops->mode != MTD_OPS_RAW)) { 1507 (ops->mode != MTD_OPS_RAW)) {
1507 chip->pagebuf = realpage; 1508 chip->pagebuf = realpage;
@@ -3415,6 +3416,10 @@ int nand_scan_tail(struct mtd_info *mtd)
3415 /* Invalidate the pagebuffer reference */ 3416 /* Invalidate the pagebuffer reference */
3416 chip->pagebuf = -1; 3417 chip->pagebuf = -1;
3417 3418
3419 /* Large page NAND with SOFT_ECC should support subpage reads */
3420 if ((chip->ecc.mode == NAND_ECC_SOFT) && (chip->page_shift > 9))
3421 chip->options |= NAND_SUBPAGE_READ;
3422
3418 /* Fill in remaining MTD driver data */ 3423 /* Fill in remaining MTD driver data */
3419 mtd->type = MTD_NANDFLASH; 3424 mtd->type = MTD_NANDFLASH;
3420 mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM : 3425 mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 6bdad331cee4..8f99d3621e12 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -194,6 +194,9 @@ typedef enum {
194/* Device behaves just like nand, but is readonly */ 194/* Device behaves just like nand, but is readonly */
195#define NAND_ROM 0x00000800 195#define NAND_ROM 0x00000800
196 196
197/* Device supports subpage reads */
198#define NAND_SUBPAGE_READ 0x00001000
199
197/* Options valid for Samsung large page devices */ 200/* Options valid for Samsung large page devices */
198#define NAND_SAMSUNG_LP_OPTIONS \ 201#define NAND_SAMSUNG_LP_OPTIONS \
199 (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK) 202 (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
@@ -202,9 +205,7 @@ typedef enum {
202#define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING)) 205#define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING))
203#define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG)) 206#define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG))
204#define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK)) 207#define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK))
205/* Large page NAND with SOFT_ECC should support subpage reads */ 208#define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ))
206#define NAND_SUBPAGE_READ(chip) ((chip->ecc.mode == NAND_ECC_SOFT) \
207 && (chip->page_shift > 9))
208 209
209/* Non chip related options */ 210/* Non chip related options */
210/* This option skips the bbt scan during initialization. */ 211/* This option skips the bbt scan during initialization. */