diff options
Diffstat (limited to 'drivers/tty/tty_port.c')
| -rw-r--r-- | drivers/tty/tty_port.c | 73 | 
1 files changed, 68 insertions, 5 deletions
| diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 1d21a9c1d33e..6b137194069f 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -129,19 +129,85 @@ struct device *tty_port_register_device_attr(struct tty_port *port,  		struct device *device, void *drvdata,  		const struct attribute_group **attr_grp)  { +	tty_port_link_device(port, driver, index); +	return tty_register_device_attr(driver, index, device, drvdata, +			attr_grp); +} +EXPORT_SYMBOL_GPL(tty_port_register_device_attr); + +/** + * tty_port_register_device_attr_serdev - register tty or serdev device + * @port: tty_port of the device + * @driver: tty_driver for this device + * @index: index of the tty + * @device: parent if exists, otherwise NULL + * @drvdata: driver data for the device + * @attr_grp: attribute group for the device + * + * Register a serdev or tty device depending on if the parent device has any + * defined serdev clients or not. + */ +struct device *tty_port_register_device_attr_serdev(struct tty_port *port, +		struct tty_driver *driver, unsigned index, +		struct device *device, void *drvdata, +		const struct attribute_group **attr_grp) +{  	struct device *dev;  	tty_port_link_device(port, driver, index);  	dev = serdev_tty_port_register(port, device, driver, index); -	if (PTR_ERR(dev) != -ENODEV) +	if (PTR_ERR(dev) != -ENODEV) {  		/* Skip creating cdev if we registered a serdev device */  		return dev; +	}  	return tty_register_device_attr(driver, index, device, drvdata,  			attr_grp);  } -EXPORT_SYMBOL_GPL(tty_port_register_device_attr); +EXPORT_SYMBOL_GPL(tty_port_register_device_attr_serdev); + +/** + * tty_port_register_device_serdev - register tty or serdev device + * @port: tty_port of the device + * @driver: tty_driver for this device + * @index: index of the tty + * @device: parent if exists, otherwise NULL + * + * Register a serdev or tty device depending on if the parent device has any + * defined serdev clients or not. + */ +struct device *tty_port_register_device_serdev(struct tty_port *port, +		struct tty_driver *driver, unsigned index, +		struct device *device) +{ +	return tty_port_register_device_attr_serdev(port, driver, index, +			device, NULL, NULL); +} +EXPORT_SYMBOL_GPL(tty_port_register_device_serdev); + +/** + * tty_port_unregister_device - deregister a tty or serdev device + * @port: tty_port of the device + * @driver: tty_driver for this device + * @index: index of the tty + * + * If a tty or serdev device is registered with a call to + * tty_port_register_device_serdev() then this function must be called when + * the device is gone. + */ +void tty_port_unregister_device(struct tty_port *port, +		struct tty_driver *driver, unsigned index) +{ +	int ret; + +	ret = serdev_tty_port_unregister(port); +	if (ret == 0) +		return; + +	tty_unregister_device(driver, index); +} +EXPORT_SYMBOL_GPL(tty_port_unregister_device);  int tty_port_alloc_xmit_buf(struct tty_port *port)  { @@ -189,9 +255,6 @@ static void tty_port_destructor(struct kref *kref)  	/* check if last port ref was dropped before tty release */  	if (WARN_ON(port->itty))  		return; - -	serdev_tty_port_unregister(port); -  	if (port->xmit_buf)  		free_page((unsigned long)port->xmit_buf);  	tty_port_destroy(port); |