* dmaengine: i.MX SDMA fixes
@ 2011-01-31 11:59 Sascha Hauer
2011-01-31 11:59 ` [PATCH 1/5] dmaengine i.MX sdma: set maximum segment size for our device Sascha Hauer
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Sascha Hauer @ 2011-01-31 11:59 UTC (permalink / raw)
To: linux-arm-kernel
The following contains fixes for the i.MX SDMA driver.
Sascha
The following changes since commit 1bae4ce27c9c90344f23c65ea6966c50ffeae2f5:
Linux 2.6.38-rc2 (2011-01-21 19:01:34 -0800)
are available in the git repository at:
git://git.pengutronix.de/git/imx/linux-2.6 dmaengine-sdma
Sascha Hauer (5):
dmaengine i.MX sdma: set maximum segment size for our device
dmaengine i.MX sdma: check sg entries for valid addresses and lengths
dmaengine i.MX SDMA: do not initialize chan_id field
dmaengine i.MX SDMA: initialize dma capabilities outside channel loop
dmaengine i.MX SDMA: reserve channel 0 by not registering it
drivers/dma/imx-sdma.c | 60 ++++++++++++++++++++++++++++--------------------
1 files changed, 35 insertions(+), 25 deletions(-)
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 1/5] dmaengine i.MX sdma: set maximum segment size for our device 2011-01-31 11:59 dmaengine: i.MX SDMA fixes Sascha Hauer @ 2011-01-31 11:59 ` Sascha Hauer 2011-01-31 11:59 ` [PATCH 2/5] dmaengine i.MX sdma: check sg entries for valid addresses and lengths Sascha Hauer ` (3 subsequent siblings) 4 siblings, 0 replies; 6+ messages in thread From: Sascha Hauer @ 2011-01-31 11:59 UTC (permalink / raw) To: linux-arm-kernel Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/dma/imx-sdma.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index d5a5d4d..c503050 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -301,6 +301,7 @@ struct sdma_firmware_header { struct sdma_engine { struct device *dev; + struct device_dma_parameters dma_parms; struct sdma_channel channel[MAX_DMA_CHANNELS]; struct sdma_channel_control *channel_control; void __iomem *regs; @@ -1317,6 +1318,8 @@ static int __init sdma_probe(struct platform_device *pdev) sdma->dma_device.device_prep_dma_cyclic = sdma_prep_dma_cyclic; sdma->dma_device.device_control = sdma_control; sdma->dma_device.device_issue_pending = sdma_issue_pending; + sdma->dma_device.dev->dma_parms = &sdma->dma_parms; + dma_set_max_seg_size(sdma->dma_device.dev, 65535); ret = dma_async_device_register(&sdma->dma_device); if (ret) { -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/5] dmaengine i.MX sdma: check sg entries for valid addresses and lengths 2011-01-31 11:59 dmaengine: i.MX SDMA fixes Sascha Hauer 2011-01-31 11:59 ` [PATCH 1/5] dmaengine i.MX sdma: set maximum segment size for our device Sascha Hauer @ 2011-01-31 11:59 ` Sascha Hauer 2011-01-31 11:59 ` [PATCH 3/5] dmaengine i.MX SDMA: do not initialize chan_id field Sascha Hauer ` (2 subsequent siblings) 4 siblings, 0 replies; 6+ messages in thread From: Sascha Hauer @ 2011-01-31 11:59 UTC (permalink / raw) To: linux-arm-kernel This patch lets sdma_prep_slave_sg fail if the entries of an sg list do not start on multiples of the word size or if the lengths are not multiple of the word size. Also, catch the previously unhandled DMA_SLAVE_BUSWIDTH_8_BYTES and DMA_SLAVE_BUSWIDTH_UNDEFINED cases. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/dma/imx-sdma.c | 20 +++++++++++++++++--- 1 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index c503050..8707723 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -925,10 +925,24 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( ret = -EINVAL; goto err_out; } - if (sdmac->word_size == DMA_SLAVE_BUSWIDTH_4_BYTES) + + switch (sdmac->word_size) { + case DMA_SLAVE_BUSWIDTH_4_BYTES: bd->mode.command = 0; - else - bd->mode.command = sdmac->word_size; + if (count & 3 || sg->dma_address & 3) + return NULL; + break; + case DMA_SLAVE_BUSWIDTH_2_BYTES: + bd->mode.command = 2; + if (count & 1 || sg->dma_address & 1) + return NULL; + break; + case DMA_SLAVE_BUSWIDTH_1_BYTE: + bd->mode.command = 1; + break; + default: + return NULL; + } param = BD_DONE | BD_EXTD | BD_CONT; -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/5] dmaengine i.MX SDMA: do not initialize chan_id field 2011-01-31 11:59 dmaengine: i.MX SDMA fixes Sascha Hauer 2011-01-31 11:59 ` [PATCH 1/5] dmaengine i.MX sdma: set maximum segment size for our device Sascha Hauer 2011-01-31 11:59 ` [PATCH 2/5] dmaengine i.MX sdma: check sg entries for valid addresses and lengths Sascha Hauer @ 2011-01-31 11:59 ` Sascha Hauer 2011-01-31 11:59 ` [PATCH 4/5] dmaengine i.MX SDMA: initialize dma capabilities outside channel loop Sascha Hauer 2011-01-31 11:59 ` [PATCH 5/5] dmaengine i.MX SDMA: reserve channel 0 by not registering it Sascha Hauer 4 siblings, 0 replies; 6+ messages in thread From: Sascha Hauer @ 2011-01-31 11:59 UTC (permalink / raw) To: linux-arm-kernel This is bogus as the dmaengine core will overwrite this field. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/dma/imx-sdma.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 8707723..3e848ee 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1307,7 +1307,6 @@ static int __init sdma_probe(struct platform_device *pdev) dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask); sdmac->chan.device = &sdma->dma_device; - sdmac->chan.chan_id = i; sdmac->channel = i; /* Add the channel to the DMAC list */ -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/5] dmaengine i.MX SDMA: initialize dma capabilities outside channel loop 2011-01-31 11:59 dmaengine: i.MX SDMA fixes Sascha Hauer ` (2 preceding siblings ...) 2011-01-31 11:59 ` [PATCH 3/5] dmaengine i.MX SDMA: do not initialize chan_id field Sascha Hauer @ 2011-01-31 11:59 ` Sascha Hauer 2011-01-31 11:59 ` [PATCH 5/5] dmaengine i.MX SDMA: reserve channel 0 by not registering it Sascha Hauer 4 siblings, 0 replies; 6+ messages in thread From: Sascha Hauer @ 2011-01-31 11:59 UTC (permalink / raw) To: linux-arm-kernel The capabilities are device specific fields, not channel specific fields. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/dma/imx-sdma.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 3e848ee..eb25068 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1295,6 +1295,9 @@ static int __init sdma_probe(struct platform_device *pdev) sdma->version = pdata->sdma_version; + dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask); + dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask); + INIT_LIST_HEAD(&sdma->dma_device.channels); /* Initialize channel parameters */ for (i = 0; i < MAX_DMA_CHANNELS; i++) { @@ -1303,9 +1306,6 @@ static int __init sdma_probe(struct platform_device *pdev) sdmac->sdma = sdma; spin_lock_init(&sdmac->lock); - dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask); - dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask); - sdmac->chan.device = &sdma->dma_device; sdmac->channel = i; -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 5/5] dmaengine i.MX SDMA: reserve channel 0 by not registering it 2011-01-31 11:59 dmaengine: i.MX SDMA fixes Sascha Hauer ` (3 preceding siblings ...) 2011-01-31 11:59 ` [PATCH 4/5] dmaengine i.MX SDMA: initialize dma capabilities outside channel loop Sascha Hauer @ 2011-01-31 11:59 ` Sascha Hauer 4 siblings, 0 replies; 6+ messages in thread From: Sascha Hauer @ 2011-01-31 11:59 UTC (permalink / raw) To: linux-arm-kernel 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> --- drivers/dma/imx-sdma.c | 30 ++++++++++++------------------ 1 files changed, 12 insertions(+), 18 deletions(-) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index eb25068..1eb3f00 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -230,7 +230,7 @@ struct sdma_engine; * struct sdma_channel - housekeeping for a SDMA channel * * @sdma pointer to the SDMA engine for this channel - * @channel the channel number, matches dmaengine chan_id + * @channel the channel number, matches dmaengine chan_id + 1 * @direction transfer type. Needed for setting SDMA script * @peripheral_type Peripheral type. Needed for setting SDMA script * @event_id0 aka dma request line @@ -799,7 +799,7 @@ static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx) cookie = sdma_assign_cookie(sdmac); - sdma_enable_channel(sdma, tx->chan->chan_id); + sdma_enable_channel(sdma, sdmac->channel); spin_unlock_irq(&sdmac->lock); @@ -812,10 +812,6 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan) struct imx_dma_data *data = chan->private; int prio, ret; - /* No need to execute this for internal channel 0 */ - if (chan->chan_id == 0) - return 0; - if (!data) return -EINVAL; @@ -880,7 +876,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( struct sdma_channel *sdmac = to_sdma_chan(chan); struct sdma_engine *sdma = sdmac->sdma; int ret, i, count; - int channel = chan->chan_id; + int channel = sdmac->channel; struct scatterlist *sg; if (sdmac->status == DMA_IN_PROGRESS) @@ -978,7 +974,7 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( struct sdma_channel *sdmac = to_sdma_chan(chan); struct sdma_engine *sdma = sdmac->sdma; int num_periods = buf_len / period_len; - int channel = chan->chan_id; + int channel = sdmac->channel; int ret, i = 0, buf = 0; dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel); @@ -1252,7 +1248,6 @@ static int __init sdma_probe(struct platform_device *pdev) struct resource *iores; struct sdma_platform_data *pdata = pdev->dev.platform_data; int i; - dma_cap_mask_t mask; struct sdma_engine *sdma; sdma = kzalloc(sizeof(*sdma), GFP_KERNEL); @@ -1309,8 +1304,14 @@ static int __init sdma_probe(struct platform_device *pdev) sdmac->chan.device = &sdma->dma_device; sdmac->channel = i; - /* Add the channel to the DMAC list */ - list_add_tail(&sdmac->chan.device_node, &sdma->dma_device.channels); + /* + * Add the channel to the DMAC list. Do not add channel 0 though + * because we need it internally in the SDMA driver. This also means + * that channel 0 in dmaengine counting matches sdma channel 1. + */ + if (i) + list_add_tail(&sdmac->chan.device_node, + &sdma->dma_device.channels); } ret = sdma_init(sdma); @@ -1340,13 +1341,6 @@ static int __init sdma_probe(struct platform_device *pdev) goto err_init; } - /* request channel 0. This is an internal control channel - * to the SDMA engine and not available to clients. - */ - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - dma_request_channel(mask, NULL, NULL); - dev_info(sdma->dev, "initialized\n"); return 0; -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-01-31 11:59 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-01-31 11:59 dmaengine: i.MX SDMA fixes Sascha Hauer 2011-01-31 11:59 ` [PATCH 1/5] dmaengine i.MX sdma: set maximum segment size for our device Sascha Hauer 2011-01-31 11:59 ` [PATCH 2/5] dmaengine i.MX sdma: check sg entries for valid addresses and lengths Sascha Hauer 2011-01-31 11:59 ` [PATCH 3/5] dmaengine i.MX SDMA: do not initialize chan_id field Sascha Hauer 2011-01-31 11:59 ` [PATCH 4/5] dmaengine i.MX SDMA: initialize dma capabilities outside channel loop Sascha Hauer 2011-01-31 11:59 ` [PATCH 5/5] dmaengine i.MX SDMA: reserve channel 0 by not registering it Sascha Hauer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).