From f3c681c028846bd5d39f563909409832a295ca69 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 15 Jul 2007 23:53:32 -0700 Subject: [SERIAL]: Fix console write locking in sparc drivers. Mirror the logic in 8250 for proper console write locking when SYSRQ is triggered or an OOPS is in progress. Signed-off-by: David S. Miller --- drivers/serial/sunhv.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'drivers/serial/sunhv.c') diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index 96557e6dba6..17bcca53d6a 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c @@ -440,8 +440,16 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign { struct uart_port *port = sunhv_port; unsigned long flags; + int locked = 1; + + local_irq_save(flags); + if (port->sysrq) { + locked = 0; + } else if (oops_in_progress) { + locked = spin_trylock(&port->lock); + } else + spin_lock(&port->lock); - spin_lock_irqsave(&port->lock, flags); while (n > 0) { unsigned long ra = __pa(con_write_page); unsigned long page_bytes; @@ -469,7 +477,10 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign ra += written; } } - spin_unlock_irqrestore(&port->lock, flags); + + if (locked) + spin_unlock(&port->lock); + local_irq_restore(flags); } static inline void sunhv_console_putchar(struct uart_port *port, char c) @@ -488,7 +499,15 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig { struct uart_port *port = sunhv_port; unsigned long flags; - int i; + int i, locked = 1; + + local_irq_save(flags); + if (port->sysrq) { + locked = 0; + } else if (oops_in_progress) { + locked = spin_trylock(&port->lock); + } else + spin_lock(&port->lock); spin_lock_irqsave(&port->lock, flags); for (i = 0; i < n; i++) { @@ -496,7 +515,10 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig sunhv_console_putchar(port, '\r'); sunhv_console_putchar(port, *s++); } - spin_unlock_irqrestore(&port->lock, flags); + + if (locked) + spin_unlock(&port->lock); + local_irq_restore(flags); } static struct console sunhv_console = { -- cgit v1.2.3