diff options
Diffstat (limited to 'drivers/serial/8250.c')
-rw-r--r-- | drivers/serial/8250.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index bbf78aaf9e01..0ae9ced00ed4 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -19,7 +19,6 @@ | |||
19 | * mapbase is the physical address of the IO port. | 19 | * mapbase is the physical address of the IO port. |
20 | * membase is an 'ioremapped' cookie. | 20 | * membase is an 'ioremapped' cookie. |
21 | */ | 21 | */ |
22 | #include <linux/config.h> | ||
23 | 22 | ||
24 | #if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | 23 | #if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
25 | #define SUPPORT_SYSRQ | 24 | #define SUPPORT_SYSRQ |
@@ -49,7 +48,7 @@ | |||
49 | 48 | ||
50 | /* | 49 | /* |
51 | * Configuration: | 50 | * Configuration: |
52 | * share_irqs - whether we pass SA_SHIRQ to request_irq(). This option | 51 | * share_irqs - whether we pass IRQF_SHARED to request_irq(). This option |
53 | * is unsafe when used on edge-triggered interrupts. | 52 | * is unsafe when used on edge-triggered interrupts. |
54 | */ | 53 | */ |
55 | static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; | 54 | static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; |
@@ -300,6 +299,7 @@ static inline int map_8250_out_reg(struct uart_8250_port *up, int offset) | |||
300 | 299 | ||
301 | static unsigned int serial_in(struct uart_8250_port *up, int offset) | 300 | static unsigned int serial_in(struct uart_8250_port *up, int offset) |
302 | { | 301 | { |
302 | unsigned int tmp; | ||
303 | offset = map_8250_in_reg(up, offset) << up->port.regshift; | 303 | offset = map_8250_in_reg(up, offset) << up->port.regshift; |
304 | 304 | ||
305 | switch (up->port.iotype) { | 305 | switch (up->port.iotype) { |
@@ -318,6 +318,13 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset) | |||
318 | return __raw_readl(up->port.membase + offset); | 318 | return __raw_readl(up->port.membase + offset); |
319 | #endif | 319 | #endif |
320 | 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 | |||
321 | default: | 328 | default: |
322 | return inb(up->port.iobase + offset); | 329 | return inb(up->port.iobase + offset); |
323 | } | 330 | } |
@@ -347,6 +354,10 @@ serial_out(struct uart_8250_port *up, int offset, int value) | |||
347 | __raw_writel(value, up->port.membase + offset); | 354 | __raw_writel(value, up->port.membase + offset); |
348 | break; | 355 | break; |
349 | #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; | ||
350 | 361 | ||
351 | default: | 362 | default: |
352 | outb(value, up->port.iobase + offset); | 363 | outb(value, up->port.iobase + offset); |
@@ -1401,7 +1412,7 @@ static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up) | |||
1401 | static int serial_link_irq_chain(struct uart_8250_port *up) | 1412 | static int serial_link_irq_chain(struct uart_8250_port *up) |
1402 | { | 1413 | { |
1403 | struct irq_info *i = irq_lists + up->port.irq; | 1414 | struct irq_info *i = irq_lists + up->port.irq; |
1404 | int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? SA_SHIRQ : 0; | 1415 | int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0; |
1405 | 1416 | ||
1406 | spin_lock_irq(&i->lock); | 1417 | spin_lock_irq(&i->lock); |
1407 | 1418 | ||
@@ -2241,10 +2252,14 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
2241 | 2252 | ||
2242 | touch_nmi_watchdog(); | 2253 | touch_nmi_watchdog(); |
2243 | 2254 | ||
2244 | if (oops_in_progress) { | 2255 | local_irq_save(flags); |
2245 | 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); | ||
2246 | } else | 2261 | } else |
2247 | spin_lock_irqsave(&up->port.lock, flags); | 2262 | spin_lock(&up->port.lock); |
2248 | 2263 | ||
2249 | /* | 2264 | /* |
2250 | * First save the IER then disable the interrupts | 2265 | * First save the IER then disable the interrupts |
@@ -2266,7 +2281,8 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
2266 | serial_out(up, UART_IER, ier); | 2281 | serial_out(up, UART_IER, ier); |
2267 | 2282 | ||
2268 | if (locked) | 2283 | if (locked) |
2269 | spin_unlock_irqrestore(&up->port.lock, flags); | 2284 | spin_unlock(&up->port.lock); |
2285 | local_irq_restore(flags); | ||
2270 | } | 2286 | } |
2271 | 2287 | ||
2272 | static int serial8250_console_setup(struct console *co, char *options) | 2288 | static int serial8250_console_setup(struct console *co, char *options) |
@@ -2354,7 +2370,6 @@ int __init serial8250_start_console(struct uart_port *port, char *options) | |||
2354 | static struct uart_driver serial8250_reg = { | 2370 | static struct uart_driver serial8250_reg = { |
2355 | .owner = THIS_MODULE, | 2371 | .owner = THIS_MODULE, |
2356 | .driver_name = "serial", | 2372 | .driver_name = "serial", |
2357 | .devfs_name = "tts/", | ||
2358 | .dev_name = "ttyS", | 2373 | .dev_name = "ttyS", |
2359 | .major = TTY_MAJOR, | 2374 | .major = TTY_MAJOR, |
2360 | .minor = 64, | 2375 | .minor = 64, |