aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2008-02-06 04:36:11 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-06 13:41:00 -0500
commitd9afa43532adf8a31b93c4c7601fda3f423d8972 (patch)
tree1f5cc6d5050af80b5015b536c8b4f4fe1b6dd3d5 /drivers/char
parent1c17d18e3775485bf1e0ce79575eb637a94494a2 (diff)
riscom8: fix SMP brokenness
After analyzing the elements that save_flags/cli/sti/restore_flags were protecting, convert their usages to a global spinlock (the easiest and most obvious next-step). There were some usages of flags being intentionally cached, because the code already knew the state of interrupts. These have been taken into account. This allows us to remove CONFIG_BROKEN_ON_SMP. Completely untested. [akpm@linux-foundation.org: use DEFINE_SPINLOCK] Signed-off-by: Jeff Garzik <jgarzik@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/riscom8.c147
2 files changed, 94 insertions, 55 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 466629594776..eb5687beea91 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -276,7 +276,7 @@ config N_HDLC
276 276
277config RISCOM8 277config RISCOM8
278 tristate "SDL RISCom/8 card support" 278 tristate "SDL RISCom/8 card support"
279 depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP 279 depends on SERIAL_NONSTANDARD
280 help 280 help
281 This is a driver for the SDL Communications RISCom/8 multiport card, 281 This is a driver for the SDL Communications RISCom/8 multiport card,
282 which gives you many serial ports. You would need something like 282 which gives you many serial ports. You would need something like
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 102ece4c4e0e..d130b87d8ed7 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -47,6 +47,7 @@
47#include <linux/init.h> 47#include <linux/init.h>
48#include <linux/delay.h> 48#include <linux/delay.h>
49#include <linux/tty_flip.h> 49#include <linux/tty_flip.h>
50#include <linux/spinlock.h>
50 51
51#include <asm/uaccess.h> 52#include <asm/uaccess.h>
52 53
@@ -81,6 +82,8 @@
81 82
82static struct tty_driver *riscom_driver; 83static struct tty_driver *riscom_driver;
83 84
85static DEFINE_SPINLOCK(riscom_lock);
86
84static struct riscom_board rc_board[RC_NBOARD] = { 87static struct riscom_board rc_board[RC_NBOARD] = {
85 { 88 {
86 .base = RC_IOBASE1, 89 .base = RC_IOBASE1,
@@ -217,13 +220,14 @@ static void __init rc_init_CD180(struct riscom_board const * bp)
217{ 220{
218 unsigned long flags; 221 unsigned long flags;
219 222
220 save_flags(flags); cli(); 223 spin_lock_irqsave(&riscom_lock, flags);
224
221 rc_out(bp, RC_CTOUT, 0); /* Clear timeout */ 225 rc_out(bp, RC_CTOUT, 0); /* Clear timeout */
222 rc_wait_CCR(bp); /* Wait for CCR ready */ 226 rc_wait_CCR(bp); /* Wait for CCR ready */
223 rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */ 227 rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */
224 sti(); 228 spin_unlock_irqrestore(&riscom_lock, flags);
225 msleep(50); /* Delay 0.05 sec */ 229 msleep(50); /* Delay 0.05 sec */
226 cli(); 230 spin_lock_irqsave(&riscom_lock, flags);
227 rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */ 231 rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */
228 rc_out(bp, CD180_GICR, 0); /* Clear all bits */ 232 rc_out(bp, CD180_GICR, 0); /* Clear all bits */
229 rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */ 233 rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */
@@ -234,7 +238,7 @@ static void __init rc_init_CD180(struct riscom_board const * bp)
234 rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8); 238 rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8);
235 rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff); 239 rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff);
236 240
237 restore_flags(flags); 241 spin_unlock_irqrestore(&riscom_lock, flags);
238} 242}
239 243
240/* Main probing routine, also sets irq. */ 244/* Main probing routine, also sets irq. */
@@ -812,9 +816,9 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
812 } 816 }
813 port->xmit_buf = (unsigned char *) tmp; 817 port->xmit_buf = (unsigned char *) tmp;
814 } 818 }
815 819
816 save_flags(flags); cli(); 820 spin_lock_irqsave(&riscom_lock, flags);
817 821
818 if (port->tty) 822 if (port->tty)
819 clear_bit(TTY_IO_ERROR, &port->tty->flags); 823 clear_bit(TTY_IO_ERROR, &port->tty->flags);
820 824
@@ -825,7 +829,7 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
825 rc_change_speed(bp, port); 829 rc_change_speed(bp, port);
826 port->flags |= ASYNC_INITIALIZED; 830 port->flags |= ASYNC_INITIALIZED;
827 831
828 restore_flags(flags); 832 spin_unlock_irqrestore(&riscom_lock, flags);
829 return 0; 833 return 0;
830} 834}
831 835
@@ -901,6 +905,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
901 int retval; 905 int retval;
902 int do_clocal = 0; 906 int do_clocal = 0;
903 int CD; 907 int CD;
908 unsigned long flags;
904 909
905 /* 910 /*
906 * If the device is in the middle of being closed, then block 911 * If the device is in the middle of being closed, then block
@@ -936,19 +941,26 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
936 */ 941 */
937 retval = 0; 942 retval = 0;
938 add_wait_queue(&port->open_wait, &wait); 943 add_wait_queue(&port->open_wait, &wait);
939 cli(); 944
945 spin_lock_irqsave(&riscom_lock, flags);
946
940 if (!tty_hung_up_p(filp)) 947 if (!tty_hung_up_p(filp))
941 port->count--; 948 port->count--;
942 sti(); 949
950 spin_unlock_irqrestore(&riscom_lock, flags);
951
943 port->blocked_open++; 952 port->blocked_open++;
944 while (1) { 953 while (1) {
945 cli(); 954 spin_lock_irqsave(&riscom_lock, flags);
955
946 rc_out(bp, CD180_CAR, port_No(port)); 956 rc_out(bp, CD180_CAR, port_No(port));
947 CD = rc_in(bp, CD180_MSVR) & MSVR_CD; 957 CD = rc_in(bp, CD180_MSVR) & MSVR_CD;
948 rc_out(bp, CD180_MSVR, MSVR_RTS); 958 rc_out(bp, CD180_MSVR, MSVR_RTS);
949 bp->DTR &= ~(1u << port_No(port)); 959 bp->DTR &= ~(1u << port_No(port));
950 rc_out(bp, RC_DTR, bp->DTR); 960 rc_out(bp, RC_DTR, bp->DTR);
951 sti(); 961
962 spin_unlock_irqrestore(&riscom_lock, flags);
963
952 set_current_state(TASK_INTERRUPTIBLE); 964 set_current_state(TASK_INTERRUPTIBLE);
953 if (tty_hung_up_p(filp) || 965 if (tty_hung_up_p(filp) ||
954 !(port->flags & ASYNC_INITIALIZED)) { 966 !(port->flags & ASYNC_INITIALIZED)) {
@@ -1020,8 +1032,9 @@ static void rc_close(struct tty_struct * tty, struct file * filp)
1020 1032
1021 if (!port || rc_paranoia_check(port, tty->name, "close")) 1033 if (!port || rc_paranoia_check(port, tty->name, "close"))
1022 return; 1034 return;
1023 1035
1024 save_flags(flags); cli(); 1036 spin_lock_irqsave(&riscom_lock, flags);
1037
1025 if (tty_hung_up_p(filp)) 1038 if (tty_hung_up_p(filp))
1026 goto out; 1039 goto out;
1027 1040
@@ -1088,7 +1101,9 @@ static void rc_close(struct tty_struct * tty, struct file * filp)
1088 } 1101 }
1089 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 1102 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1090 wake_up_interruptible(&port->close_wait); 1103 wake_up_interruptible(&port->close_wait);
1091out: restore_flags(flags); 1104
1105out:
1106 spin_unlock_irqrestore(&riscom_lock, flags);
1092} 1107}
1093 1108
1094static int rc_write(struct tty_struct * tty, 1109static int rc_write(struct tty_struct * tty,
@@ -1107,34 +1122,33 @@ static int rc_write(struct tty_struct * tty,
1107 if (!tty || !port->xmit_buf) 1122 if (!tty || !port->xmit_buf)
1108 return 0; 1123 return 0;
1109 1124
1110 save_flags(flags);
1111 while (1) { 1125 while (1) {
1112 cli(); 1126 spin_lock_irqsave(&riscom_lock, flags);
1127
1113 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, 1128 c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
1114 SERIAL_XMIT_SIZE - port->xmit_head)); 1129 SERIAL_XMIT_SIZE - port->xmit_head));
1115 if (c <= 0) { 1130 if (c <= 0)
1116 restore_flags(flags); 1131 break; /* lock continues to be held */
1117 break;
1118 }
1119 1132
1120 memcpy(port->xmit_buf + port->xmit_head, buf, c); 1133 memcpy(port->xmit_buf + port->xmit_head, buf, c);
1121 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); 1134 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1122 port->xmit_cnt += c; 1135 port->xmit_cnt += c;
1123 restore_flags(flags); 1136
1137 spin_unlock_irqrestore(&riscom_lock, flags);
1124 1138
1125 buf += c; 1139 buf += c;
1126 count -= c; 1140 count -= c;
1127 total += c; 1141 total += c;
1128 } 1142 }
1129 1143
1130 cli();
1131 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped && 1144 if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
1132 !(port->IER & IER_TXRDY)) { 1145 !(port->IER & IER_TXRDY)) {
1133 port->IER |= IER_TXRDY; 1146 port->IER |= IER_TXRDY;
1134 rc_out(bp, CD180_CAR, port_No(port)); 1147 rc_out(bp, CD180_CAR, port_No(port));
1135 rc_out(bp, CD180_IER, port->IER); 1148 rc_out(bp, CD180_IER, port->IER);
1136 } 1149 }
1137 restore_flags(flags); 1150
1151 spin_unlock_irqrestore(&riscom_lock, flags);
1138 1152
1139 return total; 1153 return total;
1140} 1154}
@@ -1150,7 +1164,7 @@ static void rc_put_char(struct tty_struct * tty, unsigned char ch)
1150 if (!tty || !port->xmit_buf) 1164 if (!tty || !port->xmit_buf)
1151 return; 1165 return;
1152 1166
1153 save_flags(flags); cli(); 1167 spin_lock_irqsave(&riscom_lock, flags);
1154 1168
1155 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) 1169 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
1156 goto out; 1170 goto out;
@@ -1158,7 +1172,9 @@ static void rc_put_char(struct tty_struct * tty, unsigned char ch)
1158 port->xmit_buf[port->xmit_head++] = ch; 1172 port->xmit_buf[port->xmit_head++] = ch;
1159 port->xmit_head &= SERIAL_XMIT_SIZE - 1; 1173 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1160 port->xmit_cnt++; 1174 port->xmit_cnt++;
1161out: restore_flags(flags); 1175
1176out:
1177 spin_unlock_irqrestore(&riscom_lock, flags);
1162} 1178}
1163 1179
1164static void rc_flush_chars(struct tty_struct * tty) 1180static void rc_flush_chars(struct tty_struct * tty)
@@ -1173,11 +1189,13 @@ static void rc_flush_chars(struct tty_struct * tty)
1173 !port->xmit_buf) 1189 !port->xmit_buf)
1174 return; 1190 return;
1175 1191
1176 save_flags(flags); cli(); 1192 spin_lock_irqsave(&riscom_lock, flags);
1193
1177 port->IER |= IER_TXRDY; 1194 port->IER |= IER_TXRDY;
1178 rc_out(port_Board(port), CD180_CAR, port_No(port)); 1195 rc_out(port_Board(port), CD180_CAR, port_No(port));
1179 rc_out(port_Board(port), CD180_IER, port->IER); 1196 rc_out(port_Board(port), CD180_IER, port->IER);
1180 restore_flags(flags); 1197
1198 spin_unlock_irqrestore(&riscom_lock, flags);
1181} 1199}
1182 1200
1183static int rc_write_room(struct tty_struct * tty) 1201static int rc_write_room(struct tty_struct * tty)
@@ -1212,9 +1230,11 @@ static void rc_flush_buffer(struct tty_struct *tty)
1212 if (rc_paranoia_check(port, tty->name, "rc_flush_buffer")) 1230 if (rc_paranoia_check(port, tty->name, "rc_flush_buffer"))
1213 return; 1231 return;
1214 1232
1215 save_flags(flags); cli(); 1233 spin_lock_irqsave(&riscom_lock, flags);
1234
1216 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; 1235 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1217 restore_flags(flags); 1236
1237 spin_unlock_irqrestore(&riscom_lock, flags);
1218 1238
1219 tty_wakeup(tty); 1239 tty_wakeup(tty);
1220} 1240}
@@ -1231,11 +1251,15 @@ static int rc_tiocmget(struct tty_struct *tty, struct file *file)
1231 return -ENODEV; 1251 return -ENODEV;
1232 1252
1233 bp = port_Board(port); 1253 bp = port_Board(port);
1234 save_flags(flags); cli(); 1254
1255 spin_lock_irqsave(&riscom_lock, flags);
1256
1235 rc_out(bp, CD180_CAR, port_No(port)); 1257 rc_out(bp, CD180_CAR, port_No(port));
1236 status = rc_in(bp, CD180_MSVR); 1258 status = rc_in(bp, CD180_MSVR);
1237 result = rc_in(bp, RC_RI) & (1u << port_No(port)) ? 0 : TIOCM_RNG; 1259 result = rc_in(bp, RC_RI) & (1u << port_No(port)) ? 0 : TIOCM_RNG;
1238 restore_flags(flags); 1260
1261 spin_unlock_irqrestore(&riscom_lock, flags);
1262
1239 result |= ((status & MSVR_RTS) ? TIOCM_RTS : 0) 1263 result |= ((status & MSVR_RTS) ? TIOCM_RTS : 0)
1240 | ((status & MSVR_DTR) ? TIOCM_DTR : 0) 1264 | ((status & MSVR_DTR) ? TIOCM_DTR : 0)
1241 | ((status & MSVR_CD) ? TIOCM_CAR : 0) 1265 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
@@ -1256,7 +1280,8 @@ static int rc_tiocmset(struct tty_struct *tty, struct file *file,
1256 1280
1257 bp = port_Board(port); 1281 bp = port_Board(port);
1258 1282
1259 save_flags(flags); cli(); 1283 spin_lock_irqsave(&riscom_lock, flags);
1284
1260 if (set & TIOCM_RTS) 1285 if (set & TIOCM_RTS)
1261 port->MSVR |= MSVR_RTS; 1286 port->MSVR |= MSVR_RTS;
1262 if (set & TIOCM_DTR) 1287 if (set & TIOCM_DTR)
@@ -1270,7 +1295,9 @@ static int rc_tiocmset(struct tty_struct *tty, struct file *file,
1270 rc_out(bp, CD180_CAR, port_No(port)); 1295 rc_out(bp, CD180_CAR, port_No(port));
1271 rc_out(bp, CD180_MSVR, port->MSVR); 1296 rc_out(bp, CD180_MSVR, port->MSVR);
1272 rc_out(bp, RC_DTR, bp->DTR); 1297 rc_out(bp, RC_DTR, bp->DTR);
1273 restore_flags(flags); 1298
1299 spin_unlock_irqrestore(&riscom_lock, flags);
1300
1274 return 0; 1301 return 0;
1275} 1302}
1276 1303
@@ -1279,7 +1306,8 @@ static inline void rc_send_break(struct riscom_port * port, unsigned long length
1279 struct riscom_board *bp = port_Board(port); 1306 struct riscom_board *bp = port_Board(port);
1280 unsigned long flags; 1307 unsigned long flags;
1281 1308
1282 save_flags(flags); cli(); 1309 spin_lock_irqsave(&riscom_lock, flags);
1310
1283 port->break_length = RISCOM_TPS / HZ * length; 1311 port->break_length = RISCOM_TPS / HZ * length;
1284 port->COR2 |= COR2_ETC; 1312 port->COR2 |= COR2_ETC;
1285 port->IER |= IER_TXRDY; 1313 port->IER |= IER_TXRDY;
@@ -1289,7 +1317,8 @@ static inline void rc_send_break(struct riscom_port * port, unsigned long length
1289 rc_wait_CCR(bp); 1317 rc_wait_CCR(bp);
1290 rc_out(bp, CD180_CCR, CCR_CORCHG2); 1318 rc_out(bp, CD180_CCR, CCR_CORCHG2);
1291 rc_wait_CCR(bp); 1319 rc_wait_CCR(bp);
1292 restore_flags(flags); 1320
1321 spin_unlock_irqrestore(&riscom_lock, flags);
1293} 1322}
1294 1323
1295static inline int rc_set_serial_info(struct riscom_port * port, 1324static inline int rc_set_serial_info(struct riscom_port * port,
@@ -1298,7 +1327,6 @@ static inline int rc_set_serial_info(struct riscom_port * port,
1298 struct serial_struct tmp; 1327 struct serial_struct tmp;
1299 struct riscom_board *bp = port_Board(port); 1328 struct riscom_board *bp = port_Board(port);
1300 int change_speed; 1329 int change_speed;
1301 unsigned long flags;
1302 1330
1303 if (copy_from_user(&tmp, newinfo, sizeof(tmp))) 1331 if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
1304 return -EFAULT; 1332 return -EFAULT;
@@ -1332,9 +1360,11 @@ static inline int rc_set_serial_info(struct riscom_port * port,
1332 port->closing_wait = tmp.closing_wait; 1360 port->closing_wait = tmp.closing_wait;
1333 } 1361 }
1334 if (change_speed) { 1362 if (change_speed) {
1335 save_flags(flags); cli(); 1363 unsigned long flags;
1364
1365 spin_lock_irqsave(&riscom_lock, flags);
1336 rc_change_speed(bp, port); 1366 rc_change_speed(bp, port);
1337 restore_flags(flags); 1367 spin_unlock_irqrestore(&riscom_lock, flags);
1338 } 1368 }
1339 return 0; 1369 return 0;
1340} 1370}
@@ -1414,17 +1444,19 @@ static void rc_throttle(struct tty_struct * tty)
1414 return; 1444 return;
1415 1445
1416 bp = port_Board(port); 1446 bp = port_Board(port);
1417 1447
1418 save_flags(flags); cli(); 1448 spin_lock_irqsave(&riscom_lock, flags);
1449
1419 port->MSVR &= ~MSVR_RTS; 1450 port->MSVR &= ~MSVR_RTS;
1420 rc_out(bp, CD180_CAR, port_No(port)); 1451 rc_out(bp, CD180_CAR, port_No(port));
1421 if (I_IXOFF(tty)) { 1452 if (I_IXOFF(tty)) {
1422 rc_wait_CCR(bp); 1453 rc_wait_CCR(bp);
1423 rc_out(bp, CD180_CCR, CCR_SSCH2); 1454 rc_out(bp, CD180_CCR, CCR_SSCH2);
1424 rc_wait_CCR(bp); 1455 rc_wait_CCR(bp);
1425 } 1456 }
1426 rc_out(bp, CD180_MSVR, port->MSVR); 1457 rc_out(bp, CD180_MSVR, port->MSVR);
1427 restore_flags(flags); 1458
1459 spin_unlock_irqrestore(&riscom_lock, flags);
1428} 1460}
1429 1461
1430static void rc_unthrottle(struct tty_struct * tty) 1462static void rc_unthrottle(struct tty_struct * tty)
@@ -1438,7 +1470,8 @@ static void rc_unthrottle(struct tty_struct * tty)
1438 1470
1439 bp = port_Board(port); 1471 bp = port_Board(port);
1440 1472
1441 save_flags(flags); cli(); 1473 spin_lock_irqsave(&riscom_lock, flags);
1474
1442 port->MSVR |= MSVR_RTS; 1475 port->MSVR |= MSVR_RTS;
1443 rc_out(bp, CD180_CAR, port_No(port)); 1476 rc_out(bp, CD180_CAR, port_No(port));
1444 if (I_IXOFF(tty)) { 1477 if (I_IXOFF(tty)) {
@@ -1447,7 +1480,8 @@ static void rc_unthrottle(struct tty_struct * tty)
1447 rc_wait_CCR(bp); 1480 rc_wait_CCR(bp);
1448 } 1481 }
1449 rc_out(bp, CD180_MSVR, port->MSVR); 1482 rc_out(bp, CD180_MSVR, port->MSVR);
1450 restore_flags(flags); 1483
1484 spin_unlock_irqrestore(&riscom_lock, flags);
1451} 1485}
1452 1486
1453static void rc_stop(struct tty_struct * tty) 1487static void rc_stop(struct tty_struct * tty)
@@ -1461,11 +1495,13 @@ static void rc_stop(struct tty_struct * tty)
1461 1495
1462 bp = port_Board(port); 1496 bp = port_Board(port);
1463 1497
1464 save_flags(flags); cli(); 1498 spin_lock_irqsave(&riscom_lock, flags);
1499
1465 port->IER &= ~IER_TXRDY; 1500 port->IER &= ~IER_TXRDY;
1466 rc_out(bp, CD180_CAR, port_No(port)); 1501 rc_out(bp, CD180_CAR, port_No(port));
1467 rc_out(bp, CD180_IER, port->IER); 1502 rc_out(bp, CD180_IER, port->IER);
1468 restore_flags(flags); 1503
1504 spin_unlock_irqrestore(&riscom_lock, flags);
1469} 1505}
1470 1506
1471static void rc_start(struct tty_struct * tty) 1507static void rc_start(struct tty_struct * tty)
@@ -1479,13 +1515,15 @@ static void rc_start(struct tty_struct * tty)
1479 1515
1480 bp = port_Board(port); 1516 bp = port_Board(port);
1481 1517
1482 save_flags(flags); cli(); 1518 spin_lock_irqsave(&riscom_lock, flags);
1519
1483 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { 1520 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
1484 port->IER |= IER_TXRDY; 1521 port->IER |= IER_TXRDY;
1485 rc_out(bp, CD180_CAR, port_No(port)); 1522 rc_out(bp, CD180_CAR, port_No(port));
1486 rc_out(bp, CD180_IER, port->IER); 1523 rc_out(bp, CD180_IER, port->IER);
1487 } 1524 }
1488 restore_flags(flags); 1525
1526 spin_unlock_irqrestore(&riscom_lock, flags);
1489} 1527}
1490 1528
1491/* 1529/*
@@ -1537,9 +1575,9 @@ static void rc_set_termios(struct tty_struct * tty, struct ktermios * old_termio
1537 tty->termios->c_iflag == old_termios->c_iflag) 1575 tty->termios->c_iflag == old_termios->c_iflag)
1538 return; 1576 return;
1539 1577
1540 save_flags(flags); cli(); 1578 spin_lock_irqsave(&riscom_lock, flags);
1541 rc_change_speed(port_Board(port), port); 1579 rc_change_speed(port_Board(port), port);
1542 restore_flags(flags); 1580 spin_unlock_irqrestore(&riscom_lock, flags);
1543 1581
1544 if ((old_termios->c_cflag & CRTSCTS) && 1582 if ((old_termios->c_cflag & CRTSCTS) &&
1545 !(tty->termios->c_cflag & CRTSCTS)) { 1583 !(tty->termios->c_cflag & CRTSCTS)) {
@@ -1627,11 +1665,12 @@ static void rc_release_drivers(void)
1627{ 1665{
1628 unsigned long flags; 1666 unsigned long flags;
1629 1667
1630 save_flags(flags); 1668 spin_lock_irqsave(&riscom_lock, flags);
1631 cli(); 1669
1632 tty_unregister_driver(riscom_driver); 1670 tty_unregister_driver(riscom_driver);
1633 put_tty_driver(riscom_driver); 1671 put_tty_driver(riscom_driver);
1634 restore_flags(flags); 1672
1673 spin_unlock_irqrestore(&riscom_lock, flags);
1635} 1674}
1636 1675
1637#ifndef MODULE 1676#ifndef MODULE