summaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/sh-sci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/sh-sci.c')
-rw-r--r--drivers/tty/serial/sh-sci.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 107801b1279..63a23eadd7e 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -2203,7 +2203,21 @@ static void serial_console_write(struct console *co, const char *s,
{
struct sci_port *sci_port = &sci_ports[co->index];
struct uart_port *port = &sci_port->port;
- unsigned short bits;
+ unsigned short bits, ctrl;
+ 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);
+
+ /* first save the SCSCR then disable the interrupts */
+ ctrl = serial_port_in(port, SCSCR);
+ serial_port_out(port, SCSCR, sci_port->cfg->scscr);
uart_console_write(port, s, count, serial_console_putchar);
@@ -2211,6 +2225,13 @@ static void serial_console_write(struct console *co, const char *s,
bits = SCxSR_TDxE(port) | SCxSR_TEND(port);
while ((serial_port_in(port, SCxSR) & bits) != bits)
cpu_relax();
+
+ /* restore the SCSCR */
+ serial_port_out(port, SCSCR, ctrl);
+
+ if (locked)
+ spin_unlock(&port->lock);
+ local_irq_restore(flags);
}
static int __devinit serial_console_setup(struct console *co, char *options)