summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/greybus/uart.c3
-rw-r--r--drivers/tty/tty_io.c18
-rw-r--r--drivers/usb/class/cdc-acm.c2
-rw-r--r--drivers/usb/serial/usb-serial.c3
-rw-r--r--include/linux/tty_driver.h6
5 files changed, 21 insertions, 11 deletions
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index 24b4dab06..172cf900e 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -948,7 +948,8 @@ static int gb_tty_init(void)
int retval = 0;
gb_tty_driver = tty_alloc_driver(GB_NUM_MINORS, TTY_DRIVER_REAL_RAW |
- TTY_DRIVER_DYNAMIC_DEV);
+ TTY_DRIVER_DYNAMIC_DEV |
+ TTY_DRIVER_RESET_SAVED_TERMIOS);
if (IS_ERR(gb_tty_driver)) {
pr_err("Can not allocate tty driver\n");
retval = PTR_ERR(gb_tty_driver);
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 1c30faae9..1a6c8a1bc 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3256,14 +3256,16 @@ struct device *tty_register_device_attr(struct tty_driver *driver,
goto err_put;
if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) {
- /*
- * Free any saved termios data so that the termios state is
- * reset when reusing a minor number.
- */
- tp = driver->termios[index];
- if (tp) {
- driver->termios[index] = NULL;
- kfree(tp);
+ if (driver->flags & TTY_DRIVER_RESET_SAVED_TERMIOS) {
+ /*
+ * Free any saved termios data so that the termios
+ * state is reset when reusing a minor number.
+ */
+ tp = driver->termios[index];
+ if (tp) {
+ driver->termios[index] = NULL;
+ kfree(tp);
+ }
}
retval = tty_cdev_add(driver, devt, index, 1);
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 7bc5329fa..eeb401c0e 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -2140,7 +2140,7 @@ static int __init acm_init(void)
{
int retval;
acm_tty_driver = tty_alloc_driver(ACM_TTY_MINORS, TTY_DRIVER_REAL_RAW |
- TTY_DRIVER_DYNAMIC_DEV);
+ TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_RESET_SAVED_TERMIOS);
if (IS_ERR(acm_tty_driver))
return PTR_ERR(acm_tty_driver);
acm_tty_driver->driver_name = "acm",
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 17edc057a..06e246426 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1313,7 +1313,8 @@ static int __init usb_serial_init(void)
int result;
usb_serial_tty_driver = tty_alloc_driver(USB_SERIAL_TTY_MINORS,
- TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV);
+ TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV |
+ TTY_DRIVER_RESET_SAVED_TERMIOS);
if (IS_ERR(usb_serial_tty_driver))
return PTR_ERR(usb_serial_tty_driver);
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index 1f2896e56..62e459c5d 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -73,6 +73,11 @@ struct serial_struct;
* @TTY_DRIVER_NO_WORKQUEUE:
* Do not create workqueue when tty_register_driver(). Whenever set, flip
* buffer workqueue can be set by tty_port_link_wq() for every port.
+ *
+ * @TTY_DRIVER_RESET_SAVED_TERMIOS
+ * Reset any saved termios settings on device registration when reusing a
+ * minor number. Must only be set by drivers that guarantee that the minor
+ * number is no longer in use.
*/
enum tty_driver_flag {
TTY_DRIVER_INSTALLED = BIT(0),
@@ -84,6 +89,7 @@ enum tty_driver_flag {
TTY_DRIVER_DYNAMIC_ALLOC = BIT(6),
TTY_DRIVER_UNNUMBERED_NODE = BIT(7),
TTY_DRIVER_NO_WORKQUEUE = BIT(8),
+ TTY_DRIVER_RESET_SAVED_TERMIOS = BIT(9),
};
enum tty_driver_type {