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

Commit 0b58828c authored by Linus Walleij's avatar Linus Walleij Committed by Dan Williams
Browse files

DMAENGINE: COH 901 318 remove irq counting



This removes the pointless irq counting for the COH 901 318, as
it turns out the hardware will only ever fire one IRQ for a linked
list anyway. In the process also a missing spinlock was introduced.

Signed-off-by: default avatarLinus Walleij <linus.walleij@stericsson.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent b87108a7
Loading
Loading
Loading
Loading
+31 −45
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ struct coh901318_desc {
	unsigned int sg_len;
	struct coh901318_lli *data;
	enum dma_data_direction dir;
	int pending_irqs;
	unsigned long flags;
};

@@ -72,7 +71,6 @@ struct coh901318_chan {

	unsigned long nbr_active_done;
	unsigned long busy;
	int pending_irqs;

	struct coh901318_base *base;
};
@@ -368,10 +366,6 @@ static void
coh901318_desc_submit(struct coh901318_chan *cohc, struct coh901318_desc *desc)
{
	list_add_tail(&desc->node, &cohc->active);

	BUG_ON(cohc->pending_irqs != 0);

	cohc->pending_irqs = desc->pending_irqs;
}

static struct coh901318_desc *
@@ -617,36 +611,30 @@ static void dma_tasklet(unsigned long data)
	/* get first active descriptor entry from list */
	cohd_fin = coh901318_first_active_get(cohc);

	BUG_ON(cohd_fin->pending_irqs == 0);

	if (cohd_fin == NULL)
		goto err;

	cohd_fin->pending_irqs--;
	cohc->completed = cohd_fin->desc.cookie;
	/* locate callback to client */
	callback = cohd_fin->desc.callback;
	callback_param = cohd_fin->desc.callback_param;

	if (cohc->nbr_active_done == 0)
		return;
	/* sign this job as completed on the channel */
	cohc->completed = cohd_fin->desc.cookie;

	if (!cohd_fin->pending_irqs) {
		/* release the lli allocation*/
	/* release the lli allocation and remove the descriptor */
	coh901318_lli_free(&cohc->base->pool, &cohd_fin->data);
	}

	dev_vdbg(COHC_2_DEV(cohc), "[%s] chan_id %d pending_irqs %d"
		 " nbr_active_done %ld\n", __func__,
		 cohc->id, cohc->pending_irqs, cohc->nbr_active_done);
	/* return desc to free-list */
	coh901318_desc_remove(cohd_fin);
	coh901318_desc_free(cohc, cohd_fin);

	/* callback to client */
	callback = cohd_fin->desc.callback;
	callback_param = cohd_fin->desc.callback_param;
	spin_unlock_irqrestore(&cohc->lock, flags);

	if (!cohd_fin->pending_irqs) {
		coh901318_desc_remove(cohd_fin);
	/* Call the callback when we're done */
	if (callback)
		callback(callback_param);

		/* return desc to free-list */
		coh901318_desc_free(cohc, cohd_fin);
	}
	spin_lock_irqsave(&cohc->lock, flags);

	/*
	 * If another interrupt fired while the tasklet was scheduling,
@@ -655,9 +643,7 @@ static void dma_tasklet(unsigned long data)
	 * be handled for this channel. If there happen to be more than
	 * one IRQ to be ack:ed, we simply schedule this tasklet again.
	 */
	if (cohc->nbr_active_done)
	cohc->nbr_active_done--;

	if (cohc->nbr_active_done) {
		dev_dbg(COHC_2_DEV(cohc), "scheduling tasklet again, new IRQs "
			"came in while we were scheduling this tasklet\n");
@@ -666,10 +652,8 @@ static void dma_tasklet(unsigned long data)
		else
			tasklet_schedule(&cohc->tasklet);
	}
	spin_unlock_irqrestore(&cohc->lock, flags);

	if (callback)
		callback(callback_param);
	spin_unlock_irqrestore(&cohc->lock, flags);

	return;

@@ -688,16 +672,17 @@ static void dma_tc_handle(struct coh901318_chan *cohc)
	if (!cohc->allocated)
		return;

	BUG_ON(cohc->pending_irqs == 0);
	spin_lock(&cohc->lock);

	cohc->pending_irqs--;
	cohc->nbr_active_done++;

	if (cohc->pending_irqs == 0 && coh901318_queue_start(cohc) == NULL)
	if (coh901318_queue_start(cohc) == NULL)
		cohc->busy = 0;

	BUG_ON(list_empty(&cohc->active));

	spin_unlock(&cohc->lock);

	if (cohc_chan_conf(cohc)->priority_high)
		tasklet_hi_schedule(&cohc->tasklet);
	else
@@ -951,6 +936,7 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
	u32 ctrl = cohc_chan_param(cohc)->ctrl_lli;
	u32 ctrl_last = cohc_chan_param(cohc)->ctrl_lli_last;
	unsigned long flg;
	int ret;

	if (!sgl)
		goto out;
@@ -1010,13 +996,14 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
		goto err_dma_alloc;

	/* initiate allocated data list */
	cohd->pending_irqs =
		coh901318_lli_fill_sg(&cohc->base->pool, data, sgl, sg_len,
	ret = coh901318_lli_fill_sg(&cohc->base->pool, data, sgl, sg_len,
				    cohc_dev_addr(cohc),
				    ctrl_chained,
				    ctrl,
				    ctrl_last,
				    direction, COH901318_CX_CTRL_TC_IRQ_ENABLE);
	if (ret)
		goto err_lli_fill;

	COH_DBG(coh901318_list_print(cohc, data));

@@ -1030,6 +1017,7 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
	spin_unlock_irqrestore(&cohc->lock, flg);

	return &cohd->desc;
 err_lli_fill:
 err_dma_alloc:
 err_direction:
	spin_unlock_irqrestore(&cohc->lock, flg);
@@ -1121,7 +1109,6 @@ coh901318_terminate_all(struct dma_chan *chan)

	cohc->nbr_active_done = 0;
	cohc->busy = 0;
	cohc->pending_irqs = 0;

	spin_unlock_irqrestore(&cohc->lock, flags);
}
@@ -1148,7 +1135,6 @@ void coh901318_base_init(struct dma_device *dma, const int *pick_chans,

			spin_lock_init(&cohc->lock);

			cohc->pending_irqs = 0;
			cohc->nbr_active_done = 0;
			cohc->busy = 0;
			INIT_LIST_HEAD(&cohc->free);
+3 −10
Original line number Diff line number Diff line
@@ -166,8 +166,7 @@ coh901318_lli_fill_memcpy(struct coh901318_pool *pool,
	lli->src_addr = src;
	lli->dst_addr = dst;

	/* One irq per single transfer */
	return 1;
	return 0;
}

int
@@ -223,8 +222,7 @@ coh901318_lli_fill_single(struct coh901318_pool *pool,
	lli->src_addr = src;
	lli->dst_addr = dst;

	/* One irq per single transfer */
	return 1;
	return 0;
}

int
@@ -240,7 +238,6 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
	u32 ctrl_sg;
	dma_addr_t src = 0;
	dma_addr_t dst = 0;
	int nbr_of_irq = 0;
	u32 bytes_to_transfer;
	u32 elem_size;

@@ -269,9 +266,6 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
			ctrl_sg = ctrl ? ctrl : ctrl_last;


		if ((ctrl_sg & ctrl_irq_mask))
			nbr_of_irq++;

		if (dir == DMA_TO_DEVICE)
			/* increment source address */
			src = sg_dma_address(sg);
@@ -310,8 +304,7 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
	}
	spin_unlock(&pool->lock);

	/* There can be many IRQs per sg transfer */
	return nbr_of_irq;
	return 0;
 err:
	spin_unlock(&pool->lock);
	return -EINVAL;