diff options
author | Maxime Ripard <maxime.ripard@free-electrons.com> | 2014-11-17 08:42:05 -0500 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2014-12-22 01:58:56 -0500 |
commit | bcd1b0b9015b746436d6c846a35a4310e23f44a7 (patch) | |
tree | 30651598b7d522df78fe786e5c6f34c4e012c943 /drivers/dma/amba-pl08x.c | |
parent | cb8cea513c80db1dfe2dce468d2d0772005bb9a1 (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.c | 156 |
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 | ||
1389 | static 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 | ||
1696 | static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | 1670 | static 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 | |||
1696 | static 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 | |||
1730 | static 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); | 1753 | static 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 | ||
1758 | bool pl08x_filter_id(struct dma_chan *chan, void *chan_id) | 1776 | bool 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); |