summaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert+renesas@glider.be>2018-07-06 11:05:42 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-07-06 16:41:15 +0200
commitf661131766e45bc0b3c8b85b19676a470dc75abf (patch)
treeb4b47e57b3bd04d5ad5ec074661dbd900db00603 /drivers/tty/serial
parent2c4ee23530ffc022dc22d2fd4b0eb039c6b4c5e9 (diff)
downloadlinux-f661131766e45bc0b3c8b85b19676a470dc75abf.tar.bz2
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: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r--drivers/tty/serial/sh-sci.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index c5c891c8714e..f3432cca3fdc 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1293,6 +1293,7 @@ static void sci_tx_dma_release(struct sci_port *s)
{
struct dma_chan *chan = s->chan_tx_saved;
+ cancel_work_sync(&s->work_tx);
s->chan_tx_saved = s->chan_tx = NULL;
s->cookie_tx = -EINVAL;
dmaengine_terminate_all(chan);
@@ -1548,10 +1549,9 @@ static void sci_request_dma(struct uart_port *port)
__func__, UART_XMIT_SIZE,
port->state->xmit.buf, &s->tx_dma_addr);
+ INIT_WORK(&s->work_tx, work_fn_tx);
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);