summaryrefslogtreecommitdiffstats
path: root/sys/dev/uart/uart_dev_ns8250.c
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2003-09-13 06:25:04 +0000
committermarcel <marcel@FreeBSD.org>2003-09-13 06:25:04 +0000
commit67475622c3e1726e9abdfdf59c37bae5abd1457c (patch)
tree6c822d38e98ac588bdf33e1289902dfa38c835d6 /sys/dev/uart/uart_dev_ns8250.c
parentee4ef644cf8abb7a54eb097d0ce4ccc2ad21a827 (diff)
downloadFreeBSD-src-67475622c3e1726e9abdfdf59c37bae5abd1457c.zip
FreeBSD-src-67475622c3e1726e9abdfdf59c37bae5abd1457c.tar.gz
Add support for automatic hardware flow control for 16[679]50 UARTs.
We simply use the detected FIFO size to determine whether we have a post 16550 UART or not. The support lacks proper serialization of hardware access for now.
Diffstat (limited to 'sys/dev/uart/uart_dev_ns8250.c')
-rw-r--r--sys/dev/uart/uart_dev_ns8250.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c
index ea5d5d0..ada5710 100644
--- a/sys/dev/uart/uart_dev_ns8250.c
+++ b/sys/dev/uart/uart_dev_ns8250.c
@@ -461,7 +461,7 @@ static int
ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
{
struct uart_bas *bas;
- uint8_t lcr;
+ uint8_t efr, lcr;
bas = &sc->sc_bas;
switch (request) {
@@ -474,6 +474,36 @@ ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
uart_setreg(bas, REG_LCR, lcr);
uart_barrier(bas);
break;
+ case UART_IOCTL_IFLOW:
+ lcr = uart_getreg(bas, REG_LCR);
+ uart_barrier(bas);
+ uart_setreg(bas, REG_LCR, 0xbf);
+ uart_barrier(bas);
+ efr = uart_getreg(bas, REG_EFR);
+ if (data)
+ efr |= EFR_RTS;
+ else
+ efr &= ~EFR_RTS;
+ uart_setreg(bas, REG_EFR, efr);
+ uart_barrier(bas);
+ uart_setreg(bas, REG_LCR, lcr);
+ uart_barrier(bas);
+ break;
+ case UART_IOCTL_OFLOW:
+ lcr = uart_getreg(bas, REG_LCR);
+ uart_barrier(bas);
+ uart_setreg(bas, REG_LCR, 0xbf);
+ uart_barrier(bas);
+ efr = uart_getreg(bas, REG_EFR);
+ if (data)
+ efr |= EFR_CTS;
+ else
+ efr &= ~EFR_CTS;
+ uart_setreg(bas, REG_EFR, efr);
+ uart_barrier(bas);
+ uart_setreg(bas, REG_LCR, lcr);
+ uart_barrier(bas);
+ break;
default:
return (EINVAL);
}
@@ -650,6 +680,12 @@ ns8250_bus_probe(struct uart_softc *sc)
*/
sc->sc_txfifosz = 16;
+ /* 16650s or higher have automatic flow control. */
+ if (sc->sc_rxfifosz > 16) {
+ sc->sc_hwiflow = 1;
+ sc->sc_hwoflow = 1;
+ }
+
return (0);
}
OpenPOWER on IntegriCloud