[PATCH 3/6] USB: serial: add stop and start callbacks

From: Crescent Hsieh

Date: Fri Oct 16 2026 - 06:10:01 EST


The tty layer uses the stop and start operations to suspend and resume
output, but the USB serial core does not currently provide them. This
prevents USB serial subdrivers from handling output flow control through
the normal tty path.

Add tty stop and start operations and forward them to optional USB
serial driver callbacks. Drivers which do not provide the callbacks
retain the existing behaviour.

Signed-off-by: Crescent Hsieh <crescentcy.hsieh@xxxxxxxx>
---
drivers/usb/serial/usb-serial.c | 18 ++++++++++++++++++
include/linux/usb/serial.h | 2 ++
2 files changed, 20 insertions(+)

diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 4a19621f08ba..73bb0cb0be6c 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -429,6 +429,22 @@ static void serial_unthrottle(struct tty_struct *tty)
port->serial->type->unthrottle(tty);
}

+static void serial_stop(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+
+ if (port->serial->type->stop)
+ port->serial->type->stop(tty);
+}
+
+static void serial_start(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+
+ if (port->serial->type->start)
+ port->serial->type->start(tty);
+}
+
static int serial_get_serial(struct tty_struct *tty, struct serial_struct *ss)
{
struct usb_serial_port *port = tty->driver_data;
@@ -1351,6 +1367,8 @@ static const struct tty_operations serial_ops = {
.set_termios = serial_set_termios,
.throttle = serial_throttle,
.unthrottle = serial_unthrottle,
+ .stop = serial_stop,
+ .start = serial_start,
.break_ctl = serial_break,
.chars_in_buffer = serial_chars_in_buffer,
.wait_until_sent = serial_wait_until_sent,
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 5866f19d3c7b..633bdde530c5 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -285,6 +285,8 @@ struct usb_serial_driver {
bool (*tx_empty)(struct usb_serial_port *port);
void (*throttle)(struct tty_struct *tty);
void (*unthrottle)(struct tty_struct *tty);
+ void (*stop)(struct tty_struct *tty);
+ void (*start)(struct tty_struct *tty);
int (*tiocmget)(struct tty_struct *tty);
int (*tiocmset)(struct tty_struct *tty,
unsigned int set, unsigned int clear);
--
2.53.0