diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-13 16:38:02 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-13 16:38:02 -0700 |
commit | 7b69a4c360e8787877ebf5e42609b8bab13afa6a (patch) | |
tree | 3eaaae28ed398396f0f3f134e53dd8a730574781 /drivers/serial/8250.c | |
parent | a23f4636c9ae7f1f15c448080f1552864b404136 (diff) | |
parent | 68aa2c0d4a36b43ea9c6d77134c94b4501fd2eb4 (diff) | |
download | op-kernel-dev-7b69a4c360e8787877ebf5e42609b8bab13afa6a.zip op-kernel-dev-7b69a4c360e8787877ebf5e42609b8bab13afa6a.tar.gz |
Merge master.kernel.org:/home/rmk/linux-2.6-serial
* master.kernel.org:/home/rmk/linux-2.6-serial:
[SERIAL] 8250: sysrq deadlock fix
[SERIAL] 8250: add tsi108 serial support
[SERIAL] IP22: fix serial console hangs
[SERIAL] dz: Fix compilation error
Diffstat (limited to 'drivers/serial/8250.c')
-rw-r--r-- | drivers/serial/8250.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 0995430..0ae9ced 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -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) |