diff options
Diffstat (limited to 'arch/um/drivers/line.c')
-rw-r--r-- | arch/um/drivers/line.c | 32 |
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; |