diff options
| -rw-r--r-- | drivers/serial/sunhv.c | 30 | ||||
| -rw-r--r-- | drivers/serial/sunsab.c | 19 | ||||
| -rw-r--r-- | drivers/serial/sunsu.c | 14 | ||||
| -rw-r--r-- | drivers/serial/sunzilog.c | 17 |
4 files changed, 68 insertions, 12 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 | ||
| 475 | static inline void sunhv_console_putchar(struct uart_port *port, char c) | 486 | 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 | |||
| 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 | ||
| 502 | static struct console sunhv_console = { | 524 | static struct console sunhv_console = { |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index deb9ab4b5a0b..8a0f9e4408d4 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
| @@ -860,22 +860,31 @@ static int num_channels; | |||
| 860 | static void sunsab_console_putchar(struct uart_port *port, int c) | 860 | static void sunsab_console_putchar(struct uart_port *port, int c) |
| 861 | { | 861 | { |
| 862 | struct uart_sunsab_port *up = (struct uart_sunsab_port *)port; | 862 | struct uart_sunsab_port *up = (struct uart_sunsab_port *)port; |
| 863 | unsigned long flags; | ||
| 864 | |||
| 865 | spin_lock_irqsave(&up->port.lock, flags); | ||
| 866 | 863 | ||
| 867 | sunsab_tec_wait(up); | 864 | sunsab_tec_wait(up); |
| 868 | writeb(c, &up->regs->w.tic); | 865 | writeb(c, &up->regs->w.tic); |
| 869 | |||
| 870 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
| 871 | } | 866 | } |
| 872 | 867 | ||
| 873 | static void sunsab_console_write(struct console *con, const char *s, unsigned n) | 868 | static void sunsab_console_write(struct console *con, const char *s, unsigned n) |
| 874 | { | 869 | { |
| 875 | struct uart_sunsab_port *up = &sunsab_ports[con->index]; | 870 | struct uart_sunsab_port *up = &sunsab_ports[con->index]; |
| 871 | unsigned long flags; | ||
| 872 | int locked = 1; | ||
| 873 | |||
| 874 | local_irq_save(flags); | ||
| 875 | if (up->port.sysrq) { | ||
| 876 | locked = 0; | ||
| 877 | } else if (oops_in_progress) { | ||
| 878 | locked = spin_trylock(&up->port.lock); | ||
| 879 | } else | ||
| 880 | spin_lock(&up->port.lock); | ||
| 876 | 881 | ||
| 877 | uart_console_write(&up->port, s, n, sunsab_console_putchar); | 882 | uart_console_write(&up->port, s, n, sunsab_console_putchar); |
| 878 | sunsab_tec_wait(up); | 883 | sunsab_tec_wait(up); |
| 884 | |||
| 885 | if (locked) | ||
| 886 | spin_unlock(&up->port.lock); | ||
| 887 | local_irq_restore(flags); | ||
| 879 | } | 888 | } |
| 880 | 889 | ||
| 881 | static int sunsab_console_setup(struct console *con, char *options) | 890 | static int sunsab_console_setup(struct console *con, char *options) |
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 2a63cdba3208..26d720baf88c 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
| @@ -1288,7 +1288,17 @@ static void sunsu_console_write(struct console *co, const char *s, | |||
| 1288 | unsigned int count) | 1288 | unsigned int count) |
| 1289 | { | 1289 | { |
| 1290 | struct uart_sunsu_port *up = &sunsu_ports[co->index]; | 1290 | struct uart_sunsu_port *up = &sunsu_ports[co->index]; |
| 1291 | unsigned long flags; | ||
| 1291 | unsigned int ier; | 1292 | unsigned int ier; |
| 1293 | int locked = 1; | ||
| 1294 | |||
| 1295 | local_irq_save(flags); | ||
| 1296 | if (up->port.sysrq) { | ||
| 1297 | locked = 0; | ||
| 1298 | } else if (oops_in_progress) { | ||
| 1299 | locked = spin_trylock(&up->port.lock); | ||
| 1300 | } else | ||
| 1301 | spin_lock(&up->port.lock); | ||
| 1292 | 1302 | ||
| 1293 | /* | 1303 | /* |
| 1294 | * First save the UER then disable the interrupts | 1304 | * First save the UER then disable the interrupts |
| @@ -1304,6 +1314,10 @@ static void sunsu_console_write(struct console *co, const char *s, | |||
| 1304 | */ | 1314 | */ |
| 1305 | wait_for_xmitr(up); | 1315 | wait_for_xmitr(up); |
| 1306 | serial_out(up, UART_IER, ier); | 1316 | serial_out(up, UART_IER, ier); |
| 1317 | |||
| 1318 | if (locked) | ||
| 1319 | spin_unlock(&up->port.lock); | ||
| 1320 | local_irq_restore(flags); | ||
| 1307 | } | 1321 | } |
| 1308 | 1322 | ||
| 1309 | /* | 1323 | /* |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 15b6e1cb040b..0a3e10a4a35d 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | * C. Dost, Pete Zaitcev, Ted Ts'o and Alex Buell for their | 9 | * C. Dost, Pete Zaitcev, Ted Ts'o and Alex Buell for their |
| 10 | * work there. | 10 | * work there. |
| 11 | * | 11 | * |
| 12 | * Copyright (C) 2002, 2006 David S. Miller (davem@davemloft.net) | 12 | * Copyright (C) 2002, 2006, 2007 David S. Miller (davem@davemloft.net) |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| @@ -1151,11 +1151,22 @@ sunzilog_console_write(struct console *con, const char *s, unsigned int count) | |||
| 1151 | { | 1151 | { |
| 1152 | struct uart_sunzilog_port *up = &sunzilog_port_table[con->index]; | 1152 | struct uart_sunzilog_port *up = &sunzilog_port_table[con->index]; |
| 1153 | unsigned long flags; | 1153 | unsigned long flags; |
| 1154 | int locked = 1; | ||
| 1155 | |||
| 1156 | local_irq_save(flags); | ||
| 1157 | if (up->port.sysrq) { | ||
| 1158 | locked = 0; | ||
| 1159 | } else if (oops_in_progress) { | ||
| 1160 | locked = spin_trylock(&up->port.lock); | ||
| 1161 | } else | ||
| 1162 | spin_lock(&up->port.lock); | ||
| 1154 | 1163 | ||
| 1155 | spin_lock_irqsave(&up->port.lock, flags); | ||
| 1156 | uart_console_write(&up->port, s, count, sunzilog_putchar); | 1164 | uart_console_write(&up->port, s, count, sunzilog_putchar); |
| 1157 | udelay(2); | 1165 | udelay(2); |
| 1158 | spin_unlock_irqrestore(&up->port.lock, flags); | 1166 | |
| 1167 | if (locked) | ||
| 1168 | spin_unlock(&up->port.lock); | ||
| 1169 | local_irq_restore(flags); | ||
| 1159 | } | 1170 | } |
| 1160 | 1171 | ||
| 1161 | static int __init sunzilog_console_setup(struct console *con, char *options) | 1172 | static int __init sunzilog_console_setup(struct console *con, char *options) |
