diff options
Diffstat (limited to 'drivers/dma/shdma.c')
-rw-r--r-- | drivers/dma/shdma.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 323afef77802..a2a519fd2a24 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
@@ -597,12 +597,17 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( | |||
597 | direction, flags); | 597 | direction, flags); |
598 | } | 598 | } |
599 | 599 | ||
600 | static void sh_dmae_terminate_all(struct dma_chan *chan) | 600 | static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, |
601 | unsigned long arg) | ||
601 | { | 602 | { |
602 | struct sh_dmae_chan *sh_chan = to_sh_chan(chan); | 603 | struct sh_dmae_chan *sh_chan = to_sh_chan(chan); |
603 | 604 | ||
605 | /* Only supports DMA_TERMINATE_ALL */ | ||
606 | if (cmd != DMA_TERMINATE_ALL) | ||
607 | return -ENXIO; | ||
608 | |||
604 | if (!chan) | 609 | if (!chan) |
605 | return; | 610 | return -EINVAL; |
606 | 611 | ||
607 | dmae_halt(sh_chan); | 612 | dmae_halt(sh_chan); |
608 | 613 | ||
@@ -618,6 +623,8 @@ static void sh_dmae_terminate_all(struct dma_chan *chan) | |||
618 | spin_unlock_bh(&sh_chan->desc_lock); | 623 | spin_unlock_bh(&sh_chan->desc_lock); |
619 | 624 | ||
620 | sh_dmae_chan_ld_cleanup(sh_chan, true); | 625 | sh_dmae_chan_ld_cleanup(sh_chan, true); |
626 | |||
627 | return 0; | ||
621 | } | 628 | } |
622 | 629 | ||
623 | static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) | 630 | static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) |
@@ -715,6 +722,10 @@ static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) | |||
715 | { | 722 | { |
716 | while (__ld_cleanup(sh_chan, all)) | 723 | while (__ld_cleanup(sh_chan, all)) |
717 | ; | 724 | ; |
725 | |||
726 | if (all) | ||
727 | /* Terminating - forgive uncompleted cookies */ | ||
728 | sh_chan->completed_cookie = sh_chan->common.cookie; | ||
718 | } | 729 | } |
719 | 730 | ||
720 | static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) | 731 | static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) |
@@ -749,10 +760,9 @@ static void sh_dmae_memcpy_issue_pending(struct dma_chan *chan) | |||
749 | sh_chan_xfer_ld_queue(sh_chan); | 760 | sh_chan_xfer_ld_queue(sh_chan); |
750 | } | 761 | } |
751 | 762 | ||
752 | static enum dma_status sh_dmae_is_complete(struct dma_chan *chan, | 763 | static enum dma_status sh_dmae_tx_status(struct dma_chan *chan, |
753 | dma_cookie_t cookie, | 764 | dma_cookie_t cookie, |
754 | dma_cookie_t *done, | 765 | struct dma_tx_state *txstate) |
755 | dma_cookie_t *used) | ||
756 | { | 766 | { |
757 | struct sh_dmae_chan *sh_chan = to_sh_chan(chan); | 767 | struct sh_dmae_chan *sh_chan = to_sh_chan(chan); |
758 | dma_cookie_t last_used; | 768 | dma_cookie_t last_used; |
@@ -764,12 +774,7 @@ static enum dma_status sh_dmae_is_complete(struct dma_chan *chan, | |||
764 | last_used = chan->cookie; | 774 | last_used = chan->cookie; |
765 | last_complete = sh_chan->completed_cookie; | 775 | last_complete = sh_chan->completed_cookie; |
766 | BUG_ON(last_complete < 0); | 776 | BUG_ON(last_complete < 0); |
767 | 777 | dma_set_tx_state(txstate, last_complete, last_used, 0); | |
768 | if (done) | ||
769 | *done = last_complete; | ||
770 | |||
771 | if (used) | ||
772 | *used = last_used; | ||
773 | 778 | ||
774 | spin_lock_bh(&sh_chan->desc_lock); | 779 | spin_lock_bh(&sh_chan->desc_lock); |
775 | 780 | ||
@@ -1041,12 +1046,12 @@ static int __init sh_dmae_probe(struct platform_device *pdev) | |||
1041 | = sh_dmae_alloc_chan_resources; | 1046 | = sh_dmae_alloc_chan_resources; |
1042 | shdev->common.device_free_chan_resources = sh_dmae_free_chan_resources; | 1047 | shdev->common.device_free_chan_resources = sh_dmae_free_chan_resources; |
1043 | shdev->common.device_prep_dma_memcpy = sh_dmae_prep_memcpy; | 1048 | shdev->common.device_prep_dma_memcpy = sh_dmae_prep_memcpy; |
1044 | shdev->common.device_is_tx_complete = sh_dmae_is_complete; | 1049 | shdev->common.device_tx_status = sh_dmae_tx_status; |
1045 | shdev->common.device_issue_pending = sh_dmae_memcpy_issue_pending; | 1050 | shdev->common.device_issue_pending = sh_dmae_memcpy_issue_pending; |
1046 | 1051 | ||
1047 | /* Compulsory for DMA_SLAVE fields */ | 1052 | /* Compulsory for DMA_SLAVE fields */ |
1048 | shdev->common.device_prep_slave_sg = sh_dmae_prep_slave_sg; | 1053 | shdev->common.device_prep_slave_sg = sh_dmae_prep_slave_sg; |
1049 | shdev->common.device_terminate_all = sh_dmae_terminate_all; | 1054 | shdev->common.device_control = sh_dmae_control; |
1050 | 1055 | ||
1051 | shdev->common.dev = &pdev->dev; | 1056 | shdev->common.dev = &pdev->dev; |
1052 | /* Default transfer size of 32 bytes requires 32-byte alignment */ | 1057 | /* Default transfer size of 32 bytes requires 32-byte alignment */ |
@@ -1187,6 +1192,7 @@ static struct platform_driver sh_dmae_driver = { | |||
1187 | .remove = __exit_p(sh_dmae_remove), | 1192 | .remove = __exit_p(sh_dmae_remove), |
1188 | .shutdown = sh_dmae_shutdown, | 1193 | .shutdown = sh_dmae_shutdown, |
1189 | .driver = { | 1194 | .driver = { |
1195 | .owner = THIS_MODULE, | ||
1190 | .name = "sh-dma-engine", | 1196 | .name = "sh-dma-engine", |
1191 | }, | 1197 | }, |
1192 | }; | 1198 | }; |