aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/sunhv.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2007-07-16 02:53:32 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-16 07:05:28 -0400
commitf3c681c028846bd5d39f563909409832a295ca69 (patch)
treeff492b31f535a76f1d8ad82b916bb6293f550123 /drivers/serial/sunhv.c
parent9918cc2e3275bf7f3561e4de1d5a3314183e71dc (diff)
[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 <davem@davemloft.net>
Diffstat (limited to 'drivers/serial/sunhv.c')
-rw-r--r--drivers/serial/sunhv.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index 96557e6dba60..17bcca53d6a1 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
440{ 440{
441 struct uart_port *port = sunhv_port; 441 struct uart_port *port = sunhv_port;
442 unsigned long flags; 442 unsigned long flags;
443 int locked = 1;
444
445 local_irq_save(flags);
446 if (port->sysrq) {
447 locked = 0;
448 } else if (oops_in_progress) {
449 locked = spin_trylock(&port->lock);
450 } else
451 spin_lock(&port->lock);
443 452
444 spin_lock_irqsave(&port->lock, flags);
445 while (n > 0) { 453 while (n > 0) {
446 unsigned long ra = __pa(con_write_page); 454 unsigned long ra = __pa(con_write_page);
447 unsigned long page_bytes; 455 unsigned long page_bytes;
@@ -469,7 +477,10 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign
469 ra += written; 477 ra += written;
470 } 478 }
471 } 479 }
472 spin_unlock_irqrestore(&port->lock, flags); 480
481 if (locked)
482 spin_unlock(&port->lock);
483 local_irq_restore(flags);
473} 484}
474 485
475static inline void sunhv_console_putchar(struct uart_port *port, char c) 486static 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
488{ 499{
489 struct uart_port *port = sunhv_port; 500 struct uart_port *port = sunhv_port;
490 unsigned long flags; 501 unsigned long flags;
491 int i; 502 int i, locked = 1;
503
504 local_irq_save(flags);
505 if (port->sysrq) {
506 locked = 0;
507 } else if (oops_in_progress) {
508 locked = spin_trylock(&port->lock);
509 } else
510 spin_lock(&port->lock);
492 511
493 spin_lock_irqsave(&port->lock, flags); 512 spin_lock_irqsave(&port->lock, flags);
494 for (i = 0; i < n; i++) { 513 for (i = 0; i < n; i++) {
@@ -496,7 +515,10 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig
496 sunhv_console_putchar(port, '\r'); 515 sunhv_console_putchar(port, '\r');
497 sunhv_console_putchar(port, *s++); 516 sunhv_console_putchar(port, *s++);
498 } 517 }
499 spin_unlock_irqrestore(&port->lock, flags); 518
519 if (locked)
520 spin_unlock(&port->lock);
521 local_irq_restore(flags);
500} 522}
501 523
502static struct console sunhv_console = { 524static struct console sunhv_console = {