Commit dabe2c1385cd53d91c0a318c0fb7d2c015c61458

Authored by Jiri Slaby
Committed by Greg Kroah-Hartman
1 parent 6732c8bb86

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>

Showing 1 changed file with 115 additions and 122 deletions Side-by-side Diff

drivers/tty/cyclades.c
... ... @@ -917,7 +917,7 @@
917 917 return 0;
918 918 } /* cyz_issue_cmd */
919 919  
920   -static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty)
  920 +static void cyz_handle_rx(struct cyclades_port *info)
921 921 {
922 922 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
923 923 struct cyclades_card *cinfo = info->card;
924 924  
925 925  
926 926  
927 927  
928 928  
929 929  
930 930  
931 931  
932 932  
933 933  
934 934  
... ... @@ -940,80 +940,77 @@
940 940 else
941 941 char_count = rx_put - rx_get + rx_bufsize;
942 942  
943   - if (char_count) {
  943 + if (!char_count)
  944 + return;
  945 +
944 946 #ifdef CY_ENABLE_MONITORING
945   - info->mon.int_count++;
946   - info->mon.char_count += char_count;
947   - if (char_count > info->mon.char_max)
948   - info->mon.char_max = char_count;
949   - info->mon.char_last = char_count;
  947 + info->mon.int_count++;
  948 + info->mon.char_count += char_count;
  949 + if (char_count > info->mon.char_max)
  950 + info->mon.char_max = char_count;
  951 + info->mon.char_last = char_count;
950 952 #endif
951   - if (tty == NULL) {
952   - /* flush received characters */
953   - new_rx_get = (new_rx_get + char_count) &
954   - (rx_bufsize - 1);
955   - info->rflush_count++;
956   - } else {
  953 +
957 954 #ifdef BLOCKMOVE
958   - /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
959   - for performance, but because of buffer boundaries, there
960   - may be several steps to the operation */
961   - while (1) {
962   - len = tty_prepare_flip_string(port, &buf,
963   - char_count);
964   - if (!len)
965   - break;
  955 + /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
  956 + for performance, but because of buffer boundaries, there
  957 + may be several steps to the operation */
  958 + while (1) {
  959 + len = tty_prepare_flip_string(port, &buf,
  960 + char_count);
  961 + if (!len)
  962 + break;
966 963  
967   - len = min_t(unsigned int, min(len, char_count),
968   - rx_bufsize - new_rx_get);
  964 + len = min_t(unsigned int, min(len, char_count),
  965 + rx_bufsize - new_rx_get);
969 966  
970   - memcpy_fromio(buf, cinfo->base_addr +
971   - rx_bufaddr + new_rx_get, len);
  967 + memcpy_fromio(buf, cinfo->base_addr +
  968 + rx_bufaddr + new_rx_get, len);
972 969  
973   - new_rx_get = (new_rx_get + len) &
974   - (rx_bufsize - 1);
975   - char_count -= len;
976   - info->icount.rx += len;
977   - info->idle_stats.recv_bytes += len;
978   - }
  970 + new_rx_get = (new_rx_get + len) &
  971 + (rx_bufsize - 1);
  972 + char_count -= len;
  973 + info->icount.rx += len;
  974 + info->idle_stats.recv_bytes += len;
  975 + }
979 976 #else
980   - len = tty_buffer_request_room(port, char_count);
981   - while (len--) {
982   - data = readb(cinfo->base_addr + rx_bufaddr +
983   - new_rx_get);
984   - new_rx_get = (new_rx_get + 1) &
985   - (rx_bufsize - 1);
986   - tty_insert_flip_char(port, data, TTY_NORMAL);
987   - info->idle_stats.recv_bytes++;
988   - info->icount.rx++;
989   - }
  977 + len = tty_buffer_request_room(port, char_count);
  978 + while (len--) {
  979 + data = readb(cinfo->base_addr + rx_bufaddr +
  980 + new_rx_get);
  981 + new_rx_get = (new_rx_get + 1) &
  982 + (rx_bufsize - 1);
  983 + tty_insert_flip_char(port, data, TTY_NORMAL);
  984 + info->idle_stats.recv_bytes++;
  985 + info->icount.rx++;
  986 + }
990 987 #endif
991 988 #ifdef CONFIG_CYZ_INTR
992   - /* 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 */
994   - rx_put = readl(&buf_ctrl->rx_put);
995   - if (rx_put >= rx_get)
996   - char_count = rx_put - rx_get;
997   - else
998   - char_count = rx_put - rx_get + rx_bufsize;
999   - if (char_count >= readl(&buf_ctrl->rx_threshold) &&
1000   - !timer_pending(&cyz_rx_full_timer[
1001   - info->line]))
1002   - mod_timer(&cyz_rx_full_timer[info->line],
1003   - jiffies + 1);
  989 + /* Recalculate the number of chars in the RX buffer and issue
  990 + a cmd in case it's higher than the RX high water mark */
  991 + rx_put = readl(&buf_ctrl->rx_put);
  992 + if (rx_put >= rx_get)
  993 + char_count = rx_put - rx_get;
  994 + else
  995 + char_count = rx_put - rx_get + rx_bufsize;
  996 + if (char_count >= readl(&buf_ctrl->rx_threshold) &&
  997 + !timer_pending(&cyz_rx_full_timer[
  998 + info->line]))
  999 + mod_timer(&cyz_rx_full_timer[info->line],
  1000 + jiffies + 1);
1004 1001 #endif
1005   - info->idle_stats.recv_idle = jiffies;
1006   - tty_schedule_flip(&info->port);
1007   - }
1008   - /* Update rx_get */
1009   - cy_writel(&buf_ctrl->rx_get, new_rx_get);
1010   - }
  1002 + info->idle_stats.recv_idle = jiffies;
  1003 + tty_schedule_flip(&info->port);
  1004 +
  1005 + /* Update rx_get */
  1006 + cy_writel(&buf_ctrl->rx_get, new_rx_get);
1011 1007 }
1012 1008  
1013   -static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty)
  1009 +static void cyz_handle_tx(struct cyclades_port *info)
