aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2013-01-03 09:53:08 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-16 01:43:15 -0500
commitdabe2c1385cd53d91c0a318c0fb7d2c015c61458 (patch)
tree417c0165f0caee36a0060f03bc6ca171585c7962
parent6732c8bb8671acbdac6cdc93dd72ddd581dd5e25 (diff)
cyclades: push down tty_port_tty_get
Now, the tty is not needed at all places in the ISR. So we can just request in on demand when really needed. This cleans TX and RX paths a bit as the indentation level can be dropped by two now when we also invert the char_count if condition. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/cyclades.c237
1 files changed, 115 insertions, 122 deletions
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c
index 42a329b8af9f..345bd0e0884e 100644
--- a/drivers/tty/cyclades.c
+++ b/drivers/tty/cyclades.c
@@ -917,7 +917,7 @@ cyz_issue_cmd(struct cyclades_card *cinfo,
917 return 0; 917 return 0;
918} /* cyz_issue_cmd */ 918} /* cyz_issue_cmd */
919 919
920static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty) 920static void cyz_handle_rx(struct cyclades_port *info)
921{ 921{
922 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; 922 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
923 struct cyclades_card *cinfo = info->card; 923 struct cyclades_card *cinfo = info->card;
@@ -940,80 +940,77 @@ static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty)
940 else 940 else
941 char_count = rx_put - rx_get + rx_bufsize; 941 char_count = rx_put - rx_get + rx_bufsize;
942 942
943 if (char_count) { 943 if (!char_count)
944 return;
945
944#ifdef CY_ENABLE_MONITORING 946#ifdef CY_ENABLE_MONITORING
945 info->mon.int_count++; 947 info->mon.int_count++;
946 info->mon.char_count += char_count; 948 info->mon.char_count += char_count;
947 if (char_count > info->mon.char_max) 949 if (char_count > info->mon.char_max)
948 info->mon.char_max = char_count; 950 info->mon.char_max = char_count;
949 info->mon.char_last = char_count; 951 info->mon.char_last = char_count;
950#endif 952#endif
951 if (tty == NULL) { 953
952 /* flush received characters */
953 new_rx_get = (new_rx_get + char_count) &
954 (rx_bufsize - 1);
955 info->rflush_count++;
956 } else {
957#ifdef BLOCKMOVE 954#ifdef BLOCKMOVE
958 /* we'd like to use memcpy(t, f, n) and memset(s, c, count) 955 /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
959 for performance, but because of buffer boundaries, there 956 for performance, but because of buffer boundaries, there
960 may be several steps to the operation */ 957 may be several steps to the operation */
961 while (1) { 958 while (1) {
962 len = tty_prepare_flip_string(port, &buf, 959 len = tty_prepare_flip_string(port, &buf,
963 char_count); 960 char_count);
964 if (!len) 961 if (!len)
965 break; 962 break;
966 963
967 len = min_t(unsigned int, min(len, char_count), 964 len = min_t(unsigned int, min(len, char_count),
968 rx_bufsize - new_rx_get); 965 rx_bufsize - new_rx_get);
969 966
970 memcpy_fromio(buf, cinfo->base_addr + 967 memcpy_fromio(buf, cinfo->base_addr +
971 rx_bufaddr + new_rx_get, len); 968 rx_bufaddr + new_rx_get, len);
972 969
973 new_rx_get = (new_rx_get + len) & 970 new_rx_get = (new_rx_get + len) &
974 (rx_bufsize - 1); 971 (rx_bufsize - 1);
975 char_count -= len; 972 char_count -= len;
976 info->icount.rx += len; 973 info->icount.rx += len;
977 info->idle_stats.recv_bytes += len; 974 info->idle_stats.recv_bytes += len;
978 } 975 }
979#else 976#else
980 len = tty_buffer_request_room(port, char_count); 977 len = tty_buffer_request_room(port, char_count);
981 while (len--) { 978 while (len--) {
982 data = readb(cinfo->base_addr + rx_bufaddr + 979 data = readb(cinfo->base_addr + rx_bufaddr +
983 new_rx_get); 980 new_rx_get);
984 new_rx_get = (new_rx_get + 1) & 981 new_rx_get = (new_rx_get + 1) &
985 (rx_bufsize - 1); 982 (rx_bufsize - 1);
986 tty_insert_flip_char(port, data, TTY_NORMAL); 983 tty_insert_flip_char(port, data, TTY_NORMAL);
987 info->idle_stats.recv_bytes++; 984 info->idle_stats.recv_bytes++;
988 info->icount.rx++; 985 info->icount.rx++;
989 } 986 }
990#endif 987#endif
991#ifdef CONFIG_CYZ_INTR 988#ifdef CONFIG_CYZ_INTR
992 /* Recalculate the number of chars in the RX buffer and issue 989 /* Recalculate the number of chars in the RX buffer and issue
993 a cmd in case it's higher than the RX high water mark */ 990 a cmd in case it's higher than the RX high water mark */
994 rx_put = readl(&buf_ctrl->rx_put); 991 rx_put = readl(&buf_ctrl->rx_put);
995 if (rx_put >= rx_get) 992 if (rx_put >= rx_get)
996 char_count = rx_put - rx_get; 993 char_count = rx_put - rx_get;
997 else 994 else
998 char_count = rx_put - rx_get + rx_bufsize; 995 char_count = rx_put - rx_get + rx_bufsize;
999 if (char_count >= readl(&buf_ctrl->rx_threshold) && 996 if (char_count >= readl(&buf_ctrl->rx_threshold) &&
1000 !timer_pending(&cyz_rx_full_timer[ 997 !timer_pending(&cyz_rx_full_timer[
1001 info->line])) 998 info->line]))
1002 mod_timer(&cyz_rx_full_timer[info->line], 999 mod_timer(&cyz_rx_full_timer[info->line],
1003 jiffies + 1); 1000 jiffies + 1);
1004#endif 1001#endif
1005 info->idle_stats.recv_idle = jiffies; 1002 info->idle_stats.recv_idle = jiffies;
1006 tty_schedule_flip(&info->port); 1003 tty_schedule_flip(&info->port);
1007 } 1004
1008 /* Update rx_get */ 1005 /* Update rx_get */
1009 cy_writel(&buf_ctrl->rx_get, new_rx_get); 1006 cy_writel(&buf_ctrl->rx_get, new_rx_get);
1010 }
1011} 1007}
1012 1008
1013static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty) 1009static void cyz_handle_tx(struct cyclades_port *info)
1014{ 1010{
1015 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl; 1011 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
1016 struct cyclades_card *cinfo = info->card; 1012 struct cyclades_card *cinfo = info->card;
1013 struct tty_struct *tty;
1017 u8 data; 1014 u8 data;
1018 unsigned int char_count; 1015 unsigned int char_count;
1019#ifdef BLOCKMOVE 1016#ifdef BLOCKMOVE
@@ -1033,63 +1030,63 @@ static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty)
1033 else 1030 else
1034 char_count = tx_get - tx_put - 1; 1031 char_count = tx_get - tx_put - 1;
1035 1032
1036 if (char_count) { 1033 if (!char_count)
1037 1034 return;
1038 if (tty == NULL) 1035
1039 goto ztxdone; 1036 tty = tty_port_tty_get(&info->port);
1037 if (tty == NULL)
1038 goto ztxdone;
1040 1039
1041 if (info->x_char) { /* send special char */ 1040 if (info->x_char) { /* send special char */
1042 data = info->x_char; 1041 data = info->x_char;
1043 1042
1044 cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); 1043 cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
1045 tx_put = (tx_put + 1) & (tx_bufsize - 1); 1044 tx_put = (tx_put + 1) & (tx_bufsize - 1);
1046 info->x_char = 0; 1045 info->x_char = 0;
1047 char_count--; 1046 char_count--;
1048 info->icount.tx++; 1047 info->icount.tx++;
1049 } 1048 }
1050#ifdef BLOCKMOVE 1049#ifdef BLOCKMOVE
1051 while (0 < (small_count = min_t(unsigned int, 1050 while (0 < (small_count = min_t(unsigned int,
1052 tx_bufsize - tx_put, min_t(unsigned int, 1051 tx_bufsize - tx_put, min_t(unsigned int,
1053 (SERIAL_XMIT_SIZE - info->xmit_tail), 1052 (SERIAL_XMIT_SIZE - info->xmit_tail),
1054 min_t(unsigned int, info->xmit_cnt, 1053 min_t(unsigned int, info->xmit_cnt,
1055 char_count))))) { 1054 char_count))))) {
1056 1055
1057 memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + 1056 memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + tx_put),
1058 tx_put), 1057 &info->port.xmit_buf[info->xmit_tail],
1059 &info->port.xmit_buf[info->xmit_tail], 1058 small_count);
1060 small_count); 1059
1061 1060 tx_put = (tx_put + small_count) & (tx_bufsize - 1);
1062 tx_put = (tx_put + small_count) & (tx_bufsize - 1); 1061 char_count -= small_count;
1063 char_count -= small_count; 1062 info->icount.tx += small_count;
1064 info->icount.tx += small_count; 1063 info->xmit_cnt -= small_count;
1065 info->xmit_cnt -= small_count; 1064 info->xmit_tail = (info->xmit_tail + small_count) &
1066 info->xmit_tail = (info->xmit_tail + small_count) & 1065 (SERIAL_XMIT_SIZE - 1);
1067 (SERIAL_XMIT_SIZE - 1); 1066 }
1068 }
1069#else 1067#else
1070 while (info->xmit_cnt && char_count) { 1068 while (info->xmit_cnt && char_count) {
1071 data = info->port.xmit_buf[info->xmit_tail]; 1069 data = info->port.xmit_buf[info->xmit_tail];
1072 info->xmit_cnt--; 1070 info->xmit_cnt--;
1073 info->xmit_tail = (info->xmit_tail + 1) & 1071 info->xmit_tail = (info->xmit_tail + 1) &
1074 (SERIAL_XMIT_SIZE - 1); 1072 (SERIAL_XMIT_SIZE - 1);
1075 1073
1076 cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); 1074 cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
1077 tx_put = (tx_put + 1) & (tx_bufsize - 1); 1075 tx_put = (tx_put + 1) & (tx_bufsize - 1);
1078 char_count--; 1076 char_count--;
1079 info->icount.tx++; 1077 info->icount.tx++;
1080 } 1078 }
1081#endif 1079#endif
1082 tty_wakeup(tty); 1080 tty_wakeup(tty);
1081 tty_kref_put(tty);
1083ztxdone: 1082ztxdone:
1084 /* Update tx_put */ 1083 /* Update tx_put */
1085 cy_writel(&buf_ctrl->tx_put, tx_put); 1084 cy_writel(&buf_ctrl->tx_put, tx_put);
1086 }
1087} 1085}
1088 1086
1089static void cyz_handle_cmd(struct cyclades_card *cinfo) 1087static void cyz_handle_cmd(struct cyclades_card *cinfo)
1090{ 1088{
1091 struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl; 1089 struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
1092 struct tty_struct *tty;
1093 struct cyclades_port *info; 1090 struct cyclades_port *info;
1094 __u32 channel, param, fw_ver; 1091 __u32 channel, param, fw_ver;
1095 __u8 cmd; 1092 __u8 cmd;
@@ -1102,9 +1099,6 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1102 special_count = 0; 1099 special_count = 0;
1103 delta_count = 0; 1100 delta_count = 0;
1104 info = &cinfo->ports[channel]; 1101 info = &cinfo->ports[channel];
1105 tty = tty_port_tty_get(&info->port);
1106 if (tty == NULL)
1107 continue;
1108 1102
1109 switch (cmd) { 1103 switch (cmd) {
1110 case C_CM_PR_ERROR: 1104 case C_CM_PR_ERROR:
@@ -1130,8 +1124,14 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1130 readl(&info->u.cyz.ch_ctrl->rs_status); 1124 readl(&info->u.cyz.ch_ctrl->rs_status);
1131 if (dcd & C_RS_DCD) 1125 if (dcd & C_RS_DCD)
1132 wake_up_interruptible(&info->port.open_wait); 1126 wake_up_interruptible(&info->port.open_wait);
1133 else 1127 else {
1134 tty_hangup(tty); 1128 struct tty_struct *tty;
1129 tty = tty_port_tty_get(&info->port);
1130 if (tty) {
1131 tty_hangup(tty);
1132 tty_kref_put(tty);
1133 }
1134 }
1135 } 1135 }
1136 break; 1136 break;
1137 case C_CM_MCTS: 1137 case C_CM_MCTS:
@@ -1160,7 +1160,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1160 printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " 1160 printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, "
1161 "port %ld\n", info->card, channel); 1161 "port %ld\n", info->card, channel);
1162#endif 1162#endif
1163 cyz_handle_rx(info, tty); 1163 cyz_handle_rx(info);
1164 break; 1164 break;
1165 case C_CM_TXBEMPTY: 1165 case C_CM_TXBEMPTY:
1166 case C_CM_TXLOWWM: 1166 case C_CM_TXLOWWM:
@@ -1170,7 +1170,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1170 printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " 1170 printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, "
1171 "port %ld\n", info->card, channel); 1171 "port %ld\n", info->card, channel);
1172#endif 1172#endif
1173 cyz_handle_tx(info, tty); 1173 cyz_handle_tx(info);
1174 break; 1174 break;
1175#endif /* CONFIG_CYZ_INTR */ 1175#endif /* CONFIG_CYZ_INTR */
1176 case C_CM_FATAL: 1176 case C_CM_FATAL:
@@ -1183,7 +1183,6 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1183 wake_up_interruptible(&info->port.delta_msr_wait); 1183 wake_up_interruptible(&info->port.delta_msr_wait);
1184 if (special_count) 1184 if (special_count)
1185 tty_schedule_flip(&info->port); 1185 tty_schedule_flip(&info->port);
1186 tty_kref_put(tty);
1187 } 1186 }
1188} 1187}
1189 1188
@@ -1249,17 +1248,11 @@ static void cyz_poll(unsigned long arg)
1249 cyz_handle_cmd(cinfo); 1248 cyz_handle_cmd(cinfo);
1250 1249
1251 for (port = 0; port < cinfo->nports; port++) { 1250 for (port = 0; port < cinfo->nports; port++) {
1252 struct tty_struct *tty;
1253
1254 info = &cinfo->ports[port]; 1251 info = &cinfo->ports[port];
1255 tty = tty_port_tty_get(&info->port);
1256 /* OK to pass NULL to the handle functions below.
1257 They need to drop the data in that case. */
1258 1252
1259 if (!info->throttle) 1253 if (!info->throttle)
1260 cyz_handle_rx(info, tty); 1254 cyz_handle_rx(info);
1261 cyz_handle_tx(info, tty); 1255 cyz_handle_tx(info);
1262 tty_kref_put(tty);
1263 } 1256 }
1264 /* poll every 'cyz_polling_cycle' period */ 1257 /* poll every 'cyz_polling_cycle' period */
1265 expires = jiffies + cyz_polling_cycle; 1258 expires = jiffies + cyz_polling_cycle;