Commit 2df41d05 authored by Russell King's avatar Russell King

mtd: omap2: remove private DMA API implementation

Remove the private DMA API implementation from nand/omap2.c
making it use entirely the DMA engine API.
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 763e7359
...@@ -126,7 +126,6 @@ struct omap_nand_info { ...@@ -126,7 +126,6 @@ struct omap_nand_info {
unsigned long phys_base; unsigned long phys_base;
struct completion comp; struct completion comp;
struct dma_chan *dma; struct dma_chan *dma;
int dma_ch;
int gpmc_irq; int gpmc_irq;
enum { enum {
OMAP_NAND_IO_READ = 0, /* read */ OMAP_NAND_IO_READ = 0, /* read */
...@@ -339,15 +338,9 @@ static void omap_write_buf_pref(struct mtd_info *mtd, ...@@ -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 * omap_nand_dma_callback: callback on the completion of dma transfer
* @lch: logical channel
* @ch_satuts: channel status
* @data: pointer to completion data structure * @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) static void omap_nand_dma_callback(void *data)
{ {
complete((struct completion *) data); complete((struct completion *) data);
...@@ -365,17 +358,13 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, ...@@ -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 *info = container_of(mtd,
struct omap_nand_info, mtd); struct omap_nand_info, mtd);
struct dma_async_tx_descriptor *tx;
enum dma_data_direction dir = is_write ? DMA_TO_DEVICE : enum dma_data_direction dir = is_write ? DMA_TO_DEVICE :
DMA_FROM_DEVICE; DMA_FROM_DEVICE;
dma_addr_t dma_addr; struct scatterlist sg;
int ret;
unsigned long tim, limit; unsigned long tim, limit;
unsigned n;
/* The fifo depth is 64 bytes max. int ret;
* 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;
if (addr >= high_memory) { if (addr >= high_memory) {
struct page *p1; struct page *p1;
...@@ -389,89 +378,33 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, ...@@ -389,89 +378,33 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
addr = page_address(p1) + ((size_t)addr & ~PAGE_MASK); addr = page_address(p1) + ((size_t)addr & ~PAGE_MASK);
} }
if (info->dma) { sg_init_one(&sg, addr, len);
struct dma_async_tx_descriptor *tx; n = dma_map_sg(info->dma->device->dev, &sg, 1, dir);
struct scatterlist sg; if (n == 0) {
unsigned n;
sg_init_one(&sg, addr, len);
n = dma_map_sg(info->dma->device->dev, &sg, 1, dir);
if (n == 0) {
dev_err(&info->pdev->dev,
"Couldn't DMA map a %d byte buffer\n", len);
goto out_copy;
}
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;
}
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, dev_err(&info->pdev->dev,
"Couldn't DMA map a %d byte buffer\n", len); "Couldn't DMA map a %d byte buffer\n", len);
goto out_copy; goto out_copy;
} }
if (is_write) { tx = dmaengine_prep_slave_sg(info->dma, &sg, n,
omap_set_dma_dest_params(info->dma_ch, 0, OMAP_DMA_AMODE_CONSTANT, is_write ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
info->phys_base, 0, 0); DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
omap_set_dma_src_params(info->dma_ch, 0, OMAP_DMA_AMODE_POST_INC, if (!tx)
dma_addr, 0, 0); goto out_copy_unmap;
omap_set_dma_transfer_params(info->dma_ch, OMAP_DMA_DATA_TYPE_S32,
0x10, buf_len, OMAP_DMA_SYNC_FRAME, tx->callback = omap_nand_dma_callback;
OMAP24XX_DMA_GPMC, OMAP_DMA_DST_SYNC); tx->callback_param = &info->comp;
} else { dmaengine_submit(tx);
omap_set_dma_src_params(info->dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
info->phys_base, 0, 0); /* configure and start prefetch transfer */
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, ret = gpmc_prefetch_enable(info->gpmc_cs,
PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write); PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write);
if (ret) if (ret)
/* PFPW engine is busy, use cpu copy method */ /* PFPW engine is busy, use cpu copy method */
goto out_copy_unmap; goto out_copy_unmap;
init_completion(&info->comp); init_completion(&info->comp);
omap_start_dma(info->dma_ch); dma_async_issue_pending(info->dma);
/* setup and start DMA using dma_addr */ /* setup and start DMA using dma_addr */
wait_for_completion(&info->comp); wait_for_completion(&info->comp);
...@@ -483,11 +416,11 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, ...@@ -483,11 +416,11 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,
/* disable and stop the PFPW engine */ /* disable and stop the PFPW engine */
gpmc_prefetch_reset(info->gpmc_cs); 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; return 0;
out_copy_unmap: 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: out_copy:
if (info->nand.options & NAND_BUSWIDTH_16) if (info->nand.options & NAND_BUSWIDTH_16)
is_write == 0 ? omap_read_buf16(mtd, (u_char *) addr, len) is_write == 0 ? omap_read_buf16(mtd, (u_char *) addr, len)
...@@ -1307,7 +1240,9 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) ...@@ -1307,7 +1240,9 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
sig = OMAP24XX_DMA_GPMC; sig = OMAP24XX_DMA_GPMC;
info->dma = dma_request_channel(mask, omap_dma_filter_fn, &sig); info->dma = dma_request_channel(mask, omap_dma_filter_fn, &sig);
if (!info->dma) { 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 { } else {
struct dma_slave_config cfg; struct dma_slave_config cfg;
int rc; int rc;
...@@ -1327,22 +1262,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) ...@@ -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.read_buf = omap_read_buf_dma_pref;
info->nand.write_buf = omap_write_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; break;
...@@ -1460,9 +1379,6 @@ static int omap_nand_remove(struct platform_device *pdev) ...@@ -1460,9 +1379,6 @@ static int omap_nand_remove(struct platform_device *pdev)
omap3_free_bch(&info->mtd); omap3_free_bch(&info->mtd);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
if (info->dma_ch != -1)
omap_free_dma(info->dma_ch);
if (info->dma) if (info->dma)
dma_release_channel(info->dma); dma_release_channel(info->dma);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment