summaryrefslogtreecommitdiffstats
path: root/sys/dev/uart
diff options
context:
space:
mode:
authorganbold <ganbold@FreeBSD.org>2013-03-01 01:42:31 +0000
committerganbold <ganbold@FreeBSD.org>2013-03-01 01:42:31 +0000
commit07edb9e32756de1022f2fa472b214a481ba329be (patch)
treedebab6aac1c091a248b7bba24f5e298e17a563a9 /sys/dev/uart
parentb54216a509bd8ecbe2d99ecf22ea8c74471ab751 (diff)
downloadFreeBSD-src-07edb9e32756de1022f2fa472b214a481ba329be.zip
FreeBSD-src-07edb9e32756de1022f2fa472b214a481ba329be.tar.gz
Add support for A10 uart.
A10 uart is derived from Synopsys DesignWare uart and requires to read Uart Status Register when IIR_BUSY has detected. Also this change includes FDT check, where it checks device specific properties defined in dts and sets the busy_detect variable. broken_txfifo is also needed to be set in order to make it work for A10 uart case. Reviewed by: marcel@ Approved by: gonzo@
Diffstat (limited to 'sys/dev/uart')
-rw-r--r--sys/dev/uart/uart_dev_ns8250.c43
1 files changed, 38 insertions, 5 deletions
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c
index eb36da1..8eca8f0 100644
--- a/sys/dev/uart/uart_dev_ns8250.c
+++ b/sys/dev/uart/uart_dev_ns8250.c
@@ -24,6 +24,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "opt_platform.h"
+
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -35,6 +37,12 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <machine/bus.h>
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#endif
+
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
#include <dev/uart/uart_bus.h>
@@ -45,6 +53,11 @@ __FBSDID("$FreeBSD$");
#define DEFAULT_RCLK 1843200
+static int broken_txfifo = 0;
+SYSCTL_INT(_hw, OID_AUTO, broken_txfifo, CTLFLAG_RW | CTLFLAG_TUN,
+ &broken_txfifo, 0, "UART FIFO has QEMU emulation bug");
+TUNABLE_INT("hw.broken_txfifo", &broken_txfifo);
+
/*
* Clear pending interrupts. THRE is cleared by reading IIR. Data
* that may have been received gets lost here.
@@ -350,6 +363,7 @@ struct ns8250_softc {
uint8_t ier_mask;
uint8_t ier_rxbits;
+ uint8_t busy_detect;
};
static int ns8250_bus_attach(struct uart_softc *);
@@ -401,6 +415,24 @@ ns8250_bus_attach(struct uart_softc *sc)
struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
struct uart_bas *bas;
unsigned int ivar;
+#ifdef FDT
+ phandle_t node;
+ pcell_t cell;
+#endif
+
+ ns8250->busy_detect = 0;
+
+#ifdef FDT
+ /*
+ * Check whether uart requires to read USR reg when IIR_BUSY and
+ * has broken txfifo.
+ */
+ node = ofw_bus_get_node(sc->sc_dev);
+ if ((OF_getprop(node, "busy-detect", &cell, sizeof(cell))) > 0)
+ ns8250->busy_detect = 1;
+ if ((OF_getprop(node, "broken-txfifo", &cell, sizeof(cell))) > 0)
+ broken_txfifo = 1;
+#endif
bas = &sc->sc_bas;
@@ -592,6 +624,12 @@ ns8250_bus_ipend(struct uart_softc *sc)
bas = &sc->sc_bas;
uart_lock(sc->sc_hwmtx);
iir = uart_getreg(bas, REG_IIR);
+
+ if (ns8250->busy_detect && (iir & IIR_BUSY) == IIR_BUSY) {
+ (void)uart_getreg(bas, DW_REG_USR);
+ uart_unlock(sc->sc_hwmtx);
+ return (0);
+ }
if (iir & IIR_NOPEND) {
uart_unlock(sc->sc_hwmtx);
return (0);
@@ -847,11 +885,6 @@ ns8250_bus_setsig(struct uart_softc *sc, int sig)
return (0);
}
-static int broken_txfifo = 0;
-SYSCTL_INT(_hw, OID_AUTO, broken_txfifo, CTLFLAG_RW | CTLFLAG_TUN,
- &broken_txfifo, 0, "UART FIFO has QEMU emulation bug");
-TUNABLE_INT("hw.broken_txfifo", &broken_txfifo);
-
static int
ns8250_bus_transmit(struct uart_softc *sc)
{
OpenPOWER on IntegriCloud