static unsigned int __init probe_baud(struct uart_port *port) { unsigned char lcr, dll, dlm; unsigned int quot; lcr = serial8250_early_in(port, UART_LCR); serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB); dll = serial8250_early_in(port, UART_DLL); dlm = serial8250_early_in(port, UART_DLM); serial8250_early_out(port, UART_LCR, lcr); quot = (dlm << 8) | dll; return (port->uartclk / 16) / quot; }
static void __init wait_for_xmitr(struct uart_port *port) { unsigned int status; for (;;) { status = serial8250_early_in(port, UART_LSR); if ((status & BOTH_EMPTY) == BOTH_EMPTY) return; cpu_relax(); } }
static void __init init_port(struct earlycon_device *device) { struct uart_port *port = &device->port; unsigned int divisor; unsigned char c; unsigned int ier; serial8250_early_out(port, UART_LCR, 0x3); /* 8n1 */ ier = serial8250_early_in(port, UART_IER); serial8250_early_out(port, UART_IER, ier & UART_IER_UUE); /* no interrupt */ serial8250_early_out(port, UART_FCR, 0); /* no fifo */ serial8250_early_out(port, UART_MCR, 0x3); /* DTR + RTS */ divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * device->baud); c = serial8250_early_in(port, UART_LCR); serial8250_early_out(port, UART_LCR, c | UART_LCR_DLAB); serial8250_early_out(port, UART_DLL, divisor & 0xff); serial8250_early_out(port, UART_DLM, (divisor >> 8) & 0xff); serial8250_early_out(port, UART_LCR, c & ~UART_LCR_DLAB); }
static void __init early_serial8250_write(struct console *console, const char *s, unsigned int count) { struct uart_port *port = &early_device.port; unsigned int ier; /* Save the IER and disable interrupts */ ier = serial8250_early_in(port, UART_IER); serial8250_early_out(port, UART_IER, 0); uart_console_write(port, s, count, serial_putc); /* Wait for transmitter to become empty and restore the IER */ wait_for_xmitr(port); serial8250_early_out(port, UART_IER, ier); }