Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bcd1b0b9 authored by Maxime Ripard's avatar Maxime Ripard Committed by Vinod Koul
Browse files

dmaengine: pl08x: Split device_control



Split the device_control callback of the AMBA PL08x DMA driver to make use
of the newly introduced callbacks, that will eventually be used to retrieve
slave capabilities.

Signed-off-by: default avatarMaxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
parent cb8cea51
Loading
Loading
Loading
Loading
+90 −66
Original line number Original line Diff line number Diff line
@@ -1386,32 +1386,6 @@ static u32 pl08x_get_cctl(struct pl08x_dma_chan *plchan,
	return pl08x_cctl(cctl);
	return pl08x_cctl(cctl);
}
}


static int dma_set_runtime_config(struct dma_chan *chan,
				  struct dma_slave_config *config)
{
	struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
	struct pl08x_driver_data *pl08x = plchan->host;

	if (!plchan->slave)
		return -EINVAL;

	/* Reject definitely invalid configurations */
	if (config->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
	    config->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
		return -EINVAL;

	if (config->device_fc && pl08x->vd->pl080s) {
		dev_err(&pl08x->adev->dev,
			"%s: PL080S does not support peripheral flow control\n",
			__func__);
		return -EINVAL;
	}

	plchan->cfg = *config;

	return 0;
}

/*
/*
 * Slave transactions callback to the slave device to allow
 * Slave transactions callback to the slave device to allow
 * synchronization of slave DMA signals with the DMAC enable
 * synchronization of slave DMA signals with the DMAC enable
@@ -1693,32 +1667,44 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_cyclic(
	return vchan_tx_prep(&plchan->vc, &txd->vd, flags);
	return vchan_tx_prep(&plchan->vc, &txd->vd, flags);
}
}


static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
static int pl08x_config(struct dma_chan *chan,
			 unsigned long arg)
			struct dma_slave_config *config)
{
{
	struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
	struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
	struct pl08x_driver_data *pl08x = plchan->host;
	struct pl08x_driver_data *pl08x = plchan->host;
	unsigned long flags;
	int ret = 0;


	/* Controls applicable to inactive channels */
	if (!plchan->slave)
	if (cmd == DMA_SLAVE_CONFIG) {
		return -EINVAL;
		return dma_set_runtime_config(chan,

					      (struct dma_slave_config *)arg);
	/* Reject definitely invalid configurations */
	if (config->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
	    config->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
		return -EINVAL;

	if (config->device_fc && pl08x->vd->pl080s) {
		dev_err(&pl08x->adev->dev,
			"%s: PL080S does not support peripheral flow control\n",
			__func__);
		return -EINVAL;
	}

	plchan->cfg = *config;

	return 0;
}
}


	/*
static int pl08x_terminate_all(struct dma_chan *chan)
	 * Anything succeeds on channels with no physical allocation and
{
	 * no queued transfers.
	struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
	 */
	struct pl08x_driver_data *pl08x = plchan->host;
	unsigned long flags;

	spin_lock_irqsave(&plchan->vc.lock, flags);
	spin_lock_irqsave(&plchan->vc.lock, flags);
	if (!plchan->phychan && !plchan->at) {
	if (!plchan->phychan && !plchan->at) {
		spin_unlock_irqrestore(&plchan->vc.lock, flags);
		spin_unlock_irqrestore(&plchan->vc.lock, flags);
		return 0;
		return 0;
	}
	}


