|
@@ -299,6 +299,7 @@ static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
|
|
|
|
|
|
static unsigned int serial_in(struct uart_8250_port *up, int offset)
|
|
|
{
|
|
|
+ unsigned int tmp;
|
|
|
offset = map_8250_in_reg(up, offset) << up->port.regshift;
|
|
|
|
|
|
switch (up->port.iotype) {
|
|
@@ -317,6 +318,13 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset)
|
|
|
return __raw_readl(up->port.membase + offset);
|
|
|
#endif
|
|
|
|
|
|
+ case UPIO_TSI:
|
|
|
+ if (offset == UART_IIR) {
|
|
|
+ tmp = readl((u32 *)(up->port.membase + UART_RX));
|
|
|
+ return (cpu_to_le32(tmp) >> 8) & 0xff;
|
|
|
+ } else
|
|
|
+ return readb(up->port.membase + offset);
|
|
|
+
|
|
|
default:
|
|
|
return inb(up->port.iobase + offset);
|
|
|
}
|
|
@@ -346,6 +354,10 @@ serial_out(struct uart_8250_port *up, int offset, int value)
|
|
|
__raw_writel(value, up->port.membase + offset);
|
|
|
break;
|
|
|
#endif
|
|
|
+ case UPIO_TSI:
|
|
|
+ if (!((offset == UART_IER) && (value & UART_IER_UUE)))
|
|
|
+ writeb(value, up->port.membase + offset);
|
|
|
+ break;
|
|
|
|
|
|
default:
|
|
|
outb(value, up->port.iobase + offset);
|
|
@@ -2240,10 +2252,14 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
|
|
|
|
|
|
touch_nmi_watchdog();
|
|
|
|
|
|
- if (oops_in_progress) {
|
|
|
- locked = spin_trylock_irqsave(&up->port.lock, flags);
|
|
|
+ local_irq_save(flags);
|
|
|
+ if (up->port.sysrq) {
|
|
|
+ /* serial8250_handle_port() already took the lock */
|
|
|
+ locked = 0;
|
|
|
+ } else if (oops_in_progress) {
|
|
|
+ locked = spin_trylock(&up->port.lock);
|
|
|
} else
|
|
|
- spin_lock_irqsave(&up->port.lock, flags);
|
|
|
+ spin_lock(&up->port.lock);
|
|
|
|
|
|
/*
|
|
|
* First save the IER then disable the interrupts
|
|
@@ -2265,7 +2281,8 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
|
|
|
serial_out(up, UART_IER, ier);
|
|
|
|
|
|
if (locked)
|
|
|
- spin_unlock_irqrestore(&up->port.lock, flags);
|
|
|
+ spin_unlock(&up->port.lock);
|
|
|
+ local_irq_restore(flags);
|
|
|
}
|
|
|
|
|
|
static int serial8250_console_setup(struct console *co, char *options)
|