aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/riscom8.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/riscom8.c')
-rw-r--r--drivers/char/riscom8.c164
1 files changed, 78 insertions, 86 deletions
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 171711acf5cd..3cfa22d469e0 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -343,7 +343,7 @@ static void rc_receive_exc(struct riscom_board const *bp)
343 if (port == NULL) 343 if (port == NULL)
344 return; 344 return;
345 345
346 tty = port->port.tty; 346 tty = tty_port_tty_get(&port->port);
347 347
348#ifdef RC_REPORT_OVERRUN 348#ifdef RC_REPORT_OVERRUN
349 status = rc_in(bp, CD180_RCSR); 349 status = rc_in(bp, CD180_RCSR);
@@ -355,18 +355,18 @@ static void rc_receive_exc(struct riscom_board const *bp)
355#endif 355#endif
356 ch = rc_in(bp, CD180_RDR); 356 ch = rc_in(bp, CD180_RDR);
357 if (!status) 357 if (!status)
358 return; 358 goto out;
359 if (status & RCSR_TOUT) { 359 if (status & RCSR_TOUT) {
360 printk(KERN_WARNING "rc%d: port %d: Receiver timeout. " 360 printk(KERN_WARNING "rc%d: port %d: Receiver timeout. "
361 "Hardware problems ?\n", 361 "Hardware problems ?\n",
362 board_No(bp), port_No(port)); 362 board_No(bp), port_No(port));
363 return; 363 goto out;
364 364
365 } else if (status & RCSR_BREAK) { 365 } else if (status & RCSR_BREAK) {
366 printk(KERN_INFO "rc%d: port %d: Handling break...\n", 366 printk(KERN_INFO "rc%d: port %d: Handling break...\n",
367 board_No(bp), port_No(port)); 367 board_No(bp), port_No(port));
368 flag = TTY_BREAK; 368 flag = TTY_BREAK;
369 if (port->port.flags & ASYNC_SAK) 369 if (tty && (port->port.flags & ASYNC_SAK))
370 do_SAK(tty); 370 do_SAK(tty);
371 371
372 } else if (status & RCSR_PE) 372 } else if (status & RCSR_PE)
@@ -380,8 +380,12 @@ static void rc_receive_exc(struct riscom_board const *bp)
380 else 380 else
381 flag = TTY_NORMAL; 381 flag = TTY_NORMAL;
382 382
383 tty_insert_flip_char(tty, ch, flag); 383 if (tty) {
384 tty_flip_buffer_push(tty); 384 tty_insert_flip_char(tty, ch, flag);
385 tty_flip_buffer_push(tty);
386 }
387out:
388 tty_kref_put(tty);
385} 389}
386 390
387static void rc_receive(struct riscom_board const *bp) 391static void rc_receive(struct riscom_board const *bp)
@@ -394,7 +398,7 @@ static void rc_receive(struct riscom_board const *bp)
394 if (port == NULL) 398 if (port == NULL)
395 return; 399 return;
396 400
397 tty = port->port.tty; 401 tty = tty_port_tty_get(&port->port);
398 402
399 count = rc_in(bp, CD180_RDCR); 403 count = rc_in(bp, CD180_RDCR);
400 404
@@ -403,15 +407,14 @@ static void rc_receive(struct riscom_board const *bp)
403#endif 407#endif
404 408
405 while (count--) { 409 while (count--) {
406 if (tty_buffer_request_room(tty, 1) == 0) { 410 u8 ch = rc_in(bp, CD180_RDR);
407 printk(KERN_WARNING "rc%d: port %d: Working around " 411 if (tty)
408 "flip buffer overflow.\n", 412 tty_insert_flip_char(tty, ch, TTY_NORMAL);
409 board_No(bp), port_No(port)); 413 }
410 break; 414 if (tty) {
411 } 415 tty_flip_buffer_push(tty);
412 tty_insert_flip_char(tty, rc_in(bp, CD180_RDR), TTY_NORMAL); 416 tty_kref_put(tty);
413 } 417 }
414 tty_flip_buffer_push(tty);
415} 418}
416 419
417static void rc_transmit(struct riscom_board const *bp) 420static void rc_transmit(struct riscom_board const *bp)
@@ -424,22 +427,22 @@ static void rc_transmit(struct riscom_board const *bp)
424 if (port == NULL) 427 if (port == NULL)
425 return; 428 return;
426 429
427 tty = port->port.tty; 430 tty = tty_port_tty_get(&port->port);
428 431
429 if (port->IER & IER_TXEMPTY) { 432 if (port->IER & IER_TXEMPTY) {
430 /* FIFO drained */ 433 /* FIFO drained */
431 rc_out(bp, CD180_CAR, port_No(port)); 434 rc_out(bp, CD180_CAR, port_No(port));
432 port->IER &= ~IER_TXEMPTY; 435 port->IER &= ~IER_TXEMPTY;
433 rc_out(bp, CD180_IER, port->IER); 436 rc_out(bp, CD180_IER, port->IER);
434 return; 437 goto out;
435 } 438 }
436 439
437 if ((port->xmit_cnt <= 0 && !port->break_length) 440 if ((port->xmit_cnt <= 0 && !port->break_length)
438 || tty->stopped || tty->hw_stopped) { 441 || (tty && (tty->stopped || tty->hw_stopped))) {
439 rc_out(bp, CD180_CAR, port_No(port)); 442 rc_out(bp, CD180_CAR, port_No(port));
440 port->IER &= ~IER_TXRDY; 443 port->IER &= ~IER_TXRDY;
441 rc_out(bp, CD180_IER, port->IER); 444 rc_out(bp, CD180_IER, port->IER);
442 return; 445 goto out;
443 } 446 }
444 447
445 if (port->break_length) { 448 if (port->break_length) {
@@ -464,7 +467,7 @@ static void rc_transmit(struct riscom_board const *bp)
464 rc_out(bp, CD180_CCR, CCR_CORCHG2); 467 rc_out(bp, CD180_CCR, CCR_CORCHG2);
465 port->break_length = 0; 468 port->break_length = 0;
466 } 469 }
467 return; 470 goto out;
468 } 471 }
469 472
470 count = CD180_NFIFO; 473 count = CD180_NFIFO;
@@ -480,8 +483,10 @@ static void rc_transmit(struct riscom_board const *bp)
480 port->IER &= ~IER_TXRDY; 483 port->IER &= ~IER_TXRDY;
481 rc_out(bp, CD180_IER, port->IER); 484 rc_out(bp, CD180_IER, port->IER);
482 } 485 }
483 if (port->xmit_cnt <= port->wakeup_chars) 486 if (tty && port->xmit_cnt <= port->wakeup_chars)
484 tty_wakeup(tty); 487 tty_wakeup(tty);
488out:
489 tty_kref_put(tty);
485} 490}
486 491
487static void rc_check_modem(struct riscom_board const *bp) 492static void rc_check_modem(struct riscom_board const *bp)
@@ -494,37 +499,43 @@ static void rc_check_modem(struct riscom_board const *bp)
494 if (port == NULL) 499 if (port == NULL)
495 return; 500 return;
496 501
497 tty = port->port.tty; 502 tty = tty_port_tty_get(&port->port);
498 503
499 mcr = rc_in(bp, CD180_MCR); 504 mcr = rc_in(bp, CD180_MCR);
500 if (mcr & MCR_CDCHG) { 505 if (mcr & MCR_CDCHG) {
501 if (rc_in(bp, CD180_MSVR) & MSVR_CD) 506 if (rc_in(bp, CD180_MSVR) & MSVR_CD)
502 wake_up_interruptible(&port->port.open_wait); 507 wake_up_interruptible(&port->port.open_wait);
503 else 508 else if (tty)
504 tty_hangup(tty); 509 tty_hangup(tty);
505 } 510 }
506 511
507#ifdef RISCOM_BRAIN_DAMAGED_CTS 512#ifdef RISCOM_BRAIN_DAMAGED_CTS
508 if (mcr & MCR_CTSCHG) { 513 if (mcr & MCR_CTSCHG) {
509 if (rc_in(bp, CD180_MSVR) & MSVR_CTS) { 514 if (rc_in(bp, CD180_MSVR) & MSVR_CTS) {
510 tty->hw_stopped = 0;
511 port->IER |= IER_TXRDY; 515 port->IER |= IER_TXRDY;
512 if (port->xmit_cnt <= port->wakeup_chars) 516 if (tty) {
513 tty_wakeup(tty); 517 tty->hw_stopped = 0;
518 if (port->xmit_cnt <= port->wakeup_chars)
519 tty_wakeup(tty);
520 }
514 } else { 521 } else {
515 tty->hw_stopped = 1; 522 if (tty)
523 tty->hw_stopped = 1;
516 port->IER &= ~IER_TXRDY; 524 port->IER &= ~IER_TXRDY;
517 } 525 }
518 rc_out(bp, CD180_IER, port->IER); 526 rc_out(bp, CD180_IER, port->IER);
519 } 527 }
520 if (mcr & MCR_DSRCHG) { 528 if (mcr & MCR_DSRCHG) {
521 if (rc_in(bp, CD180_MSVR) & MSVR_DSR) { 529 if (rc_in(bp, CD180_MSVR) & MSVR_DSR) {
522 tty->hw_stopped = 0;
523 port->IER |= IER_TXRDY; 530 port->IER |= IER_TXRDY;
524 if (port->xmit_cnt <= port->wakeup_chars) 531 if (tty) {
525 tty_wakeup(tty); 532 tty->hw_stopped = 0;
533 if (port->xmit_cnt <= port->wakeup_chars)
534 tty_wakeup(tty);
535 }
526 } else { 536 } else {
527 tty->hw_stopped = 1; 537 if (tty)
538 tty->hw_stopped = 1;
528 port->IER &= ~IER_TXRDY; 539 port->IER &= ~IER_TXRDY;
529 } 540 }
530 rc_out(bp, CD180_IER, port->IER); 541 rc_out(bp, CD180_IER, port->IER);
@@ -533,6 +544,7 @@ static void rc_check_modem(struct riscom_board const *bp)
533 544
534 /* Clear change bits */ 545 /* Clear change bits */
535 rc_out(bp, CD180_MCR, 0); 546 rc_out(bp, CD180_MCR, 0);
547 tty_kref_put(tty);
536} 548}
537 549
538/* The main interrupt processing routine */ 550/* The main interrupt processing routine */
@@ -632,9 +644,9 @@ static void rc_shutdown_board(struct riscom_board *bp)
632 * Setting up port characteristics. 644 * Setting up port characteristics.
633 * Must be called with disabled interrupts 645 * Must be called with disabled interrupts
634 */ 646 */
635static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port) 647static void rc_change_speed(struct tty_struct *tty, struct riscom_board *bp,
648 struct riscom_port *port)
636{ 649{
637 struct tty_struct *tty = port->port.tty;
638 unsigned long baud; 650 unsigned long baud;
639 long tmp; 651 long tmp;
640 unsigned char cor1 = 0, cor3 = 0; 652 unsigned char cor1 = 0, cor3 = 0;
@@ -781,7 +793,8 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
781} 793}
782 794
783/* Must be called with interrupts enabled */ 795/* Must be called with interrupts enabled */
784static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port) 796static int rc_setup_port(struct tty_struct *tty, struct riscom_board *bp,
797 struct riscom_port *port)
785{ 798{
786 unsigned long flags; 799 unsigned long flags;
787 800
@@ -793,11 +806,11 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
793 806
794 spin_lock_irqsave(&riscom_lock, flags); 807 spin_lock_irqsave(&riscom_lock, flags);
795 808
796 clear_bit(TTY_IO_ERROR, &port->port.tty->flags); 809 clear_bit(TTY_IO_ERROR, &tty->flags);
797 if (port->port.count == 1) 810 if (port->port.count == 1)
798 bp->count++; 811 bp->count++;
799 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; 812 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
800 rc_change_speed(bp, port); 813 rc_change_speed(tty, bp, port);
801 port->port.flags |= ASYNC_INITIALIZED; 814 port->port.flags |= ASYNC_INITIALIZED;
802 815
803 spin_unlock_irqrestore(&riscom_lock, flags); 816 spin_unlock_irqrestore(&riscom_lock, flags);
@@ -898,9 +911,9 @@ static int rc_open(struct tty_struct *tty, struct file *filp)
898 911
899 port->port.count++; 912 port->port.count++;
900 tty->driver_data = port; 913 tty->driver_data = port;
901 port->port.tty = tty; 914 tty_port_tty_set(&port->port, tty);
902 915
903 error = rc_setup_port(bp, port); 916 error = rc_setup_port(tty, bp, port);
904 if (error == 0) 917 if (error == 0)
905 error = tty_port_block_til_ready(&port->port, tty, filp); 918 error = tty_port_block_til_ready(&port->port, tty, filp);
906 return error; 919 return error;
@@ -921,20 +934,12 @@ static void rc_flush_buffer(struct tty_struct *tty)
921 tty_wakeup(tty); 934 tty_wakeup(tty);
922} 935}
923 936
924static void rc_close(struct tty_struct *tty, struct file *filp) 937static void rc_close_port(struct tty_port *port)
925{ 938{
926 struct riscom_port *port = tty->driver_data;
927 struct riscom_board *bp;
928 unsigned long flags; 939 unsigned long flags;
940 struct riscom_port *rp = container_of(port, struct riscom_port, port);
941 struct riscom_board *bp = port_Board(rp);
929 unsigned long timeout; 942 unsigned long timeout;
930
931 if (!port || rc_paranoia_check(port, tty->name, "close"))
932 return;
933
934 bp = port_Board(port);
935
936 if (tty_port_close_start(&port->port, tty, filp) == 0)
937 return;
938 943
939 /* 944 /*
940 * At this point we stop accepting input. To do this, we 945 * At this point we stop accepting input. To do this, we
@@ -944,31 +949,37 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
944 */ 949 */
945 950
946 spin_lock_irqsave(&riscom_lock, flags); 951 spin_lock_irqsave(&riscom_lock, flags);
947 port->IER &= ~IER_RXD; 952 rp->IER &= ~IER_RXD;
948 if (port->port.flags & ASYNC_INITIALIZED) { 953 if (port->flags & ASYNC_INITIALIZED) {
949 port->IER &= ~IER_TXRDY; 954 rp->IER &= ~IER_TXRDY;
950 port->IER |= IER_TXEMPTY; 955 rp->IER |= IER_TXEMPTY;
951 rc_out(bp, CD180_CAR, port_No(port)); 956 rc_out(bp, CD180_CAR, port_No(rp));
952 rc_out(bp, CD180_IER, port->IER); 957 rc_out(bp, CD180_IER, rp->IER);
953 /* 958 /*
954 * Before we drop DTR, make sure the UART transmitter 959 * Before we drop DTR, make sure the UART transmitter
955 * has completely drained; this is especially 960 * has completely drained; this is especially
956 * important if there is a transmit FIFO! 961 * important if there is a transmit FIFO!
957 */ 962 */
958 timeout = jiffies + HZ; 963 timeout = jiffies + HZ;
959 while (port->IER & IER_TXEMPTY) { 964 while (rp->IER & IER_TXEMPTY) {
960 spin_unlock_irqrestore(&riscom_lock, flags); 965 spin_unlock_irqrestore(&riscom_lock, flags);
961 msleep_interruptible(jiffies_to_msecs(port->timeout)); 966 msleep_interruptible(jiffies_to_msecs(rp->timeout));
962 spin_lock_irqsave(&riscom_lock, flags); 967 spin_lock_irqsave(&riscom_lock, flags);
963 if (time_after(jiffies, timeout)) 968 if (time_after(jiffies, timeout))
964 break; 969 break;
965 } 970 }
966 } 971 }
967 rc_shutdown_port(tty, bp, port); 972 rc_shutdown_port(port->tty, bp, rp);
968 rc_flush_buffer(tty);
969 spin_unlock_irqrestore(&riscom_lock, flags); 973 spin_unlock_irqrestore(&riscom_lock, flags);
974}
975
976static void rc_close(struct tty_struct *tty, struct file *filp)
977{
978 struct riscom_port *port = tty->driver_data;
970 979
971 tty_port_close_end(&port->port, tty); 980 if (!port || rc_paranoia_check(port, tty->name, "close"))
981 return;
982 tty_port_close(&port->port, tty, filp);
972} 983}
973 984
974static int rc_write(struct tty_struct *tty, 985static int rc_write(struct tty_struct *tty,
@@ -1170,7 +1181,7 @@ static int rc_send_break(struct tty_struct *tty, int length)
1170 return 0; 1181 return 0;
1171} 1182}
1172 1183
1173static int rc_set_serial_info(struct riscom_port *port, 1184static int rc_set_serial_info(struct tty_struct *tty, struct riscom_port *port,
1174 struct serial_struct __user *newinfo) 1185 struct serial_struct __user *newinfo)
1175{ 1186{
1176 struct serial_struct tmp; 1187 struct serial_struct tmp;
@@ -1180,17 +1191,6 @@ static int rc_set_serial_info(struct riscom_port *port,
1180 if (copy_from_user(&tmp, newinfo, sizeof(tmp))) 1191 if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
1181 return -EFAULT; 1192 return -EFAULT;
1182 1193
1183#if 0
1184 if ((tmp.irq != bp->irq) ||
1185 (tmp.port != bp->base) ||
1186 (tmp.type != PORT_CIRRUS) ||
1187 (tmp.baud_base != (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC) ||
1188 (tmp.custom_divisor != 0) ||
1189 (tmp.xmit_fifo_size != CD180_NFIFO) ||
1190 (tmp.flags & ~RISCOM_LEGAL_FLAGS))
1191 return -EINVAL;
1192#endif
1193
1194 change_speed = ((port->port.flags & ASYNC_SPD_MASK) != 1194 change_speed = ((port->port.flags & ASYNC_SPD_MASK) !=
1195 (tmp.flags & ASYNC_SPD_MASK)); 1195 (tmp.flags & ASYNC_SPD_MASK));
1196 1196
@@ -1212,7 +1212,7 @@ static int rc_set_serial_info(struct riscom_port *port,
1212 unsigned long flags; 1212 unsigned long flags;
1213 1213
1214 spin_lock_irqsave(&riscom_lock, flags); 1214 spin_lock_irqsave(&riscom_lock, flags);
1215 rc_change_speed(bp, port); 1215 rc_change_speed(tty, bp, port);
1216 spin_unlock_irqrestore(&riscom_lock, flags); 1216 spin_unlock_irqrestore(&riscom_lock, flags);
1217 } 1217 }
1218 return 0; 1218 return 0;
@@ -1255,7 +1255,7 @@ static int rc_ioctl(struct tty_struct *tty, struct file *filp,
1255 break; 1255 break;
1256 case TIOCSSERIAL: 1256 case TIOCSSERIAL:
1257 lock_kernel(); 1257 lock_kernel();
1258 retval = rc_set_serial_info(port, argp); 1258 retval = rc_set_serial_info(tty, port, argp);
1259 unlock_kernel(); 1259 unlock_kernel();
1260 break; 1260 break;
1261 default: 1261 default:
@@ -1350,21 +1350,12 @@ static void rc_start(struct tty_struct *tty)
1350static void rc_hangup(struct tty_struct *tty) 1350static void rc_hangup(struct tty_struct *tty)
1351{ 1351{
1352 struct riscom_port *port = tty->driver_data; 1352 struct riscom_port *port = tty->driver_data;
1353 struct riscom_board *bp;
1354 unsigned long flags;
1355 1353
1356 if (rc_paranoia_check(port, tty->name, "rc_hangup")) 1354 if (rc_paranoia_check(port, tty->name, "rc_hangup"))
1357 return; 1355 return;
1358 1356
1359 bp = port_Board(port); 1357 rc_shutdown_port(tty, port_Board(port), port);
1360 1358 tty_port_hangup(&port->port);
1361 rc_shutdown_port(tty, bp, port);
1362 spin_lock_irqsave(&port->port.lock, flags);
1363 port->port.count = 0;
1364 port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1365 port->port.tty = NULL;
1366 wake_up_interruptible(&port->port.open_wait);
1367 spin_unlock_irqrestore(&port->port.lock, flags);
1368} 1359}
1369 1360
1370static void rc_set_termios(struct tty_struct *tty, 1361static void rc_set_termios(struct tty_struct *tty,
@@ -1377,7 +1368,7 @@ static void rc_set_termios(struct tty_struct *tty,
1377 return; 1368 return;
1378 1369
1379 spin_lock_irqsave(&riscom_lock, flags); 1370 spin_lock_irqsave(&riscom_lock, flags);
1380 rc_change_speed(port_Board(port), port); 1371 rc_change_speed(tty, port_Board(port), port);
1381 spin_unlock_irqrestore(&riscom_lock, flags); 1372 spin_unlock_irqrestore(&riscom_lock, flags);
1382 1373
1383 if ((old_termios->c_cflag & CRTSCTS) && 1374 if ((old_termios->c_cflag & CRTSCTS) &&
@@ -1410,6 +1401,7 @@ static const struct tty_operations riscom_ops = {
1410 1401
1411static const struct tty_port_operations riscom_port_ops = { 1402static const struct tty_port_operations riscom_port_ops = {
1412 .carrier_raised = carrier_raised, 1403 .carrier_raised = carrier_raised,
1404 .shutdown = rc_close_port,
1413}; 1405};
1414 1406
1415 1407