aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2009-11-30 08:17:35 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 18:18:07 -0500
commit6769140d304731f0a3b177470a2adb4bacd9036b (patch)
tree365b66a3b9a21cd0240c8355fc74a0c791a0ed66 /drivers/char
parent6ed847d8efd08658ece10c9129cd511c8d7452cd (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.c111
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
859static int mxser_startup(struct tty_struct *tty) 859static 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 */
964static void mxser_shutdown(struct tty_struct *tty) 953static 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)
1023static int mxser_open(struct tty_struct *tty, struct file *filp) 1002static 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
1057static void mxser_flush_buffer(struct tty_struct *tty) 1019static 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
1078static void mxser_close_port(struct tty_struct *tty, struct tty_port *port) 1040static 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 = {
2363struct tty_port_operations mxser_port_ops = { 2320struct 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/*