aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers/line.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/drivers/line.c')
-rw-r--r--arch/um/drivers/line.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index acfd0e0fd0c9..fb6e4ea09921 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -19,9 +19,11 @@ static irqreturn_t line_interrupt(int irq, void *data)
19{ 19{
20 struct chan *chan = data; 20 struct chan *chan = data;
21 struct line *line = chan->line; 21 struct line *line = chan->line;
22 struct tty_struct *tty = tty_port_tty_get(&line->port);
22 23
23 if (line) 24 if (line)
24 chan_interrupt(line, line->tty, irq); 25 chan_interrupt(line, tty, irq);
26 tty_kref_put(tty);
25 return IRQ_HANDLED; 27 return IRQ_HANDLED;
26} 28}
27 29
@@ -333,7 +335,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
333{ 335{
334 struct chan *chan = data; 336 struct chan *chan = data;
335 struct line *line = chan->line; 337 struct line *line = chan->line;
336 struct tty_struct *tty = line->tty; 338 struct tty_struct *tty;
337 int err; 339 int err;
338 340
339 /* 341 /*
@@ -352,10 +354,13 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
352 } 354 }
353 spin_unlock(&line->lock); 355 spin_unlock(&line->lock);
354 356
357 tty = tty_port_tty_get(&line->port);
355 if (tty == NULL) 358 if (tty == NULL)
356 return IRQ_NONE; 359 return IRQ_NONE;
357 360
358 tty_wakeup(tty); 361 tty_wakeup(tty);
362 tty_kref_put(tty);
363
359 return IRQ_HANDLED; 364 return IRQ_HANDLED;
360} 365}
361 366
@@ -404,12 +409,12 @@ int line_open(struct line *lines, struct tty_struct *tty)
404 goto out_unlock; 409 goto out_unlock;
405 410
406 err = 0; 411 err = 0;
407 if (line->count++) 412 if (line->port.count++)
408 goto out_unlock; 413 goto out_unlock;
409 414
410 BUG_ON(tty->driver_data); 415 BUG_ON(tty->driver_data);
411 tty->driver_data = line; 416 tty->driver_data = line;
412 line->tty = tty; 417 tty_port_tty_set(&line->port, tty);
413 418
414 err = enable_chan(line); 419 err = enable_chan(line);
415 if (err) /* line_close() will be called by our caller */ 420 if (err) /* line_close() will be called by our caller */
@@ -446,10 +451,10 @@ void line_close(struct tty_struct *tty, struct file * filp)
446 mutex_lock(&line->count_lock); 451 mutex_lock(&line->count_lock);
447 BUG_ON(!line->valid); 452 BUG_ON(!line->valid);
448 453
449 if (--line->count) 454 if (--line->port.count)
450 goto out_unlock; 455 goto out_unlock;
451 456
452 line->tty = NULL; 457 tty_port_tty_set(&line->port, NULL);
453 tty->driver_data = NULL; 458 tty->driver_data = NULL;
454 459
455 if (line->sigio) { 460 if (line->sigio) {
@@ -478,7 +483,7 @@ int setup_one_line(struct line *lines, int n, char *init,
478 483
479 mutex_lock(&line->count_lock); 484 mutex_lock(&line->count_lock);
480 485
481 if (line->count) { 486 if (line->port.count) {
482 *error_out = "Device is already open"; 487 *error_out = "Device is already open";
483 goto out; 488 goto out;
484 } 489 }
@@ -610,9 +615,15 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
610 mutex_lock(&line->count_lock); 615 mutex_lock(&line->count_lock);
611 if (!line->valid) 616 if (!line->valid)
612 CONFIG_CHUNK(str, size, n, "none", 1); 617 CONFIG_CHUNK(str, size, n, "none", 1);
613 else if (line->tty == NULL) 618 else {
614 CONFIG_CHUNK(str, size, n, line->init_str, 1); 619 struct tty_struct *tty = tty_port_tty_get(&line->port);
615 else n = chan_config_string(line, str, size, error_out); 620 if (tty == NULL) {
621 CONFIG_CHUNK(str, size, n, line->init_str, 1);
622 } else {
623 n = chan_config_string(line, str, size, error_out);
624 tty_kref_put(tty);
625 }
626 }
616 mutex_unlock(&line->count_lock); 627 mutex_unlock(&line->count_lock);
617 628
618 return n; 629 return n;
@@ -663,6 +674,7 @@ int register_lines(struct line_driver *line_driver,
663 driver->init_termios = tty_std_termios; 674 driver->init_termios = tty_std_termios;
664 675
665 for (i = 0; i < nlines; i++) { 676 for (i = 0; i < nlines; i++) {
677 tty_port_init(&lines[i].port);
666 spin_lock_init(&lines[i].lock); 678 spin_lock_init(&lines[i].lock);
667 mutex_init(&lines[i].count_lock); 679 mutex_init(&lines[i].count_lock);
668 lines[i].driver = line_driver; 680 lines[i].driver = line_driver;