aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_port.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/tty_port.c')
-rw-r--r--drivers/tty/tty_port.c94
1 files changed, 88 insertions, 6 deletions
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index bf6e238146ae..d7bdd8d0c23f 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -33,6 +33,70 @@ void tty_port_init(struct tty_port *port)
33} 33}
34EXPORT_SYMBOL(tty_port_init); 34EXPORT_SYMBOL(tty_port_init);
35 35
36/**
37 * tty_port_link_device - link tty and tty_port
38 * @port: tty_port of the device
39 * @driver: tty_driver for this device
40 * @index: index of the tty
41 *
42 * Provide the tty layer wit ha link from a tty (specified by @index) to a
43 * tty_port (@port). Use this only if neither tty_port_register_device nor
44 * tty_port_install is used in the driver. If used, this has to be called before
45 * tty_register_driver.
46 */
47void tty_port_link_device(struct tty_port *port,
48 struct tty_driver *driver, unsigned index)
49{
50 if (WARN_ON(index >= driver->num))
51 return;
52 driver->ports[index] = port;
53}
54EXPORT_SYMBOL_GPL(tty_port_link_device);
55
56/**
57 * tty_port_register_device - register tty device
58 * @port: tty_port of the device
59 * @driver: tty_driver for this device
60 * @index: index of the tty
61 * @device: parent if exists, otherwise NULL
62 *
63 * It is the same as tty_register_device except the provided @port is linked to
64 * a concrete tty specified by @index. Use this or tty_port_install (or both).
65 * Call tty_port_link_device as a last resort.
66 */
67struct device *tty_port_register_device(struct tty_port *port,
68 struct tty_driver *driver, unsigned index,
69 struct device *device)
70{
71 tty_port_link_device(port, driver, index);
72 return tty_register_device(driver, index, device);
73}
74EXPORT_SYMBOL_GPL(tty_port_register_device);
75
76/**
77 * tty_port_register_device_attr - register tty device
78 * @port: tty_port of the device
79 * @driver: tty_driver for this device
80 * @index: index of the tty
81 * @device: parent if exists, otherwise NULL
82 * @drvdata: Driver data to be set to device.
83 * @attr_grp: Attribute group to be set on device.
84 *
85 * It is the same as tty_register_device_attr except the provided @port is
86 * linked to a concrete tty specified by @index. Use this or tty_port_install
87 * (or both). Call tty_port_link_device as a last resort.
88 */
89struct device *tty_port_register_device_attr(struct tty_port *port,
90 struct tty_driver *driver, unsigned index,
91 struct device *device, void *drvdata,
92 const struct attribute_group **attr_grp)
93{
94 tty_port_link_device(port, driver, index);
95 return tty_register_device_attr(driver, index, device, drvdata,
96 attr_grp);
97}
98EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
99
36int tty_port_alloc_xmit_buf(struct tty_port *port) 100int tty_port_alloc_xmit_buf(struct tty_port *port)
37{ 101{
38 /* We may sleep in get_zeroed_page() */ 102 /* We may sleep in get_zeroed_page() */
@@ -230,7 +294,7 @@ int tty_port_block_til_ready(struct tty_port *port,
230 294
231 /* block if port is in the process of being closed */ 295 /* block if port is in the process of being closed */
232 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { 296 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
233 wait_event_interruptible_tty(port->close_wait, 297 wait_event_interruptible_tty(tty, port->close_wait,
234 !(port->flags & ASYNC_CLOSING)); 298 !(port->flags & ASYNC_CLOSING));
235 if (port->flags & ASYNC_HUP_NOTIFY) 299 if (port->flags & ASYNC_HUP_NOTIFY)
236 return -EAGAIN; 300 return -EAGAIN;
@@ -246,7 +310,7 @@ int tty_port_block_til_ready(struct tty_port *port,
246 } 310 }
247 if (filp->f_flags & O_NONBLOCK) { 311 if (filp->f_flags & O_NONBLOCK) {
248 /* Indicate we are open */ 312 /* Indicate we are open */
249 if (tty->termios->c_cflag & CBAUD) 313 if (tty->termios.c_cflag & CBAUD)
250 tty_port_raise_dtr_rts(port); 314 tty_port_raise_dtr_rts(port);
251 port->flags |= ASYNC_NORMAL_ACTIVE; 315 port->flags |= ASYNC_NORMAL_ACTIVE;
252 return 0; 316 return 0;
@@ -270,7 +334,7 @@ int tty_port_block_til_ready(struct tty_port *port,
270 334
271 while (1) { 335 while (1) {
272 /* Indicate we are open */ 336 /* Indicate we are open */
273 if (tty->termios->c_cflag & CBAUD) 337 if (tty->termios.c_cflag & CBAUD)
274 tty_port_raise_dtr_rts(port); 338 tty_port_raise_dtr_rts(port);
275 339
276 prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); 340 prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
@@ -296,9 +360,9 @@ int tty_port_block_til_ready(struct tty_port *port,
296 retval = -ERESTARTSYS; 360 retval = -ERESTARTSYS;
297 break; 361 break;
298 } 362 }
299 tty_unlock(); 363 tty_unlock(tty);
300 schedule(); 364 schedule();
301 tty_lock(); 365 tty_lock(tty);
302 } 366 }
303 finish_wait(&port->open_wait, &wait); 367 finish_wait(&port->open_wait, &wait);
304 368
@@ -369,7 +433,7 @@ int tty_port_close_start(struct tty_port *port,
369 433
370 /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to 434 /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to
371 hang up the line */ 435 hang up the line */
372 if (tty->termios->c_cflag & HUPCL) 436 if (tty->termios.c_cflag & HUPCL)
373 tty_port_lower_dtr_rts(port); 437 tty_port_lower_dtr_rts(port);
374 438
375 /* Don't call port->drop for the last reference. Callers will want 439 /* Don't call port->drop for the last reference. Callers will want
@@ -413,6 +477,24 @@ void tty_port_close(struct tty_port *port, struct tty_struct *tty,
413} 477}
414EXPORT_SYMBOL(tty_port_close); 478EXPORT_SYMBOL(tty_port_close);
415 479
480/**
481 * tty_port_install - generic tty->ops->install handler
482 * @port: tty_port of the device
483 * @driver: tty_driver for this device
484 * @tty: tty to be installed
485 *
486 * It is the same as tty_standard_install except the provided @port is linked
487 * to a concrete tty specified by @tty. Use this or tty_port_register_device
488 * (or both). Call tty_port_link_device as a last resort.
489 */
490int tty_port_install(struct tty_port *port, struct tty_driver *driver,
491 struct tty_struct *tty)
492{
493 tty->port = port;
494 return tty_standard_install(driver, tty);
495}
496EXPORT_SYMBOL_GPL(tty_port_install);
497
416int tty_port_open(struct tty_port *port, struct tty_struct *tty, 498int tty_port_open(struct tty_port *port, struct tty_struct *tty,
417 struct file *filp) 499 struct file *filp)
418{ 500{