summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/ic/ns16550.h3
-rw-r--r--sys/dev/uart/uart_dev_ns8250.c40
2 files changed, 18 insertions, 25 deletions
diff --git a/sys/dev/ic/ns16550.h b/sys/dev/ic/ns16550.h
index 29b32c5..0400f2b 100644
--- a/sys/dev/ic/ns16550.h
+++ b/sys/dev/ic/ns16550.h
@@ -127,7 +127,8 @@
#define com_dlbl com_dll
#define com_dlm 1 /* divisor latch high (R/W) */
#define com_dlbh com_dlm
-#define REG_DL com_dll
+#define REG_DLL com_dll
+#define REG_DLH com_dlm
/* 16450 register #7. Not multiplexed. */
#define com_scr 7 /* scratch register (R/W) */
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c
index 6c5af19..85cfaec 100644
--- a/sys/dev/uart/uart_dev_ns8250.c
+++ b/sys/dev/uart/uart_dev_ns8250.c
@@ -75,7 +75,7 @@ ns8250_delay(struct uart_bas *bas)
lcr = uart_getreg(bas, REG_LCR);
uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
uart_barrier(bas);
- divisor = uart_getdreg(bas, REG_DL);
+ divisor = uart_getreg(bas, REG_DLL) | (uart_getreg(bas, REG_DLH) << 8);
uart_barrier(bas);
uart_setreg(bas, REG_LCR, lcr);
uart_barrier(bas);
@@ -199,7 +199,8 @@ ns8250_param(struct uart_bas *bas, int baudrate, int databits, int stopbits,
return (EINVAL);
uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
uart_barrier(bas);
- uart_setdreg(bas, REG_DL, divisor);
+ uart_setreg(bas, REG_DLL, divisor & 0xff);
+ uart_setreg(bas, REG_DLH, (divisor >> 8) & 0xff);
uart_barrier(bas);
}
@@ -241,36 +242,22 @@ ns8250_probe(struct uart_bas *bas)
if (val & 0xe0)
return (ENXIO);
- lcr = uart_getreg(bas, REG_LCR);
- uart_setreg(bas, REG_LCR, lcr & ~LCR_DLAB);
- uart_barrier(bas);
-
- /* Check known 0 bits that depend on !DLAB. */
- val = uart_getreg(bas, REG_IER);
- if (val & 0xf0)
- goto fail;
-
- uart_setreg(bas, REG_LCR, lcr);
- uart_barrier(bas);
return (0);
-
- fail:
- uart_setreg(bas, REG_LCR, lcr);
- uart_barrier(bas);
- return (ENXIO);
}
static void
ns8250_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
int parity)
{
+ u_char ier;
if (bas->rclk == 0)
bas->rclk = DEFAULT_RCLK;
ns8250_param(bas, baudrate, databits, stopbits, parity);
/* Disable all interrupt sources. */
- uart_setreg(bas, REG_IER, 0);
+ ier = uart_getreg(bas, REG_IER) & 0xf0;
+ uart_setreg(bas, REG_IER, ier);
uart_barrier(bas);
/* Disable the FIFO (if present). */
@@ -416,7 +403,8 @@ ns8250_bus_attach(struct uart_softc *sc)
ns8250_bus_getsig(sc);
ns8250_clrint(bas);
- ns8250->ier = IER_EMSC | IER_ERLS | IER_ERXRDY;
+ ns8250->ier = uart_getreg(bas, REG_IER) & 0xf0;
+ ns8250->ier |= IER_EMSC | IER_ERLS | IER_ERXRDY;
uart_setreg(bas, REG_IER, ns8250->ier);
uart_barrier(bas);
return (0);
@@ -426,9 +414,11 @@ static int
ns8250_bus_detach(struct uart_softc *sc)
{
struct uart_bas *bas;
+ u_char ier;
bas = &sc->sc_bas;
- uart_setreg(bas, REG_IER, 0);
+ ier = uart_getreg(bas, REG_IER) & 0xf0;
+ uart_setreg(bas, REG_IER, ier);
uart_barrier(bas);
ns8250_clrint(bas);
return (0);
@@ -529,7 +519,8 @@ ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
lcr = uart_getreg(bas, REG_LCR);
uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
uart_barrier(bas);
- divisor = uart_getdreg(bas, REG_DL);
+ divisor = uart_getreg(bas, REG_DLL) |
+ (uart_getreg(bas, REG_DLH) << 8);
uart_barrier(bas);
uart_setreg(bas, REG_LCR, lcr);
uart_barrier(bas);
@@ -600,7 +591,7 @@ ns8250_bus_probe(struct uart_softc *sc)
{
struct uart_bas *bas;
int count, delay, error, limit;
- uint8_t lsr, mcr;
+ uint8_t lsr, mcr, ier;
bas = &sc->sc_bas;
@@ -684,7 +675,8 @@ ns8250_bus_probe(struct uart_softc *sc)
--limit)
DELAY(delay);
if (limit == 0) {
- uart_setreg(bas, REG_IER, 0);
+ ier = uart_getreg(bas, REG_IER) & 0xf0;
+ uart_setreg(bas, REG_IER, ier);
uart_setreg(bas, REG_MCR, mcr);
uart_setreg(bas, REG_FCR, 0);
uart_barrier(bas);
OpenPOWER on IntegriCloud