[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] ns16550: Simplify UART and UART-interrupt probing logic.
# HG changeset patch # User Keir Fraser <keir@xxxxxxx> # Date 1314971786 -3600 # Node ID f1349a968a5ac5577d67ad4a3f3490c580dbe264 # Parent a6a5bda3c962f1e9a14fcbb770c7e3b7cd62bee4 ns16550: Simplify UART and UART-interrupt probing logic. 1. No need to check for UART existence in the polling routine. We already check for UART existence during boot-time initialisation (see check_existence() function). 2. No obvious need to send a dummy character. The poll routine will run until a character is eventually sent, but for the most common use of serial ports (console logging) that will happen almost immediately. Signed-off-by: Keir Fraser <keir@xxxxxxx> --- diff -r a6a5bda3c962 -r f1349a968a5a xen/drivers/char/ns16550.c --- a/xen/drivers/char/ns16550.c Thu Sep 01 17:46:43 2011 +0100 +++ b/xen/drivers/char/ns16550.c Fri Sep 02 14:56:26 2011 +0100 @@ -43,7 +43,7 @@ /* UART with no IRQ line: periodically-polled I/O. */ struct timer timer; unsigned int timeout_ms; - bool_t probing, intr_works; + bool_t intr_works; /* PCI card parameters. */ unsigned int pb_bdf[3]; /* pci bridge BDF */ unsigned int ps_bdf[3]; /* pci serial port BDF */ @@ -138,12 +138,7 @@ struct serial_port *port = dev_id; struct ns16550 *uart = port->uart; - if ( !uart->intr_works ) - { - uart->probing = 0; - uart->intr_works = 1; - stop_timer(&uart->timer); - } + uart->intr_works = 1; while ( !(ns_read_reg(uart, IIR) & IIR_NOINT) ) { @@ -155,30 +150,26 @@ } } -/* Safe: ns16550_poll() runs in softirq context so not reentrant on a given CPU. */ +/* Safe: ns16550_poll() runs as softirq so not reentrant on a given CPU. */ static DEFINE_PER_CPU(struct serial_port *, poll_port); static void __ns16550_poll(struct cpu_user_regs *regs) { struct serial_port *port = this_cpu(poll_port); struct ns16550 *uart = port->uart; + char lsr; if ( uart->intr_works ) return; /* Interrupts work - no more polling */ - if ( uart->probing ) + while ( (lsr = ns_read_reg(uart, LSR)) & (LSR_DR|LSR_THRE) ) { - uart->probing = 0; - if ( (ns_read_reg(uart, LSR) & 0xff) == 0xff ) - return; /* All bits set - probably no UART present */ + if ( lsr & LSR_THRE ) + serial_tx_interrupt(port, regs); + if ( lsr & LSR_DR ) + serial_rx_interrupt(port, regs); } - while ( ns_read_reg(uart, LSR) & LSR_DR ) - serial_rx_interrupt(port, regs); - - if ( ns_read_reg(uart, LSR) & LSR_THRE ) - serial_tx_interrupt(port, regs); - set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms)); } @@ -235,6 +226,8 @@ unsigned char lcr; unsigned int divisor; + uart->intr_works = 0; + pci_serial_early_init(uart); lcr = (uart->data_bits - 5) | ((uart->stop_bits - 1) << 2) | uart->parity; @@ -292,11 +285,6 @@ /* Enable receive and transmit interrupts. */ ns_write_reg(uart, IER, IER_ERDAI | IER_ETHREI); - - /* Do a timed write to make sure we are getting interrupts. */ - uart->probing = 1; - uart->intr_works = 0; - ns_write_reg(uart, THR, 0xff); } if ( uart->irq >= 0 ) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |