Skip to content

Commit

Permalink
dmaengine: dw: disable BLOCK IRQs for non-cyclic xfer
Browse files Browse the repository at this point in the history
[ Upstream commit ee1cdcd ]

The commit 2895b2c ("dmaengine: dw: fix cyclic transfer callbacks")
re-enabled BLOCK interrupts with regard to make cyclic transfers work. However,
this change becomes a regression for non-cyclic transfers as interrupt counters
under stress test had been grown enormously (approximately per 4-5 bytes in the
UART loop back test).

Taking into consideration above enable BLOCK interrupts if and only if channel
is programmed to perform cyclic transfer.

Fixes: 2895b2c ("dmaengine: dw: fix cyclic transfer callbacks")
Signed-off-by: Andy Shevchenko <[email protected]>
Acked-by: Mans Rullgard <[email protected]>
Tested-by: Mans Rullgard <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Cc: <[email protected]>
Signed-off-by: Vinod Koul <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
  • Loading branch information
andy-shev authored and sashalevin committed Mar 4, 2016
1 parent 800b266 commit 6bdec2b
Showing 1 changed file with 10 additions and 5 deletions.
15 changes: 10 additions & 5 deletions drivers/dma/dw/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ static void dwc_initialize(struct dw_dma_chan *dwc)

/* Enable interrupts */
channel_set_bit(dw, MASK.XFER, dwc->mask);
channel_set_bit(dw, MASK.BLOCK, dwc->mask);
channel_set_bit(dw, MASK.ERROR, dwc->mask);

dwc->initialized = true;
Expand Down Expand Up @@ -588,6 +587,9 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,

spin_unlock_irqrestore(&dwc->lock, flags);
}

/* Re-enable interrupts */
channel_set_bit(dw, MASK.BLOCK, dwc->mask);
}

/* ------------------------------------------------------------------------- */
Expand Down Expand Up @@ -618,11 +620,8 @@ static void dw_dma_tasklet(unsigned long data)
dwc_scan_descriptors(dw, dwc);
}

/*
* Re-enable interrupts.
*/
/* Re-enable interrupts */
channel_set_bit(dw, MASK.XFER, dw->all_chan_mask);
channel_set_bit(dw, MASK.BLOCK, dw->all_chan_mask);
channel_set_bit(dw, MASK.ERROR, dw->all_chan_mask);
}

Expand Down Expand Up @@ -1256,6 +1255,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
int dw_dma_cyclic_start(struct dma_chan *chan)
{
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
struct dw_dma *dw = to_dw_dma(chan->device);
unsigned long flags;

if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) {
Expand All @@ -1264,7 +1264,12 @@ int dw_dma_cyclic_start(struct dma_chan *chan)
}

spin_lock_irqsave(&dwc->lock, flags);

/* Enable interrupts to perform cyclic transfer */
channel_set_bit(dw, MASK.BLOCK, dwc->mask);

dwc_dostart(dwc, dwc->cdesc->desc[0]);

spin_unlock_irqrestore(&dwc->lock, flags);

return 0;
Expand Down

0 comments on commit 6bdec2b

Please sign in to comment.