]> git.ipfire.org Git - people/ms/u-boot.git/blobdiff - drivers/mtd/onenand/onenand_base.c
Coding Style cleanup, update CHANGELOG
[people/ms/u-boot.git] / drivers / mtd / onenand / onenand_base.c
index 7983a4a0d82dffe63a69109789b45f04c113c9e3..9ce68e1a47c90905763b3cad235f7135d416ab70 100644 (file)
  */
 
 #include <common.h>
-
-#ifdef CONFIG_CMD_ONENAND
-
 #include <linux/mtd/compat.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
 
 #include <asm/io.h>
 #include <asm/errno.h>
+#include <malloc.h>
+
+/* It should access 16-bit instead of 8-bit */
+static inline void *memcpy_16(void *dst, const void *src, unsigned int len)
+{
+       void *ret = dst;
+       short *d = dst;
+       const short *s = src;
+
+       len >>= 1;
+       while (len-- > 0)
+               *d++ = *s++;
+       return ret;
+}
 
 static const unsigned char ffchars[] = {
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -280,22 +291,22 @@ static int onenand_wait(struct mtd_info *mtd, int state)
        ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
 
        if (ctrl & ONENAND_CTRL_ERROR) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_wait: controller error = 0x%04x\n", ctrl);
+               MTDDEBUG (MTD_DEBUG_LEVEL0,
+                         "onenand_wait: controller error = 0x%04x\n", ctrl);
                return -EAGAIN;
        }
 
        if (ctrl & ONENAND_CTRL_LOCK) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_wait: it's locked error = 0x%04x\n", ctrl);
+               MTDDEBUG (MTD_DEBUG_LEVEL0,
+                         "onenand_wait: it's locked error = 0x%04x\n", ctrl);
                return -EIO;
        }
 
        if (interrupt & ONENAND_INT_READ) {
                ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
                if (ecc & ONENAND_ECC_2BIT_ALL) {
-                       DEBUG(MTD_DEBUG_LEVEL0,
-                             "onenand_wait: ECC error = 0x%04x\n", ecc);
+                       MTDDEBUG (MTD_DEBUG_LEVEL0,
+                                 "onenand_wait: ECC error = 0x%04x\n", ecc);
                        return -EBADMSG;
                }
        }
@@ -317,7 +328,7 @@ static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
 
        if (ONENAND_CURRENT_BUFFERRAM(this)) {
                if (area == ONENAND_DATARAM)
-                       return mtd->oobblock;
+                       return mtd->writesize;
                if (area == ONENAND_SPARERAM)
                        return mtd->oobsize;
        }
@@ -345,7 +356,7 @@ static int onenand_read_bufferram(struct mtd_info *mtd, int area,
        bufferram = this->base + area;
        bufferram += onenand_bufferram_offset(mtd, area);
 
-       memcpy(buffer, bufferram + offset, count);
+       memcpy_16(buffer, bufferram + offset, count);
 
        return 0;
 }
@@ -372,7 +383,7 @@ static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
 
        this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
 
-       memcpy(buffer, bufferram + offset, count);
+       memcpy_16(buffer, bufferram + offset, count);
 
        this->mmcontrol(mtd, 0);
 
@@ -399,7 +410,7 @@ static int onenand_write_bufferram(struct mtd_info *mtd, int area,
        bufferram = this->base + area;
        bufferram += onenand_bufferram_offset(mtd, area);
 
-       memcpy(bufferram + offset, buffer, count);
+       memcpy_16(bufferram + offset, buffer, count);
 
        return 0;
 }
@@ -467,6 +478,30 @@ static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
        return 0;
 }
 
+/**
+ * onenand_invalidate_bufferram - [GENERIC] Invalidate BufferRAM information
+ * @param mtd           MTD data structure
+ * @param addr          start address to invalidate
+ * @param len           length to invalidate
+ *
+ * Invalidate BufferRAM information
+ */
+static void onenand_invalidate_bufferram(struct mtd_info *mtd, loff_t addr,
+                                        unsigned int len)
+{
+       struct onenand_chip *this = mtd->priv;
+       int i;
+       loff_t end_addr = addr + len;
+
+       /* Invalidate BufferRAM */
+       for (i = 0; i < MAX_BUFFERRAM; i++) {
+               loff_t buf_addr = this->bufferram[i].block << this->erase_shift;
+
+               if (buf_addr >= addr && buf_addr < end_addr)
+                       this->bufferram[i].valid = 0;
+       }
+}
+
 /**
  * onenand_get_device - [GENERIC] Get chip for selected access
  * @param mtd          MTD device structure
@@ -511,13 +546,14 @@ static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
        int thislen;
        int ret = 0;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ecc: from = 0x%08x, len = %i\n",
-             (unsigned int)from, (int)len);
+       MTDDEBUG (MTD_DEBUG_LEVEL3, "onenand_read_ecc: "
+                 "from = 0x%08x, len = %i\n",
+                 (unsigned int)from, (int)len);
 
        /* Do not allow reads past end of device */
        if ((from + len) > mtd->size) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_read_ecc: Attempt read beyond end of device\n");
+               MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_read_ecc: "
+                         "Attempt read beyond end of device\n");
                *retlen = 0;
                return -EINVAL;
        }
@@ -526,15 +562,15 @@ static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
        onenand_get_device(mtd, FL_READING);
 
        while (read < len) {
-               thislen = min_t(int, mtd->oobblock, len - read);
+               thislen = min_t(int, mtd->writesize, len - read);
 
-               column = from & (mtd->oobblock - 1);
-               if (column + thislen > mtd->oobblock)
-                       thislen = mtd->oobblock - column;
+               column = from & (mtd->writesize - 1);
+               if (column + thislen > mtd->writesize)
+                       thislen = mtd->writesize - column;
 
                if (!onenand_check_bufferram(mtd, from)) {
                        this->command(mtd, ONENAND_CMD_READ, from,
-                                     mtd->oobblock);
+                                     mtd->writesize);
                        ret = this->wait(mtd, FL_READING);
                        /* First copy data and check return value for ECC handling */
                        onenand_update_bufferram(mtd, from, 1);
@@ -548,8 +584,8 @@ static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
                        break;
 
                if (ret) {
-                       DEBUG(MTD_DEBUG_LEVEL0,
-                             "onenand_read_ecc: read failed = %d\n", ret);
+                       MTDDEBUG (MTD_DEBUG_LEVEL0,
+                                 "onenand_read_ecc: read failed = %d\n", ret);
                        break;
                }
 
@@ -602,16 +638,17 @@ int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
        int read = 0, thislen, column;
        int ret = 0;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n",
-             (unsigned int)from, (int)len);
+       MTDDEBUG (MTD_DEBUG_LEVEL3, "onenand_read_oob: "
+                 "from = 0x%08x, len = %i\n",
+                 (unsigned int)from, (int)len);
 
        /* Initialize return length value */
        *retlen = 0;
 
        /* Do not allow reads past end of device */
        if (unlikely((from + len) > mtd->size)) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_read_oob: Attempt read beyond end of device\n");
+               MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_read_oob: "
+                         "Attempt read beyond end of device\n");
                return -EINVAL;
        }
 
@@ -639,8 +676,8 @@ int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
                        break;
 
                if (ret) {
-                       DEBUG(MTD_DEBUG_LEVEL0,
-                             "onenand_read_oob: read failed = %d\n", ret);
+                       MTDDEBUG (MTD_DEBUG_LEVEL0,
+                                 "onenand_read_oob: read failed = %d\n", ret);
                        break;
                }
 
@@ -648,7 +685,7 @@ int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
                /* Read more? */
                if (read < len) {
                        /* Page size */
-                       from += mtd->oobblock;
+                       from += mtd->writesize;
                        column = 0;
                }
        }
@@ -665,19 +702,17 @@ int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
  * onenand_verify_page - [GENERIC] verify the chip contents after a write
  * @param mtd          MTD device structure
  * @param buf          the databuffer to verify
- * @param block                block address
- * @param page         page address
  *
  * Check DataRAM area directly
  */
 static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
-                              loff_t addr, int block, int page)
+                              loff_t addr)
 {
        struct onenand_chip *this = mtd->priv;
        void __iomem *dataram0, *dataram1;
        int ret = 0;
 
-       this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock);
+       this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
 
        ret = this->wait(mtd, FL_READING);
        if (ret)
@@ -687,9 +722,9 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
 
        /* Check, if the two dataram areas are same */
        dataram0 = this->base + ONENAND_DATARAM;
-       dataram1 = dataram0 + mtd->oobblock;
+       dataram1 = dataram0 + mtd->writesize;
 
