diff options
-rw-r--r-- | drivers/dma/fsldma.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 9854ebbaee31..d8ae18dbf1a7 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c | |||
@@ -696,6 +696,8 @@ static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data) | |||
696 | { | 696 | { |
697 | struct fsl_dma_chan *fsl_chan = (struct fsl_dma_chan *)data; | 697 | struct fsl_dma_chan *fsl_chan = (struct fsl_dma_chan *)data; |
698 | u32 stat; | 698 | u32 stat; |
699 | int update_cookie = 0; | ||
700 | int xfer_ld_q = 0; | ||
699 | 701 | ||
700 | stat = get_sr(fsl_chan); | 702 | stat = get_sr(fsl_chan); |
701 | dev_dbg(fsl_chan->dev, "event: channel %d, stat = 0x%x\n", | 703 | dev_dbg(fsl_chan->dev, "event: channel %d, stat = 0x%x\n", |
@@ -720,8 +722,8 @@ static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data) | |||
720 | * Now, update the completed cookie, and continue the | 722 | * Now, update the completed cookie, and continue the |
721 | * next uncompleted transfer. | 723 | * next uncompleted transfer. |
722 | */ | 724 | */ |
723 | fsl_dma_update_completed_cookie(fsl_chan); | 725 | update_cookie = 1; |
724 | fsl_chan_xfer_ld_queue(fsl_chan); | 726 | xfer_ld_q = 1; |
725 | } | 727 | } |
726 | stat &= ~FSL_DMA_SR_PE; | 728 | stat &= ~FSL_DMA_SR_PE; |
727 | } | 729 | } |
@@ -734,19 +736,33 @@ static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data) | |||
734 | dev_dbg(fsl_chan->dev, "event: clndar %p, nlndar %p\n", | 736 | dev_dbg(fsl_chan->dev, "event: clndar %p, nlndar %p\n", |
735 | (void *)get_cdar(fsl_chan), (void *)get_ndar(fsl_chan)); | 737 | (void *)get_cdar(fsl_chan), (void *)get_ndar(fsl_chan)); |
736 | stat &= ~FSL_DMA_SR_EOSI; | 738 | stat &= ~FSL_DMA_SR_EOSI; |
737 | fsl_dma_update_completed_cookie(fsl_chan); | 739 | update_cookie = 1; |
740 | } | ||
741 | |||
742 | /* For MPC8349, EOCDI event need to update cookie | ||
743 | * and start the next transfer if it exist. | ||
744 | */ | ||
745 | if (stat & FSL_DMA_SR_EOCDI) { | ||
746 | dev_dbg(fsl_chan->dev, "event: End-of-Chain link INT\n"); | ||
747 | stat &= ~FSL_DMA_SR_EOCDI; | ||
748 | update_cookie = 1; | ||
749 | xfer_ld_q = 1; | ||
738 | } | 750 | } |
739 | 751 | ||
740 | /* If it current transfer is the end-of-transfer, | 752 | /* If it current transfer is the end-of-transfer, |
741 | * we should clear the Channel Start bit for | 753 | * we should clear the Channel Start bit for |
742 | * prepare next transfer. | 754 | * prepare next transfer. |
743 | */ | 755 | */ |
744 | if (stat & (FSL_DMA_SR_EOLNI | FSL_DMA_SR_EOCDI)) { | 756 | if (stat & FSL_DMA_SR_EOLNI) { |
745 | dev_dbg(fsl_chan->dev, "event: End-of-link INT\n"); | 757 | dev_dbg(fsl_chan->dev, "event: End-of-link INT\n"); |
746 | stat &= ~FSL_DMA_SR_EOLNI; | 758 | stat &= ~FSL_DMA_SR_EOLNI; |
747 | fsl_chan_xfer_ld_queue(fsl_chan); | 759 | xfer_ld_q = 1; |
748 | } | 760 | } |
749 | 761 | ||
762 | if (update_cookie) | ||
763 | fsl_dma_update_completed_cookie(fsl_chan); | ||
764 | if (xfer_ld_q) | ||
765 | fsl_chan_xfer_ld_queue(fsl_chan); | ||
750 | if (stat) | 766 | if (stat) |
751 | dev_dbg(fsl_chan->dev, "event: unhandled sr 0x%02x\n", | 767 | dev_dbg(fsl_chan->dev, "event: unhandled sr 0x%02x\n", |
752 | stat); | 768 | stat); |