Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial: stm32: defer sysrq processing

Use the uart_unlock_and_check_sysrq() helper to defer sysrq processing
until receive processing is done and the port lock has been released.

This allows cleaning up the console_write() implementation by not having
to work around the recursive sysrq case (by dropping locking completely)
and also makes the console code work with PREEMPT_RT by no longer
relying on local_irq_save().

Reviewed-by: Valentin Caron<valentin.caron@foss.st.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://lore.kernel.org/r/20210416140557.25177-4-johan@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Johan Hovold and committed by
Greg Kroah-Hartman
cea37afd e359b441

+6 -10
+6 -10
drivers/tty/serial/stm32-usart.c
··· 270 270 } 271 271 } 272 272 273 - if (uart_handle_sysrq_char(port, c)) 273 + if (uart_prepare_sysrq_char(port, c)) 274 274 continue; 275 275 uart_insert_char(port, sr, USART_SR_ORE, c, flag); 276 276 } 277 277 278 - spin_unlock(&port->lock); 278 + uart_unlock_and_check_sysrq(port); 279 279 280 280 tty_flip_buffer_push(tport); 281 281 } ··· 1430 1430 u32 old_cr1, new_cr1; 1431 1431 int locked = 1; 1432 1432 1433 - local_irq_save(flags); 1434 - if (port->sysrq) 1435 - locked = 0; 1436 - else if (oops_in_progress) 1437 - locked = spin_trylock(&port->lock); 1433 + if (oops_in_progress) 1434 + locked = spin_trylock_irqsave(&port->lock, flags); 1438 1435 else 1439 - spin_lock(&port->lock); 1436 + spin_lock_irqsave(&port->lock, flags); 1440 1437 1441 1438 /* Save and disable interrupts, enable the transmitter */ 1442 1439 old_cr1 = readl_relaxed(port->membase + ofs->cr1); ··· 1447 1450 writel_relaxed(old_cr1, port->membase + ofs->cr1); 1448 1451 1449 1452 if (locked) 1450 - spin_unlock(&port->lock); 1451 - local_irq_restore(flags); 1453 + spin_unlock_irqrestore(&port->lock, flags); 1452 1454 } 1453 1455 1454 1456 static int stm32_usart_console_setup(struct console *co, char *options)