aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2011-01-31 04:56:58 -0500
committerSascha Hauer <s.hauer@pengutronix.de>2011-01-31 06:34:31 -0500
commit23889c6352ab4a842a30221bb412ff49954b2fb3 (patch)
tree1a8c6fbd0509c6dbed9702c9ab0314a8c911de22 /drivers/dma
parent7214a8b14f63a1603401124bc150e17b145aa476 (diff)
dmaengine i.MX SDMA: reserve channel 0 by not registering it
We need channel 0 of the sdma engine for internal purposes. We accomplished this by calling dma_request_channel() in the probe function. This does not work when multiple dma engines are present which is the case when IPU support for i.MX31/35 is compiled in. So instead of registering channel 0 and reserving it afterwards simply do not register it in the first place. With this the dmaengine channel counting does not match sdma channel counting anymore, so we have to use sdma channel counting in the driver. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/imx-sdma.c30
1 files changed, 12 insertions, 18 deletions
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index eb250681804..1eb3f007740 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -230,7 +230,7 @@ struct sdma_engine;
230 * struct sdma_channel - housekeeping for a SDMA channel 230 * struct sdma_channel - housekeeping for a SDMA channel
231 * 231 *
232 * @sdma pointer to the SDMA engine for this channel 232 * @sdma pointer to the SDMA engine for this channel
233 * @channel the channel number, matches dmaengine chan_id 233 * @channel the channel number, matches dmaengine chan_id + 1
234 * @direction transfer type. Needed for setting SDMA script 234 * @direction transfer type. Needed for setting SDMA script
235 * @peripheral_type Peripheral type. Needed for setting SDMA script 235 * @peripheral_type Peripheral type. Needed for setting SDMA script
236 * @event_id0 aka dma request line 236 * @event_id0 aka dma request line
@@ -799,7 +799,7 @@ static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx)
799 799
800 cookie = sdma_assign_cookie(sdmac); 800 cookie = sdma_assign_cookie(sdmac);
801 801
802 sdma_enable_channel(sdma, tx->chan->chan_id); 802 sdma_enable_channel(sdma, sdmac->channel);
803 803
804 spin_unlock_irq(&sdmac->lock); 804 spin_unlock_irq(&sdmac->lock);
805 805
@@ -812,10 +812,6 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan)
812 struct imx_dma_data *data = chan->private; 812 struct imx_dma_data *data = chan->private;
813 int prio, ret; 813 int prio, ret;
814 814
815 /* No need to execute this for internal channel 0 */
816 if (chan->chan_id == 0)
817 return 0;
818
819 if (!data) 815 if (!data)
820 return -EINVAL; 816 return -EINVAL;
821 817
@@ -880,7 +876,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
880 struct sdma_channel *sdmac = to_sdma_chan(chan); 876 struct sdma_channel *sdmac = to_sdma_chan(chan);
881 struct sdma_engine *sdma = sdmac->sdma; 877 struct sdma_engine *sdma = sdmac->sdma;
882 int ret, i, count; 878 int ret, i, count;
883 int channel = chan->chan_id; 879 int channel = sdmac->channel;
884 struct scatterlist *sg; 880 struct scatterlist *sg;
885 881
886 if (sdmac->status == DMA_IN_PROGRESS) 882 if (sdmac->status == DMA_IN_PROGRESS)
@@ -978,7 +974,7 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
978 struct sdma_channel *sdmac = to_sdma_chan(chan); 974 struct sdma_channel *sdmac = to_sdma_chan(chan);
979 struct sdma_engine *sdma = sdmac->sdma; 975 struct sdma_engine *sdma = sdmac->sdma;
980 int num_periods = buf_len / period_len; 976 int num_periods = buf_len / period_len;
981 int channel = chan->chan_id; 977 int channel = sdmac->channel;
982 int ret, i = 0, buf = 0; 978 int ret, i = 0, buf = 0;
983 979
984 dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel); 980 dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel);
@@ -1252,7 +1248,6 @@ static int __init sdma_probe(struct platform_device *pdev)
1252 struct resource *iores; 1248 struct resource *iores;
1253 struct sdma_platform_data *pdata = pdev->dev.platform_data; 1249 struct sdma_platform_data *pdata = pdev->dev.platform_data;
1254 int i; 1250 int i;
1255 dma_cap_mask_t mask;
1256 struct sdma_engine *sdma; 1251 struct sdma_engine *sdma;
1257 1252
1258 sdma = kzalloc(sizeof(*sdma), GFP_KERNEL); 1253 sdma = kzalloc(sizeof(*sdma), GFP_KERNEL);
@@ -1309,8 +1304,14 @@ static int __init sdma_probe(struct platform_device *pdev)
1309 sdmac->chan.device = &sdma->dma_device; 1304 sdmac->chan.device = &sdma->dma_device;
1310 sdmac->channel = i; 1305 sdmac->channel = i;
1311 1306
1312 /* Add the channel to the DMAC list */ 1307 /*
1313 list_add_tail(&sdmac->chan.device_node, &sdma->dma_device.channels); 1308 * Add the channel to the DMAC list. Do not add channel 0 though
1309 * because we need it internally in the SDMA driver. This also means
1310 * that channel 0 in dmaengine counting matches sdma channel 1.
1311 */
1312 if (i)
1313 list_add_tail(&sdmac->chan.device_node,
1314 &sdma->dma_device.channels);
1314 } 1315 }
1315 1316
1316 ret = sdma_init(sdma); 1317 ret = sdma_init(sdma);
@@ -1340,13 +1341,6 @@ static int __init sdma_probe(struct platform_device *pdev)
1340 goto err_init; 1341 goto err_init;
1341 } 1342 }
1342 1343
1343 /* request channel 0. This is an internal control channel
1344 * to the SDMA engine and not available to clients.
1345 */
1346 dma_cap_zero(mask);
1347 dma_cap_set(DMA_SLAVE, mask);
1348 dma_request_channel(mask, NULL, NULL);
1349
1350 dev_info(sdma->dev, "initialized\n"); 1344 dev_info(sdma->dev, "initialized\n");
1351 1345
1352 return 0; 1346 return 0;