aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/edma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/edma.c')
-rw-r--r--drivers/dma/edma.c63
1 files changed, 36 insertions, 27 deletions
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index e3d7fcb69b4c..ee3463e774f8 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -869,6 +869,13 @@ static int edma_terminate_all(struct dma_chan *chan)
869 return 0; 869 return 0;
870} 870}
871 871
872static void edma_synchronize(struct dma_chan *chan)
873{
874 struct edma_chan *echan = to_edma_chan(chan);
875
876 vchan_synchronize(&echan->vchan);
877}
878
872static int edma_slave_config(struct dma_chan *chan, 879static int edma_slave_config(struct dma_chan *chan,
873 struct dma_slave_config *cfg) 880 struct dma_slave_config *cfg)
874{ 881{
@@ -1365,36 +1372,36 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
1365static void edma_completion_handler(struct edma_chan *echan) 1372static void edma_completion_handler(struct edma_chan *echan)
1366{ 1373{
1367 struct device *dev = echan->vchan.chan.device->dev; 1374 struct device *dev = echan->vchan.chan.device->dev;
1368 struct edma_desc *edesc = echan->edesc; 1375 struct edma_desc *edesc;
1369
1370 if (!edesc)
1371 return;
1372 1376
1373 spin_lock(&echan->vchan.lock); 1377 spin_lock(&echan->vchan.lock);
1374 if (edesc->cyclic) { 1378 edesc = echan->edesc;
1375 vchan_cyclic_callback(&edesc->vdesc); 1379 if (edesc) {
1376 spin_unlock(&echan->vchan.lock); 1380 if (edesc->cyclic) {
1377 return; 1381 vchan_cyclic_callback(&edesc->vdesc);
1378 } else if (edesc->processed == edesc->pset_nr) { 1382 spin_unlock(&echan->vchan.lock);
1379 edesc->residue = 0; 1383 return;
1380 edma_stop(echan); 1384 } else if (edesc->processed == edesc->pset_nr) {
1381 vchan_cookie_complete(&edesc->vdesc); 1385 edesc->residue = 0;
1382 echan->edesc = NULL; 1386 edma_stop(echan);
1383 1387 vchan_cookie_complete(&edesc->vdesc);
1384 dev_dbg(dev, "Transfer completed on channel %d\n", 1388 echan->edesc = NULL;
1385 echan->ch_num); 1389
1386 } else { 1390 dev_dbg(dev, "Transfer completed on channel %d\n",
1387 dev_dbg(dev, "Sub transfer completed on channel %d\n", 1391 echan->ch_num);
1388 echan->ch_num); 1392 } else {
1389 1393 dev_dbg(dev, "Sub transfer completed on channel %d\n",
1390 edma_pause(echan); 1394 echan->ch_num);
1391 1395
1392 /* Update statistics for tx_status */ 1396 edma_pause(echan);
1393 edesc->residue -= edesc->sg_len; 1397
1394 edesc->residue_stat = edesc->residue; 1398 /* Update statistics for tx_status */
1395 edesc->processed_stat = edesc->processed; 1399 edesc->residue -= edesc->sg_len;
1400 edesc->residue_stat = edesc->residue;
1401 edesc->processed_stat = edesc->processed;
1402 }
1403 edma_execute(echan);
1396 } 1404 }
1397 edma_execute(echan);
1398 1405
1399 spin_unlock(&echan->vchan.lock); 1406 spin_unlock(&echan->vchan.lock);
1400} 1407}
@@ -1837,6 +1844,7 @@ static void edma_dma_init(struct edma_cc *ecc, bool legacy_mode)
1837 s_ddev->device_pause = edma_dma_pause; 1844 s_ddev->device_pause = edma_dma_pause;
1838 s_ddev->device_resume = edma_dma_resume; 1845 s_ddev->device_resume = edma_dma_resume;
1839 s_ddev->device_terminate_all = edma_terminate_all; 1846 s_ddev->device_terminate_all = edma_terminate_all;
1847 s_ddev->device_synchronize = edma_synchronize;
1840 1848
1841 s_ddev->src_addr_widths = EDMA_DMA_BUSWIDTHS; 1849 s_ddev->src_addr_widths = EDMA_DMA_BUSWIDTHS;
1842 s_ddev->dst_addr_widths = EDMA_DMA_BUSWIDTHS; 1850 s_ddev->dst_addr_widths = EDMA_DMA_BUSWIDTHS;
@@ -1862,6 +1870,7 @@ static void edma_dma_init(struct edma_cc *ecc, bool legacy_mode)
1862 m_ddev->device_pause = edma_dma_pause; 1870 m_ddev->device_pause = edma_dma_pause;
1863 m_ddev->device_resume = edma_dma_resume; 1871 m_ddev->device_resume = edma_dma_resume;
1864 m_ddev->device_terminate_all = edma_terminate_all; 1872 m_ddev->device_terminate_all = edma_terminate_all;
1873 m_ddev->device_synchronize = edma_synchronize;
1865 1874
1866 m_ddev->src_addr_widths = EDMA_DMA_BUSWIDTHS; 1875 m_ddev->src_addr_widths = EDMA_DMA_BUSWIDTHS;
1867 m_ddev->dst_addr_widths = EDMA_DMA_BUSWIDTHS; 1876 m_ddev->dst_addr_widths = EDMA_DMA_BUSWIDTHS;