From d3539347022ad4eeb9dbd29c50bfca17b9d8a146 Mon Sep 17 00:00:00 2001 From: John Ogness Date: Wed, 29 Jul 2026 14:10:33 +0206 Subject: serial: 8250: Switch to nbcon console, take 2 Implement the necessary callbacks to switch the 8250 console driver to perform as an nbcon console. Add implementations for the nbcon console callbacks: ->write_atomic() ->write_thread() ->device_lock() ->device_unlock() and add CON_NBCON to the initial @flags. All hardware access in the callbacks is within unsafe sections. The ->write_atomic() and ->write_thread() callbacks allow safe handover/takeover per byte and add a preceding newline if they take over from another context mid-line. For the ->write_atomic() callback, a new irq_work is used to defer modem control since it may be called from a context that does not allow waking up tasks. During suspend/resume the irq_work is not used as this has been shown to cause suspend problems for some hardware. Upon resume, any pending modem control is performed. Note: A new __serial8250_clear_IER() is introduced for direct clearing of UART_IER during console writing (which will not be holding the port lock for atomic printing or KDB/KGDB). This allows restoring a lockdep check to serial8250_clear_IER() in a follow-up commit. Signed-off-by: John Ogness Link: https://patch.msgid.link/20260729120439.281252-2-john.ogness@linutronix.de Signed-off-by: Greg Kroah-Hartman --- include/linux/serial_8250.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index a95b2d143d24..eba36710bc47 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -150,8 +150,20 @@ struct uart_8250_port { #define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS u16 lsr_saved_flags; u16 lsr_save_mask; + + /* + * Track when a console line has been fully written to the + * hardware, i.e. true when the most recent byte written to + * UART_TX by the console was '\n'. + */ + bool console_line_ended; + + /* Allow queuing irq_work for MSR handling */ + bool console_msr_work_allow; + #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA unsigned char msr_saved_flags; + struct irq_work console_msr_work; struct uart_8250_dma *dma; const struct uart_8250_ops *ops; @@ -203,8 +215,8 @@ void serial8250_tx_chars(struct uart_8250_port *up); unsigned int serial8250_modem_status(struct uart_8250_port *up); void serial8250_init_port(struct uart_8250_port *up); void serial8250_set_defaults(struct uart_8250_port *up); -void serial8250_console_write(struct uart_8250_port *up, const char *s, - unsigned int count); +void serial8250_console_write(struct uart_8250_port *up, + struct nbcon_write_context *wctxt, bool in_atomic); int serial8250_console_setup(struct uart_port *port, char *options, bool probe); int serial8250_console_exit(struct uart_port *port); -- cgit v1.2.3