aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2008-02-07 03:16:39 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 11:42:34 -0500
commitccfea3c98a10b9d4d49b899616a06594ec976d7d (patch)
treecea834a683e572015a51dbf122603c20d040c1f7 /drivers/char
parentd0d4e1c098754bfbb2aeb94333756d63d255688e (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.c68
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
611static struct class *stallion_class; 610static struct class *stallion_class;
612 611
612static 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 */
1776static 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;