-       if (memcmp(dataram0, dataram1, mtd->oobblock))
+       if (memcmp(dataram0, dataram1, mtd->writesize))
                return -EBADMSG;
 
        return 0;
@@ -698,7 +733,7 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
 #define onenand_verify_page(...)       (0)
 #endif
 
-#define NOTALIGNED(x)  ((x & (mtd->oobblock - 1)) != 0)
+#define NOTALIGNED(x)  ((x & (mtd->writesize - 1)) != 0)
 
 /**
  * onenand_write_ecc - [MTD Interface] OneNAND write with ECC
@@ -720,23 +755,24 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
        int written = 0;
        int ret = 0;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ecc: to = 0x%08x, len = %i\n",
-             (unsigned int)to, (int)len);
+       MTDDEBUG (MTD_DEBUG_LEVEL3, "onenand_write_ecc: "
+                 "to = 0x%08x, len = %i\n",
+                 (unsigned int)to, (int)len);
 
        /* Initialize retlen, in case of early exit */
        *retlen = 0;
 
        /* Do not allow writes past end of device */
        if (unlikely((to + len) > mtd->size)) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_write_ecc: Attempt write to past end of device\n");
+               MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_write_ecc: "
+                         "Attempt write to past end of device\n");
                return -EINVAL;
        }
 
        /* Reject writes, which are not page aligned */
        if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_write_ecc: Attempt to write not page aligned data\n");
+               MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_write_ecc: "
+                         "Attempt to write not page aligned data\n");
                return -EINVAL;
        }
 
@@ -745,32 +781,32 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
 
        /* Loop until all data write */
        while (written < len) {
-               int thislen = min_t(int, mtd->oobblock, len - written);
+               int thislen = min_t(int, mtd->writesize, len - written);
 
-               this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
+               this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->writesize);
 
                this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
                this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0,
                                      mtd->oobsize);
 
-               this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
+               this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
 
                onenand_update_bufferram(mtd, to, 1);
 
                ret = this->wait(mtd, FL_WRITING);
                if (ret) {
-                       DEBUG(MTD_DEBUG_LEVEL0,
-                             "onenand_write_ecc: write filaed %d\n", ret);
+                       MTDDEBUG (MTD_DEBUG_LEVEL0,
+                                 "onenand_write_ecc: write filaed %d\n", ret);
                        break;
                }
 
                written += thislen;
 
                /* Only check verify write turn on */
-               ret = onenand_verify_page(mtd, (u_char *) buf, to, block, page);
+               ret = onenand_verify_page(mtd, (u_char *) buf, to);
                if (ret) {
-                       DEBUG(MTD_DEBUG_LEVEL0,
-                             "onenand_write_ecc: verify failed %d\n", ret);
+                       MTDDEBUG (MTD_DEBUG_LEVEL0,
+                                 "onenand_write_ecc: verify failed %d\n", ret);
                        break;
                }
 
@@ -823,16 +859,17 @@ int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
        int column, status;
        int written = 0;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n",
-             (unsigned int)to, (int)len);
+       MTDDEBUG (MTD_DEBUG_LEVEL3, "onenand_write_oob: "
+                 "to = 0x%08x, len = %i\n",
+                 (unsigned int)to, (int)len);
 
        /* Initialize retlen, in case of early exit */
        *retlen = 0;
 
        /* Do not allow writes past end of device */
        if (unlikely((to + len) > mtd->size)) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_write_oob: Attempt write to past end of device\n");
+               MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_write_oob: "
+                         "Attempt write to past end of device\n");
                return -EINVAL;
        }
 
@@ -876,6 +913,25 @@ int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
        return 0;
 }
 
