diff options
author | Alan Cox <alan@redhat.com> | 2009-01-02 08:45:05 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-02 13:19:38 -0500 |
commit | 31f35939d1d9bcfb3099b32c67b896d2792603f9 (patch) | |
tree | 39b6ceaf0e7477e0357ff8235814f579adad3f28 /drivers/char/stallion.c | |
parent | c9b3976e3fec266be25c5001a70aa0a890b6c476 (diff) |
tty_port: Add a port level carrier detect operation
This is the first step to generalising the various pieces of waiting logic
duplicated in all sorts of serial drivers.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/stallion.c')
-rw-r--r-- | drivers/char/stallion.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 963b03fb29e5..12aecdaf61ec 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -130,6 +130,8 @@ static char stl_unwanted[SC26198_RXFIFOSIZE]; | |||
130 | static DEFINE_MUTEX(stl_brdslock); | 130 | static DEFINE_MUTEX(stl_brdslock); |
131 | static struct stlbrd *stl_brds[STL_MAXBRDS]; | 131 | static struct stlbrd *stl_brds[STL_MAXBRDS]; |
132 | 132 | ||
133 | static const struct tty_port_operations stl_port_ops; | ||
134 | |||
133 | /* | 135 | /* |
134 | * Per board state flags. Used with the state field of the board struct. | 136 | * Per board state flags. Used with the state field of the board struct. |
135 | * Not really much here! | 137 | * Not really much here! |
@@ -786,6 +788,12 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
786 | 788 | ||
787 | /*****************************************************************************/ | 789 | /*****************************************************************************/ |
788 | 790 | ||
791 | static int stl_carrier_raised(struct tty_port *port) | ||
792 | { | ||
793 | struct stlport *portp = container_of(port, struct stlport, port); | ||
794 | return (portp->sigs & TIOCM_CD) ? 1 : 0; | ||
795 | } | ||
796 | |||
789 | /* | 797 | /* |
790 | * Possibly need to wait for carrier (DCD signal) to come high. Say | 798 | * Possibly need to wait for carrier (DCD signal) to come high. Say |
791 | * maybe because if we are clocal then we don't need to wait... | 799 | * maybe because if we are clocal then we don't need to wait... |
@@ -796,6 +804,7 @@ static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp, | |||
796 | { | 804 | { |
797 | unsigned long flags; | 805 | unsigned long flags; |
798 | int rc, doclocal; | 806 | int rc, doclocal; |
807 | struct tty_port *port = &portp->port; | ||
799 | 808 | ||
800 | pr_debug("stl_waitcarrier(portp=%p,filp=%p)\n", portp, filp); | 809 | pr_debug("stl_waitcarrier(portp=%p,filp=%p)\n", portp, filp); |
801 | 810 | ||
@@ -809,32 +818,32 @@ static int stl_waitcarrier(struct tty_struct *tty, struct stlport *portp, | |||
809 | 818 | ||
810 | portp->openwaitcnt++; | 819 | portp->openwaitcnt++; |
811 | if (! tty_hung_up_p(filp)) | 820 | if (! tty_hung_up_p(filp)) |
812 | portp->port.count--; | 821 | port->count--; |
813 | 822 | ||
814 | for (;;) { | 823 | for (;;) { |
815 | /* Takes brd_lock internally */ | 824 | /* Takes brd_lock internally */ |
816 | stl_setsignals(portp, 1, 1); | 825 | stl_setsignals(portp, 1, 1); |
817 | if (tty_hung_up_p(filp) || | 826 | if (tty_hung_up_p(filp) || |
818 | ((portp->port.flags & ASYNC_INITIALIZED) == 0)) { | 827 | ((port->flags & ASYNC_INITIALIZED) == 0)) { |
819 | if (portp->port.flags & ASYNC_HUP_NOTIFY) | 828 | if (port->flags & ASYNC_HUP_NOTIFY) |
820 | rc = -EBUSY; | 829 | rc = -EBUSY; |
821 | else | 830 | else |
822 | rc = -ERESTARTSYS; | 831 | rc = -ERESTARTSYS; |
823 | break; | 832 | break; |
824 | } | 833 | } |
825 | if (((portp->port.flags & ASYNC_CLOSING) == 0) && | 834 | if (((port->flags & ASYNC_CLOSING) == 0) && |
826 | (doclocal || (portp->sigs & TIOCM_CD))) | 835 | (doclocal || tty_port_carrier_raised(port))) |
827 | break; | 836 | break; |
828 | if (signal_pending(current)) { | 837 | if (signal_pending(current)) { |
829 | rc = -ERESTARTSYS; | 838 | rc = -ERESTARTSYS; |
830 | break; | 839 | break; |
831 | } | 840 | } |
832 | /* FIXME */ | 841 | /* FIXME */ |
833 | interruptible_sleep_on(&portp->port.open_wait); | 842 | interruptible_sleep_on(&port->open_wait); |
834 | } | 843 | } |
835 | 844 | ||
836 | if (! tty_hung_up_p(filp)) | 845 | if (! tty_hung_up_p(filp)) |
837 | portp->port.count++; | 846 | port->count++; |
838 | portp->openwaitcnt--; | 847 | portp->openwaitcnt--; |
839 | spin_unlock_irqrestore(&stallion_lock, flags); | 848 | spin_unlock_irqrestore(&stallion_lock, flags); |
840 | 849 | ||
@@ -1776,6 +1785,7 @@ static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp) | |||
1776 | break; | 1785 | break; |
1777 | } | 1786 | } |
1778 | tty_port_init(&portp->port); | 1787 | tty_port_init(&portp->port); |
1788 | portp->port.ops = &stl_port_ops; | ||
1779 | portp->magic = STL_PORTMAGIC; | 1789 | portp->magic = STL_PORTMAGIC; |
1780 | portp->portnr = i; | 1790 | portp->portnr = i; |
1781 | portp->brdnr = panelp->brdnr; | 1791 | portp->brdnr = panelp->brdnr; |
@@ -2659,6 +2669,10 @@ static const struct tty_operations stl_ops = { | |||
2659 | .tiocmset = stl_tiocmset, | 2669 | .tiocmset = stl_tiocmset, |
2660 | }; | 2670 | }; |
2661 | 2671 | ||
2672 | static const struct tty_port_operations stl_port_ops = { | ||
2673 | .carrier_raised = stl_carrier_raised, | ||
2674 | }; | ||
2675 | |||
2662 | /*****************************************************************************/ | 2676 | /*****************************************************************************/ |
2663 | /* CD1400 HARDWARE FUNCTIONS */ | 2677 | /* CD1400 HARDWARE FUNCTIONS */ |
2664 | /*****************************************************************************/ | 2678 | /*****************************************************************************/ |