Loading drivers/dma/imx-dma.c +22 −4 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ struct imxdma_channel { struct imxdma_engine { struct device *dev; struct device_dma_parameters dma_parms; struct dma_device dma_device; struct imxdma_channel channel[MAX_DMA_CHANNELS]; }; Loading Loading @@ -242,6 +243,21 @@ static struct dma_async_tx_descriptor *imxdma_prep_slave_sg( else dmamode = DMA_MODE_WRITE; switch (imxdmac->word_size) { case DMA_SLAVE_BUSWIDTH_4_BYTES: if (sgl->length & 3 || sgl->dma_address & 3) return NULL; break; case DMA_SLAVE_BUSWIDTH_2_BYTES: if (sgl->length & 1 || sgl->dma_address & 1) return NULL; break; case DMA_SLAVE_BUSWIDTH_1_BYTE: break; default: return NULL; } ret = imx_dma_setup_sg(imxdmac->imxdma_channel, sgl, sg_len, dma_length, imxdmac->per_address, dmamode); if (ret) Loading Loading @@ -329,6 +345,9 @@ static int __init imxdma_probe(struct platform_device *pdev) INIT_LIST_HEAD(&imxdma->dma_device.channels); dma_cap_set(DMA_SLAVE, imxdma->dma_device.cap_mask); dma_cap_set(DMA_CYCLIC, imxdma->dma_device.cap_mask); /* Initialize channel parameters */ for (i = 0; i < MAX_DMA_CHANNELS; i++) { struct imxdma_channel *imxdmac = &imxdma->channel[i]; Loading @@ -346,11 +365,7 @@ static int __init imxdma_probe(struct platform_device *pdev) imxdmac->imxdma = imxdma; spin_lock_init(&imxdmac->lock); dma_cap_set(DMA_SLAVE, imxdma->dma_device.cap_mask); dma_cap_set(DMA_CYCLIC, imxdma->dma_device.cap_mask); imxdmac->chan.device = &imxdma->dma_device; imxdmac->chan.chan_id = i; imxdmac->channel = i; /* Add the channel to the DMAC list */ Loading @@ -370,6 +385,9 @@ static int __init imxdma_probe(struct platform_device *pdev) platform_set_drvdata(pdev, imxdma); imxdma->dma_device.dev->dma_parms = &imxdma->dma_parms; dma_set_max_seg_size(imxdma->dma_device.dev, 0xffffff); ret = dma_async_device_register(&imxdma->dma_device); if (ret) { dev_err(&pdev->dev, "unable to register\n"); Loading drivers/dma/imx-sdma.c +41 −35 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -449,7 +450,7 @@ static void sdma_handle_channel_loop(struct sdma_channel *sdmac) if (bd->mode.status & BD_RROR) sdmac->status = DMA_ERROR; else sdmac->status = DMA_SUCCESS; sdmac->status = DMA_IN_PROGRESS; bd->mode.status |= BD_DONE; sdmac->buf_tail++; Loading Loading @@ -798,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); Loading @@ -811,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; Loading Loading @@ -879,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) Loading Loading @@ -924,22 +921,33 @@ 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; if (sdmac->flags & IMX_DMA_SG_LOOP) { if (i + 1 == sg_len) { param |= BD_INTR; if (i + 1 == sg_len) param |= BD_WRAP; param |= BD_LAST; param &= ~BD_CONT; } if (i + 1 == sg_len) param |= BD_INTR; dev_dbg(sdma->dev, "entry %d: count: %d dma: 0x%08x %s%s\n", i, count, sg->dma_address, param & BD_WRAP ? "wrap" : "", Loading @@ -953,6 +961,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( return &sdmac->desc; err_out: sdmac->status = DMA_ERROR; return NULL; } Loading @@ -963,7 +972,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); Loading Loading @@ -1066,14 +1075,12 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan, { struct sdma_channel *sdmac = to_sdma_chan(chan); dma_cookie_t last_used; enum dma_status ret; last_used = chan->cookie; ret = dma_async_is_complete(cookie, sdmac->last_completed, last_used); dma_set_tx_state(txstate, sdmac->last_completed, last_used, 0); return ret; return sdmac->status; } static void sdma_issue_pending(struct dma_chan *chan) Loading Loading @@ -1237,7 +1244,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); Loading Loading @@ -1280,6 +1286,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++) { Loading @@ -1288,15 +1297,17 @@ 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->chan.chan_id = i; 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); Loading @@ -1317,6 +1328,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) { Loading @@ -1324,13 +1337,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; Loading Loading
drivers/dma/imx-dma.c +22 −4 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ struct imxdma_channel { struct imxdma_engine { struct device *dev; struct device_dma_parameters dma_parms; struct dma_device dma_device; struct imxdma_channel channel[MAX_DMA_CHANNELS]; }; Loading Loading @@ -242,6 +243,21 @@ static struct dma_async_tx_descriptor *imxdma_prep_slave_sg( else dmamode = DMA_MODE_WRITE; switch (imxdmac->word_size) { case DMA_SLAVE_BUSWIDTH_4_BYTES: if (sgl->length & 3 || sgl->dma_address & 3) return NULL; break; case DMA_SLAVE_BUSWIDTH_2_BYTES: if (sgl->length & 1 || sgl->dma_address & 1) return NULL; break; case DMA_SLAVE_BUSWIDTH_1_BYTE: break; default: return NULL; } ret = imx_dma_setup_sg(imxdmac->imxdma_channel, sgl, sg_len, dma_length, imxdmac->per_address, dmamode); if (ret) Loading Loading @@ -329,6 +345,9 @@ static int __init imxdma_probe(struct platform_device *pdev) INIT_LIST_HEAD(&imxdma->dma_device.channels); dma_cap_set(DMA_SLAVE, imxdma->dma_device.cap_mask); dma_cap_set(DMA_CYCLIC, imxdma->dma_device.cap_mask); /* Initialize channel parameters */ for (i = 0; i < MAX_DMA_CHANNELS; i++) { struct imxdma_channel *imxdmac = &imxdma->channel[i]; Loading @@ -346,11 +365,7 @@ static int __init imxdma_probe(struct platform_device *pdev) imxdmac->imxdma = imxdma; spin_lock_init(&imxdmac->lock); dma_cap_set(DMA_SLAVE, imxdma->dma_device.cap_mask); dma_cap_set(DMA_CYCLIC, imxdma->dma_device.cap_mask); imxdmac->chan.device = &imxdma->dma_device; imxdmac->chan.chan_id = i; imxdmac->channel = i; /* Add the channel to the DMAC list */ Loading @@ -370,6 +385,9 @@ static int __init imxdma_probe(struct platform_device *pdev) platform_set_drvdata(pdev, imxdma); imxdma->dma_device.dev->dma_parms = &imxdma->dma_parms; dma_set_max_seg_size(imxdma->dma_device.dev, 0xffffff); ret = dma_async_device_register(&imxdma->dma_device); if (ret) { dev_err(&pdev->dev, "unable to register\n"); Loading
drivers/dma/imx-sdma.c +41 −35 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -449,7 +450,7 @@ static void sdma_handle_channel_loop(struct sdma_channel *sdmac) if (bd->mode.status & BD_RROR) sdmac->status = DMA_ERROR; else sdmac->status = DMA_SUCCESS; sdmac->status = DMA_IN_PROGRESS; bd->mode.status |= BD_DONE; sdmac->buf_tail++; Loading Loading @@ -798,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); Loading @@ -811,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; Loading Loading @@ -879,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) Loading Loading @@ -924,22 +921,33 @@ 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; if (sdmac->flags & IMX_DMA_SG_LOOP) { if (i + 1 == sg_len) { param |= BD_INTR; if (i + 1 == sg_len) param |= BD_WRAP; param |= BD_LAST; param &= ~BD_CONT; } if (i + 1 == sg_len) param |= BD_INTR; dev_dbg(sdma->dev, "entry %d: count: %d dma: 0x%08x %s%s\n", i, count, sg->dma_address, param & BD_WRAP ? "wrap" : "", Loading @@ -953,6 +961,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( return &sdmac->desc; err_out: sdmac->status = DMA_ERROR; return NULL; } Loading @@ -963,7 +972,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); Loading Loading @@ -1066,14 +1075,12 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan, { struct sdma_channel *sdmac = to_sdma_chan(chan); dma_cookie_t last_used; enum dma_status ret; last_used = chan->cookie; ret = dma_async_is_complete(cookie, sdmac->last_completed, last_used); dma_set_tx_state(txstate, sdmac->last_completed, last_used, 0); return ret; return sdmac->status; } static void sdma_issue_pending(struct dma_chan *chan) Loading Loading @@ -1237,7 +1244,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); Loading Loading @@ -1280,6 +1286,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++) { Loading @@ -1288,15 +1297,17 @@ 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->chan.chan_id = i; 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); Loading @@ -1317,6 +1328,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) { Loading @@ -1324,13 +1337,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; Loading