]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00180636: tty/imx: lock check while handle sysrq message
authorJason Liu <r64343@freescale.com>
Wed, 11 Apr 2012 05:21:15 +0000 (13:21 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:34:29 +0000 (08:34 +0200)
Since the port->lock has already been hold when enter rx_interrupt,
and thus hold it on during handle_sysrq. We need check whether the
current console_write is for the sysrq message output or not and use
the correct lock mechanism.

Signed-off-by: Jason Liu <r64343@freescale.com>
drivers/tty/serial/imx.c

index d65c589cef60294e857c0d764c723a01b73de97c..a2a33fb815cae65e3eafb3e5cd1844fc96f2263b 100644 (file)
@@ -553,10 +553,8 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
                                continue;
                }
 
-               spin_unlock_irqrestore(&sport->port.lock, flags);
                if (uart_handle_sysrq_char(&sport->port, (unsigned char)rx))
                        continue;
-               spin_lock_irqsave(&sport->port.lock, flags);
 
                if (unlikely(rx & URXD_ERR)) {
                        if (rx & URXD_BRK)
@@ -1444,8 +1442,14 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
        struct imx_port *sport = imx_ports[co->index];
        unsigned int old_ucr1, old_ucr2, ucr1;
        unsigned long flags;
+       int locked = 1;
+
+       local_irq_save(flags);
+       if (sport->port.sysrq)
+               locked = 0;
+       else
+               spin_lock(&sport->port.lock);
 
-       spin_lock_irqsave(&sport->port.lock, flags);
        /*
         *      First, save UCR1/2 and then disable interrupts
         */
@@ -1471,7 +1475,10 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
 
        writel(old_ucr1, sport->port.membase + UCR1);
        writel(old_ucr2, sport->port.membase + UCR2);
-       spin_unlock_irqrestore(&sport->port.lock, flags);
+
+       if (locked)
+               spin_unlock(&sport->port.lock);
+       local_irq_restore(flags);
 }
 
 /*