]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
tty: introduce and use tty_port_tty_vhangup() helper
authorJiri Slaby (SUSE) <jirislaby@kernel.org>
Tue, 30 Dec 2025 18:32:36 +0000 (13:32 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 8 Jan 2026 09:14:56 +0000 (10:14 +0100)
[ Upstream commit 2b5eac0f8c6e79bc152c8804f9f88d16717013ab ]

This code (tty_get -> vhangup -> tty_put) is repeated on few places.
Introduce a helper similar to tty_port_tty_hangup() (asynchronous) to
handle even vhangup (synchronous).

And use it on those places.

In fact, reuse the tty_port_tty_hangup()'s code and call tty_vhangup()
depending on a new bool parameter.

Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
Cc: Karsten Keil <isdn@linux-pingi.de>
Cc: David Lin <dtwlin@gmail.com>
Cc: Johan Hovold <johan@kernel.org>
Cc: Alex Elder <elder@kernel.org>
Cc: Oliver Neukum <oneukum@suse.com>
Cc: Marcel Holtmann <marcel@holtmann.org>
Cc: Johan Hedberg <johan.hedberg@gmail.com>
Cc: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20250611100319.186924-2-jirislaby@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: 74098cc06e75 ("xhci: dbgtty: fix device unregister: fixup")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/isdn/capi/capi.c
drivers/staging/greybus/uart.c
drivers/tty/serial/serial_core.c
drivers/tty/tty_port.c
drivers/usb/class/cdc-acm.c
drivers/usb/serial/usb-serial.c
include/linux/tty_port.h
net/bluetooth/rfcomm/tty.c

index 70dee9ad4bae273c71eb16a8cc2b082b22e20300..78e6e7748fb937163642087bd1798e36781deeca 100644 (file)
@@ -306,15 +306,9 @@ static void capincci_alloc_minor(struct capidev *cdev, struct capincci *np)
 static void capincci_free_minor(struct capincci *np)
 {
        struct capiminor *mp = np->minorp;
-       struct tty_struct *tty;
 
        if (mp) {
-               tty = tty_port_tty_get(&mp->port);
-               if (tty) {
-                       tty_vhangup(tty);
-                       tty_kref_put(tty);
-               }
-
+               tty_port_tty_vhangup(&mp->port);
                capiminor_free(mp);
        }
 }
index cdf4ebb93b104e85296fa770a2d9692114b3d022..413a4f296d899ceba0f8f95a5865c271f5caf438 100644 (file)
@@ -914,7 +914,6 @@ static void gb_uart_remove(struct gbphy_device *gbphy_dev)
 {
        struct gb_tty *gb_tty = gb_gbphy_get_data(gbphy_dev);
        struct gb_connection *connection = gb_tty->connection;
-       struct tty_struct *tty;
        int ret;
 
        ret = gbphy_runtime_get_sync(gbphy_dev);
@@ -927,11 +926,7 @@ static void gb_uart_remove(struct gbphy_device *gbphy_dev)
        wake_up_all(&gb_tty->wioctl);
        mutex_unlock(&gb_tty->mutex);
 
-       tty = tty_port_tty_get(&gb_tty->port);
-       if (tty) {
-               tty_vhangup(tty);
-               tty_kref_put(tty);
-       }
+       tty_port_tty_vhangup(&gb_tty->port);
 
        gb_connection_disable_rx(connection);
        tty_unregister_device(gb_tty_driver, gb_tty->minor);
index 440303566b14a03f22bf7f93cfc912dc0f16bde8..75272749b39746f971ba9b6b39f61bf8560c8ffa 100644 (file)
@@ -3238,7 +3238,6 @@ static void serial_core_remove_one_port(struct uart_driver *drv,
        struct uart_state *state = drv->state + uport->line;
        struct tty_port *port = &state->port;
        struct uart_port *uart_port;
-       struct tty_struct *tty;
 
        mutex_lock(&port->mutex);
        uart_port = uart_port_check(state);
@@ -3257,11 +3256,7 @@ static void serial_core_remove_one_port(struct uart_driver *drv,
         */
        tty_port_unregister_device(port, drv->tty_driver, uport->line);
 
-       tty = tty_port_tty_get(port);
-       if (tty) {
-               tty_vhangup(port->tty);
-               tty_kref_put(tty);
-       }
+       tty_port_tty_vhangup(port);
 
        /*
         * If the port is used as a console, unregister it
index 14cca33d226930f56ecbcce0d8ad8e90df8eee4f..e6cbccbf54f2e39833047168649830ebf47b6e2f 100644 (file)
@@ -416,15 +416,19 @@ EXPORT_SYMBOL(tty_port_hangup);
  * @port: tty port
  * @check_clocal: hang only ttys with %CLOCAL unset?
  */
-void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)
+void __tty_port_tty_hangup(struct tty_port *port, bool check_clocal, bool async)
 {
        struct tty_struct *tty = tty_port_tty_get(port);
 
-       if (tty && (!check_clocal || !C_CLOCAL(tty)))
-               tty_hangup(tty);
+       if (tty && (!check_clocal || !C_CLOCAL(tty))) {
+               if (async)
+                       tty_hangup(tty);
+               else
+                       tty_vhangup(tty);
+       }
        tty_kref_put(tty);
 }
-EXPORT_SYMBOL_GPL(tty_port_tty_hangup);
+EXPORT_SYMBOL_GPL(__tty_port_tty_hangup);
 
 /**
  * tty_port_tty_wakeup - helper to wake up a tty
index 5a334e370f4d66b4d896dc3fc0524284b3467c2b..73f9476774ae6ad4113cf70a5956c7860492fc20 100644 (file)
@@ -1572,7 +1572,6 @@ err_put_port:
 static void acm_disconnect(struct usb_interface *intf)
 {
        struct acm *acm = usb_get_intfdata(intf);
-       struct tty_struct *tty;
        int i;
 
        /* sibling interface is already cleaning up */
@@ -1599,11 +1598,7 @@ static void acm_disconnect(struct usb_interface *intf)
        usb_set_intfdata(acm->data, NULL);
        mutex_unlock(&acm->mutex);
 
-       tty = tty_port_tty_get(&acm->port);
-       if (tty) {
-               tty_vhangup(tty);
-               tty_kref_put(tty);
-       }
+       tty_port_tty_vhangup(&acm->port);
 
        cancel_delayed_work_sync(&acm->dwork);
 
index df6a2ae0bf4246fd93b7becb328ece50e80c181a..2ee0b64b8be0a7b05003e9ce8a45ed1b83d1ad72 100644 (file)
@@ -1178,7 +1178,6 @@ static void usb_serial_disconnect(struct usb_interface *interface)
        struct usb_serial *serial = usb_get_intfdata(interface);
        struct device *dev = &interface->dev;
        struct usb_serial_port *port;
-       struct tty_struct *tty;
 
        /* sibling interface is cleaning up */
        if (!serial)
@@ -1193,11 +1192,7 @@ static void usb_serial_disconnect(struct usb_interface *interface)
 
        for (i = 0; i < serial->num_ports; ++i) {
                port = serial->port[i];
-               tty = tty_port_tty_get(&port->port);
-               if (tty) {
-                       tty_vhangup(tty);
-                       tty_kref_put(tty);
-               }
+               tty_port_tty_vhangup(&port->port);
                usb_serial_port_poison_urbs(port);
                wake_up_interruptible(&port->port.delta_msr_wait);
                cancel_work_sync(&port->work);
index 1b861f2100b69f120971c7dd503d6635db1fb468..67ed956767bd49054e18b1b8d2e4873f39ea0223 100644 (file)
@@ -235,7 +235,7 @@ bool tty_port_carrier_raised(struct tty_port *port);
 void tty_port_raise_dtr_rts(struct tty_port *port);
 void tty_port_lower_dtr_rts(struct tty_port *port);
 void tty_port_hangup(struct tty_port *port);
-void tty_port_tty_hangup(struct tty_port *port, bool check_clocal);
+void __tty_port_tty_hangup(struct tty_port *port, bool check_clocal, bool async);
 void tty_port_tty_wakeup(struct tty_port *port);
 int tty_port_block_til_ready(struct tty_port *port, struct tty_struct *tty,
                struct file *filp);
@@ -254,4 +254,14 @@ static inline int tty_port_users(struct tty_port *port)
        return port->count + port->blocked_open;
 }
 
+static inline void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)
+{
+       __tty_port_tty_hangup(port, check_clocal, true);
+}
+
+static inline void tty_port_tty_vhangup(struct tty_port *port)
+{
+       __tty_port_tty_hangup(port, false, false);
+}
+
 #endif
index d60996352722fd4b78b706b00ea84baf22c46ef2..e1ab395277f3d878aab70e9dcbeba3fa6d0798e4 100644 (file)
@@ -438,7 +438,6 @@ static int __rfcomm_release_dev(void __user *arg)
 {
        struct rfcomm_dev_req req;
        struct rfcomm_dev *dev;
-       struct tty_struct *tty;
 
        if (copy_from_user(&req, arg, sizeof(req)))
                return -EFAULT;
@@ -464,11 +463,7 @@ static int __rfcomm_release_dev(void __user *arg)
                rfcomm_dlc_close(dev->dlc, 0);
 
        /* Shut down TTY synchronously before freeing rfcomm_dev */
-       tty = tty_port_tty_get(&dev->port);
-       if (tty) {
-               tty_vhangup(tty);
-               tty_kref_put(tty);
-       }
+       tty_port_tty_vhangup(&dev->port);
 
        if (!test_bit(RFCOMM_TTY_OWNED, &dev->status))
                tty_port_put(&dev->port);