]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/tty/tty_port.c
Merge tag 'xfs-4.12-fixes-4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
[karo-tx-linux.git] / drivers / tty / tty_port.c
index 1d21a9c1d33e6e3c5ef007a25e4b4550fb62a51c..6b137194069fee47bc45b1866865ee27adfd33c5 100644 (file)
@@ -128,20 +128,86 @@ struct device *tty_port_register_device_attr(struct tty_port *port,
                struct tty_driver *driver, unsigned index,
                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);