Skip to content

Commit 3621311

Browse files
Peter UjfalusiBoris Brezillon
authored andcommitted
mtd: onenand: omap2: Simplify the DMA setup for various paths
We have 4 functions containing almost identical DMA setup code. Create one function which can set up the DMA for both read and write and use this in place for the setup code in the driver. The new function will use wait_for_completion_io_timeout() and it will figure out the best data_type to be used for the transfer instead of hardwiring 32 or 16 bit data. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Signed-off-by: Ladislav Michl <ladis@linux-mips.org> Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk> Acked-by: Roger Quadros <rogerq@ti.com> Tested-by: Tony Lindgren <tony@atomide.com> Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
1 parent d120568 commit 3621311

File tree

1 file changed

+45
-64
lines changed

1 file changed

+45
-64
lines changed

drivers/mtd/onenand/omap2.c

Lines changed: 45 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,33 @@ static inline int omap2_onenand_bufferram_offset(struct mtd_info *mtd, int area)
288288
return 0;
289289
}
290290

291+
static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
292+
dma_addr_t src, dma_addr_t dst,
293+
size_t count)
294+
{
295+
int data_type = __ffs((src | dst | count));
296+
297+
if (data_type > OMAP_DMA_DATA_TYPE_S32)
298+
data_type = OMAP_DMA_DATA_TYPE_S32;
299+
300+
omap_set_dma_transfer_params(c->dma_channel, data_type,
301+
count / BIT(data_type), 1, 0, 0, 0);
302+
omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
303+
src, 0, 0);
304+
omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
305+
dst, 0, 0);
306+
307+
reinit_completion(&c->dma_done);
308+
omap_start_dma(c->dma_channel);
309+
if (!wait_for_completion_io_timeout(&c->dma_done,
310+
msecs_to_jiffies(20))) {
311+
omap_stop_dma(c->dma_channel);
312+
return -ETIMEDOUT;
313+
}
314+
315+
return 0;
316+
}
317+
291318
#if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
292319

293320
static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
@@ -298,10 +325,9 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
298325
struct onenand_chip *this = mtd->priv;
299326
dma_addr_t dma_src, dma_dst;
300327
int bram_offset;
301-
unsigned long timeout;
302328
void *buf = (void *)buffer;
303329
size_t xtra;
304-
volatile unsigned *done;
330+
int ret;
305331

306332
bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
307333
if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
@@ -338,25 +364,10 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
338364
goto out_copy;
339365
}
340366

341-
omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
342-
count >> 2, 1, 0, 0, 0);
343-
omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
344-
dma_src, 0, 0);
345-
omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
346-
dma_dst, 0, 0);
347-
348-
reinit_completion(&c->dma_done);
349-
omap_start_dma(c->dma_channel);
350-
351-
timeout = jiffies + msecs_to_jiffies(20);
352-
done = &c->dma_done.done;
353-
while (time_before(jiffies, timeout))
354-
if (*done)
355-
break;
356-
367+
ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
357368
dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
358369

359-
if (!*done) {
370+
if (ret) {
360371
dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
361372
goto out_copy;
362373
}
@@ -376,9 +387,8 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
376387
struct onenand_chip *this = mtd->priv;
377388
dma_addr_t dma_src, dma_dst;
378389
int bram_offset;
379-
unsigned long timeout;
380390
void *buf = (void *)buffer;
381-
volatile unsigned *done;
391+
int ret;
382392

383393
bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
384394
if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
@@ -409,25 +419,10 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
409419
return -1;
410420
}
411421

412-
omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
413-
count >> 2, 1, 0, 0, 0);
414-
omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
415-
dma_src, 0, 0);
416-
omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
417-
dma_dst, 0, 0);
418-
419-
reinit_completion(&c->dma_done);
420-
omap_start_dma(c->dma_channel);
421-
422-
timeout = jiffies + msecs_to_jiffies(20);
423-
done = &c->dma_done.done;
424-
while (time_before(jiffies, timeout))
425-
if (*done)
426-
break;
427-
422+
ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
428423
dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
429424

430-
if (!*done) {
425+
if (ret) {
431426
dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
432427
goto out_copy;
433428
}
@@ -466,7 +461,7 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
466461
struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
467462
struct onenand_chip *this = mtd->priv;
468463
dma_addr_t dma_src, dma_dst;
469-
int bram_offset;
464+
int bram_offset, ret;
470465

471466
bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
472467
/* DMA is not used. Revisit PM requirements before enabling it. */
@@ -488,20 +483,13 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
488483
return -1;
489484
}
490485

491-
omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
492-
count / 4, 1, 0, 0, 0);
493-
omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
494-
dma_src, 0, 0);
495-
omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
496-
dma_dst, 0, 0);
497-
498-
reinit_completion(&c->dma_done);
499-
omap_start_dma(c->dma_channel);
500-
wait_for_completion(&c->dma_done);
501-
486+
ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
502487
dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
503488

504-
return 0;
489+
if (ret)
490+
dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
491+
492+
return ret;
505493
}
506494

507495
static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
@@ -511,7 +499,7 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
511499
struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
512500
struct onenand_chip *this = mtd->priv;
513501
dma_addr_t dma_src, dma_dst;
514-
int bram_offset;
502+
int bram_offset, ret;
515503

516504
bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
517505
/* DMA is not used. Revisit PM requirements before enabling it. */
@@ -533,20 +521,13 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
533521
return -1;
534522
}
535523

536-
omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S16,
537-
count / 2, 1, 0, 0, 0);
538-
omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
539-
dma_src, 0, 0);
540-
omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
541-
dma_dst, 0, 0);
542-
543-
reinit_completion(&c->dma_done);
544-
omap_start_dma(c->dma_channel);
545-
wait_for_completion(&c->dma_done);
546-
524+
ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
547525
dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
548526

549-
return 0;
527+
if (ret)
528+
dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
529+
530+
return ret;
550531
}
551532

552533
#else

0 commit comments

Comments
 (0)