aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/amba-pl08x.c
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@free-electrons.com>2014-11-17 08:42:05 -0500
committerVinod Koul <vinod.koul@intel.com>2014-12-22 01:58:56 -0500
commitbcd1b0b9015b746436d6c846a35a4310e23f44a7 (patch)
tree30651598b7d522df78fe786e5c6f34c4e012c943 /drivers/dma/amba-pl08x.c
parentcb8cea513c80db1dfe2dce468d2d0772005bb9a1 (diff)
dmaengine: pl08x: Split device_control
Split the device_control callback of the AMBA PL08x DMA driver to make use of the newly introduced callbacks, that will eventually be used to retrieve slave capabilities. Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/amba-pl08x.c')
-rw-r--r--drivers/dma/amba-pl08x.c156
1 files changed, 90 insertions, 66 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 1364d00881dd..4a5fd245014e 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1386,32 +1386,6 @@ static u32 pl08x_get_cctl(struct pl08x_dma_chan *plchan,
1386 return pl08x_cctl(cctl); 1386 return pl08x_cctl(cctl);
1387} 1387}
1388 1388
1389static int dma_set_runtime_config(struct dma_chan *chan,
1390 struct dma_slave_config *config)
1391{
1392 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1393 struct pl08x_driver_data *pl08x = plchan->host;
1394
1395 if (!plchan->slave)
1396 return -EINVAL;
1397
1398 /* Reject definitely invalid configurations */
1399 if (config->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
1400 config->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
1401 return -EINVAL;
1402
1403 if (config->device_fc && pl08x->vd->pl080s) {
1404 dev_err(&pl08x->adev->dev,
1405 "%s: PL080S does not support peripheral flow control\n",
1406 __func__);
1407 return -EINVAL;
1408 }
1409
1410 plchan->cfg = *config;
1411
1412 return 0;
1413}
1414
1415/* 1389/*
1416 * Slave transactions callback to the slave device to allow 1390 * Slave transactions callback to the slave device to allow
1417 * synchronization of slave DMA signals with the DMAC enable 1391 * synchronization of slave DMA signals with the DMAC enable
@@ -1693,20 +1667,71 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_cyclic(
1693 return vchan_tx_prep(&plchan->vc, &txd->vd, flags); 1667 return vchan_tx_prep(&plchan->vc, &txd->vd, flags);
1694} 1668}
1695 1669
1696static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, 1670static int pl08x_config(struct dma_chan *chan,
1697 unsigned long arg) 1671 struct dma_slave_config *config)
1672{
1673 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1674 struct pl08x_driver_data *pl08x = plchan->host;
1675
1676 if (!plchan->slave)
1677 return -EINVAL;
1678
1679 /* Reject definitely invalid configurations */
1680 if (config->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
1681 config->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
1682 return -EINVAL;
1683
1684 if (config->device_fc && pl08x->vd->pl080s) {
1685 dev_err(&pl08x->adev->dev,
1686 "%s: PL080S does not support peripheral flow control\n",
1687 __func__);
1688 return -EINVAL;
1689 }
1690
1691 plchan->cfg = *config;
1692
1693 return 0;
1694}
1695
1696static int pl08x_terminate_all(struct dma_chan *chan)
1698{ 1697{
1699 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); 1698 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1700 struct pl08x_driver_data *pl08x = plchan->host; 1699 struct pl08x_driver_data *pl08x = plchan->host;
1701 unsigned long flags; 1700 unsigned long flags;
1702 int ret = 0;
1703 1701
1704 /* Controls applicable to inactive channels */ 1702 spin_lock_irqsave(&plchan->vc.lock, flags);
1705 if (cmd == DMA_SLAVE_CONFIG) { 1703 if (!plchan->phychan && !plchan->at) {
1706 return dma_set_runtime_config(chan, 1704 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1707 (struct dma_slave_config *)arg); 1705 return 0;
1708 } 1706 }
1709 1707
1708 plchan->state = PL08X_CHAN_IDLE;
1709
1710 if (plchan->phychan) {
1711 /*
1712 * Mark physical channel as free and free any slave
1713 * signal
1714 */
1715 pl08x_phy_free(plchan);
1716 }
1717 /* Dequeue jobs and free LLIs */
1718 if (plchan->at) {
1719 pl08x_desc_free(&plchan->at->vd);
1720 plchan->at = NULL;
1721 }
1722 /* Dequeue jobs not yet fired as well */
1723 pl08x_free_txd_list(pl08x, plchan);
1724
1725 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1726
1727 return 0;
1728}
1729
1730static int pl08x_pause(struct dma_chan *chan)
1731{
1732 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1733 unsigned long flags;
1734
1710 /* 1735 /*
1711 * Anything succeeds on channels with no physical allocation and 1736 * Anything succeeds on channels with no physical allocation and
1712 * no queued transfers. 1737 * no queued transfers.
@@ -1717,42 +1742,35 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
1717 return 0; 1742 return 0;
1718 } 1743 }
1719 1744
1720 switch (cmd) { 1745 pl08x_pause_phy_chan(plchan->phychan);
1721 case DMA_TERMINATE_ALL: 1746 plchan->state = PL08X_CHAN_PAUSED;
1722 plchan->state = PL08X_CHAN_IDLE;
1723 1747
1724 if (plchan->phychan) { 1748 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1725 /* 1749
1726 * Mark physical channel as free and free any slave 1750 return 0;
1727 * signal 1751}
1728 */ 1752
1729 pl08x_phy_free(plchan); 1753static int pl08x_resume(struct dma_chan *chan)
1730 } 1754{
1731 /* Dequeue jobs and free LLIs */ 1755 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1732 if (plchan->at) { 1756 unsigned long flags;
1733 pl08x_desc_free(&plchan->at->vd); 1757
1734 plchan->at = NULL; 1758 /*
1735 } 1759 * Anything succeeds on channels with no physical allocation and
1736 /* Dequeue jobs not yet fired as well */ 1760 * no queued transfers.
1737 pl08x_free_txd_list(pl08x, plchan); 1761 */
1738 break; 1762 spin_lock_irqsave(&plchan->vc.lock, flags);
1739 case DMA_PAUSE: 1763 if (!plchan->phychan && !plchan->at) {
1740 pl08x_pause_phy_chan(plchan->phychan); 1764 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1741 plchan->state = PL08X_CHAN_PAUSED; 1765 return 0;
1742 break;
1743 case DMA_RESUME:
1744 pl08x_resume_phy_chan(plchan->phychan);
1745 plchan->state = PL08X_CHAN_RUNNING;
1746 break;
1747 default:
1748 /* Unknown command */
1749 ret = -ENXIO;
1750 break;
1751 } 1766 }
1752 1767
1768 pl08x_resume_phy_chan(plchan->phychan);
1769 plchan->state = PL08X_CHAN_RUNNING;
1770
1753 spin_unlock_irqrestore(&plchan->vc.lock, flags); 1771 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1754 1772
1755 return ret; 1773 return 0;
1756} 1774}
1757 1775
1758bool pl08x_filter_id(struct dma_chan *chan, void *chan_id) 1776bool pl08x_filter_id(struct dma_chan *chan, void *chan_id)
@@ -2048,7 +2066,10 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
2048 pl08x->memcpy.device_prep_dma_interrupt = pl08x_prep_dma_interrupt; 2066 pl08x->memcpy.device_prep_dma_interrupt = pl08x_prep_dma_interrupt;
2049 pl08x->memcpy.device_tx_status = pl08x_dma_tx_status; 2067 pl08x->memcpy.device_tx_status = pl08x_dma_tx_status;
2050 pl08x->memcpy.device_issue_pending = pl08x_issue_pending; 2068 pl08x->memcpy.device_issue_pending = pl08x_issue_pending;
2051 pl08x->memcpy.device_control = pl08x_control; 2069 pl08x->memcpy.device_config = pl08x_config;
2070 pl08x->memcpy.device_pause = pl08x_pause;
2071 pl08x->memcpy.device_resume = pl08x_resume;
2072 pl08x->memcpy.device_terminate_all = pl08x_terminate_all;
2052 2073
2053 /* Initialize slave engine */ 2074 /* Initialize slave engine */
2054 dma_cap_set(DMA_SLAVE, pl08x->slave.cap_mask); 2075 dma_cap_set(DMA_SLAVE, pl08x->slave.cap_mask);
@@ -2061,7 +2082,10 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
2061 pl08x->slave.device_issue_pending = pl08x_issue_pending; 2082 pl08x->slave.device_issue_pending = pl08x_issue_pending;
2062 pl08x->slave.device_prep_slave_sg = pl08x_prep_slave_sg; 2083 pl08x->slave.device_prep_slave_sg = pl08x_prep_slave_sg;
2063 pl08x->slave.device_prep_dma_cyclic = pl08x_prep_dma_cyclic; 2084 pl08x->slave.device_prep_dma_cyclic = pl08x_prep_dma_cyclic;
2064 pl08x->slave.device_control = pl08x_control; 2085 pl08x->slave.device_config = pl08x_config;
2086 pl08x->slave.device_pause = pl08x_pause;
2087 pl08x->slave.device_resume = pl08x_resume;
2088 pl08x->slave.device_terminate_all = pl08x_terminate_all;
2065 2089
2066 /* Get the platform data */ 2090 /* Get the platform data */
2067 pl08x->pd = dev_get_platdata(&adev->dev); 2091 pl08x->pd = dev_get_platdata(&adev->dev);