Commit 956e6c8e authored by Vinod Koul's avatar Vinod Koul
Browse files

Merge branch 'fix/edma' into fixes

parents 1cc3334e a482f4e0
Loading
Loading
Loading
Loading
+25 −38
Original line number Diff line number Diff line
@@ -1238,6 +1238,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
	struct edma_desc *edesc;
	dma_addr_t src_addr, dst_addr;
	enum dma_slave_buswidth dev_width;
	bool use_intermediate = false;
	u32 burst;
	int i, ret, nslots;

@@ -1279,8 +1280,21 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
	 * but the synchronization is difficult to achieve with Cyclic and
	 * cannot be guaranteed, so we error out early.
	 */
	if (nslots > MAX_NR_SG)
	if (nslots > MAX_NR_SG) {
		/*
		 * If the burst and period sizes are the same, we can put
		 * the full buffer into a single period and activate
		 * intermediate interrupts. This will produce interrupts
		 * after each burst, which is also after each desired period.
		 */
		if (burst == period_len) {
			period_len = buf_len;
			nslots = 2;
			use_intermediate = true;
		} else {
			return NULL;
		}
	}

	edesc = kzalloc(sizeof(*edesc) + nslots * sizeof(edesc->pset[0]),
			GFP_ATOMIC);
@@ -1358,8 +1372,13 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
		/*
		 * Enable period interrupt only if it is requested
		 */
		if (tx_flags & DMA_PREP_INTERRUPT)
		if (tx_flags & DMA_PREP_INTERRUPT) {
			edesc->pset[i].param.opt |= TCINTEN;

			/* Also enable intermediate interrupts if necessary */
			if (use_intermediate)
				edesc->pset[i].param.opt |= ITCINTEN;
		}
	}

	/* Place the cyclic channel to highest priority queue */
@@ -1570,32 +1589,6 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data)
	return IRQ_HANDLED;
}

static void edma_tc_set_pm_state(struct edma_tc *tc, bool enable)
{
	struct platform_device *tc_pdev;
	int ret;

	if (!IS_ENABLED(CONFIG_OF) || !tc)
		return;

	tc_pdev = of_find_device_by_node(tc->node);
	if (!tc_pdev) {
		pr_err("%s: TPTC device is not found\n", __func__);
		return;
	}
	if (!pm_runtime_enabled(&tc_pdev->dev))
		pm_runtime_enable(&tc_pdev->dev);

	if (enable)
		ret = pm_runtime_get_sync(&tc_pdev->dev);
	else
		ret = pm_runtime_put_sync(&tc_pdev->dev);

	if (ret < 0)
		pr_err("%s: pm_runtime_%s_sync() failed for %s\n", __func__,
		       enable ? "get" : "put", dev_name(&tc_pdev->dev));
}

/* Alloc channel resources */
static int edma_alloc_chan_resources(struct dma_chan *chan)
{
@@ -1632,8 +1625,6 @@ static int edma_alloc_chan_resources(struct dma_chan *chan)
		EDMA_CHAN_SLOT(echan->ch_num), chan->chan_id,
		echan->hw_triggered ? "HW" : "SW");

	edma_tc_set_pm_state(echan->tc, true);

	return 0;

err_slot:
@@ -1670,7 +1661,6 @@ static void edma_free_chan_resources(struct dma_chan *chan)
		echan->alloced = false;
	}

	edma_tc_set_pm_state(echan->tc, false);
	echan->tc = NULL;
	echan->hw_triggered = false;

@@ -2417,10 +2407,8 @@ static int edma_pm_suspend(struct device *dev)
	int i;

	for (i = 0; i < ecc->num_channels; i++) {
		if (echan[i].alloced) {
		if (echan[i].alloced)
			edma_setup_interrupt(&echan[i], false);
			edma_tc_set_pm_state(echan[i].tc, false);
		}
	}

	return 0;
@@ -2450,8 +2438,6 @@ static int edma_pm_resume(struct device *dev)

			/* Set up channel -> slot mapping for the entry slot */
			edma_set_chmap(&echan[i], echan[i].slot[0]);

			edma_tc_set_pm_state(echan[i].tc, true);
		}
	}

@@ -2475,7 +2461,8 @@ static struct platform_driver edma_driver = {

static int edma_tptc_probe(struct platform_device *pdev)
{
	return 0;
	pm_runtime_enable(&pdev->dev);
	return pm_runtime_get_sync(&pdev->dev);
}

static struct platform_driver edma_tptc_driver = {