summaryrefslogtreecommitdiffstats
path: root/sys/dev/uart/uart_dev_ns8250.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/uart/uart_dev_ns8250.c')
-rw-r--r--sys/dev/uart/uart_dev_ns8250.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c
index d2a3dcf..81642b2 100644
--- a/sys/dev/uart/uart_dev_ns8250.c
+++ b/sys/dev/uart/uart_dev_ns8250.c
@@ -258,7 +258,12 @@ ns8250_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
ns8250_param(bas, baudrate, databits, stopbits, parity);
/* Disable all interrupt sources. */
- ier = uart_getreg(bas, REG_IER) & 0xf0;
+ /*
+ * We use 0xe0 instead of 0xf0 as the mask because the XScale PXA
+ * UARTs split the receive time-out interrupt bit out separately as
+ * 0x10. This gets handled by ier_mask and ier_rxbits below.
+ */
+ ier = uart_getreg(bas, REG_IER) & 0xe0;
uart_setreg(bas, REG_IER, ier);
uart_barrier(bas);
@@ -332,6 +337,9 @@ struct ns8250_softc {
uint8_t fcr;
uint8_t ier;
uint8_t mcr;
+
+ uint8_t ier_mask;
+ uint8_t ier_rxbits;
};
static int ns8250_bus_attach(struct uart_softc *);
@@ -400,6 +408,19 @@ ns8250_bus_attach(struct uart_softc *sc)
ns8250->fcr |= FCR_RX_MEDH;
} else
ns8250->fcr |= FCR_RX_MEDH;
+
+ /* Get IER mask */
+ ivar = 0xf0;
+ resource_int_value("uart", device_get_unit(sc->sc_dev), "ier_mask",
+ &ivar);
+ ns8250->ier_mask = (uint8_t)(ivar & 0xff);
+
+ /* Get IER RX interrupt bits */
+ ivar = IER_EMSC | IER_ERLS | IER_ERXRDY;
+ resource_int_value("uart", device_get_unit(sc->sc_dev), "ier_rxbits",
+ &ivar);
+ ns8250->ier_rxbits = (uint8_t)(ivar & 0xff);
+
uart_setreg(bas, REG_FCR, ns8250->fcr);
uart_barrier(bas);
ns8250_bus_flush(sc, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER);
@@ -411,21 +432,24 @@ ns8250_bus_attach(struct uart_softc *sc)
ns8250_bus_getsig(sc);
ns8250_clrint(bas);
- ns8250->ier = uart_getreg(bas, REG_IER) & 0xf0;
- ns8250->ier |= IER_EMSC | IER_ERLS | IER_ERXRDY;
+ ns8250->ier = uart_getreg(bas, REG_IER) & ns8250->ier_mask;
+ ns8250->ier |= ns8250->ier_rxbits;
uart_setreg(bas, REG_IER, ns8250->ier);
uart_barrier(bas);
+
return (0);
}
static int
ns8250_bus_detach(struct uart_softc *sc)
{
+ struct ns8250_softc *ns8250;
struct uart_bas *bas;
u_char ier;
+ ns8250 = (struct ns8250_softc *)sc;
bas = &sc->sc_bas;
- ier = uart_getreg(bas, REG_IER) & 0xf0;
+ ier = uart_getreg(bas, REG_IER) & ns8250->ier_mask;
uart_setreg(bas, REG_IER, ier);
uart_barrier(bas);
ns8250_clrint(bas);
@@ -597,10 +621,12 @@ ns8250_bus_param(struct uart_softc *sc, int baudrate, int databits,
static int
ns8250_bus_probe(struct uart_softc *sc)
{
+ struct ns8250_softc *ns8250;
struct uart_bas *bas;
int count, delay, error, limit;
uint8_t lsr, mcr, ier;
+ ns8250 = (struct ns8250_softc *)sc;
bas = &sc->sc_bas;
error = ns8250_probe(bas);
@@ -683,7 +709,7 @@ ns8250_bus_probe(struct uart_softc *sc)
--limit)
DELAY(delay);
if (limit == 0) {
- ier = uart_getreg(bas, REG_IER) & 0xf0;
+ ier = uart_getreg(bas, REG_IER) & ns8250->ier_mask;
uart_setreg(bas, REG_IER, ier);
uart_setreg(bas, REG_MCR, mcr);
uart_setreg(bas, REG_FCR, 0);
OpenPOWER on IntegriCloud