TTY: synclink_cs, use dynamic tty devices
authorJiri Slaby <jslaby@suse.cz>
Tue, 7 Aug 2012 19:47:53 +0000 (21:47 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Aug 2012 23:50:20 +0000 (16:50 -0700)
This allows us to provide the tty layer with information about
tty_port for each link. And it also allows us to get rid of the
remove_device loop in synclink_cs_exit because we had to reorder
pcmcia and tty driver registration in init. This was because we need
to have serial_driver initialized when calling
tty_port_register_device from pcmcia ->probe.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Acked-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/char/pcmcia/synclink_cs.c

index 0606586e76abf04f56e47589d6e08afdc78582ab..ce277f74bd10b4de8c7ae93c09aa3446565c8c18 100644 (file)
@@ -2731,6 +2731,8 @@ static void mgslpc_add_device(MGSLPC_INFO *info)
 #if SYNCLINK_GENERIC_HDLC
        hdlcdev_init(info);
 #endif
+       tty_port_register_device(&info->port, serial_driver, info->line,
+                       &info->p_dev.dev);
 }
 
 static void mgslpc_remove_device(MGSLPC_INFO *remove_info)
@@ -2744,6 +2746,7 @@ static void mgslpc_remove_device(MGSLPC_INFO *remove_info)
                                last->next_device = info->next_device;
                        else
                                mgslpc_device_list = info->next_device;
+                       tty_unregister_device(serial_driver, info->line);
 #if SYNCLINK_GENERIC_HDLC
                        hdlcdev_exit(info);
 #endif
@@ -2807,13 +2810,12 @@ static int __init synclink_cs_init(void)
            BREAKPOINT();
     }
 
-    if ((rc = pcmcia_register_driver(&mgslpc_driver)) < 0)
-           return rc;
-
-    serial_driver = alloc_tty_driver(MAX_DEVICE_COUNT);
+    serial_driver = tty_alloc_driver(MAX_DEVICE_COUNT,
+                   TTY_DRIVER_REAL_RAW |
+                   TTY_DRIVER_DYNAMIC_DEV);
     if (!serial_driver) {
            rc = -ENOMEM;
-           goto err_pcmcia_drv;
+           goto err;
     }
 
     /* Initialize the tty_driver structure */
@@ -2827,7 +2829,6 @@ static int __init synclink_cs_init(void)
     serial_driver->init_termios = tty_std_termios;
     serial_driver->init_termios.c_cflag =
            B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-    serial_driver->flags = TTY_DRIVER_REAL_RAW;
     tty_set_operations(serial_driver, &mgslpc_ops);
 
     if ((rc = tty_register_driver(serial_driver)) < 0) {
@@ -2836,26 +2837,28 @@ static int __init synclink_cs_init(void)
            goto err_put_tty;
     }
 
+       rc = pcmcia_register_driver(&mgslpc_driver);
+       if (rc < 0)
+               goto err_unreg_tty;
+
     printk("%s %s, tty major#%d\n",
           driver_name, driver_version,
           serial_driver->major);
 
        return 0;
+err_unreg_tty:
+       tty_unregister_driver(serial_driver);
 err_put_tty:
        put_tty_driver(serial_driver);
-err_pcmcia_drv:
-       pcmcia_unregister_driver(&mgslpc_driver);
+err:
        return rc;
 }
 
 static void __exit synclink_cs_exit(void)
 {
-       while (mgslpc_device_list)
-               mgslpc_remove_device(mgslpc_device_list);
-
+       pcmcia_unregister_driver(&mgslpc_driver);
        tty_unregister_driver(serial_driver);
        put_tty_driver(serial_driver);
-       pcmcia_unregister_driver(&mgslpc_driver);
 }
 
 module_init(synclink_cs_init);