Commit 3099bbc59435928fbd1f4ebd835f825bca755bbb
Committed by
Linus Torvalds
1 parent
ccfea3c98a
Char: serial167, remove bottomhalf
- Cy_EVENT_OPEN_WAKEUP is simple wake_up - Cy_EVENT_HANGUP is wake_up + tty_hangup, which schedules its own work - Cy_EVENT_WRITE_WAKEUP is tty_wakeup which may be called directly too Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Acked-by: Alan Cox <alan@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 8 additions and 82 deletions Side-by-side Diff
drivers/char/serial167.c
... | ... | @@ -357,18 +357,6 @@ |
357 | 357 | local_irq_restore(flags); |
358 | 358 | } /* cy_start */ |
359 | 359 | |
360 | -/* | |
361 | - * This routine is used by the interrupt handler to schedule | |
362 | - * processing in the software interrupt portion of the driver | |
363 | - * (also known as the "bottom half"). This can be called any | |
364 | - * number of times for any channel without harm. | |
365 | - */ | |
366 | -static inline void cy_sched_event(struct cyclades_port *info, int event) | |
367 | -{ | |
368 | - info->event |= 1 << event; /* remember what kind of event and who */ | |
369 | - schedule_work(&info->tqueue); | |
370 | -} /* cy_sched_event */ | |
371 | - | |
372 | 360 | /* The real interrupt service routines are called |
373 | 361 | whenever the card wants its hand held--chars |
374 | 362 | received, out buffer empty, modem change, etc. |
375 | 363 | |
... | ... | @@ -483,10 +471,12 @@ |
483 | 471 | && (info->flags & ASYNC_CHECK_CD)) { |
484 | 472 | if (mdm_status & CyDCD) { |
485 | 473 | /* CP('!'); */ |
486 | - cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP); | |
474 | + wake_up_interruptible(&info->open_wait); | |
487 | 475 | } else { |
488 | 476 | /* CP('@'); */ |
489 | - cy_sched_event(info, Cy_EVENT_HANGUP); | |
477 | + tty_hangup(info->tty); | |
478 | + wake_up_interruptible(&info->open_wait); | |
479 | + info->flags &= ~ASYNC_NORMAL_ACTIVE; | |
490 | 480 | } |
491 | 481 | } |
492 | 482 | if ((mdm_change & CyCTS) |
... | ... | @@ -496,8 +486,7 @@ |
496 | 486 | /* !!! cy_start isn't used because... */ |
497 | 487 | info->tty->stopped = 0; |
498 | 488 | base_addr[CyIER] |= CyTxMpty; |
499 | - cy_sched_event(info, | |
500 | - Cy_EVENT_WRITE_WAKEUP); | |
489 | + tty_wakeup(info->tty); | |
501 | 490 | } |
502 | 491 | } else { |
503 | 492 | if (!(mdm_status & CyCTS)) { |
... | ... | @@ -543,9 +532,6 @@ |
543 | 532 | info->last_active = jiffies; |
544 | 533 | if (info->tty == 0) { |
545 | 534 | base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); |
546 | - if (info->xmit_cnt < WAKEUP_CHARS) { | |
547 | - cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); | |
548 | - } | |
549 | 535 | base_addr[CyTEOIR] = CyNOTRANS; |
550 | 536 | return IRQ_HANDLED; |
551 | 537 | } |
... | ... | @@ -627,9 +613,9 @@ |
627 | 613 | } |
628 | 614 | } |
629 | 615 | |
630 | - if (info->xmit_cnt < WAKEUP_CHARS) { | |
631 | - cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); | |
632 | - } | |
616 | + if (info->xmit_cnt < WAKEUP_CHARS) | |
617 | + tty_wakeup(info->tty); | |
618 | + | |
633 | 619 | base_addr[CyTEOIR] = (char_count != saved_cnt) ? 0 : CyNOTRANS; |
634 | 620 | return IRQ_HANDLED; |
635 | 621 | } /* cy_tx_interrupt */ |
... | ... | @@ -690,49 +676,6 @@ |
690 | 676 | return IRQ_HANDLED; |
691 | 677 | } /* cy_rx_interrupt */ |
692 | 678 | |
693 | -/* | |
694 | - * This routine is used to handle the "bottom half" processing for the | |
695 | - * serial driver, known also the "software interrupt" processing. | |
696 | - * This processing is done at the kernel interrupt level, after the | |
697 | - * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This | |
698 | - * is where time-consuming activities which can not be done in the | |
699 | - * interrupt driver proper are done; the interrupt driver schedules | |
700 | - * them using cy_sched_event(), and they get done here. | |
701 | - * | |
702 | - * This is done through one level of indirection--the task queue. | |
703 | - * When a hardware interrupt service routine wants service by the | |
704 | - * driver's bottom half, it enqueues the appropriate tq_struct (one | |
705 | - * per port) to the keventd work queue and sets a request flag | |
706 | - * that the work queue be processed. | |
707 | - * | |
708 | - * Although this may seem unwieldy, it gives the system a way to | |
709 | - * pass an argument (in this case the pointer to the cyclades_port | |
710 | - * structure) to the bottom half of the driver. Previous kernels | |
711 | - * had to poll every port to see if that port needed servicing. | |
712 | - */ | |
713 | -static void do_softint(struct work_struct *ugly_api) | |
714 | -{ | |
715 | - struct cyclades_port *info = | |
716 | - container_of(ugly_api, struct cyclades_port, tqueue); | |
717 | - struct tty_struct *tty; | |
718 | - | |
719 | - tty = info->tty; | |
720 | - if (!tty) | |
721 | - return; | |
722 | - | |
723 | - if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) { | |
724 | - tty_hangup(info->tty); | |
725 | - wake_up_interruptible(&info->open_wait); | |
726 | - info->flags &= ~ASYNC_NORMAL_ACTIVE; | |
727 | - } | |
728 | - if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) { | |
729 | - wake_up_interruptible(&info->open_wait); | |
730 | - } | |
731 | - if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) { | |
732 | - tty_wakeup(tty); | |
733 | - } | |
734 | -} /* do_softint */ | |
735 | - | |
736 | 679 | /* This is called whenever a port becomes active; |
737 | 680 | interrupts are enabled and DTR & RTS are turned on. |
738 | 681 | */ |
... | ... | @@ -1743,7 +1686,6 @@ |
1743 | 1686 | if (tty->driver->flush_buffer) |
1744 | 1687 | tty->driver->flush_buffer(tty); |
1745 | 1688 | tty_ldisc_flush(tty); |
1746 | - info->event = 0; | |
1747 | 1689 | info->tty = NULL; |
1748 | 1690 | if (info->blocked_open) { |
1749 | 1691 | if (info->close_delay) { |
... | ... | @@ -2234,7 +2176,6 @@ |
2234 | 2176 | info->rco = baud_co[DefSpeed] >> 5; /* Rx CO */ |
2235 | 2177 | info->close_delay = 0; |
2236 | 2178 | info->x_char = 0; |
2237 | - info->event = 0; | |
2238 | 2179 | info->count = 0; |
2239 | 2180 | #ifdef SERIAL_DEBUG_COUNT |
2240 | 2181 | printk("cyc: %d: setting count to 0\n", |
... | ... | @@ -2243,7 +2184,6 @@ |
2243 | 2184 | info->blocked_open = 0; |
2244 | 2185 | info->default_threshold = 0; |
2245 | 2186 | info->default_timeout = 0; |
2246 | - INIT_WORK(&info->tqueue, do_softint); | |
2247 | 2187 | init_waitqueue_head(&info->open_wait); |
2248 | 2188 | init_waitqueue_head(&info->close_wait); |
2249 | 2189 | /* info->session */ |
include/linux/serial167.h
... | ... | @@ -37,7 +37,6 @@ |
37 | 37 | int ignore_status_mask; |
38 | 38 | int close_delay; |
39 | 39 | int IER; /* Interrupt Enable Register */ |
40 | - unsigned long event; | |
41 | 40 | unsigned long last_active; |
42 | 41 | int count; /* # of fd on device */ |
43 | 42 | int x_char; /* to be pushed out ASAP */ |
... | ... | @@ -49,7 +48,6 @@ |
49 | 48 | int xmit_cnt; |
50 | 49 | int default_threshold; |
51 | 50 | int default_timeout; |
52 | - struct work_struct tqueue; | |
53 | 51 | wait_queue_head_t open_wait; |
54 | 52 | wait_queue_head_t close_wait; |
55 | 53 | struct cyclades_monitor mon; |
... | ... | @@ -66,18 +64,6 @@ |
66 | 64 | #define CYSETTIMEOUT 0x435907 |
67 | 65 | #define CYGETDEFTIMEOUT 0x435908 |
68 | 66 | #define CYSETDEFTIMEOUT 0x435909 |
69 | - | |
70 | -/* | |
71 | - * Events are used to schedule things to happen at timer-interrupt | |
72 | - * time, instead of at cy interrupt time. | |
73 | - */ | |
74 | -#define Cy_EVENT_READ_PROCESS 0 | |
75 | -#define Cy_EVENT_WRITE_WAKEUP 1 | |
76 | -#define Cy_EVENT_HANGUP 2 | |
77 | -#define Cy_EVENT_BREAK 3 | |
78 | -#define Cy_EVENT_OPEN_WAKEUP 4 | |
79 | - | |
80 | - | |
81 | 67 | |
82 | 68 | #define CyMaxChipsPerCard 1 |
83 | 69 |