1014 1010 {
1015 1011 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
1016 1012 struct cyclades_card *cinfo = info->card;
  1013 + struct tty_struct *tty;
1017 1014 u8 data;
1018 1015 unsigned int char_count;
1019 1016 #ifdef BLOCKMOVE
1020 1017  
1021 1018  
1022 1019  
1023 1020  
1024 1021  
1025 1022  
1026 1023  
1027 1024  
1028 1025  
1029 1026  
... ... @@ -1033,63 +1030,63 @@
1033 1030 else
1034 1031 char_count = tx_get - tx_put - 1;
1035 1032  
1036   - if (char_count) {
  1033 + if (!char_count)
  1034 + return;
  1035 +
  1036 + tty = tty_port_tty_get(&info->port);
  1037 + if (tty == NULL)
  1038 + goto ztxdone;
1037 1039  
1038   - if (tty == NULL)
1039   - goto ztxdone;
  1040 + if (info->x_char) { /* send special char */
  1041 + data = info->x_char;
1040 1042  
1041   - if (info->x_char) { /* send special char */
1042   - data = info->x_char;
1043   -
1044   - cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
1045   - tx_put = (tx_put + 1) & (tx_bufsize - 1);
1046   - info->x_char = 0;
1047   - char_count--;
1048   - info->icount.tx++;
1049   - }
  1043 + cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
  1044 + tx_put = (tx_put + 1) & (tx_bufsize - 1);
  1045 + info->x_char = 0;
  1046 + char_count--;
  1047 + info->icount.tx++;
  1048 + }
1050 1049 #ifdef BLOCKMOVE
1051   - while (0 < (small_count = min_t(unsigned int,
1052   - tx_bufsize - tx_put, min_t(unsigned int,
1053   - (SERIAL_XMIT_SIZE - info->xmit_tail),
1054   - min_t(unsigned int, info->xmit_cnt,
1055   - char_count))))) {
  1050 + while (0 < (small_count = min_t(unsigned int,
  1051 + tx_bufsize - tx_put, min_t(unsigned int,
  1052 + (SERIAL_XMIT_SIZE - info->xmit_tail),
  1053 + min_t(unsigned int, info->xmit_cnt,
  1054 + char_count))))) {
1056 1055  
1057   - memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr +
1058   - tx_put),
1059   - &info->port.xmit_buf[info->xmit_tail],
1060   - small_count);
  1056 + memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + tx_put),
  1057 + &info->port.xmit_buf[info->xmit_tail],
  1058 + small_count);
1061 1059  
1062   - tx_put = (tx_put + small_count) & (tx_bufsize - 1);
1063   - char_count -= small_count;
1064   - info->icount.tx += small_count;
1065   - info->xmit_cnt -= small_count;
1066   - info->xmit_tail = (info->xmit_tail + small_count) &
1067   - (SERIAL_XMIT_SIZE - 1);
1068   - }
  1060 + tx_put = (tx_put + small_count) & (tx_bufsize - 1);
  1061 + char_count -= small_count;
  1062 + info->icount.tx += small_count;
  1063 + info->xmit_cnt -= small_count;
  1064 + info->xmit_tail = (info->xmit_tail + small_count) &
  1065 + (SERIAL_XMIT_SIZE - 1);
  1066 + }
