diff options
author | ganbold <ganbold@FreeBSD.org> | 2013-03-01 01:42:31 +0000 |
---|---|---|
committer | ganbold <ganbold@FreeBSD.org> | 2013-03-01 01:42:31 +0000 |
commit | 07edb9e32756de1022f2fa472b214a481ba329be (patch) | |
tree | debab6aac1c091a248b7bba24f5e298e17a563a9 /sys/dev/uart/uart_dev_ns8250.c | |
parent | b54216a509bd8ecbe2d99ecf22ea8c74471ab751 (diff) | |
download | FreeBSD-src-07edb9e32756de1022f2fa472b214a481ba329be.zip FreeBSD-src-07edb9e32756de1022f2fa472b214a481ba329be.tar.gz |
Add support for A10 uart.
A10 uart is derived from Synopsys DesignWare uart and requires
to read Uart Status Register when IIR_BUSY has detected.
Also this change includes FDT check, where it checks device
specific properties defined in dts and sets the busy_detect variable.
broken_txfifo is also needed to be set in order to make it work for
A10 uart case.
Reviewed by: marcel@
Approved by: gonzo@
Diffstat (limited to 'sys/dev/uart/uart_dev_ns8250.c')
-rw-r--r-- | sys/dev/uart/uart_dev_ns8250.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c index eb36da1..8eca8f0 100644 --- a/sys/dev/uart/uart_dev_ns8250.c +++ b/sys/dev/uart/uart_dev_ns8250.c @@ -24,6 +24,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "opt_platform.h" + #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -35,6 +37,12 @@ __FBSDID("$FreeBSD$"); #include <sys/sysctl.h> #include <machine/bus.h> +#ifdef FDT +#include <dev/fdt/fdt_common.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> +#endif + #include <dev/uart/uart.h> #include <dev/uart/uart_cpu.h> #include <dev/uart/uart_bus.h> @@ -45,6 +53,11 @@ __FBSDID("$FreeBSD$"); #define DEFAULT_RCLK 1843200 +static int broken_txfifo = 0; +SYSCTL_INT(_hw, OID_AUTO, broken_txfifo, CTLFLAG_RW | CTLFLAG_TUN, + &broken_txfifo, 0, "UART FIFO has QEMU emulation bug"); +TUNABLE_INT("hw.broken_txfifo", &broken_txfifo); + /* * Clear pending interrupts. THRE is cleared by reading IIR. Data * that may have been received gets lost here. @@ -350,6 +363,7 @@ struct ns8250_softc { uint8_t ier_mask; uint8_t ier_rxbits; + uint8_t busy_detect; }; static int ns8250_bus_attach(struct uart_softc *); @@ -401,6 +415,24 @@ ns8250_bus_attach(struct uart_softc *sc) struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; struct uart_bas *bas; unsigned int ivar; +#ifdef FDT + phandle_t node; + pcell_t cell; +#endif + + ns8250->busy_detect = 0; + +#ifdef FDT + /* + * Check whether uart requires to read USR reg when IIR_BUSY and + * has broken txfifo. + */ + node = ofw_bus_get_node(sc->sc_dev); + if ((OF_getprop(node, "busy-detect", &cell, sizeof(cell))) > 0) + ns8250->busy_detect = 1; + if ((OF_getprop(node, "broken-txfifo", &cell, sizeof(cell))) > 0) + broken_txfifo = 1; +#endif bas = &sc->sc_bas; @@ -592,6 +624,12 @@ ns8250_bus_ipend(struct uart_softc *sc) bas = &sc->sc_bas; uart_lock(sc->sc_hwmtx); iir = uart_getreg(bas, REG_IIR); + + if (ns8250->busy_detect && (iir & IIR_BUSY) == IIR_BUSY) { + (void)uart_getreg(bas, DW_REG_USR); + uart_unlock(sc->sc_hwmtx); + return (0); + } if (iir & IIR_NOPEND) { uart_unlock(sc->sc_hwmtx); return (0); @@ -847,11 +885,6 @@ ns8250_bus_setsig(struct uart_softc *sc, int sig) return (0); } -static int broken_txfifo = 0; -SYSCTL_INT(_hw, OID_AUTO, broken_txfifo, CTLFLAG_RW | CTLFLAG_TUN, - &broken_txfifo, 0, "UART FIFO has QEMU emulation bug"); -TUNABLE_INT("hw.broken_txfifo", &broken_txfifo); - static int ns8250_bus_transmit(struct uart_softc *sc) { |