Commit f6611317 authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Greg Kroah-Hartman

serial: sh-sci: Stop TX DMA workqueue during port shutdown

The transmit DMA workqueue is never stopped, hence the work function may
be called after the port has been shut down.

Fix this race condition by cancelling queued work, if any, before DMA
release.  Don't initialize the work if DMA initialization failed, as it
won't be used anyway.
Signed-off-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 2c4ee235
...@@ -1293,6 +1293,7 @@ static void sci_tx_dma_release(struct sci_port *s) ...@@ -1293,6 +1293,7 @@ static void sci_tx_dma_release(struct sci_port *s)
{ {
struct dma_chan *chan = s->chan_tx_saved; struct dma_chan *chan = s->chan_tx_saved;
cancel_work_sync(&s->work_tx);
s->chan_tx_saved = s->chan_tx = NULL; s->chan_tx_saved = s->chan_tx = NULL;
s->cookie_tx = -EINVAL; s->cookie_tx = -EINVAL;
dmaengine_terminate_all(chan); dmaengine_terminate_all(chan);
...@@ -1548,10 +1549,9 @@ static void sci_request_dma(struct uart_port *port) ...@@ -1548,10 +1549,9 @@ static void sci_request_dma(struct uart_port *port)
__func__, UART_XMIT_SIZE, __func__, UART_XMIT_SIZE,
port->state->xmit.buf, &s->tx_dma_addr); port->state->xmit.buf, &s->tx_dma_addr);
INIT_WORK(&s->work_tx, work_fn_tx);
s->chan_tx_saved = s->chan_tx = chan; s->chan_tx_saved = s->chan_tx = chan;
} }
INIT_WORK(&s->work_tx, work_fn_tx);
} }
chan = sci_request_dma_chan(port, DMA_DEV_TO_MEM); chan = sci_request_dma_chan(port, DMA_DEV_TO_MEM);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment