Commit 21420841 authored by Robin Gong's avatar Robin Gong Committed by Vinod Koul
Browse files

dmaengine: imx-sdma: add sdma_transfer_init to decrease code overlap



There are lot of codes overlap between prep_sg and prep_cyclic function.
Add sdma_transfer_init() function to elimated the code overlap.

Signed-off-by: default avatarRobin Gong <yibin.gong@nxp.com>
Reviewed-by: default avatarSascha Hauer <s.hauer@pengutronix.de>
Tested-by: default avatarLucas Stach <l.stach@pengutronix.de>
Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 36e8d3b1
Loading
Loading
Loading
Loading
+37 −46
Original line number Diff line number Diff line
@@ -1248,6 +1248,40 @@ static void sdma_free_chan_resources(struct dma_chan *chan)
	clk_disable(sdma->clk_ahb);
}

static struct sdma_desc *sdma_transfer_init(struct sdma_channel *sdmac,
				enum dma_transfer_direction direction, u32 bds)
{
	struct sdma_desc *desc;

	desc = kzalloc((sizeof(*desc)), GFP_NOWAIT);
	if (!desc)
		goto err_out;

	sdmac->status = DMA_IN_PROGRESS;
	sdmac->direction = direction;
	sdmac->flags = 0;

	desc->chn_count = 0;
	desc->chn_real_count = 0;
	desc->buf_tail = 0;
	desc->buf_ptail = 0;
	desc->sdmac = sdmac;
	desc->num_bd = bds;

	if (sdma_alloc_bd(desc))
		goto err_desc_out;

	if (sdma_load_context(sdmac))
		goto err_desc_out;

	return desc;

err_desc_out:
	kfree(desc);
err_out:
	return NULL;
}

static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
		struct dma_chan *chan, struct scatterlist *sgl,
		unsigned int sg_len, enum dma_transfer_direction direction,
@@ -1260,36 +1294,13 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
	struct scatterlist *sg;
	struct sdma_desc *desc;

	if (sdmac->status == DMA_IN_PROGRESS)
		return NULL;
	sdmac->status = DMA_IN_PROGRESS;

	sdmac->flags = 0;

	desc = kzalloc((sizeof(*desc)), GFP_NOWAIT);
	desc = sdma_transfer_init(sdmac, direction, sg_len);
	if (!desc)
		goto err_out;

	desc->buf_tail = 0;
	desc->buf_ptail = 0;
	desc->sdmac = sdmac;
	desc->num_bd = sg_len;
	desc->chn_real_count = 0;

	if (sdma_alloc_bd(desc)) {
		kfree(desc);
		goto err_out;
	}

	dev_dbg(sdma->dev, "setting up %d entries for channel %d.\n",
			sg_len, channel);

	sdmac->direction = direction;
	ret = sdma_load_context(sdmac);
	if (ret)
		goto err_bd_out;

	desc->chn_count = 0;
	for_each_sg(sgl, sg, sg_len, i) {
		struct sdma_buffer_descriptor *bd = &desc->bd[i];
		int param;
@@ -1365,38 +1376,18 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
	struct sdma_engine *sdma = sdmac->sdma;
	int num_periods = buf_len / period_len;
	int channel = sdmac->channel;
	int ret, i = 0, buf = 0;
	int i = 0, buf = 0;
	struct sdma_desc *desc;

	dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel);

	if (sdmac->status == DMA_IN_PROGRESS)
		return NULL;

	sdmac->status = DMA_IN_PROGRESS;

	desc = kzalloc((sizeof(*desc)), GFP_NOWAIT);
	desc = sdma_transfer_init(sdmac, direction, num_periods);
	if (!desc)
		goto err_out;

	desc->buf_tail = 0;
	desc->buf_ptail = 0;
	desc->sdmac = sdmac;
	desc->num_bd = num_periods;
	desc->chn_real_count = 0;
	desc->period_len = period_len;

	sdmac->flags |= IMX_DMA_SG_LOOP;
	sdmac->direction = direction;

	if (sdma_alloc_bd(desc)) {
		kfree(desc);
		goto err_bd_out;
	}

	ret = sdma_load_context(sdmac);
	if (ret)
		goto err_bd_out;

	if (period_len > 0xffff) {
		dev_err(sdma->dev, "SDMA channel %d: maximum period size exceeded: %zu > %d\n",