示例#1
0
文件: fsl-edma.c 项目: 3null/linux
static int fsl_edma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
		unsigned long arg)
{
	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
	struct dma_slave_config *cfg = (void *)arg;
	unsigned long flags;
	LIST_HEAD(head);

	switch (cmd) {
	case DMA_TERMINATE_ALL:
		spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
		fsl_edma_disable_request(fsl_chan);
		fsl_chan->edesc = NULL;
		vchan_get_all_descriptors(&fsl_chan->vchan, &head);
		spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
		vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
		return 0;

	case DMA_SLAVE_CONFIG:
		fsl_chan->fsc.dir = cfg->direction;
		if (cfg->direction == DMA_DEV_TO_MEM) {
			fsl_chan->fsc.dev_addr = cfg->src_addr;
			fsl_chan->fsc.addr_width = cfg->src_addr_width;
			fsl_chan->fsc.burst = cfg->src_maxburst;
			fsl_chan->fsc.attr = fsl_edma_get_tcd_attr(cfg->src_addr_width);
		} else if (cfg->direction == DMA_MEM_TO_DEV) {
			fsl_chan->fsc.dev_addr = cfg->dst_addr;
			fsl_chan->fsc.addr_width = cfg->dst_addr_width;
			fsl_chan->fsc.burst = cfg->dst_maxburst;
			fsl_chan->fsc.attr = fsl_edma_get_tcd_attr(cfg->dst_addr_width);
		} else {
			return -EINVAL;
		}
		return 0;

	case DMA_PAUSE:
		spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
		if (fsl_chan->edesc) {
			fsl_edma_disable_request(fsl_chan);
			fsl_chan->status = DMA_PAUSED;
		}
		spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
		return 0;

	case DMA_RESUME:
		spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
		if (fsl_chan->edesc) {
			fsl_edma_enable_request(fsl_chan);
			fsl_chan->status = DMA_IN_PROGRESS;
		}
		spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
		return 0;

	default:
		return -ENXIO;
	}
}
示例#2
0
static int fsl_edma_terminate_all(struct dma_chan *chan)
{
	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
	unsigned long flags;
	LIST_HEAD(head);

	spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
	fsl_edma_disable_request(fsl_chan);
	fsl_chan->edesc = NULL;
	vchan_get_all_descriptors(&fsl_chan->vchan, &head);
	spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
	vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
	return 0;
}
示例#3
0
static int tegra_adma_terminate_all(struct dma_chan *dc)
{
	struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc);
	unsigned long flags;
	LIST_HEAD(head);

	spin_lock_irqsave(&tdc->vc.lock, flags);

	if (tdc->desc)
		tegra_adma_stop(tdc);

	tegra_adma_request_free(tdc);
	vchan_get_all_descriptors(&tdc->vc, &head);
	spin_unlock_irqrestore(&tdc->vc.lock, flags);
	vchan_dma_desc_free_list(&tdc->vc, &head);

	return 0;
}