diff options
Diffstat (limited to 'drivers/char/specialix.c')
-rw-r--r-- | drivers/char/specialix.c | 72 |
1 files changed, 4 insertions, 68 deletions
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 455855631aef..c0e08c7bca2f 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -178,9 +178,6 @@ static int sx_poll = HZ; | |||
178 | ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \ | 178 | ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \ |
179 | ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP) | 179 | ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP) |
180 | 180 | ||
181 | #undef RS_EVENT_WRITE_WAKEUP | ||
182 | #define RS_EVENT_WRITE_WAKEUP 0 | ||
183 | |||
184 | static struct tty_driver *specialix_driver; | 181 | static struct tty_driver *specialix_driver; |
185 | 182 | ||
186 | static struct specialix_board sx_board[SX_NBOARD] = { | 183 | static struct specialix_board sx_board[SX_NBOARD] = { |
@@ -602,17 +599,6 @@ static int sx_probe(struct specialix_board *bp) | |||
602 | * Interrupt processing routines. | 599 | * Interrupt processing routines. |
603 | * */ | 600 | * */ |
604 | 601 | ||
605 | static inline void sx_mark_event(struct specialix_port * port, int event) | ||
606 | { | ||
607 | func_enter(); | ||
608 | |||
609 | set_bit(event, &port->event); | ||
610 | schedule_work(&port->tqueue); | ||
611 | |||
612 | func_exit(); | ||
613 | } | ||
614 | |||
615 | |||
616 | static inline struct specialix_port * sx_get_port(struct specialix_board * bp, | 602 | static inline struct specialix_port * sx_get_port(struct specialix_board * bp, |
617 | unsigned char const * what) | 603 | unsigned char const * what) |
618 | { | 604 | { |
@@ -809,7 +795,7 @@ static inline void sx_transmit(struct specialix_board * bp) | |||
809 | sx_out(bp, CD186x_IER, port->IER); | 795 | sx_out(bp, CD186x_IER, port->IER); |
810 | } | 796 | } |
811 | if (port->xmit_cnt <= port->wakeup_chars) | 797 | if (port->xmit_cnt <= port->wakeup_chars) |
812 | sx_mark_event(port, RS_EVENT_WRITE_WAKEUP); | 798 | tty_wakeup(tty); |
813 | 799 | ||
814 | func_exit(); | 800 | func_exit(); |
815 | } | 801 | } |
@@ -839,7 +825,7 @@ static inline void sx_check_modem(struct specialix_board * bp) | |||
839 | wake_up_interruptible(&port->open_wait); | 825 | wake_up_interruptible(&port->open_wait); |
840 | } else { | 826 | } else { |
841 | dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n"); | 827 | dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n"); |
842 | schedule_work(&port->tqueue_hangup); | 828 | tty_hangup(tty); |
843 | } | 829 | } |
844 | } | 830 | } |
845 | 831 | ||
@@ -849,7 +835,7 @@ static inline void sx_check_modem(struct specialix_board * bp) | |||
849 | tty->hw_stopped = 0; | 835 | tty->hw_stopped = 0; |
850 | port->IER |= IER_TXRDY; | 836 | port->IER |= IER_TXRDY; |
851 | if (port->xmit_cnt <= port->wakeup_chars) | 837 | if (port->xmit_cnt <= port->wakeup_chars) |
852 | sx_mark_event(port, RS_EVENT_WRITE_WAKEUP); | 838 | tty_wakeup(tty); |
853 | } else { | 839 | } else { |
854 | tty->hw_stopped = 1; | 840 | tty->hw_stopped = 1; |
855 | port->IER &= ~IER_TXRDY; | 841 | port->IER &= ~IER_TXRDY; |
@@ -861,7 +847,7 @@ static inline void sx_check_modem(struct specialix_board * bp) | |||
861 | tty->hw_stopped = 0; | 847 | tty->hw_stopped = 0; |
862 | port->IER |= IER_TXRDY; | 848 | port->IER |= IER_TXRDY; |
863 | if (port->xmit_cnt <= port->wakeup_chars) | 849 | if (port->xmit_cnt <= port->wakeup_chars) |
864 | sx_mark_event(port, RS_EVENT_WRITE_WAKEUP); | 850 | tty_wakeup(tty); |
865 | } else { | 851 | } else { |
866 | tty->hw_stopped = 1; | 852 | tty->hw_stopped = 1; |
867 | port->IER &= ~IER_TXRDY; | 853 | port->IER &= ~IER_TXRDY; |
@@ -1618,7 +1604,6 @@ static void sx_close(struct tty_struct * tty, struct file * filp) | |||
1618 | tty_ldisc_flush(tty); | 1604 | tty_ldisc_flush(tty); |
1619 | spin_lock_irqsave(&port->lock, flags); | 1605 | spin_lock_irqsave(&port->lock, flags); |
1620 | tty->closing = 0; | 1606 | tty->closing = 0; |
1621 | port->event = 0; | ||
1622 | port->tty = NULL; | 1607 | port->tty = NULL; |
1623 | spin_unlock_irqrestore(&port->lock, flags); | 1608 | spin_unlock_irqrestore(&port->lock, flags); |
1624 | if (port->blocked_open) { | 1609 | if (port->blocked_open) { |
@@ -2235,32 +2220,6 @@ static void sx_start(struct tty_struct * tty) | |||
2235 | func_exit(); | 2220 | func_exit(); |
2236 | } | 2221 | } |
2237 | 2222 | ||
2238 | |||
2239 | /* | ||
2240 | * This routine is called from the work-queue when the interrupt | ||
2241 | * routine has signalled that a hangup has occurred. The path of | ||
2242 | * hangup processing is: | ||
2243 | * | ||
2244 | * serial interrupt routine -> (workqueue) -> | ||
2245 | * do_sx_hangup() -> tty->hangup() -> sx_hangup() | ||
2246 | * | ||
2247 | */ | ||
2248 | static void do_sx_hangup(struct work_struct *work) | ||
2249 | { | ||
2250 | struct specialix_port *port = | ||
2251 | container_of(work, struct specialix_port, tqueue_hangup); | ||
2252 | struct tty_struct *tty; | ||
2253 | |||
2254 | func_enter(); | ||
2255 | |||
2256 | tty = port->tty; | ||
2257 | if (tty) | ||
2258 | tty_hangup(tty); /* FIXME: module removal race here */ | ||
2259 | |||
2260 | func_exit(); | ||
2261 | } | ||
2262 | |||
2263 | |||
2264 | static void sx_hangup(struct tty_struct * tty) | 2223 | static void sx_hangup(struct tty_struct * tty) |
2265 | { | 2224 | { |
2266 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 2225 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
@@ -2278,7 +2237,6 @@ static void sx_hangup(struct tty_struct * tty) | |||
2278 | 2237 | ||
2279 | sx_shutdown_port(bp, port); | 2238 | sx_shutdown_port(bp, port); |
2280 | spin_lock_irqsave(&port->lock, flags); | 2239 | spin_lock_irqsave(&port->lock, flags); |
2281 | port->event = 0; | ||
2282 | bp->count -= port->count; | 2240 | bp->count -= port->count; |
2283 | if (bp->count < 0) { | 2241 | if (bp->count < 0) { |
2284 | printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n", | 2242 | printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n", |
@@ -2320,26 +2278,6 @@ static void sx_set_termios(struct tty_struct * tty, struct ktermios * old_termio | |||
2320 | } | 2278 | } |
2321 | } | 2279 | } |
2322 | 2280 | ||
2323 | |||
2324 | static void do_softint(struct work_struct *work) | ||
2325 | { | ||
2326 | struct specialix_port *port = | ||
2327 | container_of(work, struct specialix_port, tqueue); | ||
2328 | struct tty_struct *tty; | ||
2329 | |||
2330 | func_enter(); | ||
2331 | |||
2332 | if(!(tty = port->tty)) { | ||
2333 | func_exit(); | ||
2334 | return; | ||
2335 | } | ||
2336 | |||
2337 | if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) | ||
2338 | tty_wakeup(tty); | ||
2339 | |||
2340 | func_exit(); | ||
2341 | } | ||
2342 | |||
2343 | static const struct tty_operations sx_ops = { | 2281 | static const struct tty_operations sx_ops = { |
2344 | .open = sx_open, | 2282 | .open = sx_open, |
2345 | .close = sx_close, | 2283 | .close = sx_close, |
@@ -2397,8 +2335,6 @@ static int sx_init_drivers(void) | |||
2397 | memset(sx_port, 0, sizeof(sx_port)); | 2335 | memset(sx_port, 0, sizeof(sx_port)); |
2398 | for (i = 0; i < SX_NPORT * SX_NBOARD; i++) { | 2336 | for (i = 0; i < SX_NPORT * SX_NBOARD; i++) { |
2399 | sx_port[i].magic = SPECIALIX_MAGIC; | 2337 | sx_port[i].magic = SPECIALIX_MAGIC; |
2400 | INIT_WORK(&sx_port[i].tqueue, do_softint); | ||
2401 | INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup); | ||
2402 | sx_port[i].close_delay = 50 * HZ/100; | 2338 | sx_port[i].close_delay = 50 * HZ/100; |
2403 | sx_port[i].closing_wait = 3000 * HZ/100; | 2339 | sx_port[i].closing_wait = 3000 * HZ/100; |
2404 | init_waitqueue_head(&sx_port[i].open_wait); | 2340 | init_waitqueue_head(&sx_port[i].open_wait); |