[PATCH v1 18/31] serial: 8250: allow low-level driver to override break_ctl()

Crescent Hsieh posted 31 patches 1 day, 11 hours ago
[PATCH v1 18/31] serial: 8250: allow low-level driver to override break_ctl()
Posted by Crescent Hsieh 1 day, 11 hours ago
Moxa PCIe serial boards requires custom break signal transmission under
RS485 mdoe. However, the current 8250 driver does not provide a way for
low-level driver to override this behavior.

This patch introduces a break_ctl() function pointer in struct
uart_port, allowing low-level drivers to customize the break signal
transmission logic. If no custom implementation is provided, the default
serial8250_do_break_ctl() function is used. This ensures that
hardware-specific break signaling can be implemented without affecting
standard behavior.

Signed-off-by: Crescent Hsieh <crescentcy.hsieh@moxa.com>
---
 drivers/tty/serial/8250/8250_core.c |  2 ++
 drivers/tty/serial/8250/8250_port.c | 11 ++++++++++-
 include/linux/serial_8250.h         |  1 +
 include/linux/serial_core.h         |  1 +
 4 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 68baf75bdadc..f642e8c77911 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -802,6 +802,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)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 38825bb80749..64896f37b75d 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -2079,7 +2079,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);
 	unsigned long flags;
@@ -2094,6 +2094,15 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state)
 	uart_port_unlock_irqrestore(port, flags);
 	serial8250_rpm_put(up);
 }
+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);
+}
 
 static void wait_for_lsr(struct uart_8250_port *up, int bits)
 {
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index e0717c8393d7..88996a3194de 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -192,6 +192,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);
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 743b4afaad4c..1aa07c5187d8 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -451,6 +451,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);
-- 
2.45.2
Re: [PATCH v1 18/31] serial: 8250: allow low-level driver to override break_ctl()
Posted by Andy Shevchenko 20 hours ago
On Sun, Nov 30, 2025 at 12:45 PM Crescent Hsieh
<crescentcy.hsieh@moxa.com> wrote:
>
> Moxa PCIe serial boards requires custom break signal transmission under
> RS485 mdoe. However, the current 8250 driver does not provide a way for

mode

> low-level driver to override this behavior.
>
> This patch introduces a break_ctl() function pointer in struct
> uart_port, allowing low-level drivers to customize the break signal
> transmission logic. If no custom implementation is provided, the default
> serial8250_do_break_ctl() function is used. This ensures that
> hardware-specific break signaling can be implemented without affecting
> standard behavior.

...

> +EXPORT_SYMBOL_GPL(serial8250_do_break_ctl);

There is another (scoped) export used in this driver, use it for this
function as well.

-- 
With Best Regards,
Andy Shevchenko