Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Tty port functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/tty_driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/serdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) static int tty_port_default_receive_buf(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 					const unsigned char *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 					const unsigned char *f, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	struct tty_ldisc *disc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	tty = READ_ONCE(port->itty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	if (!tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	disc = tty_ldisc_ref(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	if (!disc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	ret = tty_ldisc_receive_buf(disc, p, (char *)f, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	tty_ldisc_deref(disc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) static void tty_port_default_wakeup(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	struct tty_struct *tty = tty_port_tty_get(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	if (tty) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		tty_wakeup(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) const struct tty_port_client_operations tty_port_default_client_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	.receive_buf = tty_port_default_receive_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	.write_wakeup = tty_port_default_wakeup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) EXPORT_SYMBOL_GPL(tty_port_default_client_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) void tty_port_init(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	memset(port, 0, sizeof(*port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	tty_buffer_init(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	init_waitqueue_head(&port->open_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	init_waitqueue_head(&port->delta_msr_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	mutex_init(&port->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	mutex_init(&port->buf_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	spin_lock_init(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	port->close_delay = (50 * HZ) / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	port->closing_wait = (3000 * HZ) / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	port->client_ops = &tty_port_default_client_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	kref_init(&port->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) EXPORT_SYMBOL(tty_port_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  * tty_port_link_device - link tty and tty_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  * @port: tty_port of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  * @driver: tty_driver for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * @index: index of the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  * Provide the tty layer with a link from a tty (specified by @index) to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  * tty_port (@port). Use this only if neither tty_port_register_device nor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  * tty_port_install is used in the driver. If used, this has to be called before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  * tty_register_driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) void tty_port_link_device(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		struct tty_driver *driver, unsigned index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	if (WARN_ON(index >= driver->num))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	driver->ports[index] = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) EXPORT_SYMBOL_GPL(tty_port_link_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  * tty_port_register_device - register tty device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  * @port: tty_port of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  * @driver: tty_driver for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * @index: index of the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * @device: parent if exists, otherwise NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  * It is the same as tty_register_device except the provided @port is linked to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  * a concrete tty specified by @index. Use this or tty_port_install (or both).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  * Call tty_port_link_device as a last resort.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct device *tty_port_register_device(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		struct tty_driver *driver, unsigned index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		struct device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	return tty_port_register_device_attr(port, driver, index, device, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) EXPORT_SYMBOL_GPL(tty_port_register_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  * tty_port_register_device_attr - register tty device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  * @port: tty_port of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  * @driver: tty_driver for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  * @index: index of the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * @device: parent if exists, otherwise NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * @drvdata: Driver data to be set to device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * @attr_grp: Attribute group to be set on device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * It is the same as tty_register_device_attr except the provided @port is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * linked to a concrete tty specified by @index. Use this or tty_port_install
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * (or both). Call tty_port_link_device as a last resort.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct device *tty_port_register_device_attr(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		struct tty_driver *driver, unsigned index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		struct device *device, void *drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		const struct attribute_group **attr_grp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	tty_port_link_device(port, driver, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	return tty_register_device_attr(driver, index, device, drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 			attr_grp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * tty_port_register_device_attr_serdev - register tty or serdev device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  * @port: tty_port of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * @driver: tty_driver for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  * @index: index of the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * @device: parent if exists, otherwise NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  * @drvdata: driver data for the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  * @attr_grp: attribute group for the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  * Register a serdev or tty device depending on if the parent device has any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  * defined serdev clients or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct device *tty_port_register_device_attr_serdev(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		struct tty_driver *driver, unsigned index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		struct device *device, void *drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		const struct attribute_group **attr_grp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	tty_port_link_device(port, driver, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	dev = serdev_tty_port_register(port, device, driver, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	if (PTR_ERR(dev) != -ENODEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		/* Skip creating cdev if we registered a serdev device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	return tty_register_device_attr(driver, index, device, drvdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			attr_grp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) EXPORT_SYMBOL_GPL(tty_port_register_device_attr_serdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  * tty_port_register_device_serdev - register tty or serdev device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * @port: tty_port of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  * @driver: tty_driver for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  * @index: index of the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  * @device: parent if exists, otherwise NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  * Register a serdev or tty device depending on if the parent device has any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  * defined serdev clients or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct device *tty_port_register_device_serdev(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		struct tty_driver *driver, unsigned index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		struct device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	return tty_port_register_device_attr_serdev(port, driver, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			device, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) EXPORT_SYMBOL_GPL(tty_port_register_device_serdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  * tty_port_unregister_device - deregister a tty or serdev device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  * @port: tty_port of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  * @driver: tty_driver for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  * @index: index of the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)  * If a tty or serdev device is registered with a call to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)  * tty_port_register_device_serdev() then this function must be called when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)  * the device is gone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) void tty_port_unregister_device(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		struct tty_driver *driver, unsigned index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	ret = serdev_tty_port_unregister(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	tty_unregister_device(driver, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) EXPORT_SYMBOL_GPL(tty_port_unregister_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int tty_port_alloc_xmit_buf(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	/* We may sleep in get_zeroed_page() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	mutex_lock(&port->buf_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	if (port->xmit_buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	mutex_unlock(&port->buf_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	if (port->xmit_buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) void tty_port_free_xmit_buf(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	mutex_lock(&port->buf_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	if (port->xmit_buf != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		free_page((unsigned long)port->xmit_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		port->xmit_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	mutex_unlock(&port->buf_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) EXPORT_SYMBOL(tty_port_free_xmit_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)  * tty_port_destroy -- destroy inited port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)  * @port: tty port to be destroyed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)  * When a port was initialized using tty_port_init, one has to destroy the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)  * port by this function. Either indirectly by using tty_port refcounting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)  * (tty_port_put) or directly if refcounting is not used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) void tty_port_destroy(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	tty_buffer_cancel_work(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	tty_buffer_free_all(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) EXPORT_SYMBOL(tty_port_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static void tty_port_destructor(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	struct tty_port *port = container_of(kref, struct tty_port, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	/* check if last port ref was dropped before tty release */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	if (WARN_ON(port->itty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	if (port->xmit_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		free_page((unsigned long)port->xmit_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	tty_port_destroy(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	if (port->ops && port->ops->destruct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		port->ops->destruct(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		kfree(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) void tty_port_put(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	if (port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		kref_put(&port->kref, tty_port_destructor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) EXPORT_SYMBOL(tty_port_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  *	tty_port_tty_get	-	get a tty reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)  *	@port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)  *	Return a refcount protected tty instance or NULL if the port is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)  *	associated with a tty (eg due to close or hangup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct tty_struct *tty_port_tty_get(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	tty = tty_kref_get(port->tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	return tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) EXPORT_SYMBOL(tty_port_tty_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)  *	tty_port_tty_set	-	set the tty of a port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)  *	@port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)  *	@tty: the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)  *	Associate the port and tty pair. Manages any internal refcounts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)  *	Pass NULL to deassociate a port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	tty_kref_put(port->tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	port->tty = tty_kref_get(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) EXPORT_SYMBOL(tty_port_tty_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	mutex_lock(&port->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	if (port->console)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	if (tty_port_initialized(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		tty_port_set_initialized(port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		 * Drop DTR/RTS if HUPCL is set. This causes any attached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		 * modem to hang up the line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		if (tty && C_HUPCL(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			tty_port_lower_dtr_rts(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		if (port->ops->shutdown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 			port->ops->shutdown(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	mutex_unlock(&port->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)  *	tty_port_hangup		-	hangup helper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)  *	@port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)  *	Perform port level tty hangup flag and count changes. Drop the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)  *	reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)  *	Caller holds tty lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) void tty_port_hangup(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	port->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	tty = port->tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	if (tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		set_bit(TTY_IO_ERROR, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	port->tty = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	tty_port_set_active(port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	tty_port_shutdown(port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	wake_up_interruptible(&port->open_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	wake_up_interruptible(&port->delta_msr_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) EXPORT_SYMBOL(tty_port_hangup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)  * tty_port_tty_hangup - helper to hang up a tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)  * @port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)  * @check_clocal: hang only ttys with CLOCAL unset?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	struct tty_struct *tty = tty_port_tty_get(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	if (tty && (!check_clocal || !C_CLOCAL(tty)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		tty_hangup(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) EXPORT_SYMBOL_GPL(tty_port_tty_hangup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)  * tty_port_tty_wakeup - helper to wake up a tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)  * @port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) void tty_port_tty_wakeup(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	port->client_ops->write_wakeup(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) EXPORT_SYMBOL_GPL(tty_port_tty_wakeup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)  *	tty_port_carrier_raised	-	carrier raised check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)  *	@port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  *	Wrapper for the carrier detect logic. For the moment this is used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)  *	to hide some internal details. This will eventually become entirely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  *	internal to the tty port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) int tty_port_carrier_raised(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	if (port->ops->carrier_raised == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	return port->ops->carrier_raised(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) EXPORT_SYMBOL(tty_port_carrier_raised);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)  *	tty_port_raise_dtr_rts	-	Raise DTR/RTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)  *	@port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)  *	Wrapper for the DTR/RTS raise logic. For the moment this is used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)  *	to hide some internal details. This will eventually become entirely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)  *	internal to the tty port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) void tty_port_raise_dtr_rts(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	if (port->ops->dtr_rts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		port->ops->dtr_rts(port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) EXPORT_SYMBOL(tty_port_raise_dtr_rts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)  *	tty_port_lower_dtr_rts	-	Lower DTR/RTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)  *	@port: tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)  *	Wrapper for the DTR/RTS raise logic. For the moment this is used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)  *	to hide some internal details. This will eventually become entirely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)  *	internal to the tty port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) void tty_port_lower_dtr_rts(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	if (port->ops->dtr_rts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		port->ops->dtr_rts(port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) EXPORT_SYMBOL(tty_port_lower_dtr_rts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)  *	tty_port_block_til_ready	-	Waiting logic for tty open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)  *	@port: the tty port being opened
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)  *	@tty: the tty device being bound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)  *	@filp: the file pointer of the opener or NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)  *	Implement the core POSIX/SuS tty behaviour when opening a tty device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)  *	Handles:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)  *		- hangup (both before and during)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)  *		- non blocking open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)  *		- rts/dtr/dcd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)  *		- signals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)  *		- port flags and counts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)  *	The passed tty_port must implement the carrier_raised method if it can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)  *	do carrier detect and the dtr_rts method if it supports software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)  *	management of these lines. Note that the dtr/rts raise is done each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)  *	iteration as a hangup may have previously dropped them while we wait.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)  *	Caller holds tty lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)  *      NB: May drop and reacquire tty lock when blocking, so tty and tty_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)  *      may have changed state (eg., may have been hung up).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) int tty_port_block_til_ready(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 				struct tty_struct *tty, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	int do_clocal = 0, retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	DEFINE_WAIT(wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	/* if non-blocking mode is set we can pass directly to open unless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	   the port has just hung up or is in another error state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	if (tty_io_error(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		tty_port_set_active(port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	if (filp == NULL || (filp->f_flags & O_NONBLOCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		/* Indicate we are open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		if (C_BAUD(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 			tty_port_raise_dtr_rts(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		tty_port_set_active(port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	if (C_CLOCAL(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		do_clocal = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	/* Block waiting until we can proceed. We may need to wait for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	   carrier, but we must also wait for any close that is in progress
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	   before the next open may complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	/* The port lock protects the port counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	port->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	port->blocked_open++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		/* Indicate we are open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		if (C_BAUD(tty) && tty_port_initialized(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 			tty_port_raise_dtr_rts(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		/* Check for a hangup or uninitialised port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 							Return accordingly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		if (tty_hung_up_p(filp) || !tty_port_initialized(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 			if (port->flags & ASYNC_HUP_NOTIFY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 				retval = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 				retval = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		 * Probe the carrier. For devices with no carrier detect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		 * tty_port_carrier_raised will always return true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		 * Never ask drivers if CLOCAL is set, this causes troubles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		 * on some hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		if (do_clocal || tty_port_carrier_raised(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 			retval = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		tty_unlock(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		tty_lock(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	finish_wait(&port->open_wait, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	/* Update counts. A parallel hangup will have set count to zero and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	   we must not mess that up further */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	if (!tty_hung_up_p(filp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		port->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	port->blocked_open--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	if (retval == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		tty_port_set_active(port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) EXPORT_SYMBOL(tty_port_block_til_ready);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) static void tty_port_drain_delay(struct tty_port *port, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	unsigned int bps = tty_get_baud_rate(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	if (bps > 1200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		timeout = (HZ * 10 * port->drain_delay) / bps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		timeout = max_t(long, timeout, HZ / 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		timeout = 2 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	schedule_timeout_interruptible(timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /* Caller holds tty lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) int tty_port_close_start(struct tty_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 				struct tty_struct *tty, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	if (tty_hung_up_p(filp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	if (tty->count == 1 && port->count != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		tty_warn(tty, "%s: tty->count = 1 port count = %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 			 port->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 		port->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	if (--port->count < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		tty_warn(tty, "%s: bad port count (%d)\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 			 port->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		port->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	if (port->count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	tty->closing = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	if (tty_port_initialized(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		/* Don't block on a stalled port, just pull the chain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		if (tty->flow_stopped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 			tty_driver_flush_buffer(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 		if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 			tty_wait_until_sent(tty, port->closing_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		if (port->drain_delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 			tty_port_drain_delay(port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	/* Flush the ldisc buffering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	tty_ldisc_flush(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	/* Report to caller this is the last port reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) EXPORT_SYMBOL(tty_port_close_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* Caller holds tty lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	tty_ldisc_flush(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	tty->closing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	if (port->blocked_open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 		spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 		if (port->close_delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 			msleep_interruptible(jiffies_to_msecs(port->close_delay));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		wake_up_interruptible(&port->open_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	tty_port_set_active(port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) EXPORT_SYMBOL(tty_port_close_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)  * tty_port_close
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)  * Caller holds tty lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) void tty_port_close(struct tty_port *port, struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 							struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	if (tty_port_close_start(port, tty, filp) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	tty_port_shutdown(port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	if (!port->console)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		set_bit(TTY_IO_ERROR, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	tty_port_close_end(port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	tty_port_tty_set(port, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) EXPORT_SYMBOL(tty_port_close);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)  * tty_port_install - generic tty->ops->install handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)  * @port: tty_port of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)  * @driver: tty_driver for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)  * @tty: tty to be installed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)  * It is the same as tty_standard_install except the provided @port is linked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)  * to a concrete tty specified by @tty. Use this or tty_port_register_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)  * (or both). Call tty_port_link_device as a last resort.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) int tty_port_install(struct tty_port *port, struct tty_driver *driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	tty->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	return tty_standard_install(driver, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) EXPORT_SYMBOL_GPL(tty_port_install);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)  * tty_port_open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)  * Caller holds tty lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)  * NB: may drop and reacquire tty lock (in tty_port_block_til_ready()) so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)  * tty and tty_port may have changed state (eg., may be hung up now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) int tty_port_open(struct tty_port *port, struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 							struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	spin_lock_irq(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	++port->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	spin_unlock_irq(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	tty_port_tty_set(port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	 * Do the device-specific open only if the hardware isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	 * already initialized. Serialize open and shutdown using the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	 * port mutex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	mutex_lock(&port->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	if (!tty_port_initialized(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 		clear_bit(TTY_IO_ERROR, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		if (port->ops->activate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 			int retval = port->ops->activate(port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 			if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 				mutex_unlock(&port->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 				return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		tty_port_set_initialized(port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	mutex_unlock(&port->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	return tty_port_block_til_ready(port, tty, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) EXPORT_SYMBOL(tty_port_open);