[ARM] 5250/1: unbalanced enable_irq() for serial_ks8695.c fix
authorDick Hollenbeck <dick@softplc.com>
Tue, 16 Sep 2008 17:30:27 +0000 (18:30 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 1 Oct 2008 21:41:43 +0000 (22:41 +0100)
The function ks8695uart_set_termios() would cause an unbalanced
enable_irq() generated message to be printk()ed. This is because
there was no book keeping support to remember if the calls to
enable_irq() and disable_irq() were balanced for the modem
control irq.

Signed-off-by: Dick Hollenbeck <dick@softplc.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/serial/serial_ks8695.c

index b9cbfc87f616adee61d6c687c69413bc386bb3e6..998e89dc5aaf2db56eda9f18c1060ea8c9189555 100644 (file)
 #define UART_DUMMY_LSR_RX      0x100
 #define UART_PORT_SIZE         (KS8695_USR - KS8695_URRB + 4)
 
-#define tx_enabled(port) ((port)->unused[0])
-#define rx_enabled(port) ((port)->unused[1])
+static inline int tx_enabled(struct uart_port *port)
+{
+       return port->unused[0] & 1;
+}
+
+static inline int rx_enabled(struct uart_port *port)
+{
+       return port->unused[0] & 2;
+}
+
+static inline int ms_enabled(struct uart_port *port)
+{
+       return port->unused[0] & 4;
+}
+
+static inline void ms_enable(struct uart_port *port, int enabled)
+{
+       if(enabled)
+               port->unused[0] |= 4;
+       else
+               port->unused[0] &= ~4;
+}
+
+static inline void rx_enable(struct uart_port *port, int enabled)
+{
+       if(enabled)
+               port->unused[0] |= 2;
+       else
+               port->unused[0] &= ~2;
+}
+
+static inline void tx_enable(struct uart_port *port, int enabled)
+{
+       if(enabled)
+               port->unused[0] |= 1;
+       else
+               port->unused[0] &= ~1;
+}
 
 
 #ifdef SUPPORT_SYSRQ
@@ -75,7 +111,7 @@ static void ks8695uart_stop_tx(struct uart_port *port)
 {
        if (tx_enabled(port)) {
                disable_irq(KS8695_IRQ_UART_TX);
-               tx_enabled(port) = 0;
+               tx_enable(port, 0);
        }
 }
 
@@ -83,7 +119,7 @@ static void ks8695uart_start_tx(struct uart_port *port)
 {
        if (!tx_enabled(port)) {
                enable_irq(KS8695_IRQ_UART_TX);
-               tx_enabled(port) = 1;
+               tx_enable(port, 1);
        }
 }
 
@@ -91,18 +127,24 @@ static void ks8695uart_stop_rx(struct uart_port *port)
 {
        if (rx_enabled(port)) {
                disable_irq(KS8695_IRQ_UART_RX);
-               rx_enabled(port) = 0;
+               rx_enable(port, 0);
        }
 }
 
 static void ks8695uart_enable_ms(struct uart_port *port)
 {
-       enable_irq(KS8695_IRQ_UART_MODEM_STATUS);
+       if (!ms_enabled(port)) {
+               enable_irq(KS8695_IRQ_UART_MODEM_STATUS);
+               ms_enable(port,1);
+       }
 }
 
 static void ks8695uart_disable_ms(struct uart_port *port)
 {
-       disable_irq(KS8695_IRQ_UART_MODEM_STATUS);
+       if (ms_enabled(port)) {
+               disable_irq(KS8695_IRQ_UART_MODEM_STATUS);
+               ms_enable(port,0);
+       }
 }
 
 static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id)
@@ -285,8 +327,9 @@ static int ks8695uart_startup(struct uart_port *port)
        int retval;
 
        set_irq_flags(KS8695_IRQ_UART_TX, IRQF_VALID | IRQF_NOAUTOEN);
-       tx_enabled(port) = 0;
-       rx_enabled(port) = 1;
+       tx_enable(port, 0);
+       rx_enable(port, 1);
+       ms_enable(port, 1);
 
        /*
         * Allocate the IRQ