aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2012-03-07 09:30:42 +0000
committerKeir Fraser <keir@xen.org>2012-03-07 09:30:42 +0000
commit3ebbff13b667f9923e65a808e639740898774180 (patch)
tree1d0d2d87a16faeb91795a0ae456617fd04656354
parentb1aff7cfd4ad96ee868dfeb392b41aab2e65e136 (diff)
downloadxen-3ebbff13b667f9923e65a808e639740898774180.tar.gz
xen-3ebbff13b667f9923e65a808e639740898774180.tar.bz2
xen-3ebbff13b667f9923e65a808e639740898774180.zip
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@xen.org> xen-unstable changeset: 23811:f1349a968a5a xen-unstable date: Fri Sep 02 14:56:26 2011 +0100 Revert part of 23811:f1349a968a5a "ns16550: Simplify UART..." The change to poll LSR.THRE in a loop from __ns16550_poll is a bug. We can loop indefinitely if there are no chars to transmit. Thanks to Jan for spotting it. Signed-off-by: Keir Fraser <keir@xen.org> xen-unstable changeset: 23948:dcb2bd283dca xen-unstable date: Wed Oct 12 17:11:28 2011 +0100
-rw-r--r--xen/drivers/char/ns16550.c25
1 files changed, 5 insertions, 20 deletions
diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index 46ae7bd6c8..cea45300d6 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -39,7 +39,7 @@ static struct ns16550 {
/* 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 */
@@ -133,12 +133,7 @@ static void ns16550_interrupt(
struct serial_port *port = dev_id;
struct ns16550 *uart = port->uart;
- if (uart->intr_works == 0)
- {
- uart->probing = 0;
- uart->intr_works = 1;
- stop_timer(&uart->timer);
- }
+ uart->intr_works = 1;
while ( !(ns_read_reg(uart, IIR) & IIR_NOINT) )
{
@@ -150,7 +145,7 @@ static void ns16550_interrupt(
}
}
-/* 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)
@@ -161,12 +156,6 @@ static void __ns16550_poll(struct cpu_user_regs *regs)
if ( uart->intr_works )
return; /* Interrupts work - no more polling */
- if ( uart->probing ) {
- uart->probing = 0;
- if ( (ns_read_reg(uart, LSR) & 0xff) == 0xff )
- return; /* All bits set - probably no UART present */
- }
-
while ( ns_read_reg(uart, LSR) & LSR_DR )
serial_rx_interrupt(port, regs);
@@ -230,6 +219,8 @@ static void __devinit ns16550_init_preirq(struct serial_port *port)
unsigned char lcr;
unsigned int divisor;
+ uart->intr_works = 0;
+
pci_serial_early_init(uart);
/* I/O ports are distinguished by their size (16 bits). */
@@ -304,12 +295,6 @@ static void __devinit ns16550_init_postirq(struct serial_port *port)
/* 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);
- set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
}
}