mtd: nand: Added a device flag for subpage read support
authorJeff Westfahl <jeff.westfahl@ni.com>
Mon, 13 Aug 2012 21:35:30 +0000 (16:35 -0500)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Sat, 29 Sep 2012 14:28:33 +0000 (15:28 +0100)
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>
drivers/mtd/nand/nand_base.c
include/linux/mtd/nand.h

index 6a8e15d6b4023c90641e86fc76436f46ecde932d..88f671cb96c70ea894c59ba44fae6f380046536a 100644 (file)
@@ -1484,7 +1484,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
                                ret = chip->ecc.read_page_raw(mtd, chip, bufpoi,
                                                              oob_required,
                                                              page);
-                       else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)
+                       else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) &&
+                                !oob)
                                ret = chip->ecc.read_subpage(mtd, chip,
                                                        col, bytes, bufpoi);
                        else
@@ -1501,7 +1502,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
 
                        /* Transfer not aligned data */
                        if (!aligned) {
-                               if (!NAND_SUBPAGE_READ(chip) && !oob &&
+                               if (!NAND_HAS_SUBPAGE_READ(chip) && !oob &&
                                    !(mtd->ecc_stats.failed - stats.failed) &&
                                    (ops->mode != MTD_OPS_RAW)) {
                                        chip->pagebuf = realpage;
@@ -3415,6 +3416,10 @@ int nand_scan_tail(struct mtd_info *mtd)
        /* Invalidate the pagebuffer reference */
        chip->pagebuf = -1;
 
+       /* Large page NAND with SOFT_ECC should support subpage reads */
+       if ((chip->ecc.mode == NAND_ECC_SOFT) && (chip->page_shift > 9))
+               chip->options |= NAND_SUBPAGE_READ;
+
        /* Fill in remaining MTD driver data */
        mtd->type = MTD_NANDFLASH;
        mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
index 6bdad331cee4a187e0c57b40dfc9139161749e93..8f99d3621e128f12967d375a8fc183b9cd956854 100644 (file)
@@ -194,6 +194,9 @@ typedef enum {
 /* Device behaves just like nand, but is readonly */
 #define NAND_ROM               0x00000800
 
+/* Device supports subpage reads */
+#define NAND_SUBPAGE_READ      0x00001000
+
 /* Options valid for Samsung large page devices */
 #define NAND_SAMSUNG_LP_OPTIONS \
        (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
@@ -202,9 +205,7 @@ typedef enum {
 #define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING))
 #define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG))
 #define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK))
-/* Large page NAND with SOFT_ECC should support subpage reads */
-#define NAND_SUBPAGE_READ(chip) ((chip->ecc.mode == NAND_ECC_SOFT) \
-                                       && (chip->page_shift > 9))
+#define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ))
 
 /* Non chip related options */
 /* This option skips the bbt scan during initialization. */