Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
[safe/jmp/linux-2.6] / drivers / mtd / onenand / omap2.c
index f2e9de1..9f322f1 100644 (file)
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 
 #include <asm/mach/flash.h>
-#include <mach/gpmc.h>
-#include <mach/onenand.h>
+#include <plat/gpmc.h>
+#include <plat/onenand.h>
 #include <mach/gpio.h>
-#include <mach/pm.h>
 
-#include <mach/dma.h>
+#include <plat/dma.h>
 
-#include <mach/board.h>
+#include <plat/board.h>
 
 #define DRIVER_NAME "omap2-onenand"
 
@@ -113,10 +113,24 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
        unsigned long timeout;
        u32 syscfg;
 
-       if (state == FL_RESETING) {
-               int i;
+       if (state == FL_RESETING || state == FL_PREPARING_ERASE ||
+           state == FL_VERIFYING_ERASE) {
+               int i = 21;
+               unsigned int intr_flags = ONENAND_INT_MASTER;
 
-               for (i = 0; i < 20; i++) {
+               switch (state) {
+               case FL_RESETING:
+                       intr_flags |= ONENAND_INT_RESET;
+                       break;
+               case FL_PREPARING_ERASE:
+                       intr_flags |= ONENAND_INT_ERASE;
+                       break;
+               case FL_VERIFYING_ERASE:
+                       i = 101;
+                       break;
+               }
+
+               while (--i) {
                        udelay(1);
                        intr = read_reg(c, ONENAND_REG_INTERRUPT);
                        if (intr & ONENAND_INT_MASTER)
@@ -127,7 +141,7 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
                        wait_err("controller error", state, ctrl, intr);
                        return -EIO;
                }
-               if (!(intr & ONENAND_INT_RESET)) {
+               if ((intr & intr_flags) != intr_flags) {
                        wait_err("timeout", state, ctrl, intr);
                        return -EIO;
                }
@@ -267,7 +281,7 @@ static inline int omap2_onenand_bufferram_offset(struct mtd_info *mtd, int area)
 
        if (ONENAND_CURRENT_BUFFERRAM(this)) {
                if (area == ONENAND_DATARAM)
-                       return mtd->writesize;
+                       return this->writesize;
                if (area == ONENAND_SPARERAM)
                        return mtd->oobsize;
        }
@@ -295,7 +309,7 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
                goto out_copy;
 
        /* panic_write() may be in an interrupt context */
-       if (in_interrupt())
+       if (in_interrupt() || oops_in_progress)
                goto out_copy;
 
        if (buf >= high_memory) {
@@ -372,7 +386,7 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
                goto out_copy;
 
        /* panic_write() may be in an interrupt context */
-       if (in_interrupt())
+       if (in_interrupt() || oops_in_progress)
                goto out_copy;
 
        if (buf >= high_memory) {
@@ -389,7 +403,7 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
 
        dma_src = dma_map_single(&c->pdev->dev, buf, count, DMA_TO_DEVICE);
        dma_dst = c->phys_base + bram_offset;
-       if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
+       if (dma_mapping_error(&c->pdev->dev, dma_src)) {
                dev_err(&c->pdev->dev,
                        "Couldn't DMA map a %d byte buffer\n",
                        count);
@@ -412,7 +426,7 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
                if (*done)
                        break;
 
-       dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_TO_DEVICE);
+       dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
 
        if (!*done) {
                dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
@@ -507,7 +521,7 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
        dma_src = dma_map_single(&c->pdev->dev, (void *) buffer, count,
                                 DMA_TO_DEVICE);
        dma_dst = c->phys_base + bram_offset;
-       if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
+       if (dma_mapping_error(&c->pdev->dev, dma_src)) {
                dev_err(&c->pdev->dev,
                        "Couldn't DMA map a %d byte buffer\n",
                        count);
@@ -525,7 +539,7 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
        omap_start_dma(c->dma_channel);
        wait_for_completion(&c->dma_done);
 
-       dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_TO_DEVICE);
+       dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
 
        return 0;
 }
@@ -566,7 +580,7 @@ int omap2_onenand_rephase(void)
                                      NULL, __adjust_timing);
 }
 
-static void __devexit omap2_onenand_shutdown(struct platform_device *pdev)
+static void omap2_onenand_shutdown(struct platform_device *pdev)
 {
        struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
 
@@ -771,6 +785,7 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev)
        }
        iounmap(c->onenand.base);
        release_mem_region(c->phys_base, ONENAND_IO_SIZE);
+       gpmc_cs_free(c->gpmc_cs);
        kfree(c);
 
        return 0;
@@ -778,7 +793,7 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev)
 
 static struct platform_driver omap2_onenand_driver = {
        .probe          = omap2_onenand_probe,
-       .remove         = omap2_onenand_remove,
+       .remove         = __devexit_p(omap2_onenand_remove),
        .shutdown       = omap2_onenand_shutdown,
        .driver         = {
                .name   = DRIVER_NAME,