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.c75
1 files changed, 70 insertions, 5 deletions
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index 1d21a9c1d33e..4fb3165384c4 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -34,7 +34,9 @@ static int tty_port_default_receive_buf(struct tty_port *port,
34 if (!disc) 34 if (!disc)
35 return 0; 35 return 0;
36 36
37 mutex_lock(&tty->atomic_write_lock);
37 ret = tty_ldisc_receive_buf(disc, p, (char *)f, count); 38 ret = tty_ldisc_receive_buf(disc, p, (char *)f, count);
39 mutex_unlock(&tty->atomic_write_lock);
38 40
39 tty_ldisc_deref(disc); 41 tty_ldisc_deref(disc);
40 42
@@ -129,19 +131,85 @@ struct device *tty_port_register_device_attr(struct tty_port *port,
129 struct device *device, void *drvdata, 131 struct device *device, void *drvdata,
130 const struct attribute_group **attr_grp) 132 const struct attribute_group **attr_grp)
131{ 133{
134 tty_port_link_device(port, driver, index);
135 return tty_register_device_attr(driver, index, device, drvdata,
136 attr_grp);
137}
138EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
139
140/**
141 * tty_port_register_device_attr_serdev - register tty or serdev device
142 * @port: tty_port of the device
143 * @driver: tty_driver for this device
144 * @index: index of the tty
145 * @device: parent if exists, otherwise NULL
146 * @drvdata: driver data for the device
147 * @attr_grp: attribute group for the device
148 *
149 * Register a serdev or tty device depending on if the parent device has any
150 * defined serdev clients or not.
151 */
152struct device *tty_port_register_device_attr_serdev(struct tty_port *port,
153 struct tty_driver *driver, unsigned index,
154 struct device *device, void *drvdata,
155 const struct attribute_group **attr_grp)
156{
132 struct device *dev; 157 struct device *dev;
133 158
134 tty_port_link_device(port, driver, index); 159 tty_port_link_device(port, driver, index);
135 160
136 dev = serdev_tty_port_register(port, device, driver, index); 161 dev = serdev_tty_port_register(port, device, driver, index);
137 if (PTR_ERR(dev) != -ENODEV) 162 if (PTR_ERR(dev) != -ENODEV) {
138 /* Skip creating cdev if we registered a serdev device */ 163 /* Skip creating cdev if we registered a serdev device */
139 return dev; 164 return dev;
165 }
140 166
141 return tty_register_device_attr(driver, index, device, drvdata, 167 return tty_register_device_attr(driver, index, device, drvdata,
142 attr_grp); 168 attr_grp);
143} 169}
144EXPORT_SYMBOL_GPL(tty_port_register_device_attr); 170EXPORT_SYMBOL_GPL(tty_port_register_device_attr_serdev);
171
172/**
173 * tty_port_register_device_serdev - register tty or serdev device
174 * @port: tty_port of the device
175 * @driver: tty_driver for this device
176 * @index: index of the tty
177 * @device: parent if exists, otherwise NULL
178 *
179 * Register a serdev or tty device depending on if the parent device has any
180 * defined serdev clients or not.
181 */
182struct device *tty_port_register_device_serdev(struct tty_port *port,
183 struct tty_driver *driver, unsigned index,
184 struct device *device)
185{
186 return tty_port_register_device_attr_serdev(port, driver, index,
187 device, NULL, NULL);
188}
189EXPORT_SYMBOL_GPL(tty_port_register_device_serdev);
190
191/**
192 * tty_port_unregister_device - deregister a tty or serdev device
193 * @port: tty_port of the device
194 * @driver: tty_driver for this device
195 * @index: index of the tty
196 *
197 * If a tty or serdev device is registered with a call to
198 * tty_port_register_device_serdev() then this function must be called when
199 * the device is gone.
200 */
201void tty_port_unregister_device(struct tty_port *port,
202 struct tty_driver *driver, unsigned index)
203{
204 int ret;
205
206 ret = serdev_tty_port_unregister(port);
207 if (ret == 0)
208 return;
209
210 tty_unregister_device(driver, index);
211}
212EXPORT_SYMBOL_GPL(tty_port_unregister_device);
145 213
146int tty_port_alloc_xmit_buf(struct tty_port *port) 214int tty_port_alloc_xmit_buf(struct tty_port *port)
147{ 215{
@@ -189,9 +257,6 @@ static void tty_port_destructor(struct kref *kref)
189 /* check if last port ref was dropped before tty release */ 257 /* check if last port ref was dropped before tty release */
190 if (WARN_ON(port->itty)) 258 if (WARN_ON(port->itty))
191 return; 259 return;
192
193 serdev_tty_port_unregister(port);
194
195 if (port->xmit_buf) 260 if (port->xmit_buf)
196 free_page((unsigned long)port->xmit_buf); 261 free_page((unsigned long)port->xmit_buf);
197 tty_port_destroy(port); 262 tty_port_destroy(port);