diff options
author | Alan Cox <alan@linux.intel.com> | 2009-11-30 08:17:08 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-12-11 18:18:06 -0500 |
commit | 338818fd802a6baacb7e5b6910d52c8996ca6d28 (patch) | |
tree | bb5373c467ce8a1720e8666eea8e13157e3dfb38 /drivers/char/istallion.c | |
parent | 047e9658ae3f67708f7dcb0169c97febce23c5d3 (diff) |
tty: istallion: tty port open/close methods
Slice/dice/repeat as with the stallion driver this is just code shuffling
and removal
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/char/istallion.c')
-rw-r--r-- | drivers/char/istallion.c | 177 |
1 files changed, 60 insertions, 117 deletions
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index babfd4401f69..4cd6c527ee41 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -213,7 +213,6 @@ static int stli_shared; | |||
213 | * with the slave. Most of them need to be updated atomically, so always | 213 | * with the slave. Most of them need to be updated atomically, so always |
214 | * use the bit setting operations (unless protected by cli/sti). | 214 | * use the bit setting operations (unless protected by cli/sti). |
215 | */ | 215 | */ |
216 | #define ST_INITIALIZING 1 | ||
217 | #define ST_OPENING 2 | 216 | #define ST_OPENING 2 |
218 | #define ST_CLOSING 3 | 217 | #define ST_CLOSING 3 |
219 | #define ST_CMDING 4 | 218 | #define ST_CMDING 4 |
@@ -783,13 +782,32 @@ static int stli_parsebrd(struct stlconf *confp, char **argp) | |||
783 | 782 | ||
784 | /*****************************************************************************/ | 783 | /*****************************************************************************/ |
785 | 784 | ||
785 | /* | ||
786 | * On the first open of the device setup the port hardware, and | ||
787 | * initialize the per port data structure. Since initializing the port | ||
788 | * requires several commands to the board we will need to wait for any | ||
789 | * other open that is already initializing the port. | ||
790 | * | ||
791 | * Locking: protected by the port mutex. | ||
792 | */ | ||
793 | |||
794 | static int stli_activate(struct tty_port *port, struct tty_struct *tty) | ||
795 | { | ||
796 | struct stliport *portp = container_of(port, struct stliport, port); | ||
797 | struct stlibrd *brdp = stli_brds[portp->brdnr]; | ||
798 | int rc; | ||
799 | |||
800 | if ((rc = stli_initopen(tty, brdp, portp)) >= 0) | ||
801 | clear_bit(TTY_IO_ERROR, &tty->flags); | ||
802 | wake_up_interruptible(&portp->raw_wait); | ||
803 | return rc; | ||
804 | } | ||
805 | |||
786 | static int stli_open(struct tty_struct *tty, struct file *filp) | 806 | static int stli_open(struct tty_struct *tty, struct file *filp) |
787 | { | 807 | { |
788 | struct stlibrd *brdp; | 808 | struct stlibrd *brdp; |
789 | struct stliport *portp; | 809 | struct stliport *portp; |
790 | struct tty_port *port; | ||
791 | unsigned int minordev, brdnr, portnr; | 810 | unsigned int minordev, brdnr, portnr; |
792 | int rc; | ||
793 | 811 | ||
794 | minordev = tty->index; | 812 | minordev = tty->index; |
795 | brdnr = MINOR2BRD(minordev); | 813 | brdnr = MINOR2BRD(minordev); |
@@ -809,95 +827,56 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
809 | return -ENODEV; | 827 | return -ENODEV; |
810 | if (portp->devnr < 1) | 828 | if (portp->devnr < 1) |
811 | return -ENODEV; | 829 | return -ENODEV; |
812 | port = &portp->port; | 830 | return tty_port_open(&portp->port, tty, filp); |
813 | |||
814 | /* | ||
815 | * On the first open of the device setup the port hardware, and | ||
816 | * initialize the per port data structure. Since initializing the port | ||
817 | * requires several commands to the board we will need to wait for any | ||
818 | * other open that is already initializing the port. | ||
819 | * | ||
820 | * Review - locking | ||
821 | */ | ||
822 | tty_port_tty_set(port, tty); | ||
823 | tty->driver_data = portp; | ||
824 | port->count++; | ||
825 | |||
826 | wait_event_interruptible(portp->raw_wait, | ||
827 | !test_bit(ST_INITIALIZING, &portp->state)); | ||
828 | if (signal_pending(current)) | ||
829 | return -ERESTARTSYS; | ||
830 | |||
831 | if ((portp->port.flags & ASYNC_INITIALIZED) == 0) { | ||
832 | set_bit(ST_INITIALIZING, &portp->state); | ||
833 | if ((rc = stli_initopen(tty, brdp, portp)) >= 0) { | ||
834 | /* Locking */ | ||
835 | port->flags |= ASYNC_INITIALIZED; | ||
836 | clear_bit(TTY_IO_ERROR, &tty->flags); | ||
837 | } | ||
838 | clear_bit(ST_INITIALIZING, &portp->state); | ||
839 | wake_up_interruptible(&portp->raw_wait); | ||
840 | if (rc < 0) | ||
841 | return rc; | ||
842 | } | ||
843 | return tty_port_block_til_ready(&portp->port, tty, filp); | ||
844 | } | 831 | } |
845 | 832 | ||
833 | |||
846 | /*****************************************************************************/ | 834 | /*****************************************************************************/ |
847 | 835 | ||
848 | static void stli_close(struct tty_struct *tty, struct file *filp) | 836 | static void stli_shutdown(struct tty_port *port) |
849 | { | 837 | { |
850 | struct stlibrd *brdp; | 838 | struct stlibrd *brdp; |
851 | struct stliport *portp; | 839 | unsigned long ftype; |
852 | struct tty_port *port; | ||
853 | unsigned long flags; | 840 | unsigned long flags; |
841 | struct stliport *portp = container_of(port, struct stliport, port); | ||
854 | 842 | ||
855 | portp = tty->driver_data; | 843 | if (portp->brdnr >= stli_nrbrds) |
856 | if (portp == NULL) | ||
857 | return; | 844 | return; |
858 | port = &portp->port; | 845 | brdp = stli_brds[portp->brdnr]; |
859 | 846 | if (brdp == NULL) | |
860 | if (tty_port_close_start(port, tty, filp) == 0) | ||
861 | return; | 847 | return; |
862 | 848 | ||
863 | /* | 849 | /* |
864 | * May want to wait for data to drain before closing. The BUSY flag | 850 | * May want to wait for data to drain before closing. The BUSY |
865 | * keeps track of whether we are still transmitting or not. It is | 851 | * flag keeps track of whether we are still transmitting or not. |
866 | * updated by messages from the slave - indicating when all chars | 852 | * It is updated by messages from the slave - indicating when all |
867 | * really have drained. | 853 | * chars really have drained. |
868 | */ | 854 | */ |
869 | spin_lock_irqsave(&stli_lock, flags); | ||
870 | if (tty == stli_txcooktty) | ||
871 | stli_flushchars(tty); | ||
872 | spin_unlock_irqrestore(&stli_lock, flags); | ||
873 | |||
874 | /* We end up doing this twice for the moment. This needs looking at | ||
875 | eventually. Note we still use portp->closing_wait as a result */ | ||
876 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) | ||
877 | tty_wait_until_sent(tty, portp->closing_wait); | ||
878 | 855 | ||
879 | /* FIXME: port locking here needs attending to */ | 856 | if (!test_bit(ST_CLOSING, &portp->state)) |
880 | port->flags &= ~ASYNC_INITIALIZED; | 857 | stli_rawclose(brdp, portp, 0, 0); |
881 | 858 | ||
882 | brdp = stli_brds[portp->brdnr]; | 859 | spin_lock_irqsave(&stli_lock, flags); |
883 | stli_rawclose(brdp, portp, 0, 0); | ||
884 | if (tty->termios->c_cflag & HUPCL) { | ||
885 | stli_mkasysigs(&portp->asig, 0, 0); | ||
886 | if (test_bit(ST_CMDING, &portp->state)) | ||
887 | set_bit(ST_DOSIGS, &portp->state); | ||
888 | else | ||
889 | stli_sendcmd(brdp, portp, A_SETSIGNALS, &portp->asig, | ||
890 | sizeof(asysigs_t), 0); | ||
891 | } | ||
892 | clear_bit(ST_TXBUSY, &portp->state); | 860 | clear_bit(ST_TXBUSY, &portp->state); |
893 | clear_bit(ST_RXSTOP, &portp->state); | 861 | clear_bit(ST_RXSTOP, &portp->state); |
894 | set_bit(TTY_IO_ERROR, &tty->flags); | 862 | spin_unlock_irqrestore(&stli_lock, flags); |
895 | tty_ldisc_flush(tty); | ||
896 | set_bit(ST_DOFLUSHRX, &portp->state); | ||
897 | stli_flushbuffer(tty); | ||
898 | 863 | ||
899 | tty_port_close_end(port, tty); | 864 | ftype = FLUSHTX | FLUSHRX; |
900 | tty_port_tty_set(port, NULL); | 865 | stli_cmdwait(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0); |
866 | } | ||
867 | |||
868 | static void stli_close(struct tty_struct *tty, struct file *filp) | ||
869 | { | ||
870 | struct stliport *portp = tty->driver_data; | ||
871 | unsigned long flags; | ||
872 | if (portp == NULL) | ||
873 | return; | ||
874 | spin_lock_irqsave(&stli_lock, flags); | ||
875 | /* Flush any internal buffering out first */ | ||
876 | if (tty == stli_txcooktty) | ||
877 | stli_flushchars(tty); | ||
878 | spin_unlock_irqrestore(&stli_lock, flags); | ||
879 | tty_port_close(&portp->port, tty, filp); | ||
901 | } | 880 | } |
902 | 881 | ||
903 | /*****************************************************************************/ | 882 | /*****************************************************************************/ |
@@ -1724,6 +1703,7 @@ static void stli_start(struct tty_struct *tty) | |||
1724 | 1703 | ||
1725 | /*****************************************************************************/ | 1704 | /*****************************************************************************/ |
1726 | 1705 | ||
1706 | |||
1727 | /* | 1707 | /* |
1728 | * Hangup this port. This is pretty much like closing the port, only | 1708 | * Hangup this port. This is pretty much like closing the port, only |
1729 | * a little more brutal. No waiting for data to drain. Shutdown the | 1709 | * a little more brutal. No waiting for data to drain. Shutdown the |
@@ -1733,47 +1713,8 @@ static void stli_start(struct tty_struct *tty) | |||
1733 | 1713 | ||
1734 | static void stli_hangup(struct tty_struct *tty) | 1714 | static void stli_hangup(struct tty_struct *tty) |
1735 | { | 1715 | { |
1736 | struct stliport *portp; | 1716 | struct stliport *portp = tty->driver_data; |
1737 | struct stlibrd *brdp; | 1717 | tty_port_hangup(&portp->port); |
1738 | struct tty_port *port; | ||
1739 | unsigned long flags; | ||
1740 | |||
1741 | portp = tty->driver_data; | ||
1742 | if (portp == NULL) | ||
1743 | return; | ||
1744 | if (portp->brdnr >= stli_nrbrds) | ||
1745 | return; | ||
1746 | brdp = stli_brds[portp->brdnr]; | ||
1747 | if (brdp == NULL) | ||
1748 | return; | ||
1749 | port = &portp->port; | ||
1750 | |||
1751 | spin_lock_irqsave(&port->lock, flags); | ||
1752 | port->flags &= ~ASYNC_INITIALIZED; | ||
1753 | spin_unlock_irqrestore(&port->lock, flags); | ||
1754 | |||
1755 | if (!test_bit(ST_CLOSING, &portp->state)) | ||
1756 | stli_rawclose(brdp, portp, 0, 0); | ||
1757 | |||
1758 | spin_lock_irqsave(&stli_lock, flags); | ||
1759 | if (tty->termios->c_cflag & HUPCL) { | ||
1760 | stli_mkasysigs(&portp->asig, 0, 0); | ||
1761 | if (test_bit(ST_CMDING, &portp->state)) { | ||
1762 | set_bit(ST_DOSIGS, &portp->state); | ||
1763 | set_bit(ST_DOFLUSHTX, &portp->state); | ||
1764 | set_bit(ST_DOFLUSHRX, &portp->state); | ||
1765 | } else { | ||
1766 | stli_sendcmd(brdp, portp, A_SETSIGNALSF, | ||
1767 | &portp->asig, sizeof(asysigs_t), 0); | ||
1768 | } | ||
1769 | } | ||
1770 | |||
1771 | clear_bit(ST_TXBUSY, &portp->state); | ||
1772 | clear_bit(ST_RXSTOP, &portp->state); | ||
1773 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
1774 | spin_unlock_irqrestore(&stli_lock, flags); | ||
1775 | |||
1776 | tty_port_hangup(port); | ||
1777 | } | 1718 | } |
1778 | 1719 | ||
1779 | /*****************************************************************************/ | 1720 | /*****************************************************************************/ |
@@ -4420,6 +4361,8 @@ static const struct tty_operations stli_ops = { | |||
4420 | static const struct tty_port_operations stli_port_ops = { | 4361 | static const struct tty_port_operations stli_port_ops = { |
4421 | .carrier_raised = stli_carrier_raised, | 4362 | .carrier_raised = stli_carrier_raised, |
4422 | .dtr_rts = stli_dtr_rts, | 4363 | .dtr_rts = stli_dtr_rts, |
4364 | .activate = stli_activate, | ||
4365 | .shutdown = stli_shutdown, | ||
4423 | }; | 4366 | }; |
4424 | 4367 | ||
4425 | /*****************************************************************************/ | 4368 | /*****************************************************************************/ |