diff options
author | Alan Cox <alan@linux.intel.com> | 2009-11-30 08:17:35 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-12-11 18:18:07 -0500 |
commit | 6769140d304731f0a3b177470a2adb4bacd9036b (patch) | |
tree | 365b66a3b9a21cd0240c8355fc74a0c791a0ed66 /drivers/char | |
parent | 6ed847d8efd08658ece10c9129cd511c8d7452cd (diff) |
tty: mxser: use the tty_port_open method
At first this looks a fairly trivial conversion but we can't quite push
everything into the right format yet. The open side is easy but care is needed
over the setserial methods. Fix up the locking now that we've adopted the
port->mutex locking rule for the initialization.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/mxser.c | 111 |
1 files changed, 35 insertions, 76 deletions
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 5e28d39b9e81..9dac516df006 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -856,9 +856,9 @@ static void mxser_check_modem_status(struct tty_struct *tty, | |||
856 | } | 856 | } |
857 | } | 857 | } |
858 | 858 | ||
859 | static int mxser_startup(struct tty_struct *tty) | 859 | static int mxser_activate(struct tty_port *port, struct tty_struct *tty) |
860 | { | 860 | { |
861 | struct mxser_port *info = tty->driver_data; | 861 | struct mxser_port *info = container_of(port, struct mxser_port, port); |
862 | unsigned long page; | 862 | unsigned long page; |
863 | unsigned long flags; | 863 | unsigned long flags; |
864 | 864 | ||
@@ -868,22 +868,13 @@ static int mxser_startup(struct tty_struct *tty) | |||
868 | 868 | ||
869 | spin_lock_irqsave(&info->slock, flags); | 869 | spin_lock_irqsave(&info->slock, flags); |
870 | 870 | ||
871 | if (info->port.flags & ASYNC_INITIALIZED) { | ||
872 | free_page(page); | ||
873 | spin_unlock_irqrestore(&info->slock, flags); | ||
874 | return 0; | ||
875 | } | ||
876 | |||
877 | if (!info->ioaddr || !info->type) { | 871 | if (!info->ioaddr || !info->type) { |
878 | set_bit(TTY_IO_ERROR, &tty->flags); | 872 | set_bit(TTY_IO_ERROR, &tty->flags); |
879 | free_page(page); | 873 | free_page(page); |
880 | spin_unlock_irqrestore(&info->slock, flags); | 874 | spin_unlock_irqrestore(&info->slock, flags); |
881 | return 0; | 875 | return 0; |
882 | } | 876 | } |
883 | if (info->port.xmit_buf) | 877 | info->port.xmit_buf = (unsigned char *) page; |
884 | free_page(page); | ||
885 | else | ||
886 | info->port.xmit_buf = (unsigned char *) page; | ||
887 | 878 | ||
888 | /* | 879 | /* |
889 | * Clear the FIFO buffers and disable them | 880 | * Clear the FIFO buffers and disable them |
@@ -951,24 +942,19 @@ static int mxser_startup(struct tty_struct *tty) | |||
951 | * and set the speed of the serial port | 942 | * and set the speed of the serial port |
952 | */ | 943 | */ |
953 | mxser_change_speed(tty, NULL); | 944 | mxser_change_speed(tty, NULL); |
954 | info->port.flags |= ASYNC_INITIALIZED; | ||
955 | spin_unlock_irqrestore(&info->slock, flags); | 945 | spin_unlock_irqrestore(&info->slock, flags); |
956 | 946 | ||
957 | return 0; | 947 | return 0; |
958 | } | 948 | } |
959 | 949 | ||
960 | /* | 950 | /* |
961 | * This routine will shutdown a serial port; interrupts maybe disabled, and | 951 | * This routine will shutdown a serial port |
962 | * DTR is dropped if the hangup on close termio flag is on. | ||
963 | */ | 952 | */ |
964 | static void mxser_shutdown(struct tty_struct *tty) | 953 | static void mxser_shutdown_port(struct tty_port *port) |
965 | { | 954 | { |
966 | struct mxser_port *info = tty->driver_data; | 955 | struct mxser_port *info = container_of(port, struct mxser_port, port); |
967 | unsigned long flags; | 956 | unsigned long flags; |
968 | 957 | ||
969 | if (!(info->port.flags & ASYNC_INITIALIZED)) | ||
970 | return; | ||
971 | |||
972 | spin_lock_irqsave(&info->slock, flags); | 958 | spin_lock_irqsave(&info->slock, flags); |
973 | 959 | ||
974 | /* | 960 | /* |
@@ -978,7 +964,7 @@ static void mxser_shutdown(struct tty_struct *tty) | |||
978 | wake_up_interruptible(&info->port.delta_msr_wait); | 964 | wake_up_interruptible(&info->port.delta_msr_wait); |
979 | 965 | ||
980 | /* | 966 | /* |
981 | * Free the IRQ, if necessary | 967 | * Free the xmit buffer, if necessary |
982 | */ | 968 | */ |
983 | if (info->port.xmit_buf) { | 969 | if (info->port.xmit_buf) { |
984 | free_page((unsigned long) info->port.xmit_buf); | 970 | free_page((unsigned long) info->port.xmit_buf); |
@@ -988,10 +974,6 @@ static void mxser_shutdown(struct tty_struct *tty) | |||
988 | info->IER = 0; | 974 | info->IER = 0; |
989 | outb(0x00, info->ioaddr + UART_IER); | 975 | outb(0x00, info->ioaddr + UART_IER); |
990 | 976 | ||
991 | if (tty->termios->c_cflag & HUPCL) | ||
992 | info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); | ||
993 | outb(info->MCR, info->ioaddr + UART_MCR); | ||
994 | |||
995 | /* clear Rx/Tx FIFO's */ | 977 | /* clear Rx/Tx FIFO's */ |
996 | if (info->board->chip_flag) | 978 | if (info->board->chip_flag) |
997 | outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | | 979 | outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | |
@@ -1004,9 +986,6 @@ static void mxser_shutdown(struct tty_struct *tty) | |||
1004 | /* read data port to reset things */ | 986 | /* read data port to reset things */ |
1005 | (void) inb(info->ioaddr + UART_RX); | 987 | (void) inb(info->ioaddr + UART_RX); |
1006 | 988 | ||
1007 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
1008 | |||
1009 | info->port.flags &= ~ASYNC_INITIALIZED; | ||
1010 | 989 | ||
1011 | if (info->board->chip_flag) | 990 | if (info->board->chip_flag) |
1012 | SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr); | 991 | SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr); |
@@ -1023,8 +1002,7 @@ static void mxser_shutdown(struct tty_struct *tty) | |||
1023 | static int mxser_open(struct tty_struct *tty, struct file *filp) | 1002 | static int mxser_open(struct tty_struct *tty, struct file *filp) |
1024 | { | 1003 | { |
1025 | struct mxser_port *info; | 1004 | struct mxser_port *info; |
1026 | unsigned long flags; | 1005 | int line; |
1027 | int retval, line; | ||
1028 | 1006 | ||
1029 | line = tty->index; | 1007 | line = tty->index; |
1030 | if (line == MXSER_PORTS) | 1008 | if (line == MXSER_PORTS) |
@@ -1035,23 +1013,7 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) | |||
1035 | if (!info->ioaddr) | 1013 | if (!info->ioaddr) |
1036 | return -ENODEV; | 1014 | return -ENODEV; |
1037 | 1015 | ||
1038 | tty->driver_data = info; | 1016 | return tty_port_open(&info->port, tty, filp); |
1039 | tty_port_tty_set(&info->port, tty); | ||
1040 | /* | ||
1041 | * Start up serial port | ||
1042 | */ | ||
1043 | spin_lock_irqsave(&info->port.lock, flags); | ||
1044 | info->port.count++; | ||
1045 | spin_unlock_irqrestore(&info->port.lock, flags); | ||
1046 | retval = mxser_startup(tty); | ||
1047 | if (retval) | ||
1048 | return retval; | ||
1049 | |||
1050 | retval = tty_port_block_til_ready(&info->port, tty, filp); | ||
1051 | if (retval) | ||
1052 | return retval; | ||
1053 | |||
1054 | return 0; | ||
1055 | } | 1017 | } |
1056 | 1018 | ||
1057 | static void mxser_flush_buffer(struct tty_struct *tty) | 1019 | static void mxser_flush_buffer(struct tty_struct *tty) |
@@ -1075,19 +1037,11 @@ static void mxser_flush_buffer(struct tty_struct *tty) | |||
1075 | } | 1037 | } |
1076 | 1038 | ||
1077 | 1039 | ||
1078 | static void mxser_close_port(struct tty_struct *tty, struct tty_port *port) | 1040 | static void mxser_close_port(struct tty_port *port) |
1079 | { | 1041 | { |
1080 | struct mxser_port *info = container_of(port, struct mxser_port, port); | 1042 | struct mxser_port *info = container_of(port, struct mxser_port, port); |
1081 | unsigned long timeout; | 1043 | unsigned long timeout; |
1082 | /* | 1044 | /* |
1083 | * Save the termios structure, since this port may have | ||
1084 | * separate termios for callout and dialin. | ||
1085 | * | ||
1086 | * FIXME: Can this go ? | ||
1087 | */ | ||
1088 | if (port->flags & ASYNC_NORMAL_ACTIVE) | ||
1089 | info->normal_termios = *tty->termios; | ||
1090 | /* | ||
1091 | * At this point we stop accepting input. To do this, we | 1045 | * At this point we stop accepting input. To do this, we |
1092 | * disable the receive line status interrupts, and tell the | 1046 | * disable the receive line status interrupts, and tell the |
1093 | * interrupt driver to stop checking the data ready bit in the | 1047 | * interrupt driver to stop checking the data ready bit in the |
@@ -1097,22 +1051,18 @@ static void mxser_close_port(struct tty_struct *tty, struct tty_port *port) | |||
1097 | if (info->board->chip_flag) | 1051 | if (info->board->chip_flag) |
1098 | info->IER &= ~MOXA_MUST_RECV_ISR; | 1052 | info->IER &= ~MOXA_MUST_RECV_ISR; |
1099 | 1053 | ||
1100 | if (port->flags & ASYNC_INITIALIZED) { | 1054 | outb(info->IER, info->ioaddr + UART_IER); |
1101 | outb(info->IER, info->ioaddr + UART_IER); | 1055 | /* |
1102 | /* | 1056 | * Before we drop DTR, make sure the UART transmitter |
1103 | * Before we drop DTR, make sure the UART transmitter | 1057 | * has completely drained; this is especially |
1104 | * has completely drained; this is especially | 1058 | * important if there is a transmit FIFO! |
1105 | * important if there is a transmit FIFO! | 1059 | */ |
1106 | */ | 1060 | timeout = jiffies + HZ; |
1107 | timeout = jiffies + HZ; | 1061 | while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) { |
1108 | while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) { | 1062 | schedule_timeout_interruptible(5); |
1109 | schedule_timeout_interruptible(5); | 1063 | if (time_after(jiffies, timeout)) |
1110 | if (time_after(jiffies, timeout)) | 1064 | break; |
1111 | break; | ||
1112 | } | ||
1113 | } | 1065 | } |
1114 | mxser_shutdown(tty); | ||
1115 | |||
1116 | } | 1066 | } |
1117 | 1067 | ||
1118 | /* | 1068 | /* |
@@ -1130,8 +1080,12 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) | |||
1130 | return; | 1080 | return; |
1131 | if (tty_port_close_start(port, tty, filp) == 0) | 1081 | if (tty_port_close_start(port, tty, filp) == 0) |
1132 | return; | 1082 | return; |
1133 | mxser_close_port(tty, port); | 1083 | mutex_lock(&port->mutex); |
1084 | mxser_close_port(port); | ||
1134 | mxser_flush_buffer(tty); | 1085 | mxser_flush_buffer(tty); |
1086 | mxser_shutdown_port(port); | ||
1087 | clear_bit(ASYNCB_INITIALIZED, &port->flags); | ||
1088 | mutex_unlock(&port->mutex); | ||
1135 | /* Right now the tty_port set is done outside of the close_end helper | 1089 | /* Right now the tty_port set is done outside of the close_end helper |
1136 | as we don't yet have everyone using refcounts */ | 1090 | as we don't yet have everyone using refcounts */ |
1137 | tty_port_close_end(port, tty); | 1091 | tty_port_close_end(port, tty); |
@@ -1329,9 +1283,13 @@ static int mxser_set_serial_info(struct tty_struct *tty, | |||
1329 | mxser_change_speed(tty, NULL); | 1283 | mxser_change_speed(tty, NULL); |
1330 | spin_unlock_irqrestore(&info->slock, sl_flags); | 1284 | spin_unlock_irqrestore(&info->slock, sl_flags); |
1331 | } | 1285 | } |
1332 | } else | 1286 | } else { |
1333 | retval = mxser_startup(tty); | 1287 | mutex_lock(&info->port.mutex); |
1334 | 1288 | retval = mxser_activate(&info->port, tty); | |
1289 | if (retval == 0) | ||
1290 | set_bit(ASYNCB_INITIALIZED, &info->port.flags); | ||
1291 | mutex_unlock(&info->port.mutex); | ||
1292 | } | ||
1335 | return retval; | 1293 | return retval; |
1336 | } | 1294 | } |
1337 | 1295 | ||
@@ -2059,7 +2017,6 @@ static void mxser_hangup(struct tty_struct *tty) | |||
2059 | struct mxser_port *info = tty->driver_data; | 2017 | struct mxser_port *info = tty->driver_data; |
2060 | 2018 | ||
2061 | mxser_flush_buffer(tty); | 2019 | mxser_flush_buffer(tty); |
2062 | mxser_shutdown(tty); | ||
2063 | tty_port_hangup(&info->port); | 2020 | tty_port_hangup(&info->port); |
2064 | } | 2021 | } |
2065 | 2022 | ||
@@ -2363,6 +2320,8 @@ static const struct tty_operations mxser_ops = { | |||
2363 | struct tty_port_operations mxser_port_ops = { | 2320 | struct tty_port_operations mxser_port_ops = { |
2364 | .carrier_raised = mxser_carrier_raised, | 2321 | .carrier_raised = mxser_carrier_raised, |
2365 | .dtr_rts = mxser_dtr_rts, | 2322 | .dtr_rts = mxser_dtr_rts, |
2323 | .activate = mxser_activate, | ||
2324 | .shutdown = mxser_shutdown_port, | ||
2366 | }; | 2325 | }; |
2367 | 2326 | ||
2368 | /* | 2327 | /* |