diff options
-rw-r--r-- | drivers/char/tty_io.c | 15 | ||||
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 14 | ||||
-rw-r--r-- | include/linux/tty_driver.h | 13 |
3 files changed, 27 insertions, 15 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index ea18a129b0b5..59499ee0fe6a 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -1389,7 +1389,7 @@ EXPORT_SYMBOL(tty_shutdown); | |||
1389 | * of ttys that the driver keeps. | 1389 | * of ttys that the driver keeps. |
1390 | * | 1390 | * |
1391 | * This method gets called from a work queue so that the driver private | 1391 | * This method gets called from a work queue so that the driver private |
1392 | * shutdown ops can sleep (needed for USB at least) | 1392 | * cleanup ops can sleep (needed for USB at least) |
1393 | */ | 1393 | */ |
1394 | static void release_one_tty(struct work_struct *work) | 1394 | static void release_one_tty(struct work_struct *work) |
1395 | { | 1395 | { |
@@ -1397,10 +1397,9 @@ static void release_one_tty(struct work_struct *work) | |||
1397 | container_of(work, struct tty_struct, hangup_work); | 1397 | container_of(work, struct tty_struct, hangup_work); |
1398 | struct tty_driver *driver = tty->driver; | 1398 | struct tty_driver *driver = tty->driver; |
1399 | 1399 | ||
1400 | if (tty->ops->shutdown) | 1400 | if (tty->ops->cleanup) |
1401 | tty->ops->shutdown(tty); | 1401 | tty->ops->cleanup(tty); |
1402 | else | 1402 | |
1403 | tty_shutdown(tty); | ||
1404 | tty->magic = 0; | 1403 | tty->magic = 0; |
1405 | tty_driver_kref_put(driver); | 1404 | tty_driver_kref_put(driver); |
1406 | module_put(driver->owner); | 1405 | module_put(driver->owner); |
@@ -1415,6 +1414,12 @@ static void release_one_tty(struct work_struct *work) | |||
1415 | static void queue_release_one_tty(struct kref *kref) | 1414 | static void queue_release_one_tty(struct kref *kref) |
1416 | { | 1415 | { |
1417 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); | 1416 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); |
1417 | |||
1418 | if (tty->ops->shutdown) | ||
1419 | tty->ops->shutdown(tty); | ||
1420 | else | ||
1421 | tty_shutdown(tty); | ||
1422 | |||
1418 | /* The hangup queue is now free so we can reuse it rather than | 1423 | /* The hangup queue is now free so we can reuse it rather than |
1419 | waste a chunk of memory for each port */ | 1424 | waste a chunk of memory for each port */ |
1420 | INIT_WORK(&tty->hangup_work, release_one_tty); | 1425 | INIT_WORK(&tty->hangup_work, release_one_tty); |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index ff75a3589e7e..aa6b2ae951ae 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -192,7 +192,7 @@ void usb_serial_put(struct usb_serial *serial) | |||
192 | * This is the first place a new tty gets used. Hence this is where we | 192 | * This is the first place a new tty gets used. Hence this is where we |
193 | * acquire references to the usb_serial structure and the driver module, | 193 | * acquire references to the usb_serial structure and the driver module, |
194 | * where we store a pointer to the port, and where we do an autoresume. | 194 | * where we store a pointer to the port, and where we do an autoresume. |
195 | * All these actions are reversed in serial_release(). | 195 | * All these actions are reversed in serial_cleanup(). |
196 | */ | 196 | */ |
197 | static int serial_install(struct tty_driver *driver, struct tty_struct *tty) | 197 | static int serial_install(struct tty_driver *driver, struct tty_struct *tty) |
198 | { | 198 | { |
@@ -339,15 +339,16 @@ static void serial_close(struct tty_struct *tty, struct file *filp) | |||
339 | } | 339 | } |
340 | 340 | ||
341 | /** | 341 | /** |
342 | * serial_release - free resources post close/hangup | 342 | * serial_cleanup - free resources post close/hangup |
343 | * @port: port to free up | 343 | * @port: port to free up |
344 | * | 344 | * |
345 | * Do the resource freeing and refcount dropping for the port. | 345 | * Do the resource freeing and refcount dropping for the port. |
346 | * Avoid freeing the console. | 346 | * Avoid freeing the console. |
347 | * | 347 | * |
348 | * Called when the last tty kref is dropped. | 348 | * Called asynchronously after the last tty kref is dropped, |
349 | * and the tty layer has already done the tty_shutdown(tty); | ||
349 | */ | 350 | */ |
350 | static void serial_release(struct tty_struct *tty) | 351 | static void serial_cleanup(struct tty_struct *tty) |
351 | { | 352 | { |
352 | struct usb_serial_port *port = tty->driver_data; | 353 | struct usb_serial_port *port = tty->driver_data; |
353 | struct usb_serial *serial; | 354 | struct usb_serial *serial; |
@@ -361,9 +362,6 @@ static void serial_release(struct tty_struct *tty) | |||
361 | 362 | ||
362 | dbg("%s - port %d", __func__, port->number); | 363 | dbg("%s - port %d", __func__, port->number); |
363 | 364 | ||
364 | /* Standard shutdown processing */ | ||
365 | tty_shutdown(tty); | ||
366 | |||
367 | tty->driver_data = NULL; | 365 | tty->driver_data = NULL; |
368 | 366 | ||
369 | serial = port->serial; | 367 | serial = port->serial; |
@@ -1210,7 +1208,7 @@ static const struct tty_operations serial_ops = { | |||
1210 | .chars_in_buffer = serial_chars_in_buffer, | 1208 | .chars_in_buffer = serial_chars_in_buffer, |
1211 | .tiocmget = serial_tiocmget, | 1209 | .tiocmget = serial_tiocmget, |
1212 | .tiocmset = serial_tiocmset, | 1210 | .tiocmset = serial_tiocmset, |
1213 | .shutdown = serial_release, | 1211 | .cleanup = serial_cleanup, |
1214 | .install = serial_install, | 1212 | .install = serial_install, |
1215 | .proc_fops = &serial_proc_fops, | 1213 | .proc_fops = &serial_proc_fops, |
1216 | }; | 1214 | }; |
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 3566129384a4..b08677982525 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h | |||
@@ -45,8 +45,16 @@ | |||
45 | * | 45 | * |
46 | * void (*shutdown)(struct tty_struct * tty); | 46 | * void (*shutdown)(struct tty_struct * tty); |
47 | * | 47 | * |
48 | * This routine is called when a particular tty device is closed for | 48 | * This routine is called synchronously when a particular tty device |
49 | * the last time freeing up the resources. | 49 | * is closed for the last time freeing up the resources. |
50 | * | ||
51 | * | ||
52 | * void (*cleanup)(struct tty_struct * tty); | ||
53 | * | ||
54 | * This routine is called asynchronously when a particular tty device | ||
55 | * is closed for the last time freeing up the resources. This is | ||
56 | * actually the second part of shutdown for routines that might sleep. | ||
57 | * | ||
50 | * | 58 | * |
51 | * int (*write)(struct tty_struct * tty, | 59 | * int (*write)(struct tty_struct * tty, |
52 | * const unsigned char *buf, int count); | 60 | * const unsigned char *buf, int count); |
@@ -233,6 +241,7 @@ struct tty_operations { | |||
233 | int (*open)(struct tty_struct * tty, struct file * filp); | 241 | int (*open)(struct tty_struct * tty, struct file * filp); |
234 | void (*close)(struct tty_struct * tty, struct file * filp); | 242 | void (*close)(struct tty_struct * tty, struct file * filp); |
235 | void (*shutdown)(struct tty_struct *tty); | 243 | void (*shutdown)(struct tty_struct *tty); |
244 | void (*cleanup)(struct tty_struct *tty); | ||
236 | int (*write)(struct tty_struct * tty, | 245 | int (*write)(struct tty_struct * tty, |
237 | const unsigned char *buf, int count); | 246 | const unsigned char *buf, int count); |
238 | int (*put_char)(struct tty_struct *tty, unsigned char ch); | 247 | int (*put_char)(struct tty_struct *tty, unsigned char ch); |