diff options
author | Jiri Slaby <jirislaby@gmail.com> | 2008-02-07 03:16:39 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 11:42:34 -0500 |
commit | ccfea3c98a10b9d4d49b899616a06594ec976d7d (patch) | |
tree | cea834a683e572015a51dbf122603c20d040c1f7 /drivers/char | |
parent | d0d4e1c098754bfbb2aeb94333756d63d255688e (diff) |
Char: stallion, remove bottomhalf
- tty_hangup schedules a bottomhalf itself, tty_wakeup doesn't need it
- call the CD code (part of work handler previously) directly from the code
(it wakes somebody up or calls tty_hangup at worse)
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>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/stallion.c | 68 |
1 files changed, 24 insertions, 44 deletions
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 5050aa5533a2..feac54e32a12 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -145,8 +145,7 @@ static struct stlbrd *stl_brds[STL_MAXBRDS]; | |||
145 | */ | 145 | */ |
146 | #define ASYI_TXBUSY 1 | 146 | #define ASYI_TXBUSY 1 |
147 | #define ASYI_TXLOW 2 | 147 | #define ASYI_TXLOW 2 |
148 | #define ASYI_DCDCHANGE 3 | 148 | #define ASYI_TXFLOWED 3 |
149 | #define ASYI_TXFLOWED 4 | ||
150 | 149 | ||
151 | /* | 150 | /* |
152 | * Define an array of board names as printable strings. Handy for | 151 | * Define an array of board names as printable strings. Handy for |
@@ -610,6 +609,23 @@ static const struct file_operations stl_fsiomem = { | |||
610 | 609 | ||
611 | static struct class *stallion_class; | 610 | static struct class *stallion_class; |
612 | 611 | ||
612 | static void stl_cd_change(struct stlport *portp) | ||
613 | { | ||
614 | unsigned int oldsigs = portp->sigs; | ||
615 | |||
616 | if (!portp->tty) | ||
617 | return; | ||
618 | |||
619 | portp->sigs = stl_getsignals(portp); | ||
620 | |||
621 | if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0)) | ||
622 | wake_up_interruptible(&portp->open_wait); | ||
623 | |||
624 | if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) | ||
625 | if (portp->flags & ASYNC_CHECK_CD) | ||
626 | tty_hangup(portp->tty); | ||
627 | } | ||
628 | |||
613 | /* | 629 | /* |
614 | * Check for any arguments passed in on the module load command line. | 630 | * Check for any arguments passed in on the module load command line. |
615 | */ | 631 | */ |
@@ -1771,41 +1787,6 @@ static int stl_echpci64intr(struct stlbrd *brdp) | |||
1771 | /*****************************************************************************/ | 1787 | /*****************************************************************************/ |
1772 | 1788 | ||
1773 | /* | 1789 | /* |
1774 | * Service an off-level request for some channel. | ||
1775 | */ | ||
1776 | static void stl_offintr(struct work_struct *work) | ||
1777 | { | ||
1778 | struct stlport *portp = container_of(work, struct stlport, tqueue); | ||
1779 | struct tty_struct *tty; | ||
1780 | unsigned int oldsigs; | ||
1781 | |||
1782 | pr_debug("stl_offintr(portp=%p)\n", portp); | ||
1783 | |||
1784 | if (portp == NULL) | ||
1785 | return; | ||
1786 | |||
1787 | tty = portp->tty; | ||
1788 | if (tty == NULL) | ||
1789 | return; | ||
1790 | |||
1791 | if (test_bit(ASYI_TXLOW, &portp->istate)) | ||
1792 | tty_wakeup(tty); | ||
1793 | |||
1794 | if (test_bit(ASYI_DCDCHANGE, &portp->istate)) { | ||
1795 | clear_bit(ASYI_DCDCHANGE, &portp->istate); | ||
1796 | oldsigs = portp->sigs; | ||
1797 | portp->sigs = stl_getsignals(portp); | ||
1798 | if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0)) | ||
1799 | wake_up_interruptible(&portp->open_wait); | ||
1800 | if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) | ||
1801 | if (portp->flags & ASYNC_CHECK_CD) | ||
1802 | tty_hangup(tty); /* FIXME: module removal race here - AKPM */ | ||
1803 | } | ||
1804 | } | ||
1805 | |||
1806 | /*****************************************************************************/ | ||
1807 | |||
1808 | /* | ||
1809 | * Initialize all the ports on a panel. | 1790 | * Initialize all the ports on a panel. |
1810 | */ | 1791 | */ |
1811 | 1792 | ||
@@ -1840,7 +1821,6 @@ static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp) | |||
1840 | portp->baud_base = STL_BAUDBASE; | 1821 | portp->baud_base = STL_BAUDBASE; |
1841 | portp->close_delay = STL_CLOSEDELAY; | 1822 | portp->close_delay = STL_CLOSEDELAY; |
1842 | portp->closing_wait = 30 * HZ; | 1823 | portp->closing_wait = 30 * HZ; |
1843 | INIT_WORK(&portp->tqueue, stl_offintr); | ||
1844 | init_waitqueue_head(&portp->open_wait); | 1824 | init_waitqueue_head(&portp->open_wait); |
1845 | init_waitqueue_head(&portp->close_wait); | 1825 | init_waitqueue_head(&portp->close_wait); |
1846 | portp->stats.brd = portp->brdnr; | 1826 | portp->stats.brd = portp->brdnr; |
@@ -3530,7 +3510,8 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr) | |||
3530 | if ((len == 0) || ((len < STL_TXBUFLOW) && | 3510 | if ((len == 0) || ((len < STL_TXBUFLOW) && |
3531 | (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { | 3511 | (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { |
3532 | set_bit(ASYI_TXLOW, &portp->istate); | 3512 | set_bit(ASYI_TXLOW, &portp->istate); |
3533 | schedule_work(&portp->tqueue); | 3513 | if (portp->tty) |
3514 | tty_wakeup(portp->tty); | ||
3534 | } | 3515 | } |
3535 | 3516 | ||
3536 | if (len == 0) { | 3517 | if (len == 0) { |
@@ -3693,8 +3674,7 @@ static void stl_cd1400mdmisr(struct stlpanel *panelp, int ioaddr) | |||
3693 | outb((MISR + portp->uartaddr), ioaddr); | 3674 | outb((MISR + portp->uartaddr), ioaddr); |
3694 | misr = inb(ioaddr + EREG_DATA); | 3675 | misr = inb(ioaddr + EREG_DATA); |
3695 | if (misr & MISR_DCD) { | 3676 | if (misr & MISR_DCD) { |
3696 | set_bit(ASYI_DCDCHANGE, &portp->istate); | 3677 | stl_cd_change(portp); |
3697 | schedule_work(&portp->tqueue); | ||
3698 | portp->stats.modem++; | 3678 | portp->stats.modem++; |
3699 | } | 3679 | } |
3700 | 3680 | ||
@@ -4448,7 +4428,8 @@ static void stl_sc26198txisr(struct stlport *portp) | |||
4448 | if ((len == 0) || ((len < STL_TXBUFLOW) && | 4428 | if ((len == 0) || ((len < STL_TXBUFLOW) && |
4449 | (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { | 4429 | (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { |
4450 | set_bit(ASYI_TXLOW, &portp->istate); | 4430 | set_bit(ASYI_TXLOW, &portp->istate); |
4451 | schedule_work(&portp->tqueue); | 4431 | if (portp->tty) |
4432 | tty_wakeup(portp->tty); | ||
4452 | } | 4433 | } |
4453 | 4434 | ||
4454 | if (len == 0) { | 4435 | if (len == 0) { |
@@ -4649,8 +4630,7 @@ static void stl_sc26198otherisr(struct stlport *portp, unsigned int iack) | |||
4649 | case CIR_SUBCOS: | 4630 | case CIR_SUBCOS: |
4650 | ipr = stl_sc26198getreg(portp, IPR); | 4631 | ipr = stl_sc26198getreg(portp, IPR); |
4651 | if (ipr & IPR_DCDCHANGE) { | 4632 | if (ipr & IPR_DCDCHANGE) { |
4652 | set_bit(ASYI_DCDCHANGE, &portp->istate); | 4633 | stl_cd_change(portp); |
4653 | schedule_work(&portp->tqueue); | ||
4654 | portp->stats.modem++; | 4634 | portp->stats.modem++; |
4655 | } | 4635 | } |
4656 | break; | 4636 | break; |