aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/8250.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial/8250.c')
-rw-r--r--drivers/serial/8250.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 0995430e4cf1..0ae9ced00ed4 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)
299 299
300static unsigned int serial_in(struct uart_8250_port *up, int offset) 300static unsigned int serial_in(struct uart_8250_port *up, int offset)
301{ 301{
302 unsigned int tmp;
302 offset = map_8250_in_reg(up, offset) << up->port.regshift; 303 offset = map_8250_in_reg(up, offset) << up->port.regshift;
303 304
304 switch (up->port.iotype) { 305 switch (up->port.iotype) {
@@ -317,6 +318,13 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset)
317 return __raw_readl(up->port.membase + offset); 318 return __raw_readl(up->port.membase + offset);
318#endif 319#endif
319 320
321 case UPIO_TSI:
322 if (offset == UART_IIR) {
323 tmp = readl((u32 *)(up->port.membase + UART_RX));
324 return (cpu_to_le32(tmp) >> 8) & 0xff;
325 } else
326 return readb(up->port.membase + offset);
327
320 default: 328 default:
321 return inb(up->port.iobase + offset); 329 return inb(up->port.iobase + offset);
322 } 330 }
@@ -346,6 +354,10 @@ serial_out(struct uart_8250_port *up, int offset, int value)
346 __raw_writel(value, up->port.membase + offset); 354 __raw_writel(value, up->port.membase + offset);
347 break; 355 break;
348#endif 356#endif
357 case UPIO_TSI:
358 if (!((offset == UART_IER) && (value & UART_IER_UUE)))
359 writeb(value, up->port.membase + offset);
360 break;
349 361
350 default: 362 default:
351 outb(value, up->port.iobase + offset); 363 outb(value, up->port.iobase + offset);
@@ -2240,10 +2252,14 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
2240 2252
2241 touch_nmi_watchdog(); 2253 touch_nmi_watchdog();
2242 2254
2243 if (oops_in_progress) { 2255 local_irq_save(flags);
2244 locked = spin_trylock_irqsave(&up->port.lock, flags); 2256 if (up->port.sysrq) {
2257 /* serial8250_handle_port() already took the lock */
2258 locked = 0;
2259 } else if (oops_in_progress) {
2260 locked = spin_trylock(&up->port.lock);
2245 } else 2261 } else
2246 spin_lock_irqsave(&up->port.lock, flags); 2262 spin_lock(&up->port.lock);
2247 2263
2248 /* 2264 /*
2249 * First save the IER then disable the interrupts 2265 * First save the IER then disable the interrupts
@@ -2265,7 +2281,8 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
2265 serial_out(up, UART_IER, ier); 2281 serial_out(up, UART_IER, ier);
2266 2282
2267 if (locked) 2283 if (locked)
2268 spin_unlock_irqrestore(&up->port.lock, flags); 2284 spin_unlock(&up->port.lock);
2285 local_irq_restore(flags);
2269} 2286}
2270 2287
2271static int serial8250_console_setup(struct console *co, char *options) 2288static int serial8250_console_setup(struct console *co, char *options)