aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/at_hdmac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/at_hdmac.c')
-rw-r--r--drivers/dma/at_hdmac.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 278cf5bceef2..bd5250e8c00c 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -760,13 +760,18 @@ err_desc_get:
760 return NULL; 760 return NULL;
761} 761}
762 762
763static void atc_terminate_all(struct dma_chan *chan) 763static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
764 unsigned long arg)
764{ 765{
765 struct at_dma_chan *atchan = to_at_dma_chan(chan); 766 struct at_dma_chan *atchan = to_at_dma_chan(chan);
766 struct at_dma *atdma = to_at_dma(chan->device); 767 struct at_dma *atdma = to_at_dma(chan->device);
767 struct at_desc *desc, *_desc; 768 struct at_desc *desc, *_desc;
768 LIST_HEAD(list); 769 LIST_HEAD(list);
769 770
771 /* Only supports DMA_TERMINATE_ALL */
772 if (cmd != DMA_TERMINATE_ALL)
773 return -ENXIO;
774
770 /* 775 /*
771 * This is only called when something went wrong elsewhere, so 776 * This is only called when something went wrong elsewhere, so
772 * we don't really care about the data. Just disable the 777 * we don't really care about the data. Just disable the
@@ -790,32 +795,30 @@ static void atc_terminate_all(struct dma_chan *chan)
790 /* Flush all pending and queued descriptors */ 795 /* Flush all pending and queued descriptors */
791 list_for_each_entry_safe(desc, _desc, &list, desc_node) 796 list_for_each_entry_safe(desc, _desc, &list, desc_node)
792 atc_chain_complete(atchan, desc); 797 atc_chain_complete(atchan, desc);
798
799 return 0;
793} 800}
794 801
795/** 802/**
796 * atc_is_tx_complete - poll for transaction completion 803 * atc_tx_status - poll for transaction completion
797 * @chan: DMA channel 804 * @chan: DMA channel
798 * @cookie: transaction identifier to check status of 805 * @cookie: transaction identifier to check status of
799 * @done: if not %NULL, updated with last completed transaction 806 * @txstate: if not %NULL updated with transaction state
800 * @used: if not %NULL, updated with last used transaction
801 * 807 *
802 * If @done and @used are passed in, upon return they reflect the driver 808 * If @txstate is passed in, upon return it reflect the driver
803 * internal state and can be used with dma_async_is_complete() to check 809 * internal state and can be used with dma_async_is_complete() to check
804 * the status of multiple cookies without re-checking hardware state. 810 * the status of multiple cookies without re-checking hardware state.
805 */ 811 */
806static enum dma_status 812static enum dma_status
807atc_is_tx_complete(struct dma_chan *chan, 813atc_tx_status(struct dma_chan *chan,
808 dma_cookie_t cookie, 814 dma_cookie_t cookie,
809 dma_cookie_t *done, dma_cookie_t *used) 815 struct dma_tx_state *txstate)
810{ 816{
811 struct at_dma_chan *atchan = to_at_dma_chan(chan); 817 struct at_dma_chan *atchan = to_at_dma_chan(chan);
812 dma_cookie_t last_used; 818 dma_cookie_t last_used;
813 dma_cookie_t last_complete; 819 dma_cookie_t last_complete;
814 enum dma_status ret; 820 enum dma_status ret;
815 821
816 dev_vdbg(chan2dev(chan), "is_tx_complete: %d (d%d, u%d)\n",
817 cookie, done ? *done : 0, used ? *used : 0);
818
819 spin_lock_bh(&atchan->lock); 822 spin_lock_bh(&atchan->lock);
820 823
821 last_complete = atchan->completed_cookie; 824 last_complete = atchan->completed_cookie;
@@ -833,10 +836,10 @@ atc_is_tx_complete(struct dma_chan *chan,
833 836
834 spin_unlock_bh(&atchan->lock); 837 spin_unlock_bh(&atchan->lock);
835 838
836 if (done) 839 dma_set_tx_state(txstate, last_complete, last_used, 0);
837 *done = last_complete; 840 dev_vdbg(chan2dev(chan), "tx_status: %d (d%d, u%d)\n",
838 if (used) 841 cookie, last_complete ? last_complete : 0,
839 *used = last_used; 842 last_used ? last_used : 0);
840 843
841 return ret; 844 return ret;
842} 845}
@@ -1082,7 +1085,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
1082 /* set base routines */ 1085 /* set base routines */
1083 atdma->dma_common.device_alloc_chan_resources = atc_alloc_chan_resources; 1086 atdma->dma_common.device_alloc_chan_resources = atc_alloc_chan_resources;
1084 atdma->dma_common.device_free_chan_resources = atc_free_chan_resources; 1087 atdma->dma_common.device_free_chan_resources = atc_free_chan_resources;
1085 atdma->dma_common.device_is_tx_complete = atc_is_tx_complete; 1088 atdma->dma_common.device_tx_status = atc_tx_status;
1086 atdma->dma_common.device_issue_pending = atc_issue_pending; 1089 atdma->dma_common.device_issue_pending = atc_issue_pending;
1087 atdma->dma_common.dev = &pdev->dev; 1090 atdma->dma_common.dev = &pdev->dev;
1088 1091
@@ -1092,7 +1095,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
1092 1095
1093 if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) { 1096 if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) {
1094 atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg; 1097 atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg;
1095 atdma->dma_common.device_terminate_all = atc_terminate_all; 1098 atdma->dma_common.device_control = atc_control;
1096 } 1099 }
1097 1100
1098 dma_writel(atdma, EN, AT_DMA_ENABLE); 1101 dma_writel(atdma, EN, AT_DMA_ENABLE);