+/**
+ * onenand_block_isbad_nolock - [GENERIC] Check if a block is marked bad
+ * @param mtd          MTD device structure
+ * @param ofs          offset from device start
+ * @param allowbbt     1, if its allowed to access the bbt area
+ *
+ * Check, if the block is bad, Either by reading the bad block table or
+ * calling of the scan function.
+ */
+static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allowbbt)
+{
+       struct onenand_chip *this = mtd->priv;
+       struct bbm_info *bbm = this->bbm;
+
+       /* Return info from the table */
+       return bbm->isbad_bbt(mtd, ofs, allowbbt);
+}
+
+
 /**
  * onenand_erase - [MTD Interface] erase block(s)
  * @param mtd          MTD device structure
@@ -891,28 +947,29 @@ int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
        int len;
        int ret = 0;
 
-       DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%08x, len = %i\n",
-             (unsigned int)instr->addr, (unsigned int)instr->len);
+       MTDDEBUG (MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%08x, len = %i\n",
+                 (unsigned int)instr->addr, (unsigned int)instr->len);
 
        block_size = (1 << this->erase_shift);
 
        /* Start address must align on block boundary */
        if (unlikely(instr->addr & (block_size - 1))) {
-               DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Unaligned address\n");
+               MTDDEBUG (MTD_DEBUG_LEVEL0,
+                         "onenand_erase: Unaligned address\n");
                return -EINVAL;
        }
 
        /* Length must align on block boundary */
        if (unlikely(instr->len & (block_size - 1))) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_erase: Length not block aligned\n");
+               MTDDEBUG (MTD_DEBUG_LEVEL0,
+                         "onenand_erase: Length not block aligned\n");
                return -EINVAL;
        }
 
        /* Do not allow erase past end of device */
        if (unlikely((instr->len + instr->addr) > mtd->size)) {
-               DEBUG(MTD_DEBUG_LEVEL0,
-                     "onenand_erase: Erase past end of device\n");
+               MTDDEBUG (MTD_DEBUG_LEVEL0,
+                         "onenand_erase: Erase past end of device\n");
                return -EINVAL;
        }
 
@@ -933,16 +990,18 @@ int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
 
                this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
 
+               onenand_invalidate_bufferram(mtd, addr, block_size);
+
                ret = this->wait(mtd, FL_ERASING);
                /* Check, if it is write protected */
                if (ret) {
                        if (ret == -EPERM)
-                               DEBUG(MTD_DEBUG_LEVEL0,
-                                     "onenand_erase: Device is write protected!!!\n");
+                               MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_erase: "
+                                         "Device is write protected!!!\n");
                        else
-                               DEBUG(MTD_DEBUG_LEVEL0,
-                                     "onenand_erase: Failed erase, block %d\n",
-                                     (unsigned)(addr >> this->erase_shift));
+                               MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_erase: "
+                                         "Failed erase, block %d\n",
+                                         (unsigned)(addr >> this->erase_shift));
                        instr->state = MTD_ERASE_FAILED;
                        instr->fail_addr = addr;
                        goto erase_exit;
@@ -975,7 +1034,7 @@ int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
  */
 void onenand_sync(struct mtd_info *mtd)
 {
-       DEBUG(MTD_DEBUG_LEVEL3, "onenand_sync: called\n");
+       MTDDEBUG (MTD_DEBUG_LEVEL3, "onenand_sync: called\n");
 
        /* Grab the lock and see if the device is available */
        onenand_get_device(mtd, FL_SYNCING);
@@ -988,30 +1047,45 @@ void onenand_sync(struct mtd_info *mtd)
  * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
  * @param mtd          MTD device structure
  * @param ofs          offset relative to mtd start
+ *
+ * Check whether the block is bad
  */
 int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
 {
-       /*
-        * TODO
-        * 1. Bad block table (BBT)
-        *   -> using NAND BBT to support JFFS2
-        * 2. Bad block management (BBM)
-        *   -> bad block replace scheme
-        *
-        * Currently we do nothing
-        */
-       return 0;
+       int ret;
+
+       /* Check for invalid offset */
+       if (ofs > mtd->size)
+               return -EINVAL;
+
+       onenand_get_device(mtd, FL_READING);
+       ret = onenand_block_isbad_nolock(mtd,ofs, 0);
+       onenand_release_device(mtd);
+       return ret;
 }
 
 /**
  * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
  * @param mtd          MTD device structure
  * @param ofs          offset relative to mtd start
+ *
+ * Mark the block as bad
  */
 int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
-       /* see above */
-       return 0;
+       struct onenand_chip *this = mtd->priv;
+       int ret;
+
+       ret = onenand_block_isbad(mtd, ofs);
+       if (ret) {
+               /* If it was bad already, return success and do nothing */
+               if (ret > 0)
+                       return 0;
+               return ret;
+       }
+
+       ret = this->block_markbad(mtd, ofs);
+       return ret;
 }
 
 /**
@@ -1094,21 +1168,21 @@ int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
  *
  * Print device ID
  */
-void onenand_print_device_info(int device, int verbose)
+char * onenand_print_device_info(int device)
 {
        int vcc, demuxed, ddp, density;
-
-       if (!verbose)
-               return;
+       char *dev_info = malloc(80);
 
        vcc = device & ONENAND_DEVICE_VCC_MASK;
        demuxed = device & ONENAND_DEVICE_IS_DEMUX;
        ddp = device & ONENAND_DEVICE_IS_DDP;
        density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
-       printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
+       sprintf(dev_info, "%sOneNAND%s %dMB %sV 16-bit (0x%02x)",
               demuxed ? "" : "Muxed ",
               ddp ? "(DDP)" : "",
               (16 << density), vcc ? "2.65/3.3" : "1.8", device);
+
+       return dev_info;
 }
 
 static const struct onenand_manufacturers onenand_manuf_ids[] = {
@@ -1167,10 +1241,8 @@ static int onenand_probe(struct mtd_info *mtd)
        /* Reset OneNAND to read default register values */
        this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
 
-       {
-               int i;
-               for (i = 0; i < 10000; i++) ;
-       }
+       /* Wait reset */
+       this->wait(mtd, FL_RESETING);
 
        /* Read manufacturer and device IDs from Register */
        maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
@@ -1180,8 +1252,14 @@ static int onenand_probe(struct mtd_info *mtd)
        if (maf_id != bram_maf_id || dev_id != bram_dev_id)
                return -ENXIO;
 
+       /* FIXME : Current OneNAND MTD doesn't support Flex-OneNAND */
+       if (dev_id & (1 << 9)) {
+               printk("Not yet support Flex-OneNAND\n");
+               return -ENXIO;
+       }
+
        /* Flash device information */
-       onenand_print_device_info(dev_id, 0);
+       mtd->name = onenand_print_device_info(dev_id);
        this->device_id = dev_id;
 
        density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
@@ -1189,16 +1267,16 @@ static int onenand_probe(struct mtd_info *mtd)
 
        /* OneNAND page size & block size */
        /* The data buffer size is equal to page size */
-       mtd->oobblock =
+       mtd->writesize =
            this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
-       mtd->oobsize = mtd->oobblock >> 5;
+       mtd->oobsize = mtd->writesize >> 5;
        /* Pagers per block is always 64 in OneNAND */
-       mtd->erasesize = mtd->oobblock << 6;
+       mtd->erasesize = mtd->writesize << 6;
 
        this->erase_shift = ffs(mtd->erasesize) - 1;
-       this->page_shift = ffs(mtd->oobblock) - 1;
+       this->page_shift = ffs(mtd->writesize) - 1;
        this->ppb_shift = (this->erase_shift - this->page_shift);
-       this->page_mask = (mtd->erasesize / mtd->oobblock) - 1;
+       this->page_mask = (mtd->erasesize / mtd->writesize) - 1;
 
        /* REVIST: Multichip handling */
 
@@ -1217,6 +1295,16 @@ static int onenand_probe(struct mtd_info *mtd)
                this->options |= ONENAND_CONT_LOCK;
        }
 
+       mtd->flags = MTD_CAP_NANDFLASH;
+       mtd->erase = onenand_erase;
+       mtd->read = onenand_read;
+       mtd->write = onenand_write;
+       mtd->read_oob = onenand_read_oob;
+       mtd->write_oob = onenand_write_oob;
+       mtd->sync = onenand_sync;
+       mtd->block_isbad = onenand_block_isbad;
+       mtd->block_markbad = onenand_block_markbad;
+
        return 0;
 }
 
@@ -1270,25 +1358,3 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 void onenand_release(struct mtd_info *mtd)
 {
 }
-
-/*
- * OneNAND initialization at U-Boot
- */
-struct mtd_info onenand_mtd;
-struct onenand_chip onenand_chip;
-
-void onenand_init(void)
-{
-       memset(&onenand_mtd, 0, sizeof(struct mtd_info));
-       memset(&onenand_chip, 0, sizeof(struct onenand_chip));
-
-       onenand_chip.base = (void *)CFG_ONENAND_BASE;
-       onenand_mtd.priv = &onenand_chip;
-
-       onenand_scan(&onenand_mtd, 1);
-
-       puts("OneNAND: ");
-       print_size(onenand_mtd.size, "\n");
-}
-
-#endif /* CONFIG_CMD_ONENAND */