Author: ian
Date: Sat May 23 20:01:20 2015
New Revision: 283324
URL: https://svnweb.freebsd.org/changeset/base/283324

Log:
  MFC r279239:
  
    Enable 'receive timeout' interrupt allowing us to not
    loose 'rx buffer full' event.

Modified:
  stable/10/sys/dev/uart/uart_dev_pl011.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/uart/uart_dev_pl011.c
==============================================================================
--- stable/10/sys/dev/uart/uart_dev_pl011.c     Sat May 23 19:57:44 2015        
(r283323)
+++ stable/10/sys/dev/uart/uart_dev_pl011.c     Sat May 23 20:01:20 2015        
(r283324)
@@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
 #define        UART_RIS        0x0f            /* Raw interrupt status 
register */
 #define        UART_RXREADY    (1 << 4)        /* RX buffer full */
 #define        UART_TXEMPTY    (1 << 5)        /* TX buffer empty */
+#define        RIS_RTIM        (1 << 6)        /* Receive timeout */
 #define        RIS_FE          (1 << 7)        /* Framing error interrupt 
status */
 #define        RIS_PE          (1 << 8)        /* Parity error interrupt 
status */
 #define        RIS_BE          (1 << 9)        /* Break error interrupt status 
*/
@@ -278,11 +279,15 @@ static int
 uart_pl011_bus_attach(struct uart_softc *sc)
 {
        struct uart_bas *bas;
+       int reg;
 
        bas = &sc->sc_bas;
-       /* Enable RX & TX interrupts */
-       __uart_setreg(bas, UART_IMSC, (UART_RXREADY | UART_TXEMPTY));
-       /* Clear RX & TX interrupts */
+
+       /* Enable interrupts */
+       reg = (UART_RXREADY | RIS_RTIM | UART_TXEMPTY);
+       __uart_setreg(bas, UART_IMSC, reg);
+
+       /* Clear interrupts */
        __uart_setreg(bas, UART_ICR, IMSC_MASK_ALL);
 
        return (0);
@@ -337,15 +342,16 @@ static int
 uart_pl011_bus_ipend(struct uart_softc *sc)
 {
        struct uart_bas *bas;
-       int ipend;
        uint32_t ints;
+       int ipend;
+       int reg;
 
        bas = &sc->sc_bas;
        uart_lock(sc->sc_hwmtx);
        ints = __uart_getreg(bas, UART_MIS);
        ipend = 0;
 
-       if (ints & UART_RXREADY)
+       if (ints & (UART_RXREADY | RIS_RTIM))
                ipend |= SER_INT_RXREADY;
        if (ints & RIS_BE)
                ipend |= SER_INT_BREAK;
@@ -355,7 +361,10 @@ uart_pl011_bus_ipend(struct uart_softc *
                if (sc->sc_txbusy)
                        ipend |= SER_INT_TXIDLE;
 
-               __uart_setreg(bas, UART_IMSC, UART_RXREADY);
+               /* Disable TX interrupt */
+               reg = __uart_getreg(bas, UART_IMSC);
+               reg &= ~(UART_TXEMPTY);
+               __uart_setreg(bas, UART_IMSC, reg);
        }
 
        uart_unlock(sc->sc_hwmtx);
@@ -391,14 +400,14 @@ static int
 uart_pl011_bus_receive(struct uart_softc *sc)
 {
        struct uart_bas *bas;
-       int rx;
        uint32_t ints, xc;
+       int rx;
 
        bas = &sc->sc_bas;
        uart_lock(sc->sc_hwmtx);
 
        ints = __uart_getreg(bas, UART_MIS);
-       while (ints & UART_RXREADY) {
+       while (ints & (UART_RXREADY | RIS_RTIM)) {
                if (uart_rx_full(sc)) {
                        sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
                        break;
@@ -411,7 +420,7 @@ uart_pl011_bus_receive(struct uart_softc
                if (xc & DR_PE)
                        rx |= UART_STAT_PARERR;
 
-               __uart_setreg(bas, UART_ICR, UART_RXREADY);
+               __uart_setreg(bas, UART_ICR, (UART_RXREADY | RIS_RTIM));
 
                uart_rx_put(sc, rx);
                ints = __uart_getreg(bas, UART_MIS);
@@ -433,6 +442,7 @@ static int
 uart_pl011_bus_transmit(struct uart_softc *sc)
 {
        struct uart_bas *bas;
+       int reg;
        int i;
 
        bas = &sc->sc_bas;
@@ -443,7 +453,12 @@ uart_pl011_bus_transmit(struct uart_soft
                uart_barrier(bas);
        }
        sc->sc_txbusy = 1;
-       __uart_setreg(bas, UART_IMSC, (UART_RXREADY | UART_TXEMPTY));
+
+       /* Enable TX interrupt */
+       reg = __uart_getreg(bas, UART_IMSC);
+       reg |= (UART_TXEMPTY);
+       __uart_setreg(bas, UART_IMSC, reg);
+
        uart_unlock(sc->sc_hwmtx);
 
        return (0);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to