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

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
...@@ -39,7 +39,6 @@ struct coh901318_desc { ...@@ -39,7 +39,6 @@ struct coh901318_desc {
unsigned int sg_len; unsigned int sg_len;
struct coh901318_lli *data; struct coh901318_lli *data;
enum dma_data_direction dir; enum dma_data_direction dir;
int pending_irqs;
unsigned long flags; unsigned long flags;
}; };
...@@ -72,7 +71,6 @@ struct coh901318_chan { ...@@ -72,7 +71,6 @@ struct coh901318_chan {
unsigned long nbr_active_done; unsigned long nbr_active_done;
unsigned long busy; unsigned long busy;
int pending_irqs;
struct coh901318_base *base; struct coh901318_base *base;
}; };
...@@ -368,10 +366,6 @@ static void ...@@ -368,10 +366,6 @@ static void
coh901318_desc_submit(struct coh901318_chan *cohc, struct coh901318_desc *desc) coh901318_desc_submit(struct coh901318_chan *cohc, struct coh901318_desc *desc)
{ {
list_add_tail(&desc->node, &cohc->active); list_add_tail(&desc->node, &cohc->active);
BUG_ON(cohc->pending_irqs != 0);
cohc->pending_irqs = desc->pending_irqs;
} }
static struct coh901318_desc * static struct coh901318_desc *
...@@ -617,36 +611,30 @@ static void dma_tasklet(unsigned long data) ...@@ -617,36 +611,30 @@ static void dma_tasklet(unsigned long data)
/* get first active descriptor entry from list */ /* get first active descriptor entry from list */
cohd_fin = coh901318_first_active_get(cohc); cohd_fin = coh901318_first_active_get(cohc);
BUG_ON(cohd_fin->pending_irqs == 0);
if (cohd_fin == NULL) if (cohd_fin == NULL)
goto err; goto err;
cohd_fin->pending_irqs--; /* locate callback to client */
cohc->completed = cohd_fin->desc.cookie; callback = cohd_fin->desc.callback;
callback_param = cohd_fin->desc.callback_param;
if (cohc->nbr_active_done == 0) /* sign this job as completed on the channel */
return; cohc->completed = cohd_fin->desc.cookie;
if (!cohd_fin->pending_irqs) { /* release the lli allocation and remove the descriptor */
/* release the lli allocation*/
coh901318_lli_free(&cohc->base->pool, &cohd_fin->data); coh901318_lli_free(&cohc->base->pool, &cohd_fin->data);
}
dev_vdbg(COHC_2_DEV(cohc), "[%s] chan_id %d pending_irqs %d" /* return desc to free-list */
" nbr_active_done %ld\n", __func__, coh901318_desc_remove(cohd_fin);
cohc->id, cohc->pending_irqs, cohc->nbr_active_done); coh901318_desc_free(cohc, cohd_fin);
/* callback to client */ spin_unlock_irqrestore(&cohc->lock, flags);
callback = cohd_fin->desc.callback;
callback_param = cohd_fin->desc.callback_param;
if (!cohd_fin->pending_irqs) { /* Call the callback when we're done */
coh901318_desc_remove(cohd_fin); if (callback)
callback(callback_param);
/* return desc to free-list */ spin_lock_irqsave(&cohc->lock, flags);
coh901318_desc_free(cohc, cohd_fin);
}
/* /*
* If another interrupt fired while the tasklet was scheduling, * If another interrupt fired while the tasklet was scheduling,
...@@ -655,9 +643,7 @@ static void dma_tasklet(unsigned long data) ...@@ -655,9 +643,7 @@ static void dma_tasklet(unsigned long data)
* be handled for this channel. If there happen to be more than * be handled for this channel. If there happen to be more than
* one IRQ to be ack:ed, we simply schedule this tasklet again. * one IRQ to be ack:ed, we simply schedule this tasklet again.
*/ */
if (cohc->nbr_active_done)
cohc->nbr_active_done--; cohc->nbr_active_done--;
if (cohc->nbr_active_done) { if (cohc->nbr_active_done) {
dev_dbg(COHC_2_DEV(cohc), "scheduling tasklet again, new IRQs " dev_dbg(COHC_2_DEV(cohc), "scheduling tasklet again, new IRQs "
"came in while we were scheduling this tasklet\n"); "came in while we were scheduling this tasklet\n");
...@@ -666,10 +652,8 @@ static void dma_tasklet(unsigned long data) ...@@ -666,10 +652,8 @@ static void dma_tasklet(unsigned long data)
else else
tasklet_schedule(&cohc->tasklet); tasklet_schedule(&cohc->tasklet);
} }
spin_unlock_irqrestore(&cohc->lock, flags);
if (callback) spin_unlock_irqrestore(&cohc->lock, flags);
callback(callback_param);
return; return;
...@@ -688,16 +672,17 @@ static void dma_tc_handle(struct coh901318_chan *cohc) ...@@ -688,16 +672,17 @@ static void dma_tc_handle(struct coh901318_chan *cohc)
if (!cohc->allocated) if (!cohc->allocated)
return; return;
BUG_ON(cohc->pending_irqs == 0); spin_lock(&cohc->lock);
cohc->pending_irqs--;
cohc->nbr_active_done++; cohc->nbr_active_done++;
if (cohc->pending_irqs == 0 && coh901318_queue_start(cohc) == NULL) if (coh901318_queue_start(cohc) == NULL)
cohc->busy = 0; cohc->busy = 0;
BUG_ON(list_empty(&cohc->active)); BUG_ON(list_empty(&cohc->active));
spin_unlock(&cohc->lock);
if (cohc_chan_conf(cohc)->priority_high) if (cohc_chan_conf(cohc)->priority_high)
tasklet_hi_schedule(&cohc->tasklet); tasklet_hi_schedule(&cohc->tasklet);
else else
...@@ -951,6 +936,7 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, ...@@ -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 = cohc_chan_param(cohc)->ctrl_lli;
u32 ctrl_last = cohc_chan_param(cohc)->ctrl_lli_last; u32 ctrl_last = cohc_chan_param(cohc)->ctrl_lli_last;
unsigned long flg; unsigned long flg;
int ret;
if (!sgl) if (!sgl)
goto out; goto out;
...@@ -1010,13 +996,14 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, ...@@ -1010,13 +996,14 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
goto err_dma_alloc; goto err_dma_alloc;
/* initiate allocated data list */ /* initiate allocated data list */
cohd->pending_irqs = ret = coh901318_lli_fill_sg(&cohc->base->pool, data, sgl, sg_len,
coh901318_lli_fill_sg(&cohc->base->pool, data, sgl, sg_len,
cohc_dev_addr(cohc), cohc_dev_addr(cohc),
ctrl_chained, ctrl_chained,
ctrl, ctrl,
ctrl_last, ctrl_last,
direction, COH901318_CX_CTRL_TC_IRQ_ENABLE); direction, COH901318_CX_CTRL_TC_IRQ_ENABLE);
if (ret)
goto err_lli_fill;
COH_DBG(coh901318_list_print(cohc, data)); COH_DBG(coh901318_list_print(cohc, data));
...@@ -1030,6 +1017,7 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, ...@@ -1030,6 +1017,7 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
spin_unlock_irqrestore(&cohc->lock, flg); spin_unlock_irqrestore(&cohc->lock, flg);
return &cohd->desc; return &cohd->desc;
err_lli_fill:
err_dma_alloc: err_dma_alloc:
err_direction: err_direction:
spin_unlock_irqrestore(&cohc->lock, flg); spin_unlock_irqrestore(&cohc->lock, flg);
...@@ -1121,7 +1109,6 @@ coh901318_terminate_all(struct dma_chan *chan) ...@@ -1121,7 +1109,6 @@ coh901318_terminate_all(struct dma_chan *chan)
cohc->nbr_active_done = 0; cohc->nbr_active_done = 0;
cohc->busy = 0; cohc->busy = 0;
cohc->pending_irqs = 0;
spin_unlock_irqrestore(&cohc->lock, flags); spin_unlock_irqrestore(&cohc->lock, flags);
} }
...@@ -1148,7 +1135,6 @@ void coh901318_base_init(struct dma_device *dma, const int *pick_chans, ...@@ -1148,7 +1135,6 @@ void coh901318_base_init(struct dma_device *dma, const int *pick_chans,
spin_lock_init(&cohc->lock); spin_lock_init(&cohc->lock);
cohc->pending_irqs = 0;
cohc->nbr_active_done = 0; cohc->nbr_active_done = 0;
cohc->busy = 0; cohc->busy = 0;
INIT_LIST_HEAD(&cohc->free); INIT_LIST_HEAD(&cohc->free);
......
...@@ -166,8 +166,7 @@ coh901318_lli_fill_memcpy(struct coh901318_pool *pool, ...@@ -166,8 +166,7 @@ coh901318_lli_fill_memcpy(struct coh901318_pool *pool,
lli->src_addr = src; lli->src_addr = src;
lli->dst_addr = dst; lli->dst_addr = dst;
/* One irq per single transfer */ return 0;
return 1;
} }
int int
...@@ -223,8 +222,7 @@ coh901318_lli_fill_single(struct coh901318_pool *pool, ...@@ -223,8 +222,7 @@ coh901318_lli_fill_single(struct coh901318_pool *pool,
lli->src_addr = src; lli->src_addr = src;
lli->dst_addr = dst; lli->dst_addr = dst;
/* One irq per single transfer */ return 0;
return 1;
} }
int int
...@@ -240,7 +238,6 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool, ...@@ -240,7 +238,6 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
u32 ctrl_sg; u32 ctrl_sg;
dma_addr_t src = 0; dma_addr_t src = 0;
dma_addr_t dst = 0; dma_addr_t dst = 0;
int nbr_of_irq = 0;
u32 bytes_to_transfer; u32 bytes_to_transfer;
u32 elem_size; u32 elem_size;
...@@ -269,9 +266,6 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool, ...@@ -269,9 +266,6 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
ctrl_sg = ctrl ? ctrl : ctrl_last; ctrl_sg = ctrl ? ctrl : ctrl_last;
if ((ctrl_sg & ctrl_irq_mask))
nbr_of_irq++;
if (dir == DMA_TO_DEVICE) if (dir == DMA_TO_DEVICE)
/* increment source address */ /* increment source address */
src = sg_dma_address(sg); src = sg_dma_address(sg);
...@@ -310,8 +304,7 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool, ...@@ -310,8 +304,7 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
} }
spin_unlock(&pool->lock); spin_unlock(&pool->lock);
/* There can be many IRQs per sg transfer */ return 0;
return nbr_of_irq;
err: err:
spin_unlock(&pool->lock); spin_unlock(&pool->lock);
return -EINVAL; return -EINVAL;
......
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