Merge branch 'Makefile' of git://git.denx.de/u-boot-arm
[platform/kernel/u-boot.git] / drivers / mtd / onenand / onenand_base.c
index 174384e..7c9438b 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(void *dst, const void *src, unsigned int len)
+static inline void *memcpy_16(void *dst, const void *src, unsigned int len)
 {
        void *ret = dst;
        short *d = dst;
@@ -293,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;
                }
        }
@@ -358,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;
 }
@@ -385,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);
 
@@ -412,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;
 }
@@ -524,13 +522,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;
        }
@@ -561,8 +560,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;
                }
 
@@ -615,16 +614,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;
        }
 
@@ -652,8 +652,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;
                }
 
@@ -678,13 +678,11 @@ 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;
@@ -733,23 +731,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;
        }
 
@@ -772,18 +771,18 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
 
                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;
                }
 
@@ -836,16 +835,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;
        }
 
@@ -904,28 +904,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;
        }
 
@@ -950,12 +951,12 @@ int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
                /* 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;
@@ -988,7 +989,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);
@@ -1107,21 +1108,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[] = {
@@ -1200,7 +1201,7 @@ static int onenand_probe(struct mtd_info *mtd)
        }
 
        /* 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;
@@ -1236,6 +1237,17 @@ static int onenand_probe(struct mtd_info *mtd)
                this->options |= ONENAND_CONT_LOCK;
        }
 
+       mtd->erase = onenand_erase;
+       mtd->read = onenand_read;
+       mtd->write = onenand_write;
+       mtd->read_ecc = onenand_read_ecc;
+       mtd->write_ecc = onenand_write_ecc;
+       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;
 }
 
@@ -1289,5 +1301,3 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 void onenand_release(struct mtd_info *mtd)
 {
 }
-
-#endif /* CONFIG_CMD_ONENAND */