aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/rocket.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/rocket.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/rocket.c')
-rw-r--r--drivers/char/rocket.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 584d791e84a6..4a4110e703a5 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -135,6 +135,7 @@ static int rcktpt_type[NUM_BOARDS];
135static int is_PCI[NUM_BOARDS]; 135static int is_PCI[NUM_BOARDS];
136static rocketModel_t rocketModel[NUM_BOARDS]; 136static rocketModel_t rocketModel[NUM_BOARDS];
137static int max_board; 137static int max_board;
138static const struct tty_port_operations rocket_port_ops;
138 139
139/* 140/*
140 * The following arrays define the interrupt bits corresponding to each AIOP. 141 * The following arrays define the interrupt bits corresponding to each AIOP.
@@ -649,9 +650,8 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
649 info->board = board; 650 info->board = board;
650 info->aiop = aiop; 651 info->aiop = aiop;
651 info->chan = chan; 652 info->chan = chan;
652 info->port.closing_wait = 3000; 653 tty_port_init(&info->port);
653 info->port.close_delay = 50; 654 info->port.ops = &rocket_port_ops;
654 init_waitqueue_head(&info->port.open_wait);
655 init_completion(&info->close_wait); 655 init_completion(&info->close_wait);
656 info->flags &= ~ROCKET_MODE_MASK; 656 info->flags &= ~ROCKET_MODE_MASK;
657 switch (pc104[board][line]) { 657 switch (pc104[board][line]) {
@@ -864,11 +864,18 @@ static void configure_r_port(struct r_port *info,
864 } 864 }
865} 865}
866 866
867static int carrier_raised(struct tty_port *port)
868{
869 struct r_port *info = container_of(port, struct r_port, port);
870 return (sGetChanStatusLo(&info->channel) & CD_ACT) ? 1 : 0;
871}
872
867/* info->port.count is considered critical, protected by spinlocks. */ 873/* info->port.count is considered critical, protected by spinlocks. */
868static int block_til_ready(struct tty_struct *tty, struct file *filp, 874static int block_til_ready(struct tty_struct *tty, struct file *filp,
869 struct r_port *info) 875 struct r_port *info)
870{ 876{
871 DECLARE_WAITQUEUE(wait, current); 877 DECLARE_WAITQUEUE(wait, current);
878 struct tty_port *port = &info->port;
872 int retval; 879 int retval;
873 int do_clocal = 0, extra_count = 0; 880 int do_clocal = 0, extra_count = 0;
874 unsigned long flags; 881 unsigned long flags;
@@ -898,13 +905,13 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
898 905
899 /* 906 /*
900 * Block waiting for the carrier detect and the line to become free. While we are in 907 * Block waiting for the carrier detect and the line to become free. While we are in
901 * this loop, info->port.count is dropped by one, so that rp_close() knows when to free things. 908 * this loop, port->count is dropped by one, so that rp_close() knows when to free things.
902 * We restore it upon exit, either normal or abnormal. 909 * We restore it upon exit, either normal or abnormal.
903 */ 910 */
904 retval = 0; 911 retval = 0;
905 add_wait_queue(&info->port.open_wait, &wait); 912 add_wait_queue(&port->open_wait, &wait);
906#ifdef ROCKET_DEBUG_OPEN 913#ifdef ROCKET_DEBUG_OPEN
907 printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, info->port.count); 914 printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, port->count);
908#endif 915#endif
909 spin_lock_irqsave(&info->slock, flags); 916 spin_lock_irqsave(&info->slock, flags);
910 917
@@ -913,10 +920,10 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
913#else 920#else
914 if (!tty_hung_up_p(filp)) { 921 if (!tty_hung_up_p(filp)) {
915 extra_count = 1; 922 extra_count = 1;
916 info->port.count--; 923 port->count--;
917 } 924 }
918#endif 925#endif
919 info->port.blocked_open++; 926 port->blocked_open++;
920 927
921 spin_unlock_irqrestore(&info->slock, flags); 928 spin_unlock_irqrestore(&info->slock, flags);
922 929
@@ -933,7 +940,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
933 retval = -ERESTARTSYS; 940 retval = -ERESTARTSYS;
934 break; 941 break;
935 } 942 }
936 if (!(info->flags & ROCKET_CLOSING) && (do_clocal || (sGetChanStatusLo(&info->channel) & CD_ACT))) 943 if (!(info->flags & ROCKET_CLOSING) &&
944 (do_clocal || tty_port_carrier_raised(port)))
937 break; 945 break;
938 if (signal_pending(current)) { 946 if (signal_pending(current)) {
939 retval = -ERESTARTSYS; 947 retval = -ERESTARTSYS;
@@ -941,24 +949,24 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
941 } 949 }
942#ifdef ROCKET_DEBUG_OPEN 950#ifdef ROCKET_DEBUG_OPEN
943 printk(KERN_INFO "block_til_ready blocking: ttyR%d, count = %d, flags=0x%0x\n", 951 printk(KERN_INFO "block_til_ready blocking: ttyR%d, count = %d, flags=0x%0x\n",
944 info->line, info->port.count, info->flags); 952 info->line, port->count, info->flags);
945#endif 953#endif
946 schedule(); /* Don't hold spinlock here, will hang PC */ 954 schedule(); /* Don't hold spinlock here, will hang PC */
947 } 955 }
948 __set_current_state(TASK_RUNNING); 956 __set_current_state(TASK_RUNNING);
949 remove_wait_queue(&info->port.open_wait, &wait); 957 remove_wait_queue(&port->open_wait, &wait);
950 958
951 spin_lock_irqsave(&info->slock, flags); 959 spin_lock_irqsave(&info->slock, flags);
952 960
953 if (extra_count) 961 if (extra_count)
954 info->port.count++; 962 port->count++;
955 info->port.blocked_open--; 963 port->blocked_open--;
956 964
957 spin_unlock_irqrestore(&info->slock, flags); 965 spin_unlock_irqrestore(&info->slock, flags);
958 966
959#ifdef ROCKET_DEBUG_OPEN 967#ifdef ROCKET_DEBUG_OPEN
960 printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n", 968 printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n",
961 info->line, info->port.count); 969 info->line, port->count);
962#endif 970#endif
963 if (retval) 971 if (retval)
964 return retval; 972 return retval;
@@ -2371,6 +2379,10 @@ static const struct tty_operations rocket_ops = {
2371 .tiocmset = rp_tiocmset, 2379 .tiocmset = rp_tiocmset,
2372}; 2380};
2373 2381
2382static const struct tty_port_operations rocket_port_ops = {
2383 .carrier_raised = carrier_raised,
2384};
2385
2374/* 2386/*
2375 * The module "startup" routine; it's run when the module is loaded. 2387 * The module "startup" routine; it's run when the module is loaded.
2376 */ 2388 */