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

Commit 86eb5fb6 authored by Rabin Vincent's avatar Rabin Vincent Committed by Dan Williams
Browse files

dma40: stop ongoing transfers in DMA_TERMINATE_ALL



The current implementation of DMA_TERMINATE_ALL leaves ongoing transfers
running.  Fix it.

Acked-by: default avatarPer Forlin <per.forlin@stericsson.com>
Acked-by: default avatarJonas Aaberg <jonas.aberg@stericsson.com>
Signed-off-by: default avatarRabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@stericsson.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 7ad74a7c
Loading
Loading
Loading
Loading
+21 −13
Original line number Diff line number Diff line
@@ -918,10 +918,8 @@ static bool d40_tx_is_linked(struct d40_chan *d40c)
	return is_link;
}

static int d40_pause(struct dma_chan *chan)
static int d40_pause(struct d40_chan *d40c)
{
	struct d40_chan *d40c =
		container_of(chan, struct d40_chan, chan);
	int res = 0;
	unsigned long flags;

@@ -945,10 +943,8 @@ static int d40_pause(struct dma_chan *chan)
	return res;
}

static int d40_resume(struct dma_chan *chan)
static int d40_resume(struct d40_chan *d40c)
{
	struct d40_chan *d40c =
		container_of(chan, struct d40_chan, chan);
	int res = 0;
	unsigned long flags;

@@ -978,6 +974,22 @@ no_suspend:
	return res;
}

static int d40_terminate_all(struct d40_chan *chan)
{
	unsigned long flags;
	int ret = 0;

	ret = d40_pause(chan);
	if (!ret && chan_is_physical(chan))
		ret = d40_channel_execute_command(chan, D40_DMA_STOP);

	spin_lock_irqsave(&chan->lock, flags);
	d40_term_all(chan);
	spin_unlock_irqrestore(&chan->lock, flags);

	return ret;
}

static dma_cookie_t d40_tx_submit(struct dma_async_tx_descriptor *tx)
{
	struct d40_chan *d40c = container_of(tx->chan,
@@ -2176,7 +2188,6 @@ static void d40_set_runtime_config(struct dma_chan *chan,
static int d40_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
		       unsigned long arg)
{
	unsigned long flags;
	struct d40_chan *d40c = container_of(chan, struct d40_chan, chan);

	if (d40c->phy_chan == NULL) {
@@ -2186,14 +2197,11 @@ static int d40_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,

	switch (cmd) {
	case DMA_TERMINATE_ALL:
		spin_lock_irqsave(&d40c->lock, flags);
		d40_term_all(d40c);
		spin_unlock_irqrestore(&d40c->lock, flags);
		return 0;
		return d40_terminate_all(d40c);
	case DMA_PAUSE:
		return d40_pause(chan);
		return d40_pause(d40c);
	case DMA_RESUME:
		return d40_resume(chan);
		return d40_resume(d40c);
	case DMA_SLAVE_CONFIG:
		d40_set_runtime_config(chan,
			(struct dma_slave_config *) arg);