On 25.11.2014 13:25, Robert Baldyga wrote: > DMA_PAUSE command is used for halting DMA transfer on chosen channel. > It can be useful when we want to safely read residue before terminating > all requests on channel. Otherwise there can be situation when some data > is transferred before channel termination but after reading residue, > which obviously results with data loss. To avoid this situation we can > pause channel, read residue and then terminate all requests. > This scenario is common, for example, in serial port drivers. > > Signed-off-by: Robert Baldyga <r.baldyga@xxxxxxxxxxx> > --- > drivers/dma/pl330.c | 20 ++++++++++++++++++++ > 1 file changed, 20 insertions(+) > > diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c > index c32806d..9c64421 100644 > --- a/drivers/dma/pl330.c > +++ b/drivers/dma/pl330.c > @@ -2115,6 +2115,26 @@ static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned > list_splice_tail_init(&pch->completed_list, &pl330->desc_pool); > spin_unlock_irqrestore(&pch->lock, flags); > break; > + case DMA_PAUSE: pm_runtime_get_sync() here? If transfer is ongoing this shouldn't be needed but if this is called after all transfers complete then device will be suspended. > + /* > + * We don't support DMA_RESUME command because of hardware > + * limitations, so after pausing the channel we cannot restore > + * it to active state. We have to terminate channel and setup > + * DMA transfer again. This pause feature was implemented to > + * allow safely read residue before channel termination. > + */ > + spin_lock_irqsave(&pch->lock, flags); > + > + spin_lock(&pl330->lock); > + _stop(pch->thread); > + spin_unlock(&pl330->lock); > + > + pch->thread->req[0].desc = NULL; > + pch->thread->req[1].desc = NULL; > + pch->thread->req_running = -1; > + > + spin_unlock_irqrestore(&pch->lock, flags); symmetric pm_runtime_put + autosuspend. Best regards, Krzysztof -- To unsubscribe from this list: send the line "unsubscribe dmaengine" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html