| .. | .. |
|---|
| 14 | 14 | * serial8250_register_8250_port() ports |
|---|
| 15 | 15 | */ |
|---|
| 16 | 16 | |
|---|
| 17 | +#include <linux/acpi.h> |
|---|
| 17 | 18 | #include <linux/module.h> |
|---|
| 18 | 19 | #include <linux/moduleparam.h> |
|---|
| 19 | 20 | #include <linux/ioport.h> |
|---|
| .. | .. |
|---|
| 22 | 23 | #include <linux/sysrq.h> |
|---|
| 23 | 24 | #include <linux/delay.h> |
|---|
| 24 | 25 | #include <linux/platform_device.h> |
|---|
| 26 | +#include <linux/pm_runtime.h> |
|---|
| 25 | 27 | #include <linux/tty.h> |
|---|
| 26 | 28 | #include <linux/ratelimit.h> |
|---|
| 27 | 29 | #include <linux/tty_flip.h> |
|---|
| .. | .. |
|---|
| 54 | 56 | |
|---|
| 55 | 57 | static unsigned int skip_txen_test; /* force skip of txen test at init time */ |
|---|
| 56 | 58 | |
|---|
| 57 | | -/* |
|---|
| 58 | | - * On -rt we can have a more delays, and legitimately |
|---|
| 59 | | - * so - so don't drop work spuriously and spam the |
|---|
| 60 | | - * syslog: |
|---|
| 61 | | - */ |
|---|
| 62 | | -#ifdef CONFIG_PREEMPT_RT_FULL |
|---|
| 63 | | -# define PASS_LIMIT 1000000 |
|---|
| 64 | | -#else |
|---|
| 65 | | -# define PASS_LIMIT 512 |
|---|
| 66 | | -#endif |
|---|
| 59 | +#define PASS_LIMIT 512 |
|---|
| 67 | 60 | |
|---|
| 68 | 61 | #include <asm/serial.h> |
|---|
| 69 | 62 | /* |
|---|
| .. | .. |
|---|
| 139 | 132 | |
|---|
| 140 | 133 | l = l->next; |
|---|
| 141 | 134 | |
|---|
| 142 | | - if (l == i->head && pass_counter++ > PASS_LIMIT) { |
|---|
| 143 | | - /* If we hit this, we're dead. */ |
|---|
| 144 | | - printk_ratelimited(KERN_ERR |
|---|
| 145 | | - "serial8250: too much work for irq%d\n", irq); |
|---|
| 135 | + if (l == i->head && pass_counter++ > PASS_LIMIT) |
|---|
| 146 | 136 | break; |
|---|
| 147 | | - } |
|---|
| 148 | 137 | } while (l != end); |
|---|
| 149 | 138 | |
|---|
| 150 | 139 | spin_unlock(&i->lock); |
|---|
| .. | .. |
|---|
| 286 | 275 | * Must disable interrupts or else we risk racing with the interrupt |
|---|
| 287 | 276 | * based handler. |
|---|
| 288 | 277 | */ |
|---|
| 289 | | - if (up->port.irq) { |
|---|
| 290 | | - ier = serial_in(up, UART_IER); |
|---|
| 291 | | - serial_out(up, UART_IER, 0); |
|---|
| 292 | | - } |
|---|
| 278 | + if (up->port.irq) |
|---|
| 279 | + ier = serial8250_clear_IER(up); |
|---|
| 293 | 280 | |
|---|
| 294 | 281 | iir = serial_in(up, UART_IIR); |
|---|
| 295 | 282 | |
|---|
| .. | .. |
|---|
| 312 | 299 | serial8250_tx_chars(up); |
|---|
| 313 | 300 | |
|---|
| 314 | 301 | if (up->port.irq) |
|---|
| 315 | | - serial_out(up, UART_IER, ier); |
|---|
| 302 | + serial8250_set_IER(up, ier); |
|---|
| 316 | 303 | |
|---|
| 317 | 304 | spin_unlock_irqrestore(&up->port.lock, flags); |
|---|
| 318 | 305 | |
|---|
| .. | .. |
|---|
| 343 | 330 | * hardware interrupt, we use a timer-based system. The original |
|---|
| 344 | 331 | * driver used to do this with IRQ0. |
|---|
| 345 | 332 | */ |
|---|
| 346 | | - if (!port->irq) { |
|---|
| 333 | + if (!port->irq) |
|---|
| 347 | 334 | mod_timer(&up->timer, jiffies + uart_poll_timeout(port)); |
|---|
| 348 | | - } else |
|---|
| 335 | + else |
|---|
| 349 | 336 | retval = serial_link_irq_chain(up); |
|---|
| 350 | 337 | |
|---|
| 351 | 338 | return retval; |
|---|
| .. | .. |
|---|
| 584 | 571 | |
|---|
| 585 | 572 | up->port.dev = dev; |
|---|
| 586 | 573 | |
|---|
| 574 | + if (uart_console_enabled(&up->port)) |
|---|
| 575 | + pm_runtime_get_sync(up->port.dev); |
|---|
| 576 | + |
|---|
| 587 | 577 | serial8250_apply_quirks(up); |
|---|
| 588 | 578 | uart_add_one_port(drv, &up->port); |
|---|
| 589 | 579 | } |
|---|
| .. | .. |
|---|
| 591 | 581 | } |
|---|
| 592 | 582 | |
|---|
| 593 | 583 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
|---|
| 584 | + |
|---|
| 585 | +static void univ8250_console_write_atomic(struct console *co, const char *s, |
|---|
| 586 | + unsigned int count) |
|---|
| 587 | +{ |
|---|
| 588 | + struct uart_8250_port *up = &serial8250_ports[co->index]; |
|---|
| 589 | + |
|---|
| 590 | + serial8250_console_write_atomic(up, s, count); |
|---|
| 591 | +} |
|---|
| 594 | 592 | |
|---|
| 595 | 593 | static void univ8250_console_write(struct console *co, const char *s, |
|---|
| 596 | 594 | unsigned int count) |
|---|
| .. | .. |
|---|
| 620 | 618 | if (retval != 0) |
|---|
| 621 | 619 | port->cons = NULL; |
|---|
| 622 | 620 | return retval; |
|---|
| 621 | +} |
|---|
| 622 | + |
|---|
| 623 | +static int univ8250_console_exit(struct console *co) |
|---|
| 624 | +{ |
|---|
| 625 | + struct uart_port *port; |
|---|
| 626 | + |
|---|
| 627 | + port = &serial8250_ports[co->index].port; |
|---|
| 628 | + return serial8250_console_exit(port); |
|---|
| 623 | 629 | } |
|---|
| 624 | 630 | |
|---|
| 625 | 631 | /** |
|---|
| .. | .. |
|---|
| 677 | 683 | |
|---|
| 678 | 684 | static struct console univ8250_console = { |
|---|
| 679 | 685 | .name = "ttyS", |
|---|
| 686 | + .write_atomic = univ8250_console_write_atomic, |
|---|
| 680 | 687 | .write = univ8250_console_write, |
|---|
| 681 | 688 | .device = uart_console_device, |
|---|
| 682 | 689 | .setup = univ8250_console_setup, |
|---|
| 690 | + .exit = univ8250_console_exit, |
|---|
| 683 | 691 | .match = univ8250_console_match, |
|---|
| 684 | 692 | .flags = CON_PRINTBUFFER | CON_ANYTIME, |
|---|
| 685 | 693 | .index = -1, |
|---|
| .. | .. |
|---|
| 767 | 775 | if (!console_suspend_enabled && uart_console(port) && |
|---|
| 768 | 776 | port->type != PORT_8250) { |
|---|
| 769 | 777 | unsigned char canary = 0xa5; |
|---|
| 778 | + |
|---|
| 770 | 779 | serial_out(up, UART_SCR, canary); |
|---|
| 771 | 780 | if (serial_in(up, UART_SCR) == canary) |
|---|
| 772 | 781 | up->canary = canary; |
|---|
| .. | .. |
|---|
| 829 | 838 | uart.port.flags = p->flags; |
|---|
| 830 | 839 | uart.port.mapbase = p->mapbase; |
|---|
| 831 | 840 | uart.port.hub6 = p->hub6; |
|---|
| 841 | + uart.port.has_sysrq = p->has_sysrq; |
|---|
| 832 | 842 | uart.port.private_data = p->private_data; |
|---|
| 833 | 843 | uart.port.type = p->type; |
|---|
| 834 | 844 | uart.port.serial_in = p->serial_in; |
|---|
| .. | .. |
|---|
| 996 | 1006 | |
|---|
| 997 | 1007 | uart = serial8250_find_match_or_unused(&up->port); |
|---|
| 998 | 1008 | if (uart && uart->port.type != PORT_8250_CIR) { |
|---|
| 1009 | + struct mctrl_gpios *gpios; |
|---|
| 1010 | + |
|---|
| 999 | 1011 | if (uart->port.dev) |
|---|
| 1000 | 1012 | uart_remove_one_port(&serial8250_reg, &uart->port); |
|---|
| 1001 | 1013 | |
|---|
| .. | .. |
|---|
| 1018 | 1030 | uart->port.unthrottle = up->port.unthrottle; |
|---|
| 1019 | 1031 | uart->port.rs485_config = up->port.rs485_config; |
|---|
| 1020 | 1032 | uart->port.rs485 = up->port.rs485; |
|---|
| 1033 | + uart->rs485_start_tx = up->rs485_start_tx; |
|---|
| 1034 | + uart->rs485_stop_tx = up->rs485_stop_tx; |
|---|
| 1021 | 1035 | uart->dma = up->dma; |
|---|
| 1022 | 1036 | #ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 1023 | 1037 | uart->port.line = up->port.line; |
|---|
| .. | .. |
|---|
| 1026 | 1040 | if (uart->port.fifosize && !uart->tx_loadsz) |
|---|
| 1027 | 1041 | uart->tx_loadsz = uart->port.fifosize; |
|---|
| 1028 | 1042 | |
|---|
| 1029 | | - if (up->port.dev) |
|---|
| 1043 | + if (up->port.dev) { |
|---|
| 1030 | 1044 | uart->port.dev = up->port.dev; |
|---|
| 1045 | + ret = uart_get_rs485_mode(&uart->port); |
|---|
| 1046 | + if (ret) |
|---|
| 1047 | + goto err; |
|---|
| 1048 | + } |
|---|
| 1031 | 1049 | |
|---|
| 1032 | 1050 | if (up->port.flags & UPF_FIXED_TYPE) |
|---|
| 1033 | 1051 | uart->port.type = up->port.type; |
|---|
| 1034 | 1052 | |
|---|
| 1053 | + /* |
|---|
| 1054 | + * Only call mctrl_gpio_init(), if the device has no ACPI |
|---|
| 1055 | + * companion device |
|---|
| 1056 | + */ |
|---|
| 1057 | + if (!has_acpi_companion(uart->port.dev)) { |
|---|
| 1058 | + gpios = mctrl_gpio_init(&uart->port, 0); |
|---|
| 1059 | + if (IS_ERR(gpios)) { |
|---|
| 1060 | + ret = PTR_ERR(gpios); |
|---|
| 1061 | + goto err; |
|---|
| 1062 | + } else { |
|---|
| 1063 | + uart->gpios = gpios; |
|---|
| 1064 | + } |
|---|
| 1065 | + } |
|---|
| 1066 | + |
|---|
| 1035 | 1067 | serial8250_set_defaults(uart); |
|---|
| 1036 | 1068 | |
|---|
| 1037 | 1069 | /* Possibly override default I/O functions. */ |
|---|