aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/uart
diff options
context:
space:
mode:
authorPeter Grehan <grehan@FreeBSD.org>2012-04-12 18:46:48 +0000
committerPeter Grehan <grehan@FreeBSD.org>2012-04-12 18:46:48 +0000
commit332cda07c00e3fd29889437c2de4d5dfcd10c6a3 (patch)
tree294c5abbdb85706a536e44ca167e0d870538f4de /sys/dev/uart
parent748205a3703147c4587ea21e78bfdb84037df076 (diff)
downloadsrc-332cda07c00e3fd29889437c2de4d5dfcd10c6a3.tar.gz
src-332cda07c00e3fd29889437c2de4d5dfcd10c6a3.zip
Complete polled-mode operation by using a callout if the device will be
used in polled-mode. The callout invokes uart_intr, which rearms the timeout. Implemented for bhyve, but generically useful for e.g. embedded bringup when the interrupt controller hasn't been setup, or if it's not deemed worthy to wire an interrupt line from a serial port. Submitted by: neel Reviewed by: marcel Obtained from: NetApp MFC after: 3 weeks
Notes
Notes: svn path=/head/; revision=234194
Diffstat (limited to 'sys/dev/uart')
-rw-r--r--sys/dev/uart/uart_bus.h1
-rw-r--r--sys/dev/uart/uart_core.c15
-rw-r--r--sys/dev/uart/uart_if.m1
3 files changed, 16 insertions, 1 deletions
diff --git a/sys/dev/uart/uart_bus.h b/sys/dev/uart/uart_bus.h
index b1498f5f0a99..01752d0592c0 100644
--- a/sys/dev/uart/uart_bus.h
+++ b/sys/dev/uart/uart_bus.h
@@ -87,6 +87,7 @@ struct uart_softc {
struct resource *sc_ires; /* Interrupt resource. */
void *sc_icookie;
int sc_irid;
+ struct callout sc_timer;
int sc_callout:1; /* This UART is opened for callout. */
int sc_fastintr:1; /* This UART uses fast interrupts. */
diff --git a/sys/dev/uart/uart_core.c b/sys/dev/uart/uart_core.c
index fb1bb6433040..47d5f3d97713 100644
--- a/sys/dev/uart/uart_core.c
+++ b/sys/dev/uart/uart_core.c
@@ -58,6 +58,12 @@ SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs =
static MALLOC_DEFINE(M_UART, "UART", "UART driver");
+#ifndef UART_POLL_FREQ
+#define UART_POLL_FREQ 50
+#endif
+static int uart_poll_freq = UART_POLL_FREQ;
+TUNABLE_INT("debug.uart_poll_freq", &uart_poll_freq);
+
void
uart_add_sysdev(struct uart_devinfo *di)
{
@@ -257,6 +263,12 @@ uart_intr(void *arg)
if (ipend & SER_INT_TXIDLE)
uart_intr_txidle(sc);
}
+
+ if (sc->sc_polled) {
+ callout_reset(&sc->sc_timer, hz / uart_poll_freq,
+ (timeout_t *)uart_intr, sc);
+ }
+
return((flag)?FILTER_HANDLED:FILTER_STRAY);
}
@@ -440,8 +452,9 @@ uart_bus_attach(device_t dev)
}
}
if (sc->sc_ires == NULL) {
- /* XXX no interrupt resource. Force polled mode. */
+ /* No interrupt resource. Force polled mode. */
sc->sc_polled = 1;
+ callout_init(&sc->sc_timer, 1);
}
sc->sc_rxbufsz = 384;
diff --git a/sys/dev/uart/uart_if.m b/sys/dev/uart/uart_if.m
index 0bb145490ed4..bfac07134486 100644
--- a/sys/dev/uart/uart_if.m
+++ b/sys/dev/uart/uart_if.m
@@ -26,6 +26,7 @@
# $FreeBSD$
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/bus.h>