	switch (cmd) {
	case DMA_TERMINATE_ALL:
	plchan->state = PL08X_CHAN_IDLE;
	plchan->state = PL08X_CHAN_IDLE;


	if (plchan->phychan) {
	if (plchan->phychan) {
@@ -1735,24 +1721,56 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
	}
	}
	/* Dequeue jobs not yet fired as well */
	/* Dequeue jobs not yet fired as well */
	pl08x_free_txd_list(pl08x, plchan);
	pl08x_free_txd_list(pl08x, plchan);
		break;

	case DMA_PAUSE:
	spin_unlock_irqrestore(&plchan->vc.lock, flags);

	return 0;
}

static int pl08x_pause(struct dma_chan *chan)
{
	struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
	unsigned long flags;

	/*
	 * Anything succeeds on channels with no physical allocation and
	 * no queued transfers.
	 */
	spin_lock_irqsave(&plchan->vc.lock, flags);
	if (!plchan->phychan && !plchan->at) {
		spin_unlock_irqrestore(&plchan->vc.lock, flags);
		return 0;
	}

	pl08x_pause_phy_chan(plchan->phychan);
	pl08x_pause_phy_chan(plchan->phychan);
	plchan->state = PL08X_CHAN_PAUSED;
	plchan->state = PL08X_CHAN_PAUSED;
		break;

	case DMA_RESUME:
	spin_unlock_irqrestore(&plchan->vc.lock, flags);

	return 0;
}

static int pl08x_resume(struct dma_chan *chan)
{
	struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
	unsigned long flags;

	/*
	 * Anything succeeds on channels with no physical allocation and
	 * no queued transfers.
	 */
	spin_lock_irqsave(&plchan->vc.lock, flags);
	if (!plchan->phychan && !plchan->at) {
		spin_unlock_irqrestore(&plchan->vc.lock, flags);
		return 0;
	}

	pl08x_resume_phy_chan(plchan->phychan);
	pl08x_resume_phy_chan(plchan->phychan);
	plchan->state = PL08X_CHAN_RUNNING;
	plchan->state = PL08X_CHAN_RUNNING;
		break;
	default:
		/* Unknown command */
		ret = -ENXIO;
		break;
	}


	spin_unlock_irqrestore(&plchan->vc.lock, flags);
	spin_unlock_irqrestore(&plchan->vc.lock, flags);


	return ret;
	return 0;
}
}


bool pl08x_filter_id(struct dma_chan *chan, void *chan_id)
bool pl08x_filter_id(struct dma_chan *chan, void *chan_id)
@@ -2048,7 +2066,10 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
	pl08x->memcpy.device_prep_dma_interrupt = pl08x_prep_dma_interrupt;
	pl08x->memcpy.device_prep_dma_interrupt = pl08x_prep_dma_interrupt;
	pl08x->memcpy.device_tx_status = pl08x_dma_tx_status;
	pl08x->memcpy.device_tx_status = pl08x_dma_tx_status;
	pl08x->memcpy.device_issue_pending = pl08x_issue_pending;
	pl08x->memcpy.device_issue_pending = pl08x_issue_pending;
	pl08x->memcpy.device_control = pl08x_control;
	pl08x->memcpy.device_config = pl08x_config;
	pl08x->memcpy.device_pause = pl08x_pause;
	pl08x->memcpy.device_resume = pl08x_resume;
	pl08x->memcpy.device_terminate_all = pl08x_terminate_all;


	/* Initialize slave engine */
	/* Initialize slave engine */
	dma_cap_set(DMA_SLAVE, pl08x->slave.cap_mask);
	dma_cap_set(DMA_SLAVE, pl08x->slave.cap_mask);
@@ -2061,7 +2082,10 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
	pl08x->slave.device_issue_pending = pl08x_issue_pending;
	pl08x->slave.device_issue_pending = pl08x_issue_pending;
	pl08x->slave.device_prep_slave_sg = pl08x_prep_slave_sg;
	pl08x->slave.device_prep_slave_sg = pl08x_prep_slave_sg;
	pl08x->slave.device_prep_dma_cyclic = pl08x_prep_dma_cyclic;
	pl08x->slave.device_prep_dma_cyclic = pl08x_prep_dma_cyclic;
	pl08x->slave.device_control = pl08x_control;
	pl08x->slave.device_config = pl08x_config;
	pl08x->slave.device_pause = pl08x_pause;
	pl08x->slave.device_resume = pl08x_resume;
	pl08x->slave.device_terminate_all = pl08x_terminate_all;


	/* Get the platform data */
	/* Get the platform data */
	pl08x->pd = dev_get_platdata(&adev->dev);
	pl08x->pd = dev_get_platdata(&adev->dev);