summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandrew <andrew@FreeBSD.org>2015-03-03 09:48:19 +0000
committerandrew <andrew@FreeBSD.org>2015-03-03 09:48:19 +0000
commit6e4d5a7168cd2b4477b7a3e4cef6729e6af85521 (patch)
treefadd53d6f3534ce87334ae77bd96cbb8be2b349f
parentefdf3024fd8370c0000a527463fc426d2c0a8cdf (diff)
downloadFreeBSD-src-6e4d5a7168cd2b4477b7a3e4cef6729e6af85521.zip
FreeBSD-src-6e4d5a7168cd2b4477b7a3e4cef6729e6af85521.tar.gz
Fix the pl011 driver to work when the uart will write in zero cycles. This
is the case, depending on the options, in some of the ARM hardware simulators. In these cases we don't get an interrupt so will need to schedule the task to write more data to the uart. MFC after: 1 week Sponsored by: The FreeBSD Foundation
-rw-r--r--sys/dev/uart/uart_dev_pl011.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/sys/dev/uart/uart_dev_pl011.c b/sys/dev/uart/uart_dev_pl011.c
index 1d17286..e8e23d5 100644
--- a/sys/dev/uart/uart_dev_pl011.c
+++ b/sys/dev/uart/uart_dev_pl011.c
@@ -452,15 +452,23 @@ uart_pl011_bus_transmit(struct uart_softc *sc)
__uart_setreg(bas, UART_DR, sc->sc_txbuf[i]);
uart_barrier(bas);
}
- sc->sc_txbusy = 1;
- /* Enable TX interrupt */
- reg = __uart_getreg(bas, UART_IMSC);
- reg |= (UART_TXEMPTY);
- __uart_setreg(bas, UART_IMSC, reg);
+ /* If not empty wait until it is */
+ if ((__uart_getreg(bas, UART_FR) & FR_TXFE) != FR_TXFE) {
+ sc->sc_txbusy = 1;
+
+ /* Enable TX interrupt */
+ reg = __uart_getreg(bas, UART_IMSC);
+ reg |= (UART_TXEMPTY);
+ __uart_setreg(bas, UART_IMSC, reg);
+ }
uart_unlock(sc->sc_hwmtx);
+ /* No interrupt expected, schedule the next fifo write */
+ if (!sc->sc_txbusy)
+ uart_sched_softih(sc, SER_INT_TXIDLE);
+
return (0);
}
OpenPOWER on IntegriCloud