1069 1067 #else
1070   - while (info->xmit_cnt && char_count) {
1071   - data = info->port.xmit_buf[info->xmit_tail];
1072   - info->xmit_cnt--;
1073   - info->xmit_tail = (info->xmit_tail + 1) &
1074   - (SERIAL_XMIT_SIZE - 1);
  1068 + while (info->xmit_cnt && char_count) {
  1069 + data = info->port.xmit_buf[info->xmit_tail];
  1070 + info->xmit_cnt--;
  1071 + info->xmit_tail = (info->xmit_tail + 1) &
  1072 + (SERIAL_XMIT_SIZE - 1);
1075 1073  
1076   - cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
1077   - tx_put = (tx_put + 1) & (tx_bufsize - 1);
1078   - char_count--;
1079   - info->icount.tx++;
1080   - }
  1074 + cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data);
  1075 + tx_put = (tx_put + 1) & (tx_bufsize - 1);
  1076 + char_count--;
  1077 + info->icount.tx++;
  1078 + }
1081 1079 #endif
1082   - tty_wakeup(tty);
  1080 + tty_wakeup(tty);
  1081 + tty_kref_put(tty);
1083 1082 ztxdone:
1084   - /* Update tx_put */
1085   - cy_writel(&buf_ctrl->tx_put, tx_put);
1086   - }
  1083 + /* Update tx_put */
  1084 + cy_writel(&buf_ctrl->tx_put, tx_put);
1087 1085 }
1088 1086  
1089 1087 static void cyz_handle_cmd(struct cyclades_card *cinfo)
1090 1088 {
1091 1089 struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
1092   - struct tty_struct *tty;
1093 1090 struct cyclades_port *info;
1094 1091 __u32 channel, param, fw_ver;
1095 1092 __u8 cmd;
... ... @@ -1102,9 +1099,6 @@
1102 1099 special_count = 0;
1103 1100 delta_count = 0;
1104 1101 info = &cinfo->ports[channel];
1105   - tty = tty_port_tty_get(&info->port);
1106   - if (tty == NULL)
1107   - continue;
1108 1102  
1109 1103 switch (cmd) {
1110 1104 case C_CM_PR_ERROR:
... ... @@ -1130,8 +1124,14 @@
1130 1124 readl(&info->u.cyz.ch_ctrl->rs_status);
1131 1125 if (dcd & C_RS_DCD)
1132 1126 wake_up_interruptible(&info->port.open_wait);
1133   - else
1134   - tty_hangup(tty);
  1127 + else {
  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 1136 break;
1137 1137 case C_CM_MCTS:
... ... @@ -1160,7 +1160,7 @@
1160 1160 printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, "
1161 1161 "port %ld\n", info->card, channel);
1162 1162 #endif
1163   - cyz_handle_rx(info, tty);
  1163 + cyz_handle_rx(info);
1164 1164 break;
1165 1165 case C_CM_TXBEMPTY:
1166 1166 case C_CM_TXLOWWM:
... ... @@ -1170,7 +1170,7 @@
1170 1170 printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, "
1171 1171 "port %ld\n", info->card, channel);
1172 1172 #endif
1173   - cyz_handle_tx(info, tty);
  1173 + cyz_handle_tx(info);
1174 1174 break;
1175 1175 #endif /* CONFIG_CYZ_INTR */
1176 1176 case C_CM_FATAL:
... ... @@ -1183,7 +1183,6 @@
1183 1183 wake_up_interruptible(&info->port.delta_msr_wait);
1184 1184 if (special_count)
1185 1185 tty_schedule_flip(&info->port);
1186   - tty_kref_put(tty);
1187 1186 }
1188 1187 }
1189 1188  
1190 1189  
1191 1190  
... ... @@ -1249,17 +1248,11 @@
1249 1248 cyz_handle_cmd(cinfo);
1250 1249  
1251 1250 for (port = 0; port < cinfo->nports; port++) {
1252   - struct tty_struct *tty;
1253   -
1254 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 1253 if (!info->throttle)
1260   - cyz_handle_rx(info, tty);
1261   - cyz_handle_tx(info, tty);
1262   - tty_kref_put(tty);
  1254 + cyz_handle_rx(info);
  1255 + cyz_handle_tx(info);
1263 1256 }
1264 1257 /* poll every 'cyz_polling_cycle' period */
1265 1258 expires = jiffies + cyz_polling_cycle;