serial: 8250: allow low-level drivers to override break control

Some UARTs require driver-specific handling for break signaling, which
cannot be expressed by the generic 8250 break implementation alone.

Add an optional uart_port break_ctl callback and route
serial8250_break_ctl() through it when provided. Rename the existing
8250 implementation to serial8250_do_break_ctl() and export it so
low-level drivers can reuse the default 8250 behavior when appropriate.

Signed-off-by: Crescent Hsieh <crescentcy.hsieh@moxa.com>
Link: https://patch.msgid.link/20260731074820.735619-11-crescentcy.hsieh@moxa.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Crescent Hsieh 2026-07-31 15:48:16 +08:00 committed by Greg Kroah-Hartman
parent d21a1509c6
commit af1ba61b62
4 changed files with 14 additions and 1 deletions

View File

@ -849,6 +849,8 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
uart->port.startup = up->port.startup;
if (up->port.shutdown)
uart->port.shutdown = up->port.shutdown;
if (up->port.break_ctl)
uart->port.break_ctl = up->port.break_ctl;
if (up->port.pm)
uart->port.pm = up->port.pm;
if (up->port.handle_break)

View File

@ -1972,7 +1972,7 @@ static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
serial8250_do_set_mctrl(port, mctrl);
}
static void serial8250_break_ctl(struct uart_port *port, int break_state)
void serial8250_do_break_ctl(struct uart_port *port, int break_state)
{
struct uart_8250_port *up = up_to_u8250p(port);
@ -1985,6 +1985,15 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state)
up->lcr &= ~UART_LCR_SBC;
serial_port_out(port, UART_LCR, up->lcr);
}
EXPORT_SYMBOL_GPL(serial8250_do_break_ctl);
static void serial8250_break_ctl(struct uart_port *port, int break_state)
{
if (port->break_ctl)
port->break_ctl(port, break_state);
else
serial8250_do_break_ctl(port, break_state);
}
/* Returns true if @bits were set, false on timeout */
static bool wait_for_lsr(struct uart_8250_port *up, int bits)

View File

@ -204,6 +204,7 @@ void serial8250_do_shutdown(struct uart_port *port);
void serial8250_do_pm(struct uart_port *port, unsigned int state,
unsigned int oldstate);
void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl);
void serial8250_do_break_ctl(struct uart_port *port, int break_state);
void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud,
unsigned int quot);
int fsl8250_handle_irq(struct uart_port *port);

View File

@ -464,6 +464,7 @@ struct uart_port {
void (*shutdown)(struct uart_port *port);
void (*throttle)(struct uart_port *port);
void (*unthrottle)(struct uart_port *port);
void (*break_ctl)(struct uart_port *port, int break_state);
int (*handle_irq)(struct uart_port *);
void (*pm)(struct uart_port *, unsigned int state,
unsigned int old);