Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 23 May 2015 20:01:21 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r283324 - stable/10/sys/dev/uart
Message-ID:  <201505232001.t4NK1L0w061202@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505232001.t4NK1L0w061202>