diff options
author | Peter Ujfalusi <peter.ujfalusi@ti.com> | 2018-01-12 08:16:08 -0500 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@free-electrons.com> | 2018-01-12 09:34:21 -0500 |
commit | 3ed6a4d1de2c5855a9e0164872b6adfd6b7a4215 (patch) | |
tree | fb0c65211c75464d404e9a9187a0ee89a4a5cce6 /drivers/mtd/onenand | |
parent | fb25070afdf07cc62282c27357dc30ef3d7ef262 (diff) |
mtd: onenand: omap2: Convert to use dmaengine for memcpy
Do not use the legacy and deprecated omap-dma interface for setting up the
memcpy.
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>
Diffstat (limited to 'drivers/mtd/onenand')
-rw-r--r-- | drivers/mtd/onenand/omap2.c | 80 |
1 files changed, 38 insertions, 42 deletions
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 36314124488d..c9ff67100ef4 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
34 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
35 | #include <linux/dmaengine.h> | ||
35 | #include <linux/io.h> | 36 | #include <linux/io.h> |
36 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
37 | #include <linux/gpio.h> | 38 | #include <linux/gpio.h> |
@@ -39,8 +40,6 @@ | |||
39 | #include <asm/mach/flash.h> | 40 | #include <asm/mach/flash.h> |
40 | #include <linux/platform_data/mtd-onenand-omap2.h> | 41 | #include <linux/platform_data/mtd-onenand-omap2.h> |
41 | 42 | ||
42 | #include <linux/omap-dma.h> | ||
43 | |||
44 | #define DRIVER_NAME "omap2-onenand" | 43 | #define DRIVER_NAME "omap2-onenand" |
45 | 44 | ||
46 | #define ONENAND_BUFRAM_SIZE (1024 * 5) | 45 | #define ONENAND_BUFRAM_SIZE (1024 * 5) |
@@ -55,17 +54,15 @@ struct omap2_onenand { | |||
55 | struct onenand_chip onenand; | 54 | struct onenand_chip onenand; |
56 | struct completion irq_done; | 55 | struct completion irq_done; |
57 | struct completion dma_done; | 56 | struct completion dma_done; |
58 | int dma_channel; | 57 | struct dma_chan *dma_chan; |
59 | int freq; | 58 | int freq; |
60 | int (*setup)(void __iomem *base, int *freq_ptr); | 59 | int (*setup)(void __iomem *base, int *freq_ptr); |
61 | u8 flags; | 60 | u8 flags; |
62 | }; | 61 | }; |
63 | 62 | ||
64 | static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data) | 63 | static void omap2_onenand_dma_complete_func(void *completion) |
65 | { | 64 | { |
66 | struct omap2_onenand *c = data; | 65 | complete(completion); |
67 | |||
68 | complete(&c->dma_done); | ||
69 | } | 66 | } |
70 | 67 | ||
71 | static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id) | 68 | static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id) |
@@ -292,23 +289,31 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c, | |||
292 | dma_addr_t src, dma_addr_t dst, | 289 | dma_addr_t src, dma_addr_t dst, |
293 | size_t count) | 290 | size_t count) |
294 | { | 291 | { |
295 | int data_type = __ffs((src | dst | count)); | 292 | struct dma_async_tx_descriptor *tx; |
293 | dma_cookie_t cookie; | ||
296 | 294 | ||
297 | if (data_type > OMAP_DMA_DATA_TYPE_S32) | 295 | tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, 0); |
298 | data_type = OMAP_DMA_DATA_TYPE_S32; | 296 | if (!tx) { |
299 | 297 | dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n"); | |
300 | omap_set_dma_transfer_params(c->dma_channel, data_type, | 298 | return -EIO; |
301 | count / BIT(data_type), 1, 0, 0, 0); | 299 | } |
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 | 300 | ||
307 | reinit_completion(&c->dma_done); | 301 | reinit_completion(&c->dma_done); |
308 | omap_start_dma(c->dma_channel); | 302 | |
303 | tx->callback = omap2_onenand_dma_complete_func; | ||
304 | tx->callback_param = &c->dma_done; | ||
305 | |||
306 | cookie = tx->tx_submit(tx); | ||
307 | if (dma_submit_error(cookie)) { | ||
308 | dev_err(&c->pdev->dev, "Failed to do DMA tx_submit\n"); | ||
309 | return -EIO; | ||
310 | } | ||
311 | |||
312 | dma_async_issue_pending(c->dma_chan); | ||
313 | |||
309 | if (!wait_for_completion_io_timeout(&c->dma_done, | 314 | if (!wait_for_completion_io_timeout(&c->dma_done, |
310 | msecs_to_jiffies(20))) { | 315 | msecs_to_jiffies(20))) { |
311 | omap_stop_dma(c->dma_channel); | 316 | dmaengine_terminate_sync(c->dma_chan); |
312 | return -ETIMEDOUT; | 317 | return -ETIMEDOUT; |
313 | } | 318 | } |
314 | 319 | ||
@@ -468,8 +473,7 @@ static int omap2_onenand_probe(struct platform_device *pdev) | |||
468 | c->flags = pdata->flags; | 473 | c->flags = pdata->flags; |
469 | c->gpmc_cs = pdata->cs; | 474 | c->gpmc_cs = pdata->cs; |
470 | c->gpio_irq = pdata->gpio_irq; | 475 | c->gpio_irq = pdata->gpio_irq; |
471 | c->dma_channel = pdata->dma_channel; | 476 | if (pdata->dma_channel < 0) { |
472 | if (c->dma_channel < 0) { | ||
473 | /* if -1, don't use DMA */ | 477 | /* if -1, don't use DMA */ |
474 | c->gpio_irq = 0; | 478 | c->gpio_irq = 0; |
475 | } | 479 | } |
@@ -521,25 +525,17 @@ static int omap2_onenand_probe(struct platform_device *pdev) | |||
521 | goto err_release_gpio; | 525 | goto err_release_gpio; |
522 | } | 526 | } |
523 | 527 | ||
524 | if (c->dma_channel >= 0) { | 528 | if (pdata->dma_channel >= 0) { |
525 | r = omap_request_dma(0, pdev->dev.driver->name, | 529 | dma_cap_mask_t mask; |
526 | omap2_onenand_dma_cb, (void *) c, | 530 | |
527 | &c->dma_channel); | 531 | dma_cap_zero(mask); |
528 | if (r == 0) { | 532 | dma_cap_set(DMA_MEMCPY, mask); |
529 | omap_set_dma_write_mode(c->dma_channel, | 533 | |
530 | OMAP_DMA_WRITE_NON_POSTED); | 534 | c->dma_chan = dma_request_channel(mask, NULL, NULL); |
531 | omap_set_dma_src_data_pack(c->dma_channel, 1); | 535 | if (!c->dma_chan) |
532 | omap_set_dma_src_burst_mode(c->dma_channel, | ||
533 | OMAP_DMA_DATA_BURST_8); | ||
534 | omap_set_dma_dest_data_pack(c->dma_channel, 1); | ||
535 | omap_set_dma_dest_burst_mode(c->dma_channel, | ||
536 | OMAP_DMA_DATA_BURST_8); | ||
537 | } else { | ||
538 | dev_info(&pdev->dev, | 536 | dev_info(&pdev->dev, |
539 | "failed to allocate DMA for OneNAND, " | 537 | "failed to allocate DMA for OneNAND, " |
540 | "using PIO instead\n"); | 538 | "using PIO instead\n"); |
541 | c->dma_channel = -1; | ||
542 | } | ||
543 | } | 539 | } |
544 | 540 | ||
545 | dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual " | 541 | dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual " |
@@ -553,7 +549,7 @@ static int omap2_onenand_probe(struct platform_device *pdev) | |||
553 | mtd_set_of_node(&c->mtd, pdata->of_node); | 549 | mtd_set_of_node(&c->mtd, pdata->of_node); |
554 | 550 | ||
555 | this = &c->onenand; | 551 | this = &c->onenand; |
556 | if (c->dma_channel >= 0) { | 552 | if (c->dma_chan) { |
557 | this->wait = omap2_onenand_wait; | 553 | this->wait = omap2_onenand_wait; |
558 | this->read_bufferram = omap2_onenand_read_bufferram; | 554 | this->read_bufferram = omap2_onenand_read_bufferram; |
559 | this->write_bufferram = omap2_onenand_write_bufferram; | 555 | this->write_bufferram = omap2_onenand_write_bufferram; |
@@ -573,8 +569,8 @@ static int omap2_onenand_probe(struct platform_device *pdev) | |||
573 | err_release_onenand: | 569 | err_release_onenand: |
574 | onenand_release(&c->mtd); | 570 | onenand_release(&c->mtd); |
575 | err_release_dma: | 571 | err_release_dma: |
576 | if (c->dma_channel != -1) | 572 | if (c->dma_chan) |
577 | omap_free_dma(c->dma_channel); | 573 | dma_release_channel(c->dma_chan); |
578 | if (c->gpio_irq) | 574 | if (c->gpio_irq) |
579 | free_irq(gpio_to_irq(c->gpio_irq), c); | 575 | free_irq(gpio_to_irq(c->gpio_irq), c); |
580 | err_release_gpio: | 576 | err_release_gpio: |
@@ -595,8 +591,8 @@ static int omap2_onenand_remove(struct platform_device *pdev) | |||
595 | struct omap2_onenand *c = dev_get_drvdata(&pdev->dev); | 591 | struct omap2_onenand *c = dev_get_drvdata(&pdev->dev); |
596 | 592 | ||
597 | onenand_release(&c->mtd); | 593 | onenand_release(&c->mtd); |
598 | if (c->dma_channel != -1) | 594 | if (c->dma_chan) |
599 | omap_free_dma(c->dma_channel); | 595 | dma_release_channel(c->dma_chan); |
600 | omap2_onenand_shutdown(pdev); | 596 | omap2_onenand_shutdown(pdev); |
601 | if (c->gpio_irq) { | 597 | if (c->gpio_irq) { |
602 | free_irq(gpio_to_irq(c->gpio_irq), c); | 598 | free_irq(gpio_to_irq(c->gpio_irq), c); |