blob: e7dea942e4e0077243dcf50b2044e5d3230e2792 [file] [log] [blame]
From c7a8465db9172e278a9427e04ed69092a9351bd2 Mon Sep 17 00:00:00 2001
From: Takatoshi Akiyama <takatoshi.akiyama.kj@ps.hitachi-solutions.com>
Date: Mon, 7 Nov 2016 16:56:50 +0100
Subject: [PATCH 104/299] serial: sh-sci: Fix deadlock caused by serial output
request
While spin is already locked, serial output request causes the deadlock,
because serial output process also tries to lock the spin.
This patch removes serial output with spin locked.
Signed-off-by: Takatoshi Akiyama <takatoshi.akiyama.kj@ps.hitachi-solutions.com>
Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 6fc5a520429e29ae84cb9ce8e8c584166a54a1ee)
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
drivers/tty/serial/sh-sci.c | 20 +++++---------------
1 file changed, 5 insertions(+), 15 deletions(-)
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1143,11 +1143,8 @@ static int sci_dma_rx_push(struct sci_po
int copied;
copied = tty_insert_flip_string(tport, buf, count);
- if (copied < count) {
- dev_warn(port->dev, "Rx overrun: dropping %zu bytes\n",
- count - copied);
+ if (copied < count)
port->icount.buf_overrun++;
- }
port->icount.rx += copied;
@@ -1162,8 +1159,6 @@ static int sci_dma_rx_find_active(struct
if (s->active_rx == s->cookie_rx[i])
return i;
- dev_err(s->port.dev, "%s: Rx cookie %d not found!\n", __func__,
- s->active_rx);
return -1;
}
@@ -1224,9 +1219,9 @@ static void sci_dma_rx_complete(void *ar
dma_async_issue_pending(chan);
+ spin_unlock_irqrestore(&port->lock, flags);
dev_dbg(port->dev, "%s: cookie %d #%d, new active cookie %d\n",
__func__, s->cookie_rx[active], active, s->active_rx);
- spin_unlock_irqrestore(&port->lock, flags);
return;
fail:
@@ -1274,8 +1269,6 @@ static void sci_submit_rx(struct sci_por
if (dma_submit_error(s->cookie_rx[i]))
goto fail;
- dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n", __func__,
- s->cookie_rx[i], i);
}
s->active_rx = s->cookie_rx[0];
@@ -1289,7 +1282,6 @@ fail:
for (i = 0; i < 2; i++)
s->cookie_rx[i] = -EINVAL;
s->active_rx = -EINVAL;
- dev_warn(s->port.dev, "Failed to re-start Rx DMA, using PIO\n");
sci_rx_dma_release(s, true);
}
@@ -1359,10 +1351,10 @@ static void rx_timer_fn(unsigned long ar
int active, count;
u16 scr;
- spin_lock_irqsave(&port->lock, flags);
-
dev_dbg(port->dev, "DMA Rx timed out\n");
+ spin_lock_irqsave(&port->lock, flags);
+
active = sci_dma_rx_find_active(s);
if (active < 0) {
spin_unlock_irqrestore(&port->lock, flags);
@@ -1371,9 +1363,9 @@ static void rx_timer_fn(unsigned long ar
status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state);
if (status == DMA_COMPLETE) {
+ spin_unlock_irqrestore(&port->lock, flags);
dev_dbg(port->dev, "Cookie %d #%d has already completed\n",
s->active_rx, active);
- spin_unlock_irqrestore(&port->lock, flags);
/* Let packet complete handler take care of the packet */
return;
@@ -1397,8 +1389,6 @@ static void rx_timer_fn(unsigned long ar
/* Handle incomplete DMA receive */
dmaengine_terminate_all(s->chan_rx);
read = sg_dma_len(&s->sg_rx[active]) - state.residue;
- dev_dbg(port->dev, "Read %u bytes with cookie %d\n", read,
- s->active_rx);
if (read) {
count = sci_dma_rx_push(s, s->rx_buf[active], read);