Commit 831ae3c1 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'fixes' of git://git.infradead.org/users/vkoul/slave-dma

Pull slave-dmaengine fixes from Vinod Koul:
 "Here is the slave dmanegine fixes.  We have the fix for deadlock issue
  on imx-dma by Michael and Josh's edma config fix along with author
  change"

* 'fixes' of git://git.infradead.org/users/vkoul/slave-dma:
  dmaengine: imx-dma: fix callback path in tasklet
  dmaengine: imx-dma: fix lockdep issue between irqhandler and tasklet
  dmaengine: imx-dma: fix slow path issue in prep_dma_cyclic
  dma/Kconfig: Make TI_EDMA select TI_PRIV_EDMA
  edma: Update author email address
parents e62063d6 fcaaba6c
...@@ -198,6 +198,7 @@ config TI_EDMA ...@@ -198,6 +198,7 @@ config TI_EDMA
depends on ARCH_DAVINCI || ARCH_OMAP depends on ARCH_DAVINCI || ARCH_OMAP
select DMA_ENGINE select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS select DMA_VIRTUAL_CHANNELS
select TI_PRIV_EDMA
default n default n
help help
Enable support for the TI EDMA controller. This DMA Enable support for the TI EDMA controller. This DMA
......
...@@ -749,6 +749,6 @@ static void __exit edma_exit(void) ...@@ -749,6 +749,6 @@ static void __exit edma_exit(void)
} }
module_exit(edma_exit); module_exit(edma_exit);
MODULE_AUTHOR("Matt Porter <mporter@ti.com>"); MODULE_AUTHOR("Matt Porter <matt.porter@linaro.org>");
MODULE_DESCRIPTION("TI EDMA DMA engine driver"); MODULE_DESCRIPTION("TI EDMA DMA engine driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -437,17 +437,18 @@ static void dma_irq_handle_channel(struct imxdma_channel *imxdmac) ...@@ -437,17 +437,18 @@ static void dma_irq_handle_channel(struct imxdma_channel *imxdmac)
struct imxdma_engine *imxdma = imxdmac->imxdma; struct imxdma_engine *imxdma = imxdmac->imxdma;
int chno = imxdmac->channel; int chno = imxdmac->channel;
struct imxdma_desc *desc; struct imxdma_desc *desc;
unsigned long flags;
spin_lock(&imxdma->lock); spin_lock_irqsave(&imxdma->lock, flags);
if (list_empty(&imxdmac->ld_active)) { if (list_empty(&imxdmac->ld_active)) {
spin_unlock(&imxdma->lock); spin_unlock_irqrestore(&imxdma->lock, flags);
goto out; goto out;
} }
desc = list_first_entry(&imxdmac->ld_active, desc = list_first_entry(&imxdmac->ld_active,
struct imxdma_desc, struct imxdma_desc,
node); node);
spin_unlock(&imxdma->lock); spin_unlock_irqrestore(&imxdma->lock, flags);
if (desc->sg) { if (desc->sg) {
u32 tmp; u32 tmp;
...@@ -519,7 +520,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) ...@@ -519,7 +520,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d)
{ {
struct imxdma_channel *imxdmac = to_imxdma_chan(d->desc.chan); struct imxdma_channel *imxdmac = to_imxdma_chan(d->desc.chan);
struct imxdma_engine *imxdma = imxdmac->imxdma; struct imxdma_engine *imxdma = imxdmac->imxdma;
unsigned long flags;
int slot = -1; int slot = -1;
int i; int i;
...@@ -527,7 +527,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) ...@@ -527,7 +527,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d)
switch (d->type) { switch (d->type) {
case IMXDMA_DESC_INTERLEAVED: case IMXDMA_DESC_INTERLEAVED:
/* Try to get a free 2D slot */ /* Try to get a free 2D slot */
spin_lock_irqsave(&imxdma->lock, flags);
for (i = 0; i < IMX_DMA_2D_SLOTS; i++) { for (i = 0; i < IMX_DMA_2D_SLOTS; i++) {
if ((imxdma->slots_2d[i].count > 0) && if ((imxdma->slots_2d[i].count > 0) &&
((imxdma->slots_2d[i].xsr != d->x) || ((imxdma->slots_2d[i].xsr != d->x) ||
...@@ -537,10 +536,8 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) ...@@ -537,10 +536,8 @@ static int imxdma_xfer_desc(struct imxdma_desc *d)
slot = i; slot = i;
break; break;
} }
if (slot < 0) { if (slot < 0)
spin_unlock_irqrestore(&imxdma->lock, flags);
return -EBUSY; return -EBUSY;
}
imxdma->slots_2d[slot].xsr = d->x; imxdma->slots_2d[slot].xsr = d->x;
imxdma->slots_2d[slot].ysr = d->y; imxdma->slots_2d[slot].ysr = d->y;
...@@ -549,7 +546,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) ...@@ -549,7 +546,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d)
imxdmac->slot_2d = slot; imxdmac->slot_2d = slot;
imxdmac->enabled_2d = true; imxdmac->enabled_2d = true;
spin_unlock_irqrestore(&imxdma->lock, flags);
if (slot == IMX_DMA_2D_SLOT_A) { if (slot == IMX_DMA_2D_SLOT_A) {
d->config_mem &= ~CCR_MSEL_B; d->config_mem &= ~CCR_MSEL_B;
...@@ -625,18 +621,17 @@ static void imxdma_tasklet(unsigned long data) ...@@ -625,18 +621,17 @@ static void imxdma_tasklet(unsigned long data)
struct imxdma_channel *imxdmac = (void *)data; struct imxdma_channel *imxdmac = (void *)data;
struct imxdma_engine *imxdma = imxdmac->imxdma; struct imxdma_engine *imxdma = imxdmac->imxdma;
struct imxdma_desc *desc; struct imxdma_desc *desc;
unsigned long flags;
spin_lock(&imxdma->lock); spin_lock_irqsave(&imxdma->lock, flags);
if (list_empty(&imxdmac->ld_active)) { if (list_empty(&imxdmac->ld_active)) {
/* Someone might have called terminate all */ /* Someone might have called terminate all */
goto out; spin_unlock_irqrestore(&imxdma->lock, flags);
return;
} }
desc = list_first_entry(&imxdmac->ld_active, struct imxdma_desc, node); desc = list_first_entry(&imxdmac->ld_active, struct imxdma_desc, node);
if (desc->desc.callback)
desc->desc.callback(desc->desc.callback_param);
/* If we are dealing with a cyclic descriptor, keep it on ld_active /* If we are dealing with a cyclic descriptor, keep it on ld_active
* and dont mark the descriptor as complete. * and dont mark the descriptor as complete.
* Only in non-cyclic cases it would be marked as complete * Only in non-cyclic cases it would be marked as complete
...@@ -663,7 +658,11 @@ static void imxdma_tasklet(unsigned long data) ...@@ -663,7 +658,11 @@ static void imxdma_tasklet(unsigned long data)
__func__, imxdmac->channel); __func__, imxdmac->channel);
} }
out: out:
spin_unlock(&imxdma->lock); spin_unlock_irqrestore(&imxdma->lock, flags);
if (desc->desc.callback)
desc->desc.callback(desc->desc.callback_param);
} }
static int imxdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, static int imxdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
...@@ -883,7 +882,7 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic( ...@@ -883,7 +882,7 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic(
kfree(imxdmac->sg_list); kfree(imxdmac->sg_list);
imxdmac->sg_list = kcalloc(periods + 1, imxdmac->sg_list = kcalloc(periods + 1,
sizeof(struct scatterlist), GFP_KERNEL); sizeof(struct scatterlist), GFP_ATOMIC);
if (!imxdmac->sg_list) if (!imxdmac->sg_list)
return NULL; return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment