Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / drivers / mtd / nand / omap2.c
index 297c965..1a62f71 100644 (file)
@@ -24,6 +24,7 @@
 #include <plat/dma.h>
 #include <plat/gpmc.h>
 #include <plat/nand.h>
+#include <asm/system.h>
 
 #define        DRIVER_NAME     "omap2-nand"
 #define        OMAP_NAND_TIMEOUT_MS    5000
@@ -402,14 +403,18 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
                        PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write);
        if (ret)
                /* PFPW engine is busy, use cpu copy method */
-               goto out_copy;
+               goto out_copy_unmap;
 
+       /* this will be short, avoid CPU wakeup latency */
+       disable_hlt();
        init_completion(&info->comp);
 
        omap_start_dma(info->dma_ch);
 
        /* setup and start DMA using dma_addr */
        wait_for_completion(&info->comp);
+       enable_hlt();
+
        tim = 0;
        limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS));
        while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit))
@@ -421,6 +426,8 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
        dma_unmap_single(&info->pdev->dev, dma_addr, len, dir);
        return 0;
 
+out_copy_unmap:
+       dma_unmap_single(&info->pdev->dev, dma_addr, len, dir);
 out_copy:
        if (info->nand.options & NAND_BUSWIDTH_16)
                is_write == 0 ? omap_read_buf16(mtd, (u_char *) addr, len)
@@ -861,68 +868,13 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode)
        gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size);
 }
 
-/**
- * omap_wait - wait until the command is done
- * @mtd: MTD device structure
- * @chip: NAND Chip structure
- *
- * Wait function is called during Program and erase operations and
- * the way it is called from MTD layer, we should wait till the NAND
- * chip is ready after the programming/erase operation has completed.
- *
- * Erase can take up to 400ms and program up to 20ms according to
- * general NAND and SmartMedia specs
- */
-static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
-{
-       struct nand_chip *this = mtd->priv;
-       struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-                                                       mtd);
-       unsigned long timeo = jiffies;
-       int status = NAND_STATUS_FAIL, state = this->state;
-
-       if (state == FL_ERASING)
-               timeo += (HZ * 400) / 1000;
-       else
-               timeo += (HZ * 20) / 1000;
-
-       gpmc_nand_write(info->gpmc_cs,
-                       GPMC_NAND_COMMAND, (NAND_CMD_STATUS & 0xFF));
-       while (time_before(jiffies, timeo)) {
-               status = gpmc_nand_read(info->gpmc_cs, GPMC_NAND_DATA);
-               if (status & NAND_STATUS_READY)
-                       break;
-               cond_resched();
-       }
-       return status;
-}
-
 /**
  * omap_dev_ready - calls the platform specific dev_ready function
  * @mtd: MTD device structure
  */
 static int omap_dev_ready(struct mtd_info *mtd)
 {
-       unsigned int val = 0;
-       struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-                                                       mtd);
-
-       val = gpmc_read_status(GPMC_GET_IRQ_STATUS);
-       if ((val & 0x100) == 0x100) {
-               /* Clear IRQ Interrupt */
-               val |= 0x100;
-               val &= ~(0x0);
-               gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, val);
-       } else {
-               unsigned int cnt = 0;
-               while (cnt++ < 0x1FF) {
-                       if  ((val & 0x100) == 0x100)
-                               return 0;
-                       val = gpmc_read_status(GPMC_GET_IRQ_STATUS);
-               }
-       }
-
-       return 1;
+       return !!gpmc_read_status(GPMC_STATUS_WAIT);
 }
 
 static int __devinit omap_nand_probe(struct platform_device *pdev)
@@ -990,7 +942,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
                info->nand.dev_ready = omap_dev_ready;
                info->nand.chip_delay = 0;
        } else {
-               info->nand.waitfunc = omap_wait;
                info->nand.chip_delay = 50;
        }