diff options
Diffstat (limited to 'drivers/char/riscom8.c')
-rw-r--r-- | drivers/char/riscom8.c | 89 |
1 files changed, 41 insertions, 48 deletions
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 3cfa22d469e0..0a8d1e56c993 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -793,26 +793,21 @@ static void rc_change_speed(struct tty_struct *tty, struct riscom_board *bp, | |||
793 | } | 793 | } |
794 | 794 | ||
795 | /* Must be called with interrupts enabled */ | 795 | /* Must be called with interrupts enabled */ |
796 | static int rc_setup_port(struct tty_struct *tty, struct riscom_board *bp, | 796 | static int rc_activate_port(struct tty_port *port, struct tty_struct *tty) |
797 | struct riscom_port *port) | ||
798 | { | 797 | { |
798 | struct riscom_port *rp = container_of(port, struct riscom_port, port); | ||
799 | struct riscom_board *bp = port_Board(rp); | ||
799 | unsigned long flags; | 800 | unsigned long flags; |
800 | 801 | ||
801 | if (port->port.flags & ASYNC_INITIALIZED) | 802 | if (tty_port_alloc_xmit_buf(port) < 0) |
802 | return 0; | ||
803 | |||
804 | if (tty_port_alloc_xmit_buf(&port->port) < 0) | ||
805 | return -ENOMEM; | 803 | return -ENOMEM; |
806 | 804 | ||
807 | spin_lock_irqsave(&riscom_lock, flags); | 805 | spin_lock_irqsave(&riscom_lock, flags); |
808 | 806 | ||
809 | clear_bit(TTY_IO_ERROR, &tty->flags); | 807 | clear_bit(TTY_IO_ERROR, &tty->flags); |
810 | if (port->port.count == 1) | 808 | bp->count++; |
811 | bp->count++; | 809 | rp->xmit_cnt = rp->xmit_head = rp->xmit_tail = 0; |
812 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | 810 | rc_change_speed(tty, bp, rp); |
813 | rc_change_speed(tty, bp, port); | ||
814 | port->port.flags |= ASYNC_INITIALIZED; | ||
815 | |||
816 | spin_unlock_irqrestore(&riscom_lock, flags); | 811 | spin_unlock_irqrestore(&riscom_lock, flags); |
817 | return 0; | 812 | return 0; |
818 | } | 813 | } |
@@ -821,9 +816,6 @@ static int rc_setup_port(struct tty_struct *tty, struct riscom_board *bp, | |||
821 | static void rc_shutdown_port(struct tty_struct *tty, | 816 | static void rc_shutdown_port(struct tty_struct *tty, |
822 | struct riscom_board *bp, struct riscom_port *port) | 817 | struct riscom_board *bp, struct riscom_port *port) |
823 | { | 818 | { |
824 | if (!(port->port.flags & ASYNC_INITIALIZED)) | ||
825 | return; | ||
826 | |||
827 | #ifdef RC_REPORT_OVERRUN | 819 | #ifdef RC_REPORT_OVERRUN |
828 | printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n", | 820 | printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n", |
829 | board_No(bp), port_No(port), port->overrun); | 821 | board_No(bp), port_No(port), port->overrun); |
@@ -840,11 +832,6 @@ static void rc_shutdown_port(struct tty_struct *tty, | |||
840 | } | 832 | } |
841 | #endif | 833 | #endif |
842 | tty_port_free_xmit_buf(&port->port); | 834 | tty_port_free_xmit_buf(&port->port); |
843 | if (C_HUPCL(tty)) { | ||
844 | /* Drop DTR */ | ||
845 | bp->DTR |= (1u << port_No(port)); | ||
846 | rc_out(bp, RC_DTR, bp->DTR); | ||
847 | } | ||
848 | 835 | ||
849 | /* Select port */ | 836 | /* Select port */ |
850 | rc_out(bp, CD180_CAR, port_No(port)); | 837 | rc_out(bp, CD180_CAR, port_No(port)); |
@@ -856,7 +843,6 @@ static void rc_shutdown_port(struct tty_struct *tty, | |||
856 | rc_out(bp, CD180_IER, port->IER); | 843 | rc_out(bp, CD180_IER, port->IER); |
857 | 844 | ||
858 | set_bit(TTY_IO_ERROR, &tty->flags); | 845 | set_bit(TTY_IO_ERROR, &tty->flags); |
859 | port->port.flags &= ~ASYNC_INITIALIZED; | ||
860 | 846 | ||
861 | if (--bp->count < 0) { | 847 | if (--bp->count < 0) { |
862 | printk(KERN_INFO "rc%d: rc_shutdown_port: " | 848 | printk(KERN_INFO "rc%d: rc_shutdown_port: " |
@@ -889,6 +875,20 @@ static int carrier_raised(struct tty_port *port) | |||
889 | return CD; | 875 | return CD; |
890 | } | 876 | } |
891 | 877 | ||
878 | static void dtr_rts(struct tty_port *port, int onoff) | ||
879 | { | ||
880 | struct riscom_port *p = container_of(port, struct riscom_port, port); | ||
881 | struct riscom_board *bp = port_Board(p); | ||
882 | unsigned long flags; | ||
883 | |||
884 | spin_lock_irqsave(&riscom_lock, flags); | ||
885 | bp->DTR &= ~(1u << port_No(p)); | ||
886 | if (onoff == 0) | ||
887 | bp->DTR |= (1u << port_No(p)); | ||
888 | rc_out(bp, RC_DTR, bp->DTR); | ||
889 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
890 | } | ||
891 | |||
892 | static int rc_open(struct tty_struct *tty, struct file *filp) | 892 | static int rc_open(struct tty_struct *tty, struct file *filp) |
893 | { | 893 | { |
894 | int board; | 894 | int board; |
@@ -909,14 +909,7 @@ static int rc_open(struct tty_struct *tty, struct file *filp) | |||
909 | if (error) | 909 | if (error) |
910 | return error; | 910 | return error; |
911 | 911 | ||
912 | port->port.count++; | 912 | return tty_port_open(&port->port, tty, filp); |
913 | tty->driver_data = port; | ||
914 | tty_port_tty_set(&port->port, tty); | ||
915 | |||
916 | error = rc_setup_port(tty, bp, port); | ||
917 | if (error == 0) | ||
918 | error = tty_port_block_til_ready(&port->port, tty, filp); | ||
919 | return error; | ||
920 | } | 913 | } |
921 | 914 | ||
922 | static void rc_flush_buffer(struct tty_struct *tty) | 915 | static void rc_flush_buffer(struct tty_struct *tty) |
@@ -950,24 +943,23 @@ static void rc_close_port(struct tty_port *port) | |||
950 | 943 | ||
951 | spin_lock_irqsave(&riscom_lock, flags); | 944 | spin_lock_irqsave(&riscom_lock, flags); |
952 | rp->IER &= ~IER_RXD; | 945 | rp->IER &= ~IER_RXD; |
953 | if (port->flags & ASYNC_INITIALIZED) { | 946 | |
954 | rp->IER &= ~IER_TXRDY; | 947 | rp->IER &= ~IER_TXRDY; |
955 | rp->IER |= IER_TXEMPTY; | 948 | rp->IER |= IER_TXEMPTY; |
956 | rc_out(bp, CD180_CAR, port_No(rp)); | 949 | rc_out(bp, CD180_CAR, port_No(rp)); |
957 | rc_out(bp, CD180_IER, rp->IER); | 950 | rc_out(bp, CD180_IER, rp->IER); |
958 | /* | 951 | /* |
959 | * Before we drop DTR, make sure the UART transmitter | 952 | * Before we drop DTR, make sure the UART transmitter |
960 | * has completely drained; this is especially | 953 | * has completely drained; this is especially |
961 | * important if there is a transmit FIFO! | 954 | * important if there is a transmit FIFO! |
962 | */ | 955 | */ |
963 | timeout = jiffies + HZ; | 956 | timeout = jiffies + HZ; |
964 | while (rp->IER & IER_TXEMPTY) { | 957 | while (rp->IER & IER_TXEMPTY) { |
965 | spin_unlock_irqrestore(&riscom_lock, flags); | 958 | spin_unlock_irqrestore(&riscom_lock, flags); |
966 | msleep_interruptible(jiffies_to_msecs(rp->timeout)); | 959 | msleep_interruptible(jiffies_to_msecs(rp->timeout)); |
967 | spin_lock_irqsave(&riscom_lock, flags); | 960 | spin_lock_irqsave(&riscom_lock, flags); |
968 | if (time_after(jiffies, timeout)) | 961 | if (time_after(jiffies, timeout)) |
969 | break; | 962 | break; |
970 | } | ||
971 | } | 963 | } |
972 | rc_shutdown_port(port->tty, bp, rp); | 964 | rc_shutdown_port(port->tty, bp, rp); |
973 | spin_unlock_irqrestore(&riscom_lock, flags); | 965 | spin_unlock_irqrestore(&riscom_lock, flags); |
@@ -1354,7 +1346,6 @@ static void rc_hangup(struct tty_struct *tty) | |||
1354 | if (rc_paranoia_check(port, tty->name, "rc_hangup")) | 1346 | if (rc_paranoia_check(port, tty->name, "rc_hangup")) |
1355 | return; | 1347 | return; |
1356 | 1348 | ||
1357 | rc_shutdown_port(tty, port_Board(port), port); | ||
1358 | tty_port_hangup(&port->port); | 1349 | tty_port_hangup(&port->port); |
1359 | } | 1350 | } |
1360 | 1351 | ||
@@ -1401,7 +1392,9 @@ static const struct tty_operations riscom_ops = { | |||
1401 | 1392 | ||
1402 | static const struct tty_port_operations riscom_port_ops = { | 1393 | static const struct tty_port_operations riscom_port_ops = { |
1403 | .carrier_raised = carrier_raised, | 1394 | .carrier_raised = carrier_raised, |
1395 | .dtr_rts = dtr_rts, | ||
1404 | .shutdown = rc_close_port, | 1396 | .shutdown = rc_close_port, |
1397 | .activate = rc_activate_port, | ||
1405 | }; | 1398 | }; |
1406 | 1399 | ||
1407 | 1400 | ||