Loading drivers/mtd/nand/omap2.c +26 −110 Original line number Diff line number Diff line Loading @@ -126,7 +126,6 @@ struct omap_nand_info { unsigned long phys_base; struct completion comp; struct dma_chan *dma; int dma_ch; int gpmc_irq; enum { OMAP_NAND_IO_READ = 0, /* read */ Loading Loading @@ -339,15 +338,9 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } /* * omap_nand_dma_cb: callback on the completion of dma transfer * @lch: logical channel * @ch_satuts: channel status * omap_nand_dma_callback: callback on the completion of dma transfer * @data: pointer to completion data structure */ static void omap_nand_dma_cb(int lch, u16 ch_status, void *data) { complete((struct completion *) data); } static void omap_nand_dma_callback(void *data) { complete((struct completion *) data); Loading @@ -365,17 +358,13 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, { struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); struct dma_async_tx_descriptor *tx; enum dma_data_direction dir = is_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE; dma_addr_t dma_addr; int ret; struct scatterlist sg; unsigned long tim, limit; /* The fifo depth is 64 bytes max. * But configure the FIFO-threahold to 32 to get a sync at each frame * and frame length is 32 bytes. */ int buf_len = len >> 6; unsigned n; int ret; if (addr >= high_memory) { struct page *p1; Loading @@ -389,11 +378,6 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, addr = page_address(p1) + ((size_t)addr & ~PAGE_MASK); } if (info->dma) { struct dma_async_tx_descriptor *tx; struct scatterlist sg; unsigned n; sg_init_one(&sg, addr, len); n = dma_map_sg(info->dma->device->dev, &sg, 1, dir); if (n == 0) { Loading @@ -405,64 +389,13 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, tx = dmaengine_prep_slave_sg(info->dma, &sg, n, is_write ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!tx) { dma_unmap_sg(info->dma->device->dev, &sg, 1, dir); goto out_copy; } if (!tx) goto out_copy_unmap; tx->callback = omap_nand_dma_callback; tx->callback_param = &info->comp; dmaengine_submit(tx); /* configure and start prefetch transfer */ ret = gpmc_prefetch_enable(info->gpmc_cs, PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write); if (ret) { /* PFPW engine is busy, use cpu copy method */ dma_unmap_sg(info->dma->device->dev, &sg, 1, dir); goto out_copy; } init_completion(&info->comp); dma_async_issue_pending(info->dma); /* setup and start DMA using dma_addr */ wait_for_completion(&info->comp); tim = 0; limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) cpu_relax(); /* disable and stop the PFPW engine */ gpmc_prefetch_reset(info->gpmc_cs); dma_unmap_sg(info->dma->device->dev, &sg, 1, dir); return 0; } dma_addr = dma_map_single(&info->pdev->dev, addr, len, dir); if (dma_mapping_error(&info->pdev->dev, dma_addr)) { dev_err(&info->pdev->dev, "Couldn't DMA map a %d byte buffer\n", len); goto out_copy; } if (is_write) { omap_set_dma_dest_params(info->dma_ch, 0, OMAP_DMA_AMODE_CONSTANT, info->phys_base, 0, 0); omap_set_dma_src_params(info->dma_ch, 0, OMAP_DMA_AMODE_POST_INC, dma_addr, 0, 0); omap_set_dma_transfer_params(info->dma_ch, OMAP_DMA_DATA_TYPE_S32, 0x10, buf_len, OMAP_DMA_SYNC_FRAME, OMAP24XX_DMA_GPMC, OMAP_DMA_DST_SYNC); } else { omap_set_dma_src_params(info->dma_ch, 0, OMAP_DMA_AMODE_CONSTANT, info->phys_base, 0, 0); omap_set_dma_dest_params(info->dma_ch, 0, OMAP_DMA_AMODE_POST_INC, dma_addr, 0, 0); omap_set_dma_transfer_params(info->dma_ch, OMAP_DMA_DATA_TYPE_S32, 0x10, buf_len, OMAP_DMA_SYNC_FRAME, OMAP24XX_DMA_GPMC, OMAP_DMA_SRC_SYNC); } /* configure and start prefetch transfer */ ret = gpmc_prefetch_enable(info->gpmc_cs, PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write); Loading @@ -471,7 +404,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, goto out_copy_unmap; init_completion(&info->comp); omap_start_dma(info->dma_ch); dma_async_issue_pending(info->dma); /* setup and start DMA using dma_addr */ wait_for_completion(&info->comp); Loading @@ -483,11 +416,11 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, /* disable and stop the PFPW engine */ gpmc_prefetch_reset(info->gpmc_cs); dma_unmap_single(&info->pdev->dev, dma_addr, len, dir); dma_unmap_sg(info->dma->device->dev, &sg, 1, dir); return 0; out_copy_unmap: dma_unmap_single(&info->pdev->dev, dma_addr, len, dir); dma_unmap_sg(info->dma->device->dev, &sg, 1, dir); out_copy: if (info->nand.options & NAND_BUSWIDTH_16) is_write == 0 ? omap_read_buf16(mtd, (u_char *) addr, len) Loading Loading @@ -1307,7 +1240,9 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) sig = OMAP24XX_DMA_GPMC; info->dma = dma_request_channel(mask, omap_dma_filter_fn, &sig); if (!info->dma) { dev_warn(&pdev->dev, "DMA engine request failed\n"); dev_err(&pdev->dev, "DMA engine request failed\n"); err = -ENXIO; goto out_release_mem_region; } else { struct dma_slave_config cfg; int rc; Loading @@ -1327,22 +1262,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } info->nand.read_buf = omap_read_buf_dma_pref; info->nand.write_buf = omap_write_buf_dma_pref; break; } err = omap_request_dma(OMAP24XX_DMA_GPMC, "NAND", omap_nand_dma_cb, &info->comp, &info->dma_ch); if (err < 0) { info->dma_ch = -1; dev_err(&pdev->dev, "DMA request failed!\n"); goto out_release_mem_region; } else { omap_set_dma_dest_burst_mode(info->dma_ch, OMAP_DMA_DATA_BURST_16); omap_set_dma_src_burst_mode(info->dma_ch, OMAP_DMA_DATA_BURST_16); info->nand.read_buf = omap_read_buf_dma_pref; info->nand.write_buf = omap_write_buf_dma_pref; } break; Loading Loading @@ -1460,9 +1379,6 @@ static int omap_nand_remove(struct platform_device *pdev) omap3_free_bch(&info->mtd); platform_set_drvdata(pdev, NULL); if (info->dma_ch != -1) omap_free_dma(info->dma_ch); if (info->dma) dma_release_channel(info->dma); Loading Loading
drivers/mtd/nand/omap2.c +26 −110 Original line number Diff line number Diff line Loading @@ -126,7 +126,6 @@ struct omap_nand_info { unsigned long phys_base; struct completion comp; struct dma_chan *dma; int dma_ch; int gpmc_irq; enum { OMAP_NAND_IO_READ = 0, /* read */ Loading Loading @@ -339,15 +338,9 @@ static void omap_write_buf_pref(struct mtd_info *mtd, } /* * omap_nand_dma_cb: callback on the completion of dma transfer * @lch: logical channel * @ch_satuts: channel status * omap_nand_dma_callback: callback on the completion of dma transfer * @data: pointer to completion data structure */ static void omap_nand_dma_cb(int lch, u16 ch_status, void *data) { complete((struct completion *) data); } static void omap_nand_dma_callback(void *data) { complete((struct completion *) data); Loading @@ -365,17 +358,13 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, { struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd); struct dma_async_tx_descriptor *tx; enum dma_data_direction dir = is_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE; dma_addr_t dma_addr; int ret; struct scatterlist sg; unsigned long tim, limit; /* The fifo depth is 64 bytes max. * But configure the FIFO-threahold to 32 to get a sync at each frame * and frame length is 32 bytes. */ int buf_len = len >> 6; unsigned n; int ret; if (addr >= high_memory) { struct page *p1; Loading @@ -389,11 +378,6 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, addr = page_address(p1) + ((size_t)addr & ~PAGE_MASK); } if (info->dma) { struct dma_async_tx_descriptor *tx; struct scatterlist sg; unsigned n; sg_init_one(&sg, addr, len); n = dma_map_sg(info->dma->device->dev, &sg, 1, dir); if (n == 0) { Loading @@ -405,64 +389,13 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, tx = dmaengine_prep_slave_sg(info->dma, &sg, n, is_write ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!tx) { dma_unmap_sg(info->dma->device->dev, &sg, 1, dir); goto out_copy; } if (!tx) goto out_copy_unmap; tx->callback = omap_nand_dma_callback; tx->callback_param = &info->comp; dmaengine_submit(tx); /* configure and start prefetch transfer */ ret = gpmc_prefetch_enable(info->gpmc_cs, PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write); if (ret) { /* PFPW engine is busy, use cpu copy method */ dma_unmap_sg(info->dma->device->dev, &sg, 1, dir); goto out_copy; } init_completion(&info->comp); dma_async_issue_pending(info->dma); /* setup and start DMA using dma_addr */ wait_for_completion(&info->comp); tim = 0; limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) cpu_relax(); /* disable and stop the PFPW engine */ gpmc_prefetch_reset(info->gpmc_cs); dma_unmap_sg(info->dma->device->dev, &sg, 1, dir); return 0; } dma_addr = dma_map_single(&info->pdev->dev, addr, len, dir); if (dma_mapping_error(&info->pdev->dev, dma_addr)) { dev_err(&info->pdev->dev, "Couldn't DMA map a %d byte buffer\n", len); goto out_copy; } if (is_write) { omap_set_dma_dest_params(info->dma_ch, 0, OMAP_DMA_AMODE_CONSTANT, info->phys_base, 0, 0); omap_set_dma_src_params(info->dma_ch, 0, OMAP_DMA_AMODE_POST_INC, dma_addr, 0, 0); omap_set_dma_transfer_params(info->dma_ch, OMAP_DMA_DATA_TYPE_S32, 0x10, buf_len, OMAP_DMA_SYNC_FRAME, OMAP24XX_DMA_GPMC, OMAP_DMA_DST_SYNC); } else { omap_set_dma_src_params(info->dma_ch, 0, OMAP_DMA_AMODE_CONSTANT, info->phys_base, 0, 0); omap_set_dma_dest_params(info->dma_ch, 0, OMAP_DMA_AMODE_POST_INC, dma_addr, 0, 0); omap_set_dma_transfer_params(info->dma_ch, OMAP_DMA_DATA_TYPE_S32, 0x10, buf_len, OMAP_DMA_SYNC_FRAME, OMAP24XX_DMA_GPMC, OMAP_DMA_SRC_SYNC); } /* configure and start prefetch transfer */ ret = gpmc_prefetch_enable(info->gpmc_cs, PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write); Loading @@ -471,7 +404,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, goto out_copy_unmap; init_completion(&info->comp); omap_start_dma(info->dma_ch); dma_async_issue_pending(info->dma); /* setup and start DMA using dma_addr */ wait_for_completion(&info->comp); Loading @@ -483,11 +416,11 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, /* disable and stop the PFPW engine */ gpmc_prefetch_reset(info->gpmc_cs); dma_unmap_single(&info->pdev->dev, dma_addr, len, dir); dma_unmap_sg(info->dma->device->dev, &sg, 1, dir); return 0; out_copy_unmap: dma_unmap_single(&info->pdev->dev, dma_addr, len, dir); dma_unmap_sg(info->dma->device->dev, &sg, 1, dir); out_copy: if (info->nand.options & NAND_BUSWIDTH_16) is_write == 0 ? omap_read_buf16(mtd, (u_char *) addr, len) Loading Loading @@ -1307,7 +1240,9 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) sig = OMAP24XX_DMA_GPMC; info->dma = dma_request_channel(mask, omap_dma_filter_fn, &sig); if (!info->dma) { dev_warn(&pdev->dev, "DMA engine request failed\n"); dev_err(&pdev->dev, "DMA engine request failed\n"); err = -ENXIO; goto out_release_mem_region; } else { struct dma_slave_config cfg; int rc; Loading @@ -1327,22 +1262,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) } info->nand.read_buf = omap_read_buf_dma_pref; info->nand.write_buf = omap_write_buf_dma_pref; break; } err = omap_request_dma(OMAP24XX_DMA_GPMC, "NAND", omap_nand_dma_cb, &info->comp, &info->dma_ch); if (err < 0) { info->dma_ch = -1; dev_err(&pdev->dev, "DMA request failed!\n"); goto out_release_mem_region; } else { omap_set_dma_dest_burst_mode(info->dma_ch, OMAP_DMA_DATA_BURST_16); omap_set_dma_src_burst_mode(info->dma_ch, OMAP_DMA_DATA_BURST_16); info->nand.read_buf = omap_read_buf_dma_pref; info->nand.write_buf = omap_write_buf_dma_pref; } break; Loading Loading @@ -1460,9 +1379,6 @@ static int omap_nand_remove(struct platform_device *pdev) omap3_free_bch(&info->mtd); platform_set_drvdata(pdev, NULL); if (info->dma_ch != -1) omap_free_dma(info->dma_ch); if (info->dma) dma_release_channel(info->dma); Loading