diff options
author | ian <ian@FreeBSD.org> | 2015-05-23 20:01:20 +0000 |
---|---|---|
committer | ian <ian@FreeBSD.org> | 2015-05-23 20:01:20 +0000 |
commit | 142829f4c84994fedf96baad0c9a95317ffd241c (patch) | |
tree | c8089e7c7bef2668f6b90d723abb9238348b591b /sys/dev/uart | |
parent | 446930c903da0e661ec3358fe3105c9d0b3a9ab0 (diff) | |
download | FreeBSD-src-142829f4c84994fedf96baad0c9a95317ffd241c.zip FreeBSD-src-142829f4c84994fedf96baad0c9a95317ffd241c.tar.gz |
MFC r279239:
Enable 'receive timeout' interrupt allowing us to not
loose 'rx buffer full' event.
Diffstat (limited to 'sys/dev/uart')
-rw-r--r-- | sys/dev/uart/uart_dev_pl011.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/sys/dev/uart/uart_dev_pl011.c b/sys/dev/uart/uart_dev_pl011.c index 2e5ac8c..1d17286 100644 --- a/sys/dev/uart/uart_dev_pl011.c +++ b/sys/dev/uart/uart_dev_pl011.c @@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$"); #define UART_RIS 0x0f /* Raw interrupt status register */ #define UART_RXREADY (1 << 4) /* RX buffer full */ #define UART_TXEMPTY (1 << 5) /* TX buffer empty */ +#define RIS_RTIM (1 << 6) /* Receive timeout */ #define RIS_FE (1 << 7) /* Framing error interrupt status */ #define RIS_PE (1 << 8) /* Parity error interrupt status */ #define RIS_BE (1 << 9) /* Break error interrupt status */ @@ -278,11 +279,15 @@ static int uart_pl011_bus_attach(struct uart_softc *sc) { struct uart_bas *bas; + int reg; bas = &sc->sc_bas; - /* Enable RX & TX interrupts */ - __uart_setreg(bas, UART_IMSC, (UART_RXREADY | UART_TXEMPTY)); - /* Clear RX & TX interrupts */ + + /* Enable interrupts */ + reg = (UART_RXREADY | RIS_RTIM | UART_TXEMPTY); + __uart_setreg(bas, UART_IMSC, reg); + + /* Clear interrupts */ __uart_setreg(bas, UART_ICR, IMSC_MASK_ALL); return (0); @@ -337,15 +342,16 @@ static int uart_pl011_bus_ipend(struct uart_softc *sc) { struct uart_bas *bas; - int ipend; uint32_t ints; + int ipend; + int reg; bas = &sc->sc_bas; uart_lock(sc->sc_hwmtx); ints = __uart_getreg(bas, UART_MIS); ipend = 0; - if (ints & UART_RXREADY) + if (ints & (UART_RXREADY | RIS_RTIM)) ipend |= SER_INT_RXREADY; if (ints & RIS_BE) ipend |= SER_INT_BREAK; @@ -355,7 +361,10 @@ uart_pl011_bus_ipend(struct uart_softc *sc) if (sc->sc_txbusy) ipend |= SER_INT_TXIDLE; - __uart_setreg(bas, UART_IMSC, UART_RXREADY); + /* Disable TX interrupt */ + reg = __uart_getreg(bas, UART_IMSC); + reg &= ~(UART_TXEMPTY); + __uart_setreg(bas, UART_IMSC, reg); } uart_unlock(sc->sc_hwmtx); @@ -391,14 +400,14 @@ static int uart_pl011_bus_receive(struct uart_softc *sc) { struct uart_bas *bas; - int rx; uint32_t ints, xc; + int rx; bas = &sc->sc_bas; uart_lock(sc->sc_hwmtx); ints = __uart_getreg(bas, UART_MIS); - while (ints & UART_RXREADY) { + while (ints & (UART_RXREADY | RIS_RTIM)) { if (uart_rx_full(sc)) { sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; break; @@ -411,7 +420,7 @@ uart_pl011_bus_receive(struct uart_softc *sc) if (xc & DR_PE) rx |= UART_STAT_PARERR; - __uart_setreg(bas, UART_ICR, UART_RXREADY); + __uart_setreg(bas, UART_ICR, (UART_RXREADY | RIS_RTIM)); uart_rx_put(sc, rx); ints = __uart_getreg(bas, UART_MIS); @@ -433,6 +442,7 @@ static int uart_pl011_bus_transmit(struct uart_softc *sc) { struct uart_bas *bas; + int reg; int i; bas = &sc->sc_bas; @@ -443,7 +453,12 @@ uart_pl011_bus_transmit(struct uart_softc *sc) uart_barrier(bas); } sc->sc_txbusy = 1; - __uart_setreg(bas, UART_IMSC, (UART_RXREADY | UART_TXEMPTY)); + + /* Enable TX interrupt */ + reg = __uart_getreg(bas, UART_IMSC); + reg |= (UART_TXEMPTY); + __uart_setreg(bas, UART_IMSC, reg); + uart_unlock(sc->sc_hwmtx); return (0); |