diff options
| -rw-r--r-- | drivers/dma/dw_dmac.c | 43 | 
1 files changed, 21 insertions, 22 deletions
| diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index 635a4a5d31ae..dc3b9558a25c 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -400,6 +400,20 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)  	if (status_xfer & dwc->mask) {  		/* Everything we've submitted is done */  		dma_writel(dw, CLEAR.XFER, dwc->mask); + +		if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) { +			if (dwc->tx_node_active != dwc->tx_list) { +				desc = to_dw_desc(dwc->tx_node_active); + +				/* Submit next block */ +				dwc_do_single_block(dwc, desc); +				spin_unlock_irqrestore(&dwc->lock, flags); + +				return; +			} +			/* We are done here */ +			clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags); +		}  		spin_unlock_irqrestore(&dwc->lock, flags);  		dwc_complete_all(dw, dwc); @@ -411,6 +425,12 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)  		return;  	} +	if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) { +		dev_vdbg(chan2dev(&dwc->chan), "%s: soft LLP mode\n", __func__); +		spin_unlock_irqrestore(&dwc->lock, flags); +		return; +	} +  	dev_vdbg(chan2dev(&dwc->chan), "%s: llp=0x%llx\n", __func__,  			(unsigned long long)llp); @@ -596,29 +616,8 @@ static void dw_dma_tasklet(unsigned long data)  			dwc_handle_cyclic(dw, dwc, status_err, status_xfer);  		else if (status_err & (1 << i))  			dwc_handle_error(dw, dwc); -		else if (status_xfer & (1 << i)) { -			unsigned long flags; - -			spin_lock_irqsave(&dwc->lock, flags); -			if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) { -				if (dwc->tx_node_active != dwc->tx_list) { -					struct dw_desc *desc = -						to_dw_desc(dwc->tx_node_active); - -					dma_writel(dw, CLEAR.XFER, dwc->mask); - -					dwc_do_single_block(dwc, desc); - -					spin_unlock_irqrestore(&dwc->lock, flags); -					continue; -				} -				/* we are done here */ -				clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags); -			} -			spin_unlock_irqrestore(&dwc->lock, flags); - +		else if (status_xfer & (1 << i))  			dwc_scan_descriptors(dw, dwc); -		}  	}  	/* | 
