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

Commit 47aceb92 authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Greg Kroah-Hartman
Browse files

serial: sh-sci: Do not resubmit DMA descriptors



Resubmission of DMA descriptors is explicitly forbidden by the DMA
engine API.

Hence pass DMA_CTRL_ACK to dmaengine_prep_slave_sg(), and prepare a new
DMA descriptor instead of reusing the old one.
Remove sci_port.desc_rx[], as there's no longer a need to access the
active descriptor.

Signed-off-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 658daa95
Loading
Loading
Loading
Loading
+18 −12
Original line number Original line Diff line number Diff line
@@ -104,7 +104,6 @@ struct sci_port {
	struct dma_chan			*chan_rx;
	struct dma_chan			*chan_rx;


#ifdef CONFIG_SERIAL_SH_SCI_DMA
#ifdef CONFIG_SERIAL_SH_SCI_DMA
	struct dma_async_tx_descriptor	*desc_rx[2];
	dma_cookie_t			cookie_tx;
	dma_cookie_t			cookie_tx;
	dma_cookie_t			cookie_rx[2];
	dma_cookie_t			cookie_rx[2];
	dma_cookie_t			active_rx;
	dma_cookie_t			active_rx;
@@ -1397,11 +1396,11 @@ static void sci_submit_rx(struct sci_port *s)
		struct dma_async_tx_descriptor *desc;
		struct dma_async_tx_descriptor *desc;


		desc = dmaengine_prep_slave_sg(chan,
		desc = dmaengine_prep_slave_sg(chan,
			sg, 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
			sg, 1, DMA_DEV_TO_MEM,
			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
		if (!desc)
		if (!desc)
			goto fail;
			goto fail;


		s->desc_rx[i] = desc;
		desc->callback = sci_dma_rx_complete;
		desc->callback = sci_dma_rx_complete;
		desc->callback_param = s;
		desc->callback_param = s;
		s->cookie_rx[i] = dmaengine_submit(desc);
		s->cookie_rx[i] = dmaengine_submit(desc);
@@ -1420,10 +1419,8 @@ static void sci_submit_rx(struct sci_port *s)
fail:
fail:
	if (i)
	if (i)
		dmaengine_terminate_all(chan);
		dmaengine_terminate_all(chan);
	for (i = 0; i < 2; i++) {
	for (i = 0; i < 2; i++)
		s->desc_rx[i] = NULL;
		s->cookie_rx[i] = -EINVAL;
		s->cookie_rx[i] = -EINVAL;
	}
	s->active_rx = -EINVAL;
	s->active_rx = -EINVAL;
	dev_warn(s->port.dev, "Failed to re-start Rx DMA, using PIO\n");
	dev_warn(s->port.dev, "Failed to re-start Rx DMA, using PIO\n");
	sci_rx_dma_release(s, true);
	sci_rx_dma_release(s, true);
@@ -1447,7 +1444,6 @@ static void work_fn_rx(struct work_struct *work)
			s->active_rx);
			s->active_rx);
		return;
		return;
	}
	}
	desc = s->desc_rx[new];


	status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state);
	status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state);
	if (status != DMA_COMPLETE) {
	if (status != DMA_COMPLETE) {
@@ -1474,17 +1470,27 @@ static void work_fn_rx(struct work_struct *work)
		return;
		return;
	}
	}


	desc = dmaengine_prep_slave_sg(s->chan_rx, &s->sg_rx[new], 1,
				       DMA_DEV_TO_MEM,
				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
	if (!desc)
		goto fail;

	desc->callback = sci_dma_rx_complete;
	desc->callback_param = s;
	s->cookie_rx[new] = dmaengine_submit(desc);
	s->cookie_rx[new] = dmaengine_submit(desc);
	if (dma_submit_error(s->cookie_rx[new])) {
	if (dma_submit_error(s->cookie_rx[new]))
		dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
		goto fail;
		sci_rx_dma_release(s, true);
		return;
	}


	s->active_rx = s->cookie_rx[!new];
	s->active_rx = s->cookie_rx[!new];


	dev_dbg(port->dev, "%s: cookie %d #%d, new active cookie %d\n",
	dev_dbg(port->dev, "%s: cookie %d #%d, new active cookie %d\n",
		__func__, s->cookie_rx[new], new, s->active_rx);
		__func__, s->cookie_rx[new], new, s->active_rx);
	return;

fail:
	dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
	sci_rx_dma_release(s, true);
}
}


static void work_fn_tx(struct work_struct *work)
static void work_fn_tx(struct work_struct *work)