Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ed8485fb340056c4d9062e9d2697c8402dd19eb0
Commit:     ed8485fb340056c4d9062e9d2697c8402dd19eb0
Parent:     3dd1247f4dee214a92b42e17818703ea71233288
Author:     Paul Fulghum <[EMAIL PROTECTED]>
AuthorDate: Wed Feb 6 01:37:18 2008 -0800
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Wed Feb 6 10:41:06 2008 -0800

    synclink_gt fix missed serial input signal changes
    
    Fix missed serial input signal changes caused by rereading the serial
    status register during interrupt processing.  Now processing is performed
    on original status register value.
    
    Signed-off-by: Paul Fulghum <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 drivers/char/synclink_gt.c |   68 ++++++++++++++++++++++++--------------------
 1 files changed, 37 insertions(+), 31 deletions(-)

diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 5f6a5da..1f954ac 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -2039,37 +2039,41 @@ static void bh_transmit(struct slgt_info *info)
                tty_wakeup(tty);
 }
 
-static void dsr_change(struct slgt_info *info)
+static void dsr_change(struct slgt_info *info, unsigned short status)
 {
-       get_signals(info);
+       if (status & BIT3) {
+               info->signals |= SerialSignal_DSR;
+               info->input_signal_events.dsr_up++;
+       } else {
+               info->signals &= ~SerialSignal_DSR;
+               info->input_signal_events.dsr_down++;
+       }
        DBGISR(("dsr_change %s signals=%04X\n", info->device_name, 
info->signals));
        if ((info->dsr_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
                slgt_irq_off(info, IRQ_DSR);
                return;
        }
        info->icount.dsr++;
-       if (info->signals & SerialSignal_DSR)
-               info->input_signal_events.dsr_up++;
-       else
-               info->input_signal_events.dsr_down++;
        wake_up_interruptible(&info->status_event_wait_q);
        wake_up_interruptible(&info->event_wait_q);
        info->pending_bh |= BH_STATUS;
 }
 
-static void cts_change(struct slgt_info *info)
+static void cts_change(struct slgt_info *info, unsigned short status)
 {
-       get_signals(info);
+       if (status & BIT2) {
+               info->signals |= SerialSignal_CTS;
+               info->input_signal_events.cts_up++;
+       } else {
+               info->signals &= ~SerialSignal_CTS;
+               info->input_signal_events.cts_down++;
+       }
        DBGISR(("cts_change %s signals=%04X\n", info->device_name, 
info->signals));
        if ((info->cts_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
                slgt_irq_off(info, IRQ_CTS);
                return;
        }
        info->icount.cts++;
-       if (info->signals & SerialSignal_CTS)
-               info->input_signal_events.cts_up++;
-       else
-               info->input_signal_events.cts_down++;
        wake_up_interruptible(&info->status_event_wait_q);
        wake_up_interruptible(&info->event_wait_q);
        info->pending_bh |= BH_STATUS;
@@ -2090,20 +2094,21 @@ static void cts_change(struct slgt_info *info)
        }
 }
 
-static void dcd_change(struct slgt_info *info)
+static void dcd_change(struct slgt_info *info, unsigned short status)
 {
-       get_signals(info);
+       if (status & BIT1) {
+               info->signals |= SerialSignal_DCD;
+               info->input_signal_events.dcd_up++;
+       } else {
+               info->signals &= ~SerialSignal_DCD;
+               info->input_signal_events.dcd_down++;
+       }
        DBGISR(("dcd_change %s signals=%04X\n", info->device_name, 
info->signals));
        if ((info->dcd_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
                slgt_irq_off(info, IRQ_DCD);
                return;
        }
        info->icount.dcd++;
-       if (info->signals & SerialSignal_DCD) {
-               info->input_signal_events.dcd_up++;
-       } else {
-               info->input_signal_events.dcd_down++;
-       }
 #if SYNCLINK_GENERIC_HDLC
        if (info->netcount) {
                if (info->signals & SerialSignal_DCD)
@@ -2126,20 +2131,21 @@ static void dcd_change(struct slgt_info *info)
        }
 }
 
-static void ri_change(struct slgt_info *info)
+static void ri_change(struct slgt_info *info, unsigned short status)
 {
-       get_signals(info);
+       if (status & BIT0) {
+               info->signals |= SerialSignal_RI;
+               info->input_signal_events.ri_up++;
+       } else {
+               info->signals &= ~SerialSignal_RI;
+               info->input_signal_events.ri_down++;
+       }
        DBGISR(("ri_change %s signals=%04X\n", info->device_name, 
info->signals));
        if ((info->ri_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
                slgt_irq_off(info, IRQ_RI);
                return;
        }
-       info->icount.dcd++;
-       if (info->signals & SerialSignal_RI) {
-               info->input_signal_events.ri_up++;
-       } else {
-               info->input_signal_events.ri_down++;
-       }
+       info->icount.rng++;
        wake_up_interruptible(&info->status_event_wait_q);
        wake_up_interruptible(&info->event_wait_q);
        info->pending_bh |= BH_STATUS;
@@ -2190,13 +2196,13 @@ static void isr_serial(struct slgt_info *info)
        }
 
        if (status & IRQ_DSR)
-               dsr_change(info);
+               dsr_change(info, status);
        if (status & IRQ_CTS)
-               cts_change(info);
+               cts_change(info, status);
        if (status & IRQ_DCD)
-               dcd_change(info);
+               dcd_change(info, status);
        if (status & IRQ_RI)
-               ri_change(info);
+               ri_change(info, status);
 }
 
 static void isr_rdma(struct slgt_info *info)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to