OneNAND: Additional sync with 2.6.27
authorStefan Roese <sr@denx.de>
Tue, 2 Dec 2008 10:06:47 +0000 (11:06 +0100)
committerScott Wood <scottwood@freescale.com>
Fri, 23 Jan 2009 16:32:48 +0000 (10:32 -0600)
- Add subpage write support
- Add onenand_oob_64/32 ecclayout

This has been missing and without it UBI has some incompatibilies issues
with the current (>= 2.6.27) Linux kernel version. vid_hdr_offset is
placed differently (2048 instead of 512) without this fix.

Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Scott Wood <scottwood@freescale.com>
drivers/mtd/onenand/onenand_base.c
include/linux/mtd/onenand.h

index dcc969ff73090f04ca8e1c176b5da6a38c6e6f4a..d482437a462f254cb9ded756e97fb91a9f665c3a 100644 (file)
@@ -36,6 +36,35 @@ static inline void *memcpy_16(void *dst, const void *src, unsigned int len)
        return ret;
 }
 
+/**
+ * onenand_oob_64 - oob info for large (2KB) page
+ */
+static struct nand_ecclayout onenand_oob_64 = {
+       .eccbytes       = 20,
+       .eccpos         = {
+               8, 9, 10, 11, 12,
+               24, 25, 26, 27, 28,
+               40, 41, 42, 43, 44,
+               56, 57, 58, 59, 60,
+               },
+       .oobfree        = {
+               {2, 3}, {14, 2}, {18, 3}, {30, 2},
+               {34, 3}, {46, 2}, {50, 3}, {62, 2}
+       }
+};
+
+/**
+ * onenand_oob_32 - oob info for middle (1KB) page
+ */
+static struct nand_ecclayout onenand_oob_32 = {
+       .eccbytes       = 10,
+       .eccpos         = {
+               8, 9, 10, 11, 12,
+               24, 25, 26, 27, 28,
+               },
+       .oobfree        = { {2, 3}, {14, 2}, {18, 3}, {30, 2} }
+};
+
 static const unsigned char ffchars[] = {
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 */
@@ -1079,7 +1108,7 @@ static int onenand_verify(struct mtd_info *mtd, const u_char *buf, loff_t addr,
 #define onenand_verify_oob(...)         (0)
 #endif
 
-#define NOTALIGNED(x)  ((x & (mtd->writesize - 1)) != 0)
+#define NOTALIGNED(x)  ((x & (this->subpagesize - 1)) != 0)
 
 /**
  * onenand_fill_auto_oob - [Internal] oob auto-placement transfer
@@ -2058,6 +2087,7 @@ static int onenand_probe(struct mtd_info *mtd)
  */
 int onenand_scan(struct mtd_info *mtd, int maxchips)
 {
+       int i;
        struct onenand_chip *this = mtd->priv;
 
        if (!this->read_word)
@@ -2115,6 +2145,46 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
                this->options |= ONENAND_OOBBUF_ALLOC;
        }
 
+       this->state = FL_READY;
+
+       /*
+        * Allow subpage writes up to oobsize.
+        */
+       switch (mtd->oobsize) {
+       case 64:
+               this->ecclayout = &onenand_oob_64;
+               mtd->subpage_sft = 2;
+               break;
+
+       case 32:
+               this->ecclayout = &onenand_oob_32;
+               mtd->subpage_sft = 1;
+               break;
+
+       default:
+               printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",
+                       mtd->oobsize);
+               mtd->subpage_sft = 0;
+               /* To prevent kernel oops */
+               this->ecclayout = &onenand_oob_32;
+               break;
+       }
+
+       this->subpagesize = mtd->writesize >> mtd->subpage_sft;
+
+       /*
+        * The number of bytes available for a client to place data into
+        * the out of band area
+        */
+       this->ecclayout->oobavail = 0;
+       for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES &&
+           this->ecclayout->oobfree[i].length; i++)
+               this->ecclayout->oobavail +=
+                       this->ecclayout->oobfree[i].length;
+       mtd->oobavail = this->ecclayout->oobavail;
+
+       mtd->ecclayout = this->ecclayout;
+
        /* Unlock whole block */
        onenand_unlock_all(mtd);
 
index 7547e96e77fddd3dbafbfde7e5ce522a7fb67688..2597e347b4b19365a4aa83d22692878a68376a45 100644 (file)
@@ -107,6 +107,7 @@ struct onenand_chip {
        unsigned char           *oob_buf;
 
        struct nand_oobinfo *autooob;
+       int                     subpagesize;
        struct nand_ecclayout   *ecclayout;
 
        void *bbm;