summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Case <ryandcase@chromium.org>2018-12-19 12:33:53 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-12-20 16:26:28 +0100
commit663abb1a7a7ff8fea9ab0145463de7fcff823755 (patch)
tree09d4f0cd7a1bb3c26936f2f33e9cdef642379a8c
parent3c66eb4ba18dd1cab0d1bde651cde6d8bdb47696 (diff)
tty: serial: qcom_geni_serial: Fix UART hang
If a serial console write occured while a UART transmit command was waiting for a done signal then no further data would be sent until something new kicked the system into gear. If there is already data waiting in the circular buffer we must re-enable the tx watermark so we receive the expected interrupts. Signed-off-by: Ryan Case <ryandcase@chromium.org> Reviewed-by: Evan Green <evgreen@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/serial/qcom_geni_serial.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 2ee2d3286a6b..a72d6d9fb983 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -440,6 +440,7 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
bool locked = true;
unsigned long flags;
u32 geni_status;
+ u32 irq_en;
WARN_ON(co->index < 0 || co->index >= GENI_UART_CONS_PORTS);
@@ -474,6 +475,13 @@ static void qcom_geni_serial_console_write(struct console *co, const char *s,
* has been sent, in which case we need to look for done first.
*/
qcom_geni_serial_poll_tx_done(uport);
+
+ if (uart_circ_chars_pending(&uport->state->xmit)) {
+ irq_en = readl_relaxed(uport->membase +
+ SE_GENI_M_IRQ_EN);
+ writel_relaxed(irq_en | M_TX_FIFO_WATERMARK_EN,
+ uport->membase + SE_GENI_M_IRQ_EN);
+ }
}
__qcom_geni_serial_console_write(uport, s, count);