diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2016-02-10 08:59:42 -0500 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2016-02-15 11:49:32 -0500 |
commit | ee1cdcdae59563535485a5f56ee72c894ab7d7ad (patch) | |
tree | d6aa9036557e0d5432888038b4b62c7a44e04385 | |
parent | 4ac31d18e4125eb2970e69069a15308cbb8e4486 (diff) |
dmaengine: dw: disable BLOCK IRQs for non-cyclic xfer
The commit 2895b2cad6e7 ("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: 2895b2cad6e7 ("dmaengine: dw: fix cyclic transfer callbacks")
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Mans Rullgard <mans@mansr.com>
Tested-by: Mans Rullgard <mans@mansr.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
-rw-r--r-- | drivers/dma/dw/core.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index e893318560db..5ad0ec1f0e29 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c | |||
@@ -156,7 +156,6 @@ static void dwc_initialize(struct dw_dma_chan *dwc) | |||
156 | 156 | ||
157 | /* Enable interrupts */ | 157 | /* Enable interrupts */ |
158 | channel_set_bit(dw, MASK.XFER, dwc->mask); | 158 | channel_set_bit(dw, MASK.XFER, dwc->mask); |
159 | channel_set_bit(dw, MASK.BLOCK, dwc->mask); | ||
160 | channel_set_bit(dw, MASK.ERROR, dwc->mask); | 159 | channel_set_bit(dw, MASK.ERROR, dwc->mask); |
161 | 160 | ||
162 | dwc->initialized = true; | 161 | dwc->initialized = true; |
@@ -588,6 +587,9 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, | |||
588 | 587 | ||
589 | spin_unlock_irqrestore(&dwc->lock, flags); | 588 | spin_unlock_irqrestore(&dwc->lock, flags); |
590 | } | 589 | } |
590 | |||
591 | /* Re-enable interrupts */ | ||
592 | channel_set_bit(dw, MASK.BLOCK, dwc->mask); | ||
591 | } | 593 | } |
592 | 594 | ||
593 | /* ------------------------------------------------------------------------- */ | 595 | /* ------------------------------------------------------------------------- */ |
@@ -618,11 +620,8 @@ static void dw_dma_tasklet(unsigned long data) | |||
618 | dwc_scan_descriptors(dw, dwc); | 620 | dwc_scan_descriptors(dw, dwc); |
619 | } | 621 | } |
620 | 622 | ||
621 | /* | 623 | /* Re-enable interrupts */ |
622 | * Re-enable interrupts. | ||
623 | */ | ||
624 | channel_set_bit(dw, MASK.XFER, dw->all_chan_mask); | 624 | channel_set_bit(dw, MASK.XFER, dw->all_chan_mask); |
625 | channel_set_bit(dw, MASK.BLOCK, dw->all_chan_mask); | ||
626 | channel_set_bit(dw, MASK.ERROR, dw->all_chan_mask); | 625 | channel_set_bit(dw, MASK.ERROR, dw->all_chan_mask); |
627 | } | 626 | } |
628 | 627 | ||
@@ -1261,6 +1260,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan) | |||
1261 | int dw_dma_cyclic_start(struct dma_chan *chan) | 1260 | int dw_dma_cyclic_start(struct dma_chan *chan) |
1262 | { | 1261 | { |
1263 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); | 1262 | struct dw_dma_chan *dwc = to_dw_dma_chan(chan); |
1263 | struct dw_dma *dw = to_dw_dma(chan->device); | ||
1264 | unsigned long flags; | 1264 | unsigned long flags; |
1265 | 1265 | ||
1266 | if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) { | 1266 | if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) { |
@@ -1269,7 +1269,12 @@ int dw_dma_cyclic_start(struct dma_chan *chan) | |||
1269 | } | 1269 | } |
1270 | 1270 | ||
1271 | spin_lock_irqsave(&dwc->lock, flags); | 1271 | spin_lock_irqsave(&dwc->lock, flags); |
1272 | |||
1273 | /* Enable interrupts to perform cyclic transfer */ | ||
1274 | channel_set_bit(dw, MASK.BLOCK, dwc->mask); | ||
1275 | |||
1272 | dwc_dostart(dwc, dwc->cdesc->desc[0]); | 1276 | dwc_dostart(dwc, dwc->cdesc->desc[0]); |
1277 | |||
1273 | spin_unlock_irqrestore(&dwc->lock, flags); | 1278 | spin_unlock_irqrestore(&dwc->lock, flags); |
1274 | 1279 | ||
1275 | return 0; | 1280 | return 0; |