Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 831ae3c1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -198,6 +198,7 @@ config TI_EDMA
	depends on ARCH_DAVINCI || ARCH_OMAP
	select DMA_ENGINE
	select DMA_VIRTUAL_CHANNELS
	select TI_PRIV_EDMA
	default n
	help
	  Enable support for the TI EDMA controller. This DMA
+1 −1
Original line number Diff line number Diff line
@@ -749,6 +749,6 @@ static void __exit edma_exit(void)
}
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_LICENSE("GPL v2");
+15 −16
Original line number Diff line number Diff line
@@ -437,17 +437,18 @@ static void dma_irq_handle_channel(struct imxdma_channel *imxdmac)
	struct imxdma_engine *imxdma = imxdmac->imxdma;
	int chno = imxdmac->channel;
	struct imxdma_desc *desc;
	unsigned long flags;

	spin_lock(&imxdma->lock);
	spin_lock_irqsave(&imxdma->lock, flags);
	if (list_empty(&imxdmac->ld_active)) {
		spin_unlock(&imxdma->lock);
		spin_unlock_irqrestore(&imxdma->lock, flags);
		goto out;
	}

	desc = list_first_entry(&imxdmac->ld_active,
				struct imxdma_desc,
				node);
	spin_unlock(&imxdma->lock);
	spin_unlock_irqrestore(&imxdma->lock, flags);

	if (desc->sg) {
		u32 tmp;
@@ -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_engine *imxdma = imxdmac->imxdma;
	unsigned long flags;
	int slot = -1;
	int i;

@@ -527,7 +527,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d)
	switch (d->type) {
	case IMXDMA_DESC_INTERLEAVED:
		/* Try to get a free 2D slot */
		spin_lock_irqsave(&imxdma->lock, flags);
		for (i = 0; i < IMX_DMA_2D_SLOTS; i++) {
			if ((imxdma->slots_2d[i].count > 0) &&
			((imxdma->slots_2d[i].xsr != d->x) ||
@@ -537,10 +536,8 @@ static int imxdma_xfer_desc(struct imxdma_desc *d)
			slot = i;
			break;
		}
		if (slot < 0) {
			spin_unlock_irqrestore(&imxdma->lock, flags);
		if (slot < 0)
			return -EBUSY;
		}

		imxdma->slots_2d[slot].xsr = d->x;
		imxdma->slots_2d[slot].ysr = d->y;
@@ -549,7 +546,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d)

		imxdmac->slot_2d = slot;
		imxdmac->enabled_2d = true;
		spin_unlock_irqrestore(&imxdma->lock, flags);

		if (slot == IMX_DMA_2D_SLOT_A) {
			d->config_mem &= ~CCR_MSEL_B;
@@ -625,18 +621,17 @@ static void imxdma_tasklet(unsigned long data)
	struct imxdma_channel *imxdmac = (void *)data;
	struct imxdma_engine *imxdma = imxdmac->imxdma;
	struct imxdma_desc *desc;
	unsigned long flags;

	spin_lock(&imxdma->lock);
	spin_lock_irqsave(&imxdma->lock, flags);

	if (list_empty(&imxdmac->ld_active)) {
		/* 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);

	if (desc->desc.callback)
		desc->desc.callback(desc->desc.callback_param);

	/* If we are dealing with a cyclic descriptor, keep it on ld_active
	 * and dont mark the descriptor as complete.
	 * Only in non-cyclic cases it would be marked as complete
@@ -663,7 +658,11 @@ static void imxdma_tasklet(unsigned long data)
				 __func__, imxdmac->channel);
	}
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,
@@ -883,7 +882,7 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic(
	kfree(imxdmac->sg_list);

	imxdmac->sg_list = kcalloc(periods + 1,
			sizeof(struct scatterlist), GFP_KERNEL);
			sizeof(struct scatterlist), GFP_ATOMIC);
	if (!imxdmac->sg_list)
		return NULL;