um: switch line.c tty drivers to dynamic device creation
[firefly-linux-kernel-4.4.55.git] / arch / um / drivers / line.c
index 1a8d6591c2044af2f4ba8ec456dca34ce9592020..015209a9881529bd9495460338b048f65adc7994 100644 (file)
@@ -485,6 +485,7 @@ static int setup_one_line(struct line *lines, int n, char *init,
                          const struct chan_opts *opts, char **error_out)
 {
        struct line *line = &lines[n];
+       struct tty_driver *driver = line->driver->driver;
        int err = -EINVAL;
 
        mutex_lock(&line->count_lock);
@@ -498,6 +499,7 @@ static int setup_one_line(struct line *lines, int n, char *init,
                if (line->valid) {
                        line->valid = 0;
                        kfree(line->init_str);
+                       tty_unregister_device(driver, n);
                        parse_chan_pair(NULL, line, n, opts, error_out);
                        err = 0;
                }
@@ -507,9 +509,19 @@ static int setup_one_line(struct line *lines, int n, char *init,
                        *error_out = "Failed to allocate memory";
                        return -ENOMEM;
                }
+               if (line->valid)
+                       tty_unregister_device(driver, n);
                line->init_str = new;
                line->valid = 1;
                err = parse_chan_pair(new, line, n, opts, error_out);
+               if (!err) {
+                       struct device *d = tty_register_device(driver, n, NULL);
+                       if (IS_ERR(d)) {
+                               *error_out = "Failed to register device";
+                               err = PTR_ERR(d);
+                               parse_chan_pair(NULL, line, n, opts, error_out);
+                       }
+               }
                if (err) {
                        line->init_str = NULL;
                        line->valid = 0;
@@ -640,15 +652,15 @@ int line_remove(struct line *lines, unsigned int num, int n, char **error_out)
        return setup_one_line(lines, n, "none", NULL, error_out);
 }
 
-struct tty_driver *register_lines(struct line_driver *line_driver,
-                                 const struct tty_operations *ops,
-                                 struct line *lines, int nlines)
+int register_lines(struct line_driver *line_driver,
+                  const struct tty_operations *ops,
+                  struct line *lines, int nlines)
 {
-       int i;
        struct tty_driver *driver = alloc_tty_driver(nlines);
+       int err;
 
        if (!driver)
-               return NULL;
+               return -ENOMEM;
 
        driver->driver_name = line_driver->name;
        driver->name = line_driver->device_name;
@@ -656,24 +668,21 @@ struct tty_driver *register_lines(struct line_driver *line_driver,
        driver->minor_start = line_driver->minor_start;
        driver->type = line_driver->type;
        driver->subtype = line_driver->subtype;
-       driver->flags = TTY_DRIVER_REAL_RAW;
+       driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
        driver->init_termios = tty_std_termios;
        tty_set_operations(driver, ops);
 
-       if (tty_register_driver(driver)) {
+       err = tty_register_driver(driver);
+       if (err) {
                printk(KERN_ERR "register_lines : can't register %s driver\n",
                       line_driver->name);
                put_tty_driver(driver);
-               return NULL;
-       }
-
-       for(i = 0; i < nlines; i++) {
-               if (!lines[i].valid)
-                       tty_unregister_device(driver, i);
+               return err;
        }
 
+       line_driver->driver = driver;
        mconsole_register_dev(&line_driver->mc);
-       return driver;
+       return 0;
 }
 
 static DEFINE_SPINLOCK(winch_handler_lock);