diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-03-21 19:07:34 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-03-21 19:07:34 -0400 |
commit | 23a376f98c5dcfc392d47e8d1872884ff44e585d (patch) | |
tree | dbe476151bbd6530369c40746f2ec2365f7b500a /arch/um/drivers/line.c | |
parent | 8358f6242dd447a4f694c7bc949bbfc842ca5db1 (diff) | |
parent | a937536b868b8369b98967929045f1df54234323 (diff) |
Merge 3.9-rc3 into tty-next
Diffstat (limited to 'arch/um/drivers/line.c')
-rw-r--r-- | arch/um/drivers/line.c | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index cc206eda245c..8035145f043b 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -299,7 +299,7 @@ static int line_activate(struct tty_port *port, struct tty_struct *tty) | |||
299 | return ret; | 299 | return ret; |
300 | 300 | ||
301 | if (!line->sigio) { | 301 | if (!line->sigio) { |
302 | chan_enable_winch(line->chan_out, tty); | 302 | chan_enable_winch(line->chan_out, port); |
303 | line->sigio = 1; | 303 | line->sigio = 1; |
304 | } | 304 | } |
305 | 305 | ||
@@ -309,8 +309,22 @@ static int line_activate(struct tty_port *port, struct tty_struct *tty) | |||
309 | return 0; | 309 | return 0; |
310 | } | 310 | } |
311 | 311 | ||
312 | static void unregister_winch(struct tty_struct *tty); | ||
313 | |||
314 | static void line_destruct(struct tty_port *port) | ||
315 | { | ||
316 | struct tty_struct *tty = tty_port_tty_get(port); | ||
317 | struct line *line = tty->driver_data; | ||
318 | |||
319 | if (line->sigio) { | ||
320 | unregister_winch(tty); | ||
321 | line->sigio = 0; | ||
322 | } | ||
323 | } | ||
324 | |||
312 | static const struct tty_port_operations line_port_ops = { | 325 | static const struct tty_port_operations line_port_ops = { |
313 | .activate = line_activate, | 326 | .activate = line_activate, |
327 | .destruct = line_destruct, | ||
314 | }; | 328 | }; |
315 | 329 | ||
316 | int line_open(struct tty_struct *tty, struct file *filp) | 330 | int line_open(struct tty_struct *tty, struct file *filp) |
@@ -334,18 +348,6 @@ int line_install(struct tty_driver *driver, struct tty_struct *tty, | |||
334 | return 0; | 348 | return 0; |
335 | } | 349 | } |
336 | 350 | ||
337 | static void unregister_winch(struct tty_struct *tty); | ||
338 | |||
339 | void line_cleanup(struct tty_struct *tty) | ||
340 | { | ||
341 | struct line *line = tty->driver_data; | ||
342 | |||
343 | if (line->sigio) { | ||
344 | unregister_winch(tty); | ||
345 | line->sigio = 0; | ||
346 | } | ||
347 | } | ||
348 | |||
349 | void line_close(struct tty_struct *tty, struct file * filp) | 351 | void line_close(struct tty_struct *tty, struct file * filp) |
350 | { | 352 | { |
351 | struct line *line = tty->driver_data; | 353 | struct line *line = tty->driver_data; |
@@ -595,7 +597,7 @@ struct winch { | |||
595 | int fd; | 597 | int fd; |
596 | int tty_fd; | 598 | int tty_fd; |
597 | int pid; | 599 | int pid; |
598 | struct tty_struct *tty; | 600 | struct tty_port *port; |
599 | unsigned long stack; | 601 | unsigned long stack; |
600 | struct work_struct work; | 602 | struct work_struct work; |
601 | }; | 603 | }; |
@@ -649,7 +651,7 @@ static irqreturn_t winch_interrupt(int irq, void *data) | |||
649 | goto out; | 651 | goto out; |
650 | } | 652 | } |
651 | } | 653 | } |
652 | tty = winch->tty; | 654 | tty = tty_port_tty_get(winch->port); |
653 | if (tty != NULL) { | 655 | if (tty != NULL) { |
654 | line = tty->driver_data; | 656 | line = tty->driver_data; |
655 | if (line != NULL) { | 657 | if (line != NULL) { |
@@ -657,6 +659,7 @@ static irqreturn_t winch_interrupt(int irq, void *data) | |||
657 | &tty->winsize.ws_col); | 659 | &tty->winsize.ws_col); |
658 | kill_pgrp(tty->pgrp, SIGWINCH, 1); | 660 | kill_pgrp(tty->pgrp, SIGWINCH, 1); |
659 | } | 661 | } |
662 | tty_kref_put(tty); | ||
660 | } | 663 | } |
661 | out: | 664 | out: |
662 | if (winch->fd != -1) | 665 | if (winch->fd != -1) |
@@ -664,7 +667,7 @@ static irqreturn_t winch_interrupt(int irq, void *data) | |||
664 | return IRQ_HANDLED; | 667 | return IRQ_HANDLED; |
665 | } | 668 | } |
666 | 669 | ||
667 | void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, | 670 | void register_winch_irq(int fd, int tty_fd, int pid, struct tty_port *port, |
668 | unsigned long stack) | 671 | unsigned long stack) |
669 | { | 672 | { |
670 | struct winch *winch; | 673 | struct winch *winch; |
@@ -679,7 +682,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, | |||
679 | .fd = fd, | 682 | .fd = fd, |
680 | .tty_fd = tty_fd, | 683 | .tty_fd = tty_fd, |
681 | .pid = pid, | 684 | .pid = pid, |
682 | .tty = tty, | 685 | .port = port, |
683 | .stack = stack }); | 686 | .stack = stack }); |
684 | 687 | ||
685 | if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, | 688 | if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, |
@@ -708,15 +711,18 @@ static void unregister_winch(struct tty_struct *tty) | |||
708 | { | 711 | { |
709 | struct list_head *ele, *next; | 712 | struct list_head *ele, *next; |
710 | struct winch *winch; | 713 | struct winch *winch; |
714 | struct tty_struct *wtty; | ||
711 | 715 | ||
712 | spin_lock(&winch_handler_lock); | 716 | spin_lock(&winch_handler_lock); |
713 | 717 | ||
714 | list_for_each_safe(ele, next, &winch_handlers) { | 718 | list_for_each_safe(ele, next, &winch_handlers) { |
715 | winch = list_entry(ele, struct winch, list); | 719 | winch = list_entry(ele, struct winch, list); |
716 | if (winch->tty == tty) { | 720 | wtty = tty_port_tty_get(winch->port); |
721 | if (wtty == tty) { | ||
717 | free_winch(winch); | 722 | free_winch(winch); |
718 | break; | 723 | break; |
719 | } | 724 | } |
725 | tty_kref_put(wtty); | ||
720 | } | 726 | } |
721 | spin_unlock(&winch_handler_lock); | 727 | spin_unlock(&winch_handler_lock); |
722 | } | 728 | } |