diff --git a/sys/dev/ic/ns16550.h b/sys/dev/ic/ns16550.h index 29b32c5b6ad7..0400f2babdd2 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 6c5af1985ec2..85cfaec2b675 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);