diff options
author | Soren Brinkmann <soren.brinkmann@xilinx.com> | 2016-01-12 04:41:39 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-02-07 09:52:23 +0300 |
commit | 74ea66d4ca061a3cd4c0e924e51b60e924644852 (patch) | |
tree | fc18a04bb41bafecbc85cecfbb50cb43a751a79a /drivers/tty/serial/xilinx_uartps.c | |
parent | 354fb1a7d7e54a79d042f0a92dbd484bd3e900e6 (diff) | |
download | linux-74ea66d4ca061a3cd4c0e924e51b60e924644852.tar.xz |
tty: xuartps: Improve sysrq handling
Handling magic sysrq included dropping a lock to avoid a deadlock that
happened when cdns_uart_console_write tried to acquire a lock in the
from the sysrq code path. By making the acquisition of the lock in
cdns_uart_console_write depending on port->sysrq, cdns_uart_handle_rx can be
simplified to simply call uart_handle_sysrq.
Suggested-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/xilinx_uartps.c')
-rw-r--r-- | drivers/tty/serial/xilinx_uartps.c | 20 |
1 files changed, 5 insertions, 15 deletions
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 8014dd3c6d55..0eecba88298f 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -220,20 +220,8 @@ static void cdns_uart_handle_rx(struct uart_port *port, unsigned int isrstatus) continue; } -#ifdef SUPPORT_SYSRQ - /* - * uart_handle_sysrq_char() doesn't work if - * spinlocked, for some reason - */ - if (port->sysrq) { - spin_unlock(&port->lock); - if (uart_handle_sysrq_char(port, data)) { - spin_lock(&port->lock); - continue; - } - spin_lock(&port->lock); - } -#endif + if (uart_handle_sysrq_char(port, data)) + continue; port->icount.rx++; @@ -1128,7 +1116,9 @@ static void cdns_uart_console_write(struct console *co, const char *s, unsigned int imr, ctrl; int locked = 1; - if (oops_in_progress) + if (port->sysrq) + locked = 0; + else if (oops_in_progress) locked = spin_trylock_irqsave(&port->lock, flags); else spin_lock_irqsave(&port->lock, flags); |