aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/riscom8.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2009-01-02 08:45:05 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-02 13:19:38 -0500
commit31f35939d1d9bcfb3099b32c67b896d2792603f9 (patch)
tree39b6ceaf0e7477e0357ff8235814f579adad3f28 /drivers/char/riscom8.c
parentc9b3976e3fec266be25c5001a70aa0a890b6c476 (diff)
tty_port: Add a port level carrier detect operation
This is the first step to generalising the various pieces of waiting logic duplicated in all sorts of serial drivers. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/riscom8.c')
-rw-r--r--drivers/char/riscom8.c65
1 files changed, 40 insertions, 25 deletions
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 2c6c8f33d6b4..6ad1c2aa2a98 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -857,23 +857,40 @@ static void rc_shutdown_port(struct tty_struct *tty,
857 rc_shutdown_board(bp); 857 rc_shutdown_board(bp);
858} 858}
859 859
860static int carrier_raised(struct tty_port *port)
861{
862 struct riscom_port *p = container_of(port, struct riscom_port, port);
863 struct riscom_board *bp = port_Board(p);
864 unsigned long flags;
865 int CD;
866
867 spin_lock_irqsave(&riscom_lock, flags);
868 rc_out(bp, CD180_CAR, port_No(p));
869 CD = rc_in(bp, CD180_MSVR) & MSVR_CD;
870 rc_out(bp, CD180_MSVR, MSVR_RTS);
871 bp->DTR &= ~(1u << port_No(p));
872 rc_out(bp, RC_DTR, bp->DTR);
873 spin_unlock_irqrestore(&riscom_lock, flags);
874 return CD;
875}
876
860static int block_til_ready(struct tty_struct *tty, struct file *filp, 877static int block_til_ready(struct tty_struct *tty, struct file *filp,
861 struct riscom_port *port) 878 struct riscom_port *rp)
862{ 879{
863 DECLARE_WAITQUEUE(wait, current); 880 DECLARE_WAITQUEUE(wait, current);
864 struct riscom_board *bp = port_Board(port);
865 int retval; 881 int retval;
866 int do_clocal = 0; 882 int do_clocal = 0;
867 int CD; 883 int CD;
868 unsigned long flags; 884 unsigned long flags;
885 struct tty_port *port = &rp->port;
869 886
870 /* 887 /*
871 * If the device is in the middle of being closed, then block 888 * If the device is in the middle of being closed, then block
872 * until it's done, and then try again. 889 * until it's done, and then try again.
873 */ 890 */
874 if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) { 891 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
875 interruptible_sleep_on(&port->port.close_wait); 892 interruptible_sleep_on(&port->close_wait);
876 if (port->port.flags & ASYNC_HUP_NOTIFY) 893 if (port->flags & ASYNC_HUP_NOTIFY)
877 return -EAGAIN; 894 return -EAGAIN;
878 else 895 else
879 return -ERESTARTSYS; 896 return -ERESTARTSYS;
@@ -885,7 +902,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
885 */ 902 */
886 if ((filp->f_flags & O_NONBLOCK) || 903 if ((filp->f_flags & O_NONBLOCK) ||
887 (tty->flags & (1 << TTY_IO_ERROR))) { 904 (tty->flags & (1 << TTY_IO_ERROR))) {
888 port->port.flags |= ASYNC_NORMAL_ACTIVE; 905 port->flags |= ASYNC_NORMAL_ACTIVE;
889 return 0; 906 return 0;
890 } 907 }
891 908
@@ -900,37 +917,29 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
900 * exit, either normal or abnormal. 917 * exit, either normal or abnormal.
901 */ 918 */
902 retval = 0; 919 retval = 0;
903 add_wait_queue(&port->port.open_wait, &wait); 920 add_wait_queue(&port->open_wait, &wait);
904 921
905 spin_lock_irqsave(&riscom_lock, flags); 922 spin_lock_irqsave(&riscom_lock, flags);
906 923
907 if (!tty_hung_up_p(filp)) 924 if (!tty_hung_up_p(filp))
908 port->port.count--; 925 port->count--;
909 926
910 spin_unlock_irqrestore(&riscom_lock, flags); 927 spin_unlock_irqrestore(&riscom_lock, flags);
911 928
912 port->port.blocked_open++; 929 port->blocked_open++;
913 while (1) { 930 while (1) {
914 spin_lock_irqsave(&riscom_lock, flags);
915
916 rc_out(bp, CD180_CAR, port_No(port));
917 CD = rc_in(bp, CD180_MSVR) & MSVR_CD;
918 rc_out(bp, CD180_MSVR, MSVR_RTS);
919 bp->DTR &= ~(1u << port_No(port));
920 rc_out(bp, RC_DTR, bp->DTR);
921
922 spin_unlock_irqrestore(&riscom_lock, flags);
923 931
932 CD = tty_port_carrier_raised(port);
924 set_current_state(TASK_INTERRUPTIBLE); 933 set_current_state(TASK_INTERRUPTIBLE);
925 if (tty_hung_up_p(filp) || 934 if (tty_hung_up_p(filp) ||
926 !(port->port.flags & ASYNC_INITIALIZED)) { 935 !(port->flags & ASYNC_INITIALIZED)) {
927 if (port->port.flags & ASYNC_HUP_NOTIFY) 936 if (port->flags & ASYNC_HUP_NOTIFY)
928 retval = -EAGAIN; 937 retval = -EAGAIN;
929 else 938 else
930 retval = -ERESTARTSYS; 939 retval = -ERESTARTSYS;
931 break; 940 break;
932 } 941 }
933 if (!(port->port.flags & ASYNC_CLOSING) && 942 if (!(port->flags & ASYNC_CLOSING) &&
934 (do_clocal || CD)) 943 (do_clocal || CD))
935 break; 944 break;
936 if (signal_pending(current)) { 945 if (signal_pending(current)) {
@@ -940,14 +949,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
940 schedule(); 949 schedule();
941 } 950 }
942 __set_current_state(TASK_RUNNING); 951 __set_current_state(TASK_RUNNING);
943 remove_wait_queue(&port->port.open_wait, &wait); 952 remove_wait_queue(&port->open_wait, &wait);
944 if (!tty_hung_up_p(filp)) 953 if (!tty_hung_up_p(filp))
945 port->port.count++; 954 port->count++;
946 port->port.blocked_open--; 955 port->blocked_open--;
947 if (retval) 956 if (retval)
948 return retval; 957 return retval;
949 958
950 port->port.flags |= ASYNC_NORMAL_ACTIVE; 959 port->flags |= ASYNC_NORMAL_ACTIVE;
951 return 0; 960 return 0;
952} 961}
953 962
@@ -1510,6 +1519,11 @@ static const struct tty_operations riscom_ops = {
1510 .break_ctl = rc_send_break, 1519 .break_ctl = rc_send_break,
1511}; 1520};
1512 1521
1522static const struct tty_port_operations riscom_port_ops = {
1523 .carrier_raised = carrier_raised,
1524};
1525
1526
1513static int __init rc_init_drivers(void) 1527static int __init rc_init_drivers(void)
1514{ 1528{
1515 int error; 1529 int error;
@@ -1541,6 +1555,7 @@ static int __init rc_init_drivers(void)
1541 memset(rc_port, 0, sizeof(rc_port)); 1555 memset(rc_port, 0, sizeof(rc_port));
1542 for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { 1556 for (i = 0; i < RC_NPORT * RC_NBOARD; i++) {
1543 tty_port_init(&rc_port[i].port); 1557 tty_port_init(&rc_port[i].port);
1558 rc_port[i].port.ops = &riscom_port_ops;
1544 rc_port[i].magic = RISCOM8_MAGIC; 1559 rc_port[i].magic = RISCOM8_MAGIC;
1545 } 1560 }
1546 return 0; 1561 return 0;