[Midnightbsd-cvs] src [10057] trunk/sys/dev: update ubsec and uart

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun May 27 18:53:07 EDT 2018


Revision: 10057
          http://svnweb.midnightbsd.org/src/?rev=10057
Author:   laffer1
Date:     2018-05-27 18:53:06 -0400 (Sun, 27 May 2018)
Log Message:
-----------
update ubsec and uart

Modified Paths:
--------------
    trunk/sys/dev/uart/uart.h
    trunk/sys/dev/uart/uart_bus.h
    trunk/sys/dev/uart/uart_bus_acpi.c
    trunk/sys/dev/uart/uart_bus_ebus.c
    trunk/sys/dev/uart/uart_bus_fdt.c
    trunk/sys/dev/uart/uart_bus_isa.c
    trunk/sys/dev/uart/uart_bus_pccard.c
    trunk/sys/dev/uart/uart_bus_pci.c
    trunk/sys/dev/uart/uart_bus_puc.c
    trunk/sys/dev/uart/uart_bus_scc.c
    trunk/sys/dev/uart/uart_core.c
    trunk/sys/dev/uart/uart_cpu.h
    trunk/sys/dev/uart/uart_cpu_pc98.c
    trunk/sys/dev/uart/uart_cpu_powerpc.c
    trunk/sys/dev/uart/uart_cpu_sparc64.c
    trunk/sys/dev/uart/uart_dbg.c
    trunk/sys/dev/uart/uart_dev_ns8250.c
    trunk/sys/dev/uart/uart_dev_quicc.c
    trunk/sys/dev/uart/uart_dev_sab82532.c
    trunk/sys/dev/uart/uart_dev_z8530.c
    trunk/sys/dev/uart/uart_if.m
    trunk/sys/dev/uart/uart_kbd_sun.c
    trunk/sys/dev/uart/uart_kbd_sun.h
    trunk/sys/dev/uart/uart_kbd_sun_tables.h
    trunk/sys/dev/uart/uart_subr.c
    trunk/sys/dev/uart/uart_tty.c
    trunk/sys/dev/ubsec/ubsec.c
    trunk/sys/dev/ubsec/ubsecreg.h
    trunk/sys/dev/ubsec/ubsecvar.h

Added Paths:
-----------
    trunk/sys/dev/uart/uart_cpu_fdt.c
    trunk/sys/dev/uart/uart_cpu_fdt.h
    trunk/sys/dev/uart/uart_cpu_ia64.c
    trunk/sys/dev/uart/uart_cpu_x86.c
    trunk/sys/dev/uart/uart_dev_imx.c
    trunk/sys/dev/uart/uart_dev_imx.h
    trunk/sys/dev/uart/uart_dev_lpc.c
    trunk/sys/dev/uart/uart_dev_msm.c
    trunk/sys/dev/uart/uart_dev_msm.h
    trunk/sys/dev/uart/uart_dev_ns8250.h
    trunk/sys/dev/uart/uart_dev_pl011.c
    trunk/sys/dev/uart/uart_dev_ti8250.c
    trunk/sys/dev/uart/uart_ppstypes.h

Property Changed:
----------------
    trunk/sys/dev/uart/uart_if.m

Modified: trunk/sys/dev/uart/uart.h
===================================================================
--- trunk/sys/dev/uart/uart.h	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart.h	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 Marcel Moolenaar
  * All rights reserved.
@@ -23,7 +24,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/uart/uart.h 283327 2015-05-23 20:54:25Z ian $
  */
 
 #ifndef _DEV_UART_H_
@@ -66,6 +67,7 @@
 
 extern struct uart_class uart_ns8250_class __attribute__((weak));
 extern struct uart_class uart_quicc_class __attribute__((weak));
+extern struct uart_class uart_s3c2410_class __attribute__((weak));
 extern struct uart_class uart_sab82532_class __attribute__((weak));
 extern struct uart_class uart_sbbc_class __attribute__((weak));
 extern struct uart_class uart_z8530_class __attribute__((weak));

Modified: trunk/sys/dev/uart/uart_bus.h
===================================================================
--- trunk/sys/dev/uart/uart_bus.h	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_bus.h	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 Marcel Moolenaar
  * All rights reserved.
@@ -23,7 +24,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/uart/uart_bus.h 294229 2016-01-17 18:18:01Z ian $
  */
 
 #ifndef _DEV_UART_BUS_H_
@@ -48,14 +49,6 @@
 #define	UART_STAT_OVERRUN	0x0400
 #define	UART_STAT_PARERR	0x0800
 
-#ifdef UART_PPS_ON_CTS
-#define	UART_SIG_DPPS		SER_DCTS
-#define	UART_SIG_PPS		SER_CTS
-#else
-#define	UART_SIG_DPPS		SER_DDCD
-#define	UART_SIG_PPS		SER_DCD
-#endif
-
 /* UART_IOCTL() requests */
 #define	UART_IOCTL_BREAK	1
 #define	UART_IOCTL_IFLOW	2
@@ -87,6 +80,7 @@
 	struct resource *sc_ires;	/* Interrupt resource. */
 	void		*sc_icookie;
 	int		sc_irid;
+	struct callout	sc_timer;
 
 	int		sc_callout:1;	/* This UART is opened for callout. */
 	int		sc_fastintr:1;	/* This UART uses fast interrupts. */
@@ -97,6 +91,7 @@
 	int		sc_polled:1;	/* This UART has no interrupts. */
 	int		sc_txbusy:1;	/* This UART is transmitting. */
 	int		sc_isquelch:1;	/* This UART has input squelched. */
+	int		sc_testintr:1;	/* This UART is under int. testing. */
 
 	struct uart_devinfo *sc_sysdev;	/* System device (or NULL). */
 
@@ -117,6 +112,8 @@
 
 	/* Pulse capturing support (PPS). */
 	struct pps_state sc_pps;
+	int		 sc_pps_mode;
+	sbintime_t	 sc_pps_captime;
 
 	/* Upper layer data. */
 	void		*sc_softih;
@@ -133,7 +130,7 @@
 };
 
 extern devclass_t uart_devclass;
-extern char uart_driver_name[];
+extern const char uart_driver_name[];
 
 int uart_bus_attach(device_t dev);
 int uart_bus_detach(device_t dev);
@@ -147,6 +144,7 @@
 
 int uart_tty_attach(struct uart_softc *);
 int uart_tty_detach(struct uart_softc *);
+struct mtx *uart_tty_getlock(struct uart_softc *);
 void uart_tty_intr(void *arg);
 
 /*
@@ -155,6 +153,7 @@
 static __inline int
 uart_rx_empty(struct uart_softc *sc)
 {
+
 	return ((sc->sc_rxget == sc->sc_rxput) ? 1 : 0);
 }
 
@@ -161,8 +160,9 @@
 static __inline int
 uart_rx_full(struct uart_softc *sc)
 {
-	return ((sc->sc_rxput + 1 < sc->sc_rxbufsz)
-	    ? (sc->sc_rxput + 1 == sc->sc_rxget) : (sc->sc_rxget == 0));
+
+	return ((sc->sc_rxput + 1 < sc->sc_rxbufsz) ?
+	    (sc->sc_rxput + 1 == sc->sc_rxget) : (sc->sc_rxget == 0));
 }
 
 static __inline int

Modified: trunk/sys/dev/uart/uart_bus_acpi.c
===================================================================
--- trunk/sys/dev/uart/uart_bus_acpi.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_bus_acpi.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2001 M. Warner Losh.  All rights reserved.
  *
@@ -23,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_bus_acpi.c 315417 2017-03-16 15:43:32Z ian $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -64,6 +65,7 @@
 	{0x1005d041, "Generic IRDA-compatible device"},	/* PNP0510 */
 	{0x1105d041, "Generic IRDA-compatible device"},	/* PNP0511 */
 	{0x04f0235c, "Wacom Tablet PC Screen"},		/* WACF004 */
+	{0x0ef0235c, "Wacom Tablet PC Screen 00e"},	/* WACF00e */
 	{0xe502aa1a, "Wacom Tablet at FuS Lifebook T"},	/* FUJ02E5 */
 	{0}
 };

Modified: trunk/sys/dev/uart/uart_bus_ebus.c
===================================================================
--- trunk/sys/dev/uart/uart_bus_ebus.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_bus_ebus.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2001 by Thomas Moestl <tmm at FreeBSD.org>.
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_bus_ebus.c 200926 2009-12-23 22:31:43Z marius $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

Modified: trunk/sys/dev/uart/uart_bus_fdt.c
===================================================================
--- trunk/sys/dev/uart/uart_bus_fdt.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_bus_fdt.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2009-2010 The FreeBSD Foundation
  * All rights reserved.
@@ -28,8 +29,10 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_bus_fdt.c 283481 2015-05-24 17:57:29Z ian $");
 
+#include "opt_platform.h"
+
 #include <sys/param.h>
 #include <sys/bus.h>
 #include <sys/kernel.h>
@@ -36,7 +39,6 @@
 #include <sys/module.h>
 
 #include <machine/bus.h>
-#include <machine/fdt.h>
 
 #include <dev/fdt/fdt_common.h>
 #include <dev/ofw/ofw_bus.h>
@@ -44,6 +46,7 @@
 #include <dev/uart/uart.h>
 #include <dev/uart/uart_bus.h>
 #include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_cpu_fdt.h>
 
 static int uart_fdt_probe(device_t);
 
@@ -61,37 +64,46 @@
 	sizeof(struct uart_softc),
 };
 
-static int
+int
 uart_fdt_get_clock(phandle_t node, pcell_t *cell)
 {
-	pcell_t clock;
 
-	if ((OF_getprop(node, "clock-frequency", &clock,
-	    sizeof(clock))) <= 0)
-		return (ENXIO);
-
-	if (clock == 0)
+	/* clock-frequency is a FreeBSD-only extention. */
+	if ((OF_getencprop(node, "clock-frequency", cell,
+	    sizeof(*cell))) <= 0) {
 		/* Try to retrieve parent 'bus-frequency' */
 		/* XXX this should go to simple-bus fixup or so */
-		if ((OF_getprop(OF_parent(node), "bus-frequency", &clock,
-		    sizeof(clock))) <= 0)
-			clock = 0;
+		if ((OF_getencprop(OF_parent(node), "bus-frequency", cell,
+		    sizeof(*cell))) <= 0)
+			*cell = 0;
+	}
 
-	*cell = fdt32_to_cpu(clock);
 	return (0);
 }
 
-static int
+int
 uart_fdt_get_shift(phandle_t node, pcell_t *cell)
 {
-	pcell_t shift;
 
-	if ((OF_getprop(node, "reg-shift", &shift, sizeof(shift))) <= 0)
-		shift = 0;
-	*cell = fdt32_to_cpu(shift);
+	if ((OF_getencprop(node, "reg-shift", cell, sizeof(*cell))) <= 0)
+		*cell = 0;
 	return (0);
 }
 
+static uintptr_t
+uart_fdt_find_device(device_t dev)
+{
+	struct ofw_compat_data **cd;
+	const struct ofw_compat_data *ocd;
+
+	SET_FOREACH(cd, uart_fdt_class_and_device_set) {
+		ocd = ofw_bus_search_compatible(dev, *cd);
+		if (ocd->ocd_data != 0)
+			return (ocd->ocd_data);
+	}
+	return (0);
+}
+
 static int
 uart_fdt_probe(device_t dev)
 {
@@ -100,11 +112,14 @@
 	pcell_t clock, shift;
 	int err;
 
-	if (!ofw_bus_is_compatible(dev, "ns16550"))
+	sc = device_get_softc(dev);
+
+	if (!ofw_bus_status_okay(dev))
 		return (ENXIO);
 
-	sc = device_get_softc(dev);
-	sc->sc_class = &uart_ns8250_class;
+	sc->sc_class = (struct uart_class *)uart_fdt_find_device(dev);
+	if (sc->sc_class == NULL)
+		return (ENXIO);
 
 	node = ofw_bus_get_node(dev);
 
@@ -116,88 +131,4 @@
 }
 
 DRIVER_MODULE(uart, simplebus, uart_fdt_driver, uart_devclass, 0, 0);
-
-/*
- * UART console routines.
- */
-bus_space_tag_t uart_bus_space_io;
-bus_space_tag_t uart_bus_space_mem;
-
-int
-uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
-{
-
-	return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
-}
-
-int
-uart_cpu_getdev(int devtype, struct uart_devinfo *di)
-{
-	char buf[64];
-	struct uart_class *class;
-	phandle_t node, chosen;
-	pcell_t shift, br, rclk;
-	u_long start, size;
-	int err;
-
-	uart_bus_space_mem = fdtbus_bs_tag;
-	uart_bus_space_io = NULL;
-
-	/* Allow overriding the FDT uning the environment. */
-	class = &uart_ns8250_class;
-	err = uart_getenv(devtype, di, class);
-	if (!err)
-		return (0);
-
-	if (devtype != UART_DEV_CONSOLE)
-		return (ENXIO);
-
-	/*
-	 * Retrieve /chosen/std{in,out}.
-	 */
-	if ((chosen = OF_finddevice("/chosen")) == 0)
-		return (ENXIO);
-	if (OF_getprop(chosen, "stdin", buf, sizeof(buf)) <= 0)
-		return (ENXIO);
-	if ((node = OF_finddevice(buf)) == 0)
-		return (ENXIO);
-	if (OF_getprop(chosen, "stdout", buf, sizeof(buf)) <= 0)
-		return (ENXIO);
-	if (OF_finddevice(buf) != node)
-		/* Only stdin == stdout is supported. */
-		return (ENXIO);
-	/*
-	 * Retrieve serial attributes.
-	 */
-	uart_fdt_get_shift(node, &shift);
-
-	if (OF_getprop(node, "current-speed", &br, sizeof(br)) <= 0)
-		br = 0;
-	br = fdt32_to_cpu(br);
-
-	if ((err = uart_fdt_get_clock(node, &rclk)) != 0)
-		return (err);
-	/*
-	 * Finalize configuration.
-	 */
-	class = &uart_quicc_class;
-	if (fdt_is_compatible(node, "ns16550"))
-		class = &uart_ns8250_class;
-
-	di->bas.chan = 0;
-	di->bas.regshft = (u_int)shift;
-	di->baudrate = 0;
-	di->bas.rclk = (u_int)rclk;
-	di->ops = uart_getops(class);
-	di->databits = 8;
-	di->stopbits = 1;
-	di->parity = UART_PARITY_NONE;
-	di->bas.bst = uart_bus_space_mem;
-
-	err = fdt_regsize(node, &start, &size);
-	if (err)
-		return (ENXIO);
-	start += fdt_immr_va;
-
-	return (bus_space_map(di->bas.bst, start, size, 0, &di->bas.bsh));
-}
+DRIVER_MODULE(uart, ofwbus, uart_fdt_driver, uart_devclass, 0, 0);

Modified: trunk/sys/dev/uart/uart_bus_isa.c
===================================================================
--- trunk/sys/dev/uart/uart_bus_isa.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_bus_isa.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2008 TAKAHASHI Yoshihiro
  * Copyright (c) 2008 Marcel Moolenaar
@@ -26,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_bus_isa.c 315417 2017-03-16 15:43:32Z ian $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -142,7 +143,8 @@
 	{0x90307256, NULL},	/* USR3090 - USR ? */
 	{0x70917256, NULL},	/* USR9170 - U.S. Robotics 56K FAX INT */
 	{0x90917256, NULL},	/* USR9190 - USR 56k Voice INT */
-	{0x04f0235c, NULL},	/* WACF004 - Wacom Tablet PC Screen*/
+	{0x04f0235c, NULL},	/* WACF004 - Wacom Tablet PC Screen */
+	{0x0ef0235c, NULL},	/* WACF00e - Wacom Tablet PC Screen 00e */
 	{0x0300695c, NULL},	/* WCI0003 - Fax/Voice/Modem/Speakphone/Asvd */
 	{0x01a0896a, NULL},	/* ZTIA001 - Zoom Internal V90 Faxmodem */
 	{0x61f7896a, NULL},	/* ZTIF761 - Zoom ComStar 33.6 */

Modified: trunk/sys/dev/uart/uart_bus_pccard.c
===================================================================
--- trunk/sys/dev/uart/uart_bus_pccard.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_bus_pccard.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2001 M. Warner Losh.  All rights reserved.
  * Copyright (c) 2003 Norikatsu Shigemura, Takenori Watanabe All rights reserved.
@@ -24,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_bus_pccard.c 151791 2005-10-28 06:27:53Z marcel $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

Modified: trunk/sys/dev/uart/uart_bus_pci.c
===================================================================
--- trunk/sys/dev/uart/uart_bus_pci.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_bus_pci.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2006 Marcel Moolenaar
  * Copyright (c) 2001 M. Warner Losh
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_bus_pci.c 319511 2017-06-03 02:47:30Z emaste $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -82,6 +83,7 @@
 	0x10 },
 { 0x103c, 0x1048, 0x103c, 0x1301, "HP Diva RMP3", 0x14 },
 { 0x103c, 0x1290, 0xffff, 0, "HP Auxiliary Diva Serial Port", 0x18 },
+{ 0x103c, 0x3301, 0xffff, 0, "HP iLO serial port", 0x10 },
 { 0x11c1, 0x0480, 0xffff, 0, "Agere Systems Venus Modem (V90, 56KFlex)", 0x14 },
 { 0x115d, 0x0103, 0xffff, 0, "Xircom Cardbus Ethernet + 56k Modem", 0x10 },
 { 0x1282, 0x6585, 0xffff, 0, "Davicom 56PDV PCI Modem", 0x10 },
@@ -111,9 +113,18 @@
 	8 * DEFAULT_RCLK },
 { 0x1415, 0x950b, 0xffff, 0, "Oxford Semiconductor OXCB950 Cardbus 16950 UART",
 	0x10, 16384000 },
+{ 0x1415, 0xc120, 0xffff, 0, "Oxford Semiconductor OXPCIe952 PCIe 16950 UART",
+	0x10 },
 { 0x14e4, 0x4344, 0xffff, 0, "Sony Ericsson GC89 PC Card", 0x10},
 { 0x151f, 0x0000, 0xffff, 0, "TOPIC Semiconductor TP560 56k modem", 0x10 },
+{ 0x1fd4, 0x1999, 0x1fd4, 0x0001, "Sunix SER5xxxx Serial Port", 0x10,
+	8 * DEFAULT_RCLK },
+{ 0x8086, 0x108f, 0xffff, 0, "Intel AMT - SOL", 0x10 },
 { 0x8086, 0x1c3d, 0xffff, 0, "Intel AMT - KT Controller", 0x10 },
+{ 0x8086, 0x1d3d, 0xffff, 0, "Intel C600/X79 Series Chipset KT Controller", 0x10 },
+{ 0x8086, 0x1e3d, 0xffff, 0, "Intel Panther Point KT Controller", 0x10 },
+{ 0x8086, 0x2a07, 0xffff, 0, "Intel AMT - PM965/GM965 KT Controller", 0x10 },
+{ 0x8086, 0x2a47, 0xffff, 0, "Mobile 4 Series Chipset KT Controller", 0x10 },
 { 0x8086, 0x2e17, 0xffff, 0, "4 Series Chipset Serial KT Controller", 0x10 },
 { 0x8086, 0x3b67, 0xffff, 0, "5 Series/3400 Series Chipset KT Controller",
 	0x10 },
@@ -121,6 +132,8 @@
 { 0x8086, 0x8812, 0xffff, 0, "Intel EG20T Serial Port 1", 0x10 },
 { 0x8086, 0x8813, 0xffff, 0, "Intel EG20T Serial Port 2", 0x10 },
 { 0x8086, 0x8814, 0xffff, 0, "Intel EG20T Serial Port 3", 0x10 },
+{ 0x8086, 0x8c3d, 0xffff, 0, "Intel Lynx Point KT Controller", 0x10 },
+{ 0x8086, 0x8cbd, 0xffff, 0, "Intel Wildcat Point KT Controller", 0x10 },
 { 0x9710, 0x9820, 0x1000, 1, "NetMos NM9820 Serial Port", 0x10 },
 { 0x9710, 0x9835, 0x1000, 1, "NetMos NM9835 Serial Port", 0x10 },
 { 0x9710, 0x9865, 0xa000, 0x1000, "NetMos NM9865 Serial Port", 0x10 },
@@ -130,6 +143,8 @@
 	"MosChip MCS9901 PCIe to Peripheral Controller", 0x10 },
 { 0x9710, 0x9904, 0xa000, 0x1000,
 	"MosChip MCS9904 PCIe to Peripheral Controller", 0x10 },
+{ 0x9710, 0x9922, 0xa000, 0x1000,
+	"MosChip MCS9922 PCIe to Peripheral Controller", 0x10 },
 { 0xdeaf, 0x9051, 0xffff, 0, "Middle Digital PC Weasel Serial Port", 0x10 },
 { 0xffff, 0, 0xffff, 0, NULL, 0, 0}
 };
@@ -161,6 +176,7 @@
 {
 	struct uart_softc *sc;
 	const struct pci_id *id;
+	int result;
 
 	sc = device_get_softc(dev);
 
@@ -173,9 +189,14 @@
 	return (ENXIO);
 
  match:
+	result = uart_bus_probe(dev, 0, id->rclk, id->rid, 0);
+	/* Bail out on error. */
+	if (result > 0)
+		return (result);
+	/* Set/override the device description. */
 	if (id->desc)
 		device_set_desc(dev, id->desc);
-	return (uart_bus_probe(dev, 0, id->rclk, id->rid, 0));
+	return (result);
 }
 
 DRIVER_MODULE(uart, pci, uart_pci_driver, uart_devclass, NULL, NULL);

Modified: trunk/sys/dev/uart/uart_bus_puc.c
===================================================================
--- trunk/sys/dev/uart/uart_bus_puc.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_bus_puc.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2006 Marcel Moolenaar.  All rights reserved.
  * Copyright (c) 2002 JF Hay.  All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_bus_puc.c 158124 2006-04-28 21:21:53Z marcel $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

Modified: trunk/sys/dev/uart/uart_bus_scc.c
===================================================================
--- trunk/sys/dev/uart/uart_bus_scc.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_bus_scc.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2004-2006 Marcel Moolenaar
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_bus_scc.c 176772 2008-03-03 18:20:17Z raj $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

Modified: trunk/sys/dev/uart/uart_core.c
===================================================================
--- trunk/sys/dev/uart/uart_core.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_core.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 Marcel Moolenaar
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_core.c 294229 2016-01-17 18:18:01Z ian $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -39,6 +40,7 @@
 #include <sys/malloc.h>
 #include <sys/queue.h>
 #include <sys/reboot.h>
+#include <sys/sysctl.h>
 #include <machine/bus.h>
 #include <sys/rman.h>
 #include <machine/resource.h>
@@ -47,11 +49,12 @@
 #include <dev/uart/uart.h>
 #include <dev/uart/uart_bus.h>
 #include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_ppstypes.h>
 
 #include "uart_if.h"
 
 devclass_t uart_devclass;
-char uart_driver_name[] = "uart";
+const char uart_driver_name[] = "uart";
 
 SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs =
     SLIST_HEAD_INITIALIZER(uart_sysdevs);
@@ -58,6 +61,163 @@
 
 static MALLOC_DEFINE(M_UART, "UART", "UART driver");
 
+#ifndef	UART_POLL_FREQ
+#define	UART_POLL_FREQ		50
+#endif
+static int uart_poll_freq = UART_POLL_FREQ;
+TUNABLE_INT("debug.uart_poll_freq", &uart_poll_freq);
+
+static inline int
+uart_pps_mode_valid(int pps_mode)
+{
+	int opt;
+
+	switch(pps_mode & UART_PPS_SIGNAL_MASK) {
+	case UART_PPS_DISABLED:
+	case UART_PPS_CTS:
+	case UART_PPS_DCD:
+		break;
+	default:
+		return (false);
+	}
+
+	opt = pps_mode & UART_PPS_OPTION_MASK;
+	if ((opt & ~(UART_PPS_INVERT_PULSE | UART_PPS_NARROW_PULSE)) != 0)
+		return (false);
+
+	return (true);
+}
+
+static void
+uart_pps_print_mode(struct uart_softc *sc)
+{
+
+	device_printf(sc->sc_dev, "PPS capture mode: ");
+	switch(sc->sc_pps_mode) {
+	case UART_PPS_DISABLED:
+		printf("disabled");
+	case UART_PPS_CTS:
+		printf("CTS");
+	case UART_PPS_DCD:
+		printf("DCD");
+	default:
+		printf("invalid");
+	}
+	if (sc->sc_pps_mode & UART_PPS_INVERT_PULSE)
+		printf("-Inverted");
+	if (sc->sc_pps_mode & UART_PPS_NARROW_PULSE)
+		printf("-NarrowPulse");
+	printf("\n");
+}
+
+static int
+uart_pps_mode_sysctl(SYSCTL_HANDLER_ARGS)
+{
+	struct uart_softc *sc;
+	int err, tmp;
+
+	sc = arg1;
+	tmp = sc->sc_pps_mode;
+	err = sysctl_handle_int(oidp, &tmp, 0, req);
+	if (err != 0 || req->newptr == NULL)
+		return (err);
+	if (!uart_pps_mode_valid(tmp))
+		return (EINVAL);
+	sc->sc_pps_mode = tmp;
+	return(0);
+}
+
+static void
+uart_pps_process(struct uart_softc *sc, int ser_sig)
+{
+	sbintime_t now;
+	int is_assert, pps_sig;
+
+	/* Which signal is configured as PPS?  Early out if none. */
+	switch(sc->sc_pps_mode & UART_PPS_SIGNAL_MASK) {
+	case UART_PPS_CTS:
+		pps_sig = SER_CTS;
+		break;
+	case UART_PPS_DCD:
+		pps_sig = SER_DCD;
+		break;
+	default:
+		return;
+	}
+
+	/* Early out if there is no change in the signal configured as PPS. */
+	if ((ser_sig & SER_DELTA(pps_sig)) == 0)
+		return;
+
+	/*
+	 * In narrow-pulse mode we need to synthesize both capture and clear
+	 * events from a single "delta occurred" indication from the uart
+	 * hardware because the pulse width is too narrow to reliably detect
+	 * both edges.  However, when the pulse width is close to our interrupt
+	 * processing latency we might intermittantly catch both edges.  To
+	 * guard against generating spurious events when that happens, we use a
+	 * separate timer to ensure at least half a second elapses before we
+	 * generate another event.
+	 */
+	pps_capture(&sc->sc_pps);
+	if (sc->sc_pps_mode & UART_PPS_NARROW_PULSE) {
+		now = getsbinuptime();
+		if (now > sc->sc_pps_captime + 500 * SBT_1MS) {
+			sc->sc_pps_captime = now;
+			pps_event(&sc->sc_pps, PPS_CAPTUREASSERT);
+			pps_event(&sc->sc_pps, PPS_CAPTURECLEAR);
+		}
+	} else  {
+		is_assert = ser_sig & pps_sig;
+		if (sc->sc_pps_mode & UART_PPS_INVERT_PULSE)
+			is_assert = !is_assert;
+		pps_event(&sc->sc_pps, is_assert ? PPS_CAPTUREASSERT :
+		    PPS_CAPTURECLEAR);
+	}
+}
+
+static void
+uart_pps_init(struct uart_softc *sc)
+{
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid *tree;
+
+	ctx = device_get_sysctl_ctx(sc->sc_dev);
+	tree = device_get_sysctl_tree(sc->sc_dev);
+
+	/*
+	 * The historical default for pps capture mode is either DCD or CTS,
+	 * depending on the UART_PPS_ON_CTS kernel option.  Start with that,
+	 * then try to fetch the tunable that overrides the mode for all uart
+	 * devices, then try to fetch the sysctl-tunable that overrides the mode
+	 * for one specific device.
+	 */
+#ifdef UART_PPS_ON_CTS
+	sc->sc_pps_mode = UART_PPS_CTS;
+#else
+	sc->sc_pps_mode = UART_PPS_DCD;
+#endif
+	TUNABLE_INT_FETCH("hw.uart.pps_mode", &sc->sc_pps_mode);
+	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "pps_mode",
+	    CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0, uart_pps_mode_sysctl, "I",
+	    "pulse mode: 0/1/2=disabled/CTS/DCD; "
+	    "add 0x10 to invert, 0x20 for narrow pulse");
+
+	if (!uart_pps_mode_valid(sc->sc_pps_mode)) {
+		device_printf(sc->sc_dev, 
+		    "Invalid pps_mode 0x%02x configured; disabling PPS capture\n",
+		    sc->sc_pps_mode);
+		sc->sc_pps_mode = UART_PPS_DISABLED;
+	} else if (bootverbose) {
+		uart_pps_print_mode(sc);
+	}
+
+	sc->sc_pps.ppscap = PPS_CAPTUREBOTH;
+	sc->sc_pps.driver_mtx = uart_tty_getlock(sc);
+	sc->sc_pps.driver_abi = PPS_ABI_VERSION;
+	pps_init_abi(&sc->sc_pps);
+}
+
 void
 uart_add_sysdev(struct uart_devinfo *di)
 {
@@ -131,7 +291,7 @@
  * much of the data we can, but otherwise flush the receiver FIFO to
  * create some breathing room. The net effect is that we avoid the
  * overrun condition to happen for the next X characters, where X is
- * related to the FIFO size at the cost of loosing data right away.
+ * related to the FIFO size at the cost of losing data right away.
  * So, instead of having multiple overrun interrupts in close proximity
  * to each other and possibly pessimizing UART interrupt latency for
  * other UARTs in a multiport configuration, we create a longer segment
@@ -186,7 +346,7 @@
  * Line or modem status change (OOB signalling).
  * We pass the signals to the software interrupt handler for further
  * processing. Note that we merge the delta bits, but set the state
- * bits. This is to avoid loosing state transitions due to having more
+ * bits. This is to avoid losing state transitions due to having more
  * than 1 hardware interrupt between software interrupts.
  */
 static __inline int
@@ -197,12 +357,12 @@
 
 	sig = UART_GETSIG(sc);
 
+	/*
+	 * Time pulse counting support, invoked whenever the PPS parameters are
+	 * currently set to capture either edge of the signal.
+	 */
 	if (sc->sc_pps.ppsparam.mode & PPS_CAPTUREBOTH) {
-		if (sig & UART_SIG_DPPS) {
-			pps_capture(&sc->sc_pps);
-			pps_event(&sc->sc_pps, (sig & UART_SIG_PPS) ?
-			    PPS_CAPTUREASSERT : PPS_CAPTURECLEAR);
-		}
+		uart_pps_process(sc, sig);
 	}
 
 	/*
@@ -242,10 +402,15 @@
 uart_intr(void *arg)
 {
 	struct uart_softc *sc = arg;
-	int flag = 0, ipend;
+	int cnt, ipend, testintr;
 
-	while (!sc->sc_leaving && (ipend = UART_IPEND(sc)) != 0) {
-		flag = 1;
+	if (sc->sc_leaving)
+		return (FILTER_STRAY);
+
+	cnt = 0;
+	testintr = sc->sc_testintr;
+	while ((!testintr || cnt < 20) && (ipend = UART_IPEND(sc)) != 0) {
+		cnt++;
 		if (ipend & SER_INT_OVERRUN)
 			uart_intr_overrun(sc);
 		if (ipend & SER_INT_BREAK)
@@ -255,9 +420,17 @@
 		if (ipend & SER_INT_SIGCHG)
 			uart_intr_sigchg(sc);
 		if (ipend & SER_INT_TXIDLE)
-			uart_intr_txidle(sc);		
+			uart_intr_txidle(sc);
 	}
-	return((flag)?FILTER_HANDLED:FILTER_STRAY);
+
+	if (sc->sc_polled) {
+		callout_reset(&sc->sc_timer, hz / uart_poll_freq,
+		    (timeout_t *)uart_intr, sc);
+	}
+
+	return ((cnt == 0) ? FILTER_STRAY :
+	    ((testintr && cnt == 20) ? FILTER_SCHEDULE_THREAD :
+	    FILTER_HANDLED));
 }
 
 serdev_intr_t *
@@ -378,7 +551,7 @@
 {
 	struct uart_softc *sc, *sc0;
 	const char *sep;
-	int error;
+	int error, filt;
 
 	/*
 	 * The sc_class field defines the type of UART we're going to work
@@ -395,9 +568,16 @@
 		sc = sc0;
 
 	/*
+	 * Now that we know the softc for this device, connect the back
+	 * pointer from the sysdev for this device, if any
+	 */
+	if (sc->sc_sysdev != NULL)
+		sc->sc_sysdev->sc = sc;
+
+	/*
 	 * Protect ourselves against interrupts while we're not completely
 	 * finished attaching and initializing. We don't expect interrupts
-	 * until after UART_ATTACH() though.
+	 * until after UART_ATTACH(), though.
 	 */
 	sc->sc_leaving = 1;
 
@@ -418,33 +598,13 @@
 	sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
 	sc->sc_bas.bst = rman_get_bustag(sc->sc_rres);
 
-	sc->sc_irid = 0;
-	sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irid,
-	    RF_ACTIVE | RF_SHAREABLE);
-	if (sc->sc_ires != NULL) {
-		error = bus_setup_intr(dev,
-		    sc->sc_ires, INTR_TYPE_TTY, 
-		    uart_intr, NULL, sc, &sc->sc_icookie);		    
-		if (error)
-			error = bus_setup_intr(dev,
-			    sc->sc_ires, INTR_TYPE_TTY | INTR_MPSAFE,
-			    NULL, (driver_intr_t *)uart_intr, sc, &sc->sc_icookie);
-		else
-			sc->sc_fastintr = 1;
-
-		if (error) {
-			device_printf(dev, "could not activate interrupt\n");
-			bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid,
-			    sc->sc_ires);
-			sc->sc_ires = NULL;
-		}
-	}
-	if (sc->sc_ires == NULL) {
-		/* XXX no interrupt resource. Force polled mode. */
-		sc->sc_polled = 1;
-	}
-
-	sc->sc_rxbufsz = 384;
+	/*
+	 * Ensure there is room for at least three full FIFOs of data in the
+	 * receive buffer (handles the case of low-level drivers with huge
+	 * FIFOs), and also ensure that there is no less than the historical
+	 * size of 384 bytes (handles the typical small-FIFO case).
+	 */
+	sc->sc_rxbufsz = MAX(384, sc->sc_rxfifosz * 3);
 	sc->sc_rxbuf = malloc(sc->sc_rxbufsz * sizeof(*sc->sc_rxbuf),
 	    M_UART, M_WAITOK);
 	sc->sc_txbuf = malloc(sc->sc_txfifosz * sizeof(*sc->sc_txbuf),
@@ -468,20 +628,6 @@
 		printf("\n");
 	}
 
-	if (bootverbose && (sc->sc_fastintr || sc->sc_polled)) {
-		sep = "";
-		device_print_prettyname(dev);
-		if (sc->sc_fastintr) {
-			printf("%sfast interrupt", sep);
-			sep = ", ";
-		}
-		if (sc->sc_polled) {
-			printf("%spolled mode", sep);
-			sep = ", ";
-		}
-		printf("\n");
-	}
-
 	if (sc->sc_sysdev != NULL) {
 		if (sc->sc_sysdev->baudrate == 0) {
 			if (UART_IOCTL(sc, UART_IOCTL_BAUD,
@@ -507,19 +653,70 @@
 		    sc->sc_sysdev->stopbits);
 	}
 
-	sc->sc_pps.ppscap = PPS_CAPTUREBOTH;
-	pps_init(&sc->sc_pps);
+	sc->sc_leaving = 0;
+	sc->sc_testintr = 1;
+	filt = uart_intr(sc);
+	sc->sc_testintr = 0;
 
-	error = (sc->sc_sysdev != NULL && sc->sc_sysdev->attach != NULL)
-	    ? (*sc->sc_sysdev->attach)(sc) : uart_tty_attach(sc);
-	if (error)
-		goto fail;
+	/*
+	 * Don't use interrupts if we couldn't clear any pending interrupt
+	 * conditions. We may have broken H/W and polling is probably the
+	 * safest thing to do.
+	 */
+	if (filt != FILTER_SCHEDULE_THREAD) {
+		sc->sc_irid = 0;
+		sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+		    &sc->sc_irid, RF_ACTIVE | RF_SHAREABLE);
+	}
+	if (sc->sc_ires != NULL) {
+		error = bus_setup_intr(dev, sc->sc_ires, INTR_TYPE_TTY,
+		    uart_intr, NULL, sc, &sc->sc_icookie);
+		sc->sc_fastintr = (error == 0) ? 1 : 0;
 
+		if (!sc->sc_fastintr)
+			error = bus_setup_intr(dev, sc->sc_ires,
+			    INTR_TYPE_TTY | INTR_MPSAFE, NULL,
+			    (driver_intr_t *)uart_intr, sc, &sc->sc_icookie);
+
+		if (error) {
+			device_printf(dev, "could not activate interrupt\n");
+			bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid,
+			    sc->sc_ires);
+			sc->sc_ires = NULL;
+		}
+	}
+	if (sc->sc_ires == NULL) {
+		/* No interrupt resource. Force polled mode. */
+		sc->sc_polled = 1;
+		callout_init(&sc->sc_timer, 1);
+	}
+
+	if (bootverbose && (sc->sc_fastintr || sc->sc_polled)) {
+		sep = "";
+		device_print_prettyname(dev);
+		if (sc->sc_fastintr) {
+			printf("%sfast interrupt", sep);
+			sep = ", ";
+		}
+		if (sc->sc_polled) {
+			printf("%spolled mode (%dHz)", sep, uart_poll_freq);
+			sep = ", ";
+		}
+		printf("\n");
+	}
+
+	if (sc->sc_sysdev != NULL && sc->sc_sysdev->attach != NULL) {
+		if ((error = sc->sc_sysdev->attach(sc)) != 0)
+			goto fail;
+	} else {
+		if ((error = uart_tty_attach(sc)) != 0)
+			goto fail;
+		uart_pps_init(sc);
+	}
+
 	if (sc->sc_sysdev != NULL)
 		sc->sc_sysdev->hwmtx = sc->sc_hwmtx;
 
-	sc->sc_leaving = 0;
-	uart_intr(sc);
 	return (0);
 
  fail:
@@ -586,3 +783,19 @@
 	sc = device_get_softc(dev);
 	return (UART_ATTACH(sc));
 }
+
+void
+uart_grab(struct uart_devinfo *di)
+{
+
+	if (di->sc)
+		UART_GRAB(di->sc);
+}
+
+void
+uart_ungrab(struct uart_devinfo *di)
+{
+
+	if (di->sc)
+		UART_UNGRAB(di->sc);
+}

Modified: trunk/sys/dev/uart/uart_cpu.h
===================================================================
--- trunk/sys/dev/uart/uart_cpu.h	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_cpu.h	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003, 2004 Marcel Moolenaar
  * All rights reserved.
@@ -23,7 +24,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/uart/uart_cpu.h 262649 2014-03-01 04:16:54Z imp $
  */
 
 #ifndef _DEV_UART_CPU_H_
@@ -33,6 +34,8 @@
 #include <sys/lock.h>
 #include <sys/mutex.h>
 
+struct uart_softc;
+
 /*
  * Low-level operations for use by console and/or debug port support.
  */
@@ -51,7 +54,6 @@
 /*
  * Console and debug port device info.
  */
-struct uart_softc;
 struct uart_devinfo {
 	SLIST_ENTRY(uart_devinfo) next;
 	struct uart_ops *ops;
@@ -68,6 +70,7 @@
 	int	(*detach)(struct uart_softc*);
 	void	*cookie;		/* Type dependent use. */
 	struct mtx *hwmtx;
+	struct uart_softc *sc;		/* valid only from start of attach */
 };
 
 int uart_cpu_eqres(struct uart_bas *, struct uart_bas *);
@@ -167,4 +170,7 @@
 	return (di->ops->getc(&di->bas, di->hwmtx));
 }
 
+void uart_grab(struct uart_devinfo *di);
+void uart_ungrab(struct uart_devinfo *di);
+
 #endif /* _DEV_UART_CPU_H_ */

Added: trunk/sys/dev/uart/uart_cpu_fdt.c
===================================================================
--- trunk/sys/dev/uart/uart_cpu_fdt.c	                        (rev 0)
+++ trunk/sys/dev/uart/uart_cpu_fdt.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -0,0 +1,212 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2009-2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_cpu_fdt.c 283481 2015-05-24 17:57:29Z ian $");
+
+#include "opt_platform.h"
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_cpu_fdt.h>
+
+/*
+ * UART console routines.
+ */
+bus_space_tag_t uart_bus_space_io;
+bus_space_tag_t uart_bus_space_mem;
+
+int
+uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
+{
+
+	if (b1->bst != b2->bst)
+		return (0);
+	if (pmap_kextract(b1->bsh) == 0)
+		return (0);
+	if (pmap_kextract(b2->bsh) == 0)
+		return (0);
+	return ((pmap_kextract(b1->bsh) == pmap_kextract(b2->bsh)) ? 1 : 0);
+}
+
+static int
+phandle_chosen_propdev(phandle_t chosen, const char *name, phandle_t *node)
+{
+	char buf[64];
+
+	if (OF_getprop(chosen, name, buf, sizeof(buf)) <= 0)
+		return (ENXIO);
+	if ((*node = OF_finddevice(buf)) == -1)
+		return (ENXIO);
+	
+	return (0);
+}
+
+static const struct ofw_compat_data *
+uart_fdt_find_compatible(phandle_t node, const struct ofw_compat_data *cd)
+{
+	const struct ofw_compat_data *ocd;
+
+	for (ocd = cd; ocd->ocd_str != NULL; ocd++) {
+		if (fdt_is_compatible(node, ocd->ocd_str))
+			return (ocd);
+	}
+	return (NULL);
+}
+
+static uintptr_t
+uart_fdt_find_by_node(phandle_t node, int class_list)
+{
+	struct ofw_compat_data **cd;
+	const struct ofw_compat_data *ocd;
+
+	if (class_list) {
+		SET_FOREACH(cd, uart_fdt_class_set) {
+			ocd = uart_fdt_find_compatible(node, *cd);
+			if ((ocd != NULL) && (ocd->ocd_data != 0))
+				return (ocd->ocd_data);
+		}
+	} else {
+		SET_FOREACH(cd, uart_fdt_class_and_device_set) {
+			ocd = uart_fdt_find_compatible(node, *cd);
+			if ((ocd != NULL) && (ocd->ocd_data != 0))
+				return (ocd->ocd_data);
+		}
+	}
+	return (0);
+}
+
+int
+uart_cpu_getdev(int devtype, struct uart_devinfo *di)
+{
+	const char *propnames[] = {"stdout-path", "linux,stdout-path", "stdout",
+	    "stdin-path", "stdin", NULL};
+	const char **name;
+	struct uart_class *class;
+	phandle_t node, chosen;
+	pcell_t shift, br, rclk;
+	u_long start, size, pbase, psize;
+	int err;
+
+	uart_bus_space_mem = fdtbus_bs_tag;
+	uart_bus_space_io = NULL;
+
+	/* Allow overriding the FDT using the environment. */
+	class = &uart_ns8250_class;
+	err = uart_getenv(devtype, di, class);
+	if (!err)
+		return (0);
+
+	if (devtype != UART_DEV_CONSOLE)
+		return (ENXIO);
+
+	/*
+	 * Retrieve /chosen/std{in,out}.
+	 */
+	node = -1;
+	if ((chosen = OF_finddevice("/chosen")) != -1) {
+		for (name = propnames; *name != NULL; name++) {
+			if (phandle_chosen_propdev(chosen, *name, &node) == 0)
+				break;
+		}
+	}
+	if (chosen == -1 || *name == NULL)
+		node = OF_finddevice("serial0"); /* Last ditch */
+
+	if (node == -1) /* Can't find anything */
+		return (ENXIO);
+
+	/*
+	 * Retrieve serial attributes.
+	 */
+	uart_fdt_get_shift(node, &shift);
+	if (OF_getprop(node, "current-speed", &br, sizeof(br)) <= 0)
+		br = 0;
+	else
+		br = fdt32_to_cpu(br);
+
+	/*
+	 * Check old style of UART definition first. Unfortunately, the common
+	 * FDT processing is not possible if we have clock, power domains and
+	 * pinmux stuff.
+	 */
+	class = (struct uart_class *)uart_fdt_find_by_node(node, 0);
+	if (class != NULL) {
+		if ((err = uart_fdt_get_clock(node, &rclk)) != 0)
+			return (err);
+	} else {
+		/* Check class only linker set */
+		class =
+		    (struct uart_class *)uart_fdt_find_by_node(node, 1);
+		if (class == NULL)
+			return (ENXIO);
+		rclk = 0;
+	}
+
+	/*
+	 * Finalize configuration.
+	 */
+	di->bas.chan = 0;
+	di->bas.regshft = (u_int)shift;
+	di->baudrate = br;
+	di->bas.rclk = (u_int)rclk;
+	di->ops = uart_getops(class);
+	di->databits = 8;
+	di->stopbits = 1;
+	di->parity = UART_PARITY_NONE;
+	di->bas.bst = uart_bus_space_mem;
+
+	err = fdt_regsize(node, &start, &size);
+	if (err)
+		return (ENXIO);
+	err = fdt_get_range(OF_parent(node), 0, &pbase, &psize);
+	if (err)
+		pbase = 0;
+
+	start += pbase;
+
+	return (bus_space_map(di->bas.bst, start, size, 0, &di->bas.bsh));
+}


Property changes on: trunk/sys/dev/uart/uart_cpu_fdt.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/dev/uart/uart_cpu_fdt.h
===================================================================
--- trunk/sys/dev/uart/uart_cpu_fdt.h	                        (rev 0)
+++ trunk/sys/dev/uart/uart_cpu_fdt.h	2018-05-27 22:53:06 UTC (rev 10057)
@@ -0,0 +1,57 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright 2015 Michal Meloun
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: stable/10/sys/dev/uart/uart_cpu_fdt.h 283481 2015-05-24 17:57:29Z ian $
+ */
+
+#ifndef _DEV_UART_CPU_FDT_H_
+#define _DEV_UART_CPU_FDT_H_
+
+#include <sys/linker_set.h>
+
+#include <dev/ofw/ofw_bus_subr.h>
+
+/*
+ * If your UART driver implements only uart_class and uses uart_cpu_fdt.c
+ * for device instantiation, then use UART_FDT_CLASS_AND_DEVICE for its
+ * declaration
+ */
+SET_DECLARE(uart_fdt_class_and_device_set, struct ofw_compat_data );
+#define UART_FDT_CLASS_AND_DEVICE(data)				\
+	DATA_SET(uart_fdt_class_and_device_set, data)
+
+/*
+ * If your UART driver implements uart_class and custom device layer,
+ * then use UART_FDT_CLASS for its declaration
+ */
+SET_DECLARE(uart_fdt_class_set, struct ofw_compat_data );
+#define UART_FDT_CLASS(data)				\
+	DATA_SET(uart_fdt_class_set, data)
+
+int uart_fdt_get_clock(phandle_t node, pcell_t *cell);
+int uart_fdt_get_shift(phandle_t node, pcell_t *cell);
+
+#endif /* _DEV_UART_CPU_FDT_H_ */


Property changes on: trunk/sys/dev/uart/uart_cpu_fdt.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/dev/uart/uart_cpu_ia64.c
===================================================================
--- trunk/sys/dev/uart/uart_cpu_ia64.c	                        (rev 0)
+++ trunk/sys/dev/uart/uart_cpu_ia64.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -0,0 +1,114 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003, 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_cpu_ia64.c 168281 2007-04-02 22:00:22Z marcel $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+#include <machine/dig64.h>
+#include <machine/md_var.h>
+#include <machine/vmparam.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+
+bus_space_tag_t uart_bus_space_io = IA64_BUS_SPACE_IO;
+bus_space_tag_t uart_bus_space_mem = IA64_BUS_SPACE_MEM;
+
+static int dig64_to_uart_parity[] = {
+	UART_PARITY_NONE, UART_PARITY_NONE, UART_PARITY_EVEN,
+	UART_PARITY_ODD, UART_PARITY_MARK, UART_PARITY_SPACE
+};
+
+int
+uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
+{
+
+	return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
+}
+
+int
+uart_cpu_getdev(int devtype, struct uart_devinfo *di)
+{
+	struct dig64_hcdp_table *tbl;
+	struct dig64_hcdp_entry *ent;
+	struct uart_class *class;
+	bus_addr_t addr;
+	uint64_t hcdp;
+	unsigned int i;
+
+	class = &uart_ns8250_class;
+	if (class == NULL)
+		return (ENXIO);
+
+	/*
+	 * Use the DIG64 HCDP table if present.
+	 */
+	hcdp = ia64_get_hcdp();
+	if (hcdp != 0) {
+		tbl = (void*)IA64_PHYS_TO_RR7(hcdp);
+		for (i = 0; i < tbl->entries; i++) {
+			ent = tbl->entry + i;
+
+			if (devtype == UART_DEV_CONSOLE &&
+			    ent->type != DIG64_HCDP_CONSOLE)
+				continue;
+
+			if (devtype == UART_DEV_DBGPORT &&
+			    ent->type != DIG64_HCDP_DBGPORT)
+				continue;
+
+			addr = ent->address.addr_high;
+			addr = (addr << 32) + ent->address.addr_low;
+			di->ops = uart_getops(class);
+			di->bas.chan = 0;
+			di->bas.bst = (ent->address.addr_space == 0)
+			    ? uart_bus_space_mem : uart_bus_space_io;
+			if (bus_space_map(di->bas.bst, addr,
+			    uart_getrange(class), 0, &di->bas.bsh) != 0)
+				continue;
+			di->bas.regshft = 0;
+			di->bas.rclk = ent->pclock << 4;
+			/* We don't deal with 64-bit baud rates. */
+			di->baudrate = ent->baud_low;
+			di->databits = ent->databits;
+			di->stopbits = ent->stopbits;
+			di->parity = (ent->parity >= 6) ? UART_PARITY_NONE
+			    : dig64_to_uart_parity[ent->parity];
+			return (0);
+		}
+
+		/* FALLTHROUGH */
+	}
+
+	/* Check the environment. */
+	return (uart_getenv(devtype, di, class));
+}


Property changes on: trunk/sys/dev/uart/uart_cpu_ia64.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/dev/uart/uart_cpu_pc98.c
===================================================================
--- trunk/sys/dev/uart/uart_cpu_pc98.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_cpu_pc98.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2008 TAKAHASHI Yoshihiro
  * Copyright (c) 2003 M. Warner Losh, Marcel Moolenaar
@@ -26,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_cpu_pc98.c 216592 2010-12-20 16:39:43Z tijl $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

Modified: trunk/sys/dev/uart/uart_cpu_powerpc.c
===================================================================
--- trunk/sys/dev/uart/uart_cpu_powerpc.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_cpu_powerpc.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2006 Marcel Moolenaar
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_cpu_powerpc.c 266020 2014-05-14 14:17:51Z ian $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -61,21 +62,56 @@
 	input = OF_finddevice(buf);
 	if (input == -1)
 		return (ENXIO);
-	if (OF_getprop(opts, outputdev, buf, sizeof(buf)) == -1)
-		return (ENXIO);
-	if (OF_finddevice(buf) != input)
-		return (ENXIO);
 
+	if (outputdev != NULL) {
+		if (OF_getprop(opts, outputdev, buf, sizeof(buf)) == -1)
+			return (ENXIO);
+		if (OF_finddevice(buf) != input)
+			return (ENXIO);
+	}
+
 	*result = input;
 	return (0);
 }
 
+static int
+ofw_get_console_phandle_path(phandle_t node, phandle_t *result,
+    const char *prop)
+{
+	union {
+		char buf[64];
+		phandle_t ref;
+	} field;
+	phandle_t output;
+	ssize_t size;
+
+	size = OF_getproplen(node, prop);
+	if (size == -1)
+		return (ENXIO);
+	OF_getprop(node, prop, &field, sizeof(field));
+
+	/* This property might be either a ihandle or path. Hooray. */
+
+	output = -1;
+	if (field.buf[size - 1] == 0)
+		output = OF_finddevice(field.buf);
+	if (output == -1 && size == 4)
+		output = OF_instance_to_package(field.ref);
+	
+	if (output != -1) {
+		*result = output;
+		return (0);
+	}
+
+	return (ENXIO);
+}
+
 int
 uart_cpu_getdev(int devtype, struct uart_devinfo *di)
 {
 	char buf[64];
 	struct uart_class *class;
-	phandle_t input, opts;
+	phandle_t input, opts, chosen;
 	int error;
 
 	class = &uart_z8530_class;
@@ -82,21 +118,40 @@
 	if (class == NULL)
 		return (ENXIO);
 
-	if ((opts = OF_finddevice("/options")) == -1)
-		return (ENXIO);
+	opts = OF_finddevice("/options");
+	chosen = OF_finddevice("/chosen");
 	switch (devtype) {
 	case UART_DEV_CONSOLE:
-		if (ofw_get_uart_console(opts, &input, "input-device",
-		    "output-device")) {
-			/*
-			 * At least some G5 Xserves require that we
-			 * probe input-device-1 as well
-			 */
-	
-			if (ofw_get_uart_console(opts, &input, "input-device-1",
-			    "output-device-1"))
-				return (ENXIO);
+		error = ENXIO;
+		if (chosen != -1 && error != 0)
+			error = ofw_get_uart_console(chosen, &input,
+			    "stdout-path", NULL);
+		if (chosen != -1 && error != 0)
+			error = ofw_get_uart_console(chosen, &input,
+			    "linux,stdout-path", NULL);
+		if (chosen != -1 && error != 0)
+			error = ofw_get_console_phandle_path(chosen, &input,
+			    "stdout");
+		if (chosen != -1 && error != 0)
+			error = ofw_get_uart_console(chosen, &input,
+			    "stdin-path", NULL);
+		if (chosen != -1 && error != 0)
+			error = ofw_get_console_phandle_path(chosen, &input,
+			    "stdin");
+		if (opts != -1 && error != 0)
+			error = ofw_get_uart_console(opts, &input,
+			    "input-device", "output-device");
+		if (opts != -1 && error != 0)
+			error = ofw_get_uart_console(opts, &input,
+			    "input-device-1", "output-device-1");
+		if (error != 0) {
+			input = OF_finddevice("serial0"); /* Last ditch */
+			if (input == -1)
+				error = (ENXIO);
 		}
+
+		if (error != 0)
+			return (error);
 		break;
 	case UART_DEV_DBGPORT:
 		if (!getenv_string("hw.uart.dbgport", buf, sizeof(buf)))
@@ -113,14 +168,14 @@
 		return (ENXIO);
 	if (strcmp(buf, "serial") != 0)
 		return (ENXIO);
-	if (OF_getprop(input, "name", buf, sizeof(buf)) == -1)
+	if (OF_getprop(input, "compatible", buf, sizeof(buf)) == -1)
 		return (ENXIO);
 
-	if (strcmp(buf, "ch-a") == 0) {
+	if (strncmp(buf, "chrp,es", 7) == 0) {
 		class = &uart_z8530_class;
 		di->bas.regshft = 4;
 		di->bas.chan = 1;
-	} else if (strcmp(buf,"serial") == 0) {
+	} else if (strcmp(buf,"ns16550") == 0 || strcmp(buf,"ns8250") == 0) {
 		class = &uart_ns8250_class;
 		di->bas.regshft = 0;
 		di->bas.chan = 0;
@@ -139,6 +194,8 @@
 	if (OF_getprop(input, "current-speed", &di->baudrate, 
 	    sizeof(di->baudrate)) == -1)
 		di->baudrate = 0;
+	OF_getprop(input, "reg-shift", &di->bas.regshft,
+	    sizeof(di->bas.regshft));
 
 	di->databits = 8;
 	di->stopbits = 1;
@@ -145,3 +202,4 @@
 	di->parity = UART_PARITY_NONE;
 	return (0);
 }
+

Modified: trunk/sys/dev/uart/uart_cpu_sparc64.c
===================================================================
--- trunk/sys/dev/uart/uart_cpu_sparc64.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_cpu_sparc64.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003, 2004 Marcel Moolenaar
  * Copyright (c) 2004 - 2006 Marius Strobl <marius at FreeBSD.org>
@@ -26,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_cpu_sparc64.c 229272 2012-01-02 12:12:10Z ed $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -71,7 +72,7 @@
 	if ((aliases = OF_finddevice("/aliases")) != -1)
 		(void)OF_getprop(aliases, dev, alias, sizeof(alias));
 	len = strlen(alias);
-	if ((p = rindex(alias, ':')) == NULL)
+	if ((p = strrchr(alias, ':')) == NULL)
 		return (0);
 	p++;
 	if (p - alias == len - 1 && (*p == 'a' || *p == 'b'))

Added: trunk/sys/dev/uart/uart_cpu_x86.c
===================================================================
--- trunk/sys/dev/uart/uart_cpu_x86.c	                        (rev 0)
+++ trunk/sys/dev/uart/uart_cpu_x86.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -0,0 +1,108 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003, 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_cpu_x86.c 234118 2012-04-11 02:42:01Z marcel $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+
+bus_space_tag_t uart_bus_space_io = X86_BUS_SPACE_IO;
+bus_space_tag_t uart_bus_space_mem = X86_BUS_SPACE_MEM;
+
+int
+uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
+{
+
+	return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
+}
+
+int
+uart_cpu_getdev(int devtype, struct uart_devinfo *di)
+{
+	struct uart_class *class;
+	unsigned int i, ivar;
+
+	class = &uart_ns8250_class;
+	if (class == NULL)
+		return (ENXIO);
+
+	/* Check the environment. */
+	if (uart_getenv(devtype, di, class) == 0)
+		return (0);
+
+	/*
+	 * Scan the hints. We only try units 0 to 3 (inclusive). This
+	 * covers the ISA legacy where 4 UARTs had their resources
+	 * predefined.
+	 */
+	for (i = 0; i < 4; i++) {
+		if (resource_int_value("uart", i, "flags", &ivar))
+			continue;
+		if (devtype == UART_DEV_CONSOLE && !UART_FLAGS_CONSOLE(ivar))
+			continue;
+		if (devtype == UART_DEV_DBGPORT && !UART_FLAGS_DBGPORT(ivar))
+			continue;
+		/*
+		 * We have a possible device. Make sure it's enabled and
+		 * that we have an I/O port.
+		 */
+		if (resource_int_value("uart", i, "disabled", &ivar) == 0 &&
+		    ivar != 0)
+			continue;
+		if (resource_int_value("uart", i, "port", &ivar) != 0 ||
+		    ivar == 0)
+			continue;
+		/*
+		 * Got it. Fill in the instance and return it. We only have
+		 * ns8250 and successors on i386.
+		 */
+		di->ops = uart_getops(class);
+		di->bas.chan = 0;
+		di->bas.bst = uart_bus_space_io;
+		if (bus_space_map(di->bas.bst, ivar, uart_getrange(class), 0,
+		    &di->bas.bsh) != 0)
+			continue;
+		di->bas.regshft = 0;
+		di->bas.rclk = 0;
+		if (resource_int_value("uart", i, "baud", &ivar) != 0)
+			ivar = 0;
+		di->baudrate = ivar;
+		di->databits = 8;
+		di->stopbits = 1;
+		di->parity = UART_PARITY_NONE;
+		return (0);
+	}
+
+	return (ENXIO);
+}


Property changes on: trunk/sys/dev/uart/uart_cpu_x86.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/dev/uart/uart_dbg.c
===================================================================
--- trunk/sys/dev/uart/uart_dbg.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_dbg.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2004 Marcel Moolenaar
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_dbg.c 158950 2006-05-26 11:54:32Z phk $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

Added: trunk/sys/dev/uart/uart_dev_imx.c
===================================================================
--- trunk/sys/dev/uart/uart_dev_imx.c	                        (rev 0)
+++ trunk/sys/dev/uart/uart_dev_imx.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -0,0 +1,618 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.	Redistributions of source code must retain the above copyright
+ *	notice, this list of conditions and the following disclaimer.
+ * 2.	Redistributions in binary form must reproduce the above copyright
+ *	notice, this list of conditions and the following disclaimer in the
+ *	documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_dev_imx.c 283327 2015-05-23 20:54:25Z ian $");
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kdb.h>
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_cpu_fdt.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_dev_imx.h>
+#include "uart_if.h"
+
+#include <arm/freescale/imx/imx_ccmvar.h>
+
+/*
+ * The hardare FIFOs are 32 bytes.  We want an interrupt when there are 24 bytes
+ * available to read or space for 24 more bytes to write.  While 8 bytes of
+ * slack before over/underrun might seem excessive, the hardware can run at
+ * 5mbps, which means 2uS per char, so at full speed 8 bytes provides only 16uS
+ * to get into the interrupt handler and service the fifo.
+ */
+#define	IMX_FIFOSZ		32
+#define	IMX_RXFIFO_LEVEL	24
+#define	IMX_TXFIFO_LEVEL	24
+
+/*
+ * Low-level UART interface.
+ */
+static int imx_uart_probe(struct uart_bas *bas);
+static void imx_uart_init(struct uart_bas *bas, int, int, int, int);
+static void imx_uart_term(struct uart_bas *bas);
+static void imx_uart_putc(struct uart_bas *bas, int);
+static int imx_uart_rxready(struct uart_bas *bas);
+static int imx_uart_getc(struct uart_bas *bas, struct mtx *);
+
+static struct uart_ops uart_imx_uart_ops = {
+	.probe = imx_uart_probe,
+	.init = imx_uart_init,
+	.term = imx_uart_term,
+	.putc = imx_uart_putc,
+	.rxready = imx_uart_rxready,
+	.getc = imx_uart_getc,
+};
+
+#if 0 /* Handy when debugging. */
+static void
+dumpregs(struct uart_bas *bas, const char * msg)
+{
+
+	if (!bootverbose)
+		return;
+	printf("%s bsh 0x%08lx UCR1 0x%08x UCR2 0x%08x "
+		"UCR3 0x%08x UCR4 0x%08x USR1 0x%08x USR2 0x%08x\n",
+	    msg, bas->bsh,
+	    GETREG(bas, REG(UCR1)), GETREG(bas, REG(UCR2)), 
+	    GETREG(bas, REG(UCR3)), GETREG(bas, REG(UCR4)),
+	    GETREG(bas, REG(USR1)), GETREG(bas, REG(USR2)));
+}
+#endif
+
+static int
+imx_uart_probe(struct uart_bas *bas)
+{
+
+	return (0);
+}
+
+static u_int
+imx_uart_getbaud(struct uart_bas *bas)
+{
+	uint32_t rate, ubir, ubmr;
+	u_int baud, blo, bhi, i;
+	static const u_int predivs[] = {6, 5, 4, 3, 2, 1, 7, 1};
+	static const u_int std_rates[] = {
+		9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600
+	};
+
+	/*
+	 * Get the baud rate the hardware is programmed for, then search the
+	 * table of standard baud rates for a number that's within 3% of the
+	 * actual rate the hardware is programmed for.  It's more comforting to
+	 * see that your console is running at 115200 than 114942.  Note that
+	 * here we cannot make a simplifying assumption that the predivider and
+	 * numerator are 1 (like we do when setting the baud rate), because we
+	 * don't know what u-boot might have set up.
+	 */
+	i = (GETREG(bas, REG(UFCR)) & IMXUART_UFCR_RFDIV_MASK) >>
+	    IMXUART_UFCR_RFDIV_SHIFT;
+	rate = imx_ccm_uart_hz() / predivs[i];
+	ubir = GETREG(bas, REG(UBIR)) + 1;
+	ubmr = GETREG(bas, REG(UBMR)) + 1;
+	baud = ((rate / 16 ) * ubir) / ubmr;
+
+	blo = (baud * 100) / 103;
+	bhi = (baud * 100) / 97;
+	for (i = 0; i < nitems(std_rates); i++) {
+		rate = std_rates[i];
+		if (rate >= blo && rate <= bhi) {
+			baud = rate;
+			break;
+		}
+	}
+
+	return (baud);
+}
+
+static void
+imx_uart_init(struct uart_bas *bas, int baudrate, int databits, 
+    int stopbits, int parity)
+{
+	uint32_t baseclk, reg;
+
+        /* Enable the device and the RX/TX channels. */
+	SET(bas, REG(UCR1), FLD(UCR1, UARTEN));
+	SET(bas, REG(UCR2), FLD(UCR2, RXEN) | FLD(UCR2, TXEN));
+
+	if (databits == 7)
+		DIS(bas, UCR2, WS);
+	else
+		ENA(bas, UCR2, WS);
+
+	if (stopbits == 2)
+		ENA(bas, UCR2, STPB);
+	else
+		DIS(bas, UCR2, STPB);
+
+	switch (parity) {
+	case UART_PARITY_ODD:
+		DIS(bas, UCR2, PROE);
+		ENA(bas, UCR2, PREN);
+		break;
+	case UART_PARITY_EVEN:
+		ENA(bas, UCR2, PROE);
+		ENA(bas, UCR2, PREN);
+		break;
+	case UART_PARITY_MARK:
+	case UART_PARITY_SPACE:
+                /* FALLTHROUGH: Hardware doesn't support mark/space. */
+	case UART_PARITY_NONE:
+	default:
+		DIS(bas, UCR2, PREN);
+		break;
+	}
+
+	/*
+	 * The hardware has an extremely flexible baud clock: it allows setting
+	 * both the numerator and denominator of the divider, as well as a
+	 * separate pre-divider.  We simplify the problem of coming up with a
+	 * workable pair of numbers by assuming a pre-divider and numerator of
+	 * one because our base clock is so fast we can reach virtually any
+	 * reasonable speed with a simple divisor.  The numerator value actually
+	 * includes the 16x over-sampling (so a value of 16 means divide by 1);
+	 * the register value is the numerator-1, so we have a hard-coded 15.
+	 * Note that a quirk of the hardware requires that both UBIR and UBMR be
+	 * set back to back in order for the change to take effect.
+	 */
+	if (baudrate > 0) {
+		baseclk = imx_ccm_uart_hz();
+		reg = GETREG(bas, REG(UFCR));
+		reg = (reg & ~IMXUART_UFCR_RFDIV_MASK) | IMXUART_UFCR_RFDIV_DIV1;
+		SETREG(bas, REG(UFCR), reg);
+		SETREG(bas, REG(UBIR), 15);
+		SETREG(bas, REG(UBMR), (baseclk / baudrate) - 1);
+	}
+
+	/*
+	 * Program the tx lowater and rx hiwater levels at which fifo-service
+	 * interrupts are signaled.  The tx value is interpetted as "when there
+	 * are only this many bytes remaining" (not "this many free").
+	 */
+	reg = GETREG(bas, REG(UFCR));
+	reg &= ~(IMXUART_UFCR_TXTL_MASK | IMXUART_UFCR_RXTL_MASK);
+	reg |= (IMX_FIFOSZ - IMX_TXFIFO_LEVEL) << IMXUART_UFCR_TXTL_SHIFT;
+	reg |= IMX_RXFIFO_LEVEL << IMXUART_UFCR_RXTL_SHIFT;
+	SETREG(bas, REG(UFCR), reg);
+}
+
+static void
+imx_uart_term(struct uart_bas *bas)
+{
+
+}
+
+static void
+imx_uart_putc(struct uart_bas *bas, int c)
+{
+
+	while (!(IS(bas, USR1, TRDY)))
+		;
+	SETREG(bas, REG(UTXD), c);
+}
+
+static int
+imx_uart_rxready(struct uart_bas *bas)
+{
+
+	return ((IS(bas, USR2, RDR)) ? 1 : 0);
+}
+
+static int
+imx_uart_getc(struct uart_bas *bas, struct mtx *hwmtx)
+{
+	int c;
+
+	uart_lock(hwmtx);
+	while (!(IS(bas, USR2, RDR)))
+		;
+
+	c = GETREG(bas, REG(URXD));
+	uart_unlock(hwmtx);
+#if defined(KDB)
+	if (c & FLD(URXD, BRK)) {
+		if (kdb_break())
+			return (0);
+	}
+#endif
+	return (c & 0xff);
+}
+
+/*
+ * High-level UART interface.
+ */
+struct imx_uart_softc {
+	struct uart_softc base;
+};
+
+static int imx_uart_bus_attach(struct uart_softc *);
+static int imx_uart_bus_detach(struct uart_softc *);
+static int imx_uart_bus_flush(struct uart_softc *, int);
+static int imx_uart_bus_getsig(struct uart_softc *);
+static int imx_uart_bus_ioctl(struct uart_softc *, int, intptr_t);
+static int imx_uart_bus_ipend(struct uart_softc *);
+static int imx_uart_bus_param(struct uart_softc *, int, int, int, int);
+static int imx_uart_bus_probe(struct uart_softc *);
+static int imx_uart_bus_receive(struct uart_softc *);
+static int imx_uart_bus_setsig(struct uart_softc *, int);
+static int imx_uart_bus_transmit(struct uart_softc *);
+static void imx_uart_bus_grab(struct uart_softc *);
+static void imx_uart_bus_ungrab(struct uart_softc *);
+
+static kobj_method_t imx_uart_methods[] = {
+	KOBJMETHOD(uart_attach,		imx_uart_bus_attach),
+	KOBJMETHOD(uart_detach,		imx_uart_bus_detach),
+	KOBJMETHOD(uart_flush,		imx_uart_bus_flush),
+	KOBJMETHOD(uart_getsig,		imx_uart_bus_getsig),
+	KOBJMETHOD(uart_ioctl,		imx_uart_bus_ioctl),
+	KOBJMETHOD(uart_ipend,		imx_uart_bus_ipend),
+	KOBJMETHOD(uart_param,		imx_uart_bus_param),
+	KOBJMETHOD(uart_probe,		imx_uart_bus_probe),
+	KOBJMETHOD(uart_receive,	imx_uart_bus_receive),
+	KOBJMETHOD(uart_setsig,		imx_uart_bus_setsig),
+	KOBJMETHOD(uart_transmit,	imx_uart_bus_transmit),
+	KOBJMETHOD(uart_grab,		imx_uart_bus_grab),
+	KOBJMETHOD(uart_ungrab,		imx_uart_bus_ungrab),
+	{ 0, 0 }
+};
+
+static struct uart_class uart_imx_class = {
+	"imx",
+	imx_uart_methods,
+	sizeof(struct imx_uart_softc),
+	.uc_ops = &uart_imx_uart_ops,
+	.uc_range = 0x100,
+	.uc_rclk = 24000000 /* TODO: get value from CCM */
+};
+
+static struct ofw_compat_data compat_data[] = {
+	{"fsl,imx6q-uart",	(uintptr_t)&uart_imx_class},
+	{"fsl,imx53-uart",	(uintptr_t)&uart_imx_class},
+	{"fsl,imx51-uart",	(uintptr_t)&uart_imx_class},
+	{"fsl,imx31-uart",	(uintptr_t)&uart_imx_class},
+	{"fsl,imx27-uart",	(uintptr_t)&uart_imx_class},
+	{"fsl,imx25-uart",	(uintptr_t)&uart_imx_class},
+	{"fsl,imx21-uart",	(uintptr_t)&uart_imx_class},
+	{NULL,			(uintptr_t)NULL},
+};
+UART_FDT_CLASS_AND_DEVICE(compat_data);
+
+#define	SIGCHG(c, i, s, d)				\
+	if (c) {					\
+		i |= (i & s) ? s : s | d;		\
+	} else {					\
+		i = (i & s) ? (i & ~s) | d : i;		\
+	}
+
+static int
+imx_uart_bus_attach(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	struct uart_devinfo *di;
+
+	bas = &sc->sc_bas;
+	if (sc->sc_sysdev != NULL) {
+		di = sc->sc_sysdev;
+		imx_uart_init(bas, di->baudrate, di->databits, di->stopbits,
+		    di->parity);
+	} else {
+		imx_uart_init(bas, 115200, 8, 1, 0);
+	}
+
+	(void)imx_uart_bus_getsig(sc);
+
+	/* Clear all pending interrupts. */
+	SETREG(bas, REG(USR1), 0xffff);
+	SETREG(bas, REG(USR2), 0xffff);
+
+	DIS(bas, UCR4, DREN);
+	ENA(bas, UCR1, RRDYEN);
+	DIS(bas, UCR1, IDEN);
+	DIS(bas, UCR3, RXDSEN);
+	ENA(bas, UCR2, ATEN);
+	DIS(bas, UCR1, TXMPTYEN);
+	DIS(bas, UCR1, TRDYEN);
+	DIS(bas, UCR4, TCEN);
+	DIS(bas, UCR4, OREN);
+	ENA(bas, UCR4, BKEN);
+	DIS(bas, UCR4, WKEN);
+	DIS(bas, UCR1, ADEN);
+	DIS(bas, UCR3, ACIEN);
+	DIS(bas, UCR2, ESCI);
+	DIS(bas, UCR4, ENIRI);
+	DIS(bas, UCR3, AIRINTEN);
+	DIS(bas, UCR3, AWAKEN);
+	DIS(bas, UCR3, FRAERREN);
+	DIS(bas, UCR3, PARERREN);
+	DIS(bas, UCR1, RTSDEN);
+	DIS(bas, UCR2, RTSEN);
+	DIS(bas, UCR3, DTREN);
+	DIS(bas, UCR3, RI);
+	DIS(bas, UCR3, DCD);
+	DIS(bas, UCR3, DTRDEN);
+	ENA(bas, UCR2, IRTS);
+	ENA(bas, UCR3, RXDMUXSEL);
+
+	return (0);
+}
+
+static int
+imx_uart_bus_detach(struct uart_softc *sc)
+{
+
+	SETREG(&sc->sc_bas, REG(UCR4), 0);
+
+	return (0);
+}
+
+static int
+imx_uart_bus_flush(struct uart_softc *sc, int what)
+{
+
+	/* TODO */
+	return (0);
+}
+
+static int
+imx_uart_bus_getsig(struct uart_softc *sc)
+{
+	uint32_t new, old, sig;
+	uint8_t bes;
+
+	do {
+		old = sc->sc_hwsig;
+		sig = old;
+		uart_lock(sc->sc_hwmtx);
+		bes = GETREG(&sc->sc_bas, REG(USR2));
+		uart_unlock(sc->sc_hwmtx);
+		/* XXX: chip can show delta */
+		SIGCHG(bes & FLD(USR2, DCDIN), sig, SER_DCD, SER_DDCD);
+		new = sig & ~SER_MASK_DELTA;
+	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
+
+	return (sig);
+}
+
+static int
+imx_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+	struct uart_bas *bas;
+	int error;
+
+	bas = &sc->sc_bas;
+	error = 0;
+	uart_lock(sc->sc_hwmtx);
+	switch (request) {
+	case UART_IOCTL_BREAK:
+		/* TODO */
+		break;
+	case UART_IOCTL_BAUD:
+		*(u_int*)data = imx_uart_getbaud(bas);
+		break;
+	default:
+		error = EINVAL;
+		break;
+	}
+	uart_unlock(sc->sc_hwmtx);
+
+	return (error);
+}
+
+static int
+imx_uart_bus_ipend(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	int ipend;
+	uint32_t usr1, usr2;
+	uint32_t ucr1, ucr2, ucr4;
+
+	bas = &sc->sc_bas;
+	ipend = 0;
+
+	uart_lock(sc->sc_hwmtx);
+
+	/* Read pending interrupts */
+	usr1 = GETREG(bas, REG(USR1));
+	usr2 = GETREG(bas, REG(USR2));
+	/* ACK interrupts */
+	SETREG(bas, REG(USR1), usr1);
+	SETREG(bas, REG(USR2), usr2);
+
+	ucr1 = GETREG(bas, REG(UCR1));
+	ucr2 = GETREG(bas, REG(UCR2));
+	ucr4 = GETREG(bas, REG(UCR4));
+
+	/* If we have reached tx low-water, we can tx some more now. */
+	if ((usr1 & FLD(USR1, TRDY)) && (ucr1 & FLD(UCR1, TRDYEN))) {
+		DIS(bas, UCR1, TRDYEN);
+		ipend |= SER_INT_TXIDLE;
+	}
+
+	/*
+	 * If we have reached the rx high-water, or if there are bytes in the rx
+	 * fifo and no new data has arrived for 8 character periods (aging
+	 * timer), we have input data to process.
+	 */
+	if (((usr1 & FLD(USR1, RRDY)) && (ucr1 & FLD(UCR1, RRDYEN))) || 
+	    ((usr1 & FLD(USR1, AGTIM)) && (ucr2 & FLD(UCR2, ATEN)))) {
+		DIS(bas, UCR1, RRDYEN);
+		DIS(bas, UCR2, ATEN);
+		ipend |= SER_INT_RXREADY;
+	}
+
+	/* A break can come in at any time, it never gets disabled. */
+	if ((usr2 & FLD(USR2, BRCD)) && (ucr4 & FLD(UCR4, BKEN)))
+		ipend |= SER_INT_BREAK;
+
+	uart_unlock(sc->sc_hwmtx);
+
+	return (ipend);
+}
+
+static int
+imx_uart_bus_param(struct uart_softc *sc, int baudrate, int databits,
+    int stopbits, int parity)
+{
+
+	uart_lock(sc->sc_hwmtx);
+	imx_uart_init(&sc->sc_bas, baudrate, databits, stopbits, parity);
+	uart_unlock(sc->sc_hwmtx);
+	return (0);
+}
+
+static int
+imx_uart_bus_probe(struct uart_softc *sc)
+{
+	int error;
+
+	error = imx_uart_probe(&sc->sc_bas);
+	if (error)
+		return (error);
+
+	/*
+	 * On input we can read up to the full fifo size at once.  On output, we
+	 * want to write only as much as the programmed tx low water level,
+	 * because that's all we can be certain we have room for in the fifo
+	 * when we get a tx-ready interrupt.
+	 */
+	sc->sc_rxfifosz = IMX_FIFOSZ;
+	sc->sc_txfifosz = IMX_TXFIFO_LEVEL;
+
+	device_set_desc(sc->sc_dev, "Freescale i.MX UART");
+	return (0);
+}
+
+static int
+imx_uart_bus_receive(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	int xc, out;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+
+	/*
+	 * Empty the rx fifo.  We get the RRDY interrupt when IMX_RXFIFO_LEVEL
+	 * (the rx high-water level) is reached, but we set sc_rxfifosz to the
+	 * full hardware fifo size, so we can safely process however much is
+	 * there, not just the highwater size.
+	 */
+	while (IS(bas, USR2, RDR)) {
+		if (uart_rx_full(sc)) {
+			/* No space left in input buffer */
+			sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
+			break;
+		}
+		xc = GETREG(bas, REG(URXD));
+		out = xc & 0x000000ff;
+		if (xc & FLD(URXD, FRMERR))
+			out |= UART_STAT_FRAMERR;
+		if (xc & FLD(URXD, PRERR))
+			out |= UART_STAT_PARERR;
+		if (xc & FLD(URXD, OVRRUN))
+			out |= UART_STAT_OVERRUN;
+		if (xc & FLD(URXD, BRK))
+			out |= UART_STAT_BREAK;
+
+		uart_rx_put(sc, out);
+	}
+	ENA(bas, UCR1, RRDYEN);
+	ENA(bas, UCR2, ATEN);
+
+	uart_unlock(sc->sc_hwmtx);
+	return (0);
+}
+
+static int
+imx_uart_bus_setsig(struct uart_softc *sc, int sig)
+{
+
+	return (0);
+}
+
+static int
+imx_uart_bus_transmit(struct uart_softc *sc)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+	int i;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+
+	/*
+	 * Fill the tx fifo.  The uart core puts at most IMX_TXFIFO_LEVEL bytes
+	 * into the txbuf (because that's what sc_txfifosz is set to), and
+	 * because we got the TRDY (low-water reached) interrupt we know at
+	 * least that much space is available in the fifo.
+	 */
+	for (i = 0; i < sc->sc_txdatasz; i++) {
+		SETREG(bas, REG(UTXD), sc->sc_txbuf[i] & 0xff);
+	}
+	sc->sc_txbusy = 1;
+	ENA(bas, UCR1, TRDYEN);
+
+	uart_unlock(sc->sc_hwmtx);
+
+	return (0);
+}
+
+static void
+imx_uart_bus_grab(struct uart_softc *sc)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+	DIS(bas, UCR1, RRDYEN);
+	DIS(bas, UCR2, ATEN);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+static void
+imx_uart_bus_ungrab(struct uart_softc *sc)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+	ENA(bas, UCR1, RRDYEN);
+	ENA(bas, UCR2, ATEN);
+	uart_unlock(sc->sc_hwmtx);
+}


Property changes on: trunk/sys/dev/uart/uart_dev_imx.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/dev/uart/uart_dev_imx.h
===================================================================
--- trunk/sys/dev/uart/uart_dev_imx.h	                        (rev 0)
+++ trunk/sys/dev/uart/uart_dev_imx.h	2018-05-27 22:53:06 UTC (rev 10057)
@@ -0,0 +1,223 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Oleksandr Rybalko under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.	Redistributions of source code must retain the above copyright
+ *	notice, this list of conditions and the following disclaimer.
+ * 2.	Redistributions in binary form must reproduce the above copyright
+ *	notice, this list of conditions and the following disclaimer in the
+ *	documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: stable/10/sys/dev/uart/uart_dev_imx.h 266372 2014-05-17 22:31:40Z ian $
+ */
+
+#ifndef	_UART_DEV_IMX5XX_H
+#define	_UART_DEV_IMX5XX_H
+
+#define	IMXUART_URXD_REG	0x0000 /* UART Receiver Register */
+#define		IMXUART_URXD_CHARRDY		(1 << 15)
+#define		IMXUART_URXD_ERR		(1 << 14)
+#define		IMXUART_URXD_OVRRUN		(1 << 13)
+#define		IMXUART_URXD_FRMERR		(1 << 12)
+#define		IMXUART_URXD_BRK		(1 << 11)
+#define		IMXUART_URXD_PRERR		(1 << 10)
+#define		IMXUART_URXD_RX_DATA_MASK	0xff
+
+#define	IMXUART_UTXD_REG	0x0040 /* UART Transmitter Register */
+#define		IMXUART_UTXD_TX_DATA_MASK	0xff
+
+#define	IMXUART_UCR1_REG	0x0080 /* UART Control Register 1 */
+#define		IMXUART_UCR1_ADEN		(1 << 15)
+#define		IMXUART_UCR1_ADBR		(1 << 14)
+#define		IMXUART_UCR1_TRDYEN		(1 << 13)
+#define		IMXUART_UCR1_IDEN		(1 << 12)
+#define		IMXUART_UCR1_ICD_MASK		(3 << 10)
+#define		IMXUART_UCR1_ICD_IDLE4		(0 << 10)
+#define		IMXUART_UCR1_ICD_IDLE8		(1 << 10)
+#define		IMXUART_UCR1_ICD_IDLE16		(2 << 10)
+#define		IMXUART_UCR1_ICD_IDLE32		(3 << 10)
+#define		IMXUART_UCR1_RRDYEN		(1 << 9)
+#define		IMXUART_UCR1_RXDMAEN		(1 << 8)
+#define		IMXUART_UCR1_IREN		(1 << 7)
+#define		IMXUART_UCR1_TXMPTYEN		(1 << 6)
+#define		IMXUART_UCR1_RTSDEN		(1 << 5)
+#define		IMXUART_UCR1_SNDBRK		(1 << 4)
+#define		IMXUART_UCR1_TXDMAEN		(1 << 3)
+#define		IMXUART_UCR1_ATDMAEN		(1 << 2)
+#define		IMXUART_UCR1_DOZE		(1 << 1)
+#define		IMXUART_UCR1_UARTEN		(1 << 0)
+
+#define	IMXUART_UCR2_REG	0x0084 /* UART Control Register 2 */
+#define		IMXUART_UCR2_ESCI		(1 << 15)
+#define		IMXUART_UCR2_IRTS		(1 << 14)
+#define		IMXUART_UCR2_CTSC		(1 << 13)
+#define		IMXUART_UCR2_CTS		(1 << 12)
+#define		IMXUART_UCR2_ESCEN		(1 << 11)
+#define		IMXUART_UCR2_RTEC_MASK		(3 << 9)
+#define		IMXUART_UCR2_RTEC_REDGE		(0 << 9)
+#define		IMXUART_UCR2_RTEC_FEDGE		(1 << 9)
+#define		IMXUART_UCR2_RTEC_EDGE		(2 << 9)
+#define		IMXUART_UCR2_PREN		(1 << 8)
+#define		IMXUART_UCR2_PROE		(1 << 7)
+#define		IMXUART_UCR2_STPB		(1 << 6)
+#define		IMXUART_UCR2_WS			(1 << 5)
+#define		IMXUART_UCR2_RTSEN		(1 << 4)
+#define		IMXUART_UCR2_ATEN		(1 << 3)
+#define		IMXUART_UCR2_TXEN		(1 << 2)
+#define		IMXUART_UCR2_RXEN		(1 << 1)
+#define		IMXUART_UCR2_N_SRST		(1 << 0)
+
+#define	IMXUART_UCR3_REG	0x0088 /* UART Control Register 3 */
+#define		IMXUART_UCR3_DPEC_MASK		(3 << 14)
+#define		IMXUART_UCR3_DPEC_REDGE		(0 << 14)
+#define		IMXUART_UCR3_DPEC_FEDGE		(1 << 14)
+#define		IMXUART_UCR3_DPEC_EDGE		(2 << 14)
+#define		IMXUART_UCR3_DTREN		(1 << 13)
+#define		IMXUART_UCR3_PARERREN		(1 << 12)
+#define		IMXUART_UCR3_FRAERREN		(1 << 11)
+#define		IMXUART_UCR3_DSR		(1 << 10)
+#define		IMXUART_UCR3_DCD		(1 << 9)
+#define		IMXUART_UCR3_RI			(1 << 8)
+#define		IMXUART_UCR3_ADNIMP		(1 << 7)
+#define		IMXUART_UCR3_RXDSEN		(1 << 6)
+#define		IMXUART_UCR3_AIRINTEN		(1 << 5)
+#define		IMXUART_UCR3_AWAKEN		(1 << 4)
+#define		IMXUART_UCR3_DTRDEN		(1 << 3)
+#define		IMXUART_UCR3_RXDMUXSEL		(1 << 2)
+#define		IMXUART_UCR3_INVT		(1 << 1)
+#define		IMXUART_UCR3_ACIEN		(1 << 0)
+
+#define	IMXUART_UCR4_REG	0x008c /* UART Control Register 4 */
+#define		IMXUART_UCR4_CTSTL_MASK		(0x3f << 10)
+#define		IMXUART_UCR4_CTSTL_SHIFT	10
+#define		IMXUART_UCR4_INVR		(1 << 9)
+#define		IMXUART_UCR4_ENIRI		(1 << 8)
+#define		IMXUART_UCR4_WKEN		(1 << 7)
+#define		IMXUART_UCR4_IDDMAEN		(1 << 6)
+#define		IMXUART_UCR4_IRSC		(1 << 5)
+#define		IMXUART_UCR4_LPBYP		(1 << 4)
+#define		IMXUART_UCR4_TCEN		(1 << 3)
+#define		IMXUART_UCR4_BKEN		(1 << 2)
+#define		IMXUART_UCR4_OREN		(1 << 1)
+#define		IMXUART_UCR4_DREN		(1 << 0)
+
+#define	IMXUART_UFCR_REG	0x0090 /* UART FIFO Control Register */
+#define		IMXUART_UFCR_TXTL_MASK		(0x3f << 10)
+#define		IMXUART_UFCR_TXTL_SHIFT		10
+#define		IMXUART_UFCR_RFDIV_MASK		(0x07 << 7)
+#define		IMXUART_UFCR_RFDIV_SHIFT	7
+#define		IMXUART_UFCR_RFDIV_SHIFT	7
+#define		IMXUART_UFCR_RFDIV_DIV6		(0 << 7)
+#define		IMXUART_UFCR_RFDIV_DIV5		(1 << 7)
+#define		IMXUART_UFCR_RFDIV_DIV4		(2 << 7)
+#define		IMXUART_UFCR_RFDIV_DIV3		(3 << 7)
+#define		IMXUART_UFCR_RFDIV_DIV2		(4 << 7)
+#define		IMXUART_UFCR_RFDIV_DIV1		(5 << 7)
+#define		IMXUART_UFCR_RFDIV_DIV7		(6 << 7)
+#define		IMXUART_UFCR_DCEDTE		(1 << 6)
+#define		IMXUART_UFCR_RXTL_MASK		0x0000003f
+#define		IMXUART_UFCR_RXTL_SHIFT		0
+
+#define	IMXUART_USR1_REG	0x0094 /* UART Status Register 1 */
+#define		IMXUART_USR1_PARITYERR		(1 << 15)
+#define		IMXUART_USR1_RTSS		(1 << 14)
+#define		IMXUART_USR1_TRDY		(1 << 13)
+#define		IMXUART_USR1_RTSD		(1 << 12)
+#define		IMXUART_USR1_ESCF		(1 << 11)
+#define		IMXUART_USR1_FRAMERR		(1 << 10)
+#define		IMXUART_USR1_RRDY		(1 << 9)
+#define		IMXUART_USR1_AGTIM		(1 << 8)
+#define		IMXUART_USR1_DTRD		(1 << 7)
+#define		IMXUART_USR1_RXDS		(1 << 6)
+#define		IMXUART_USR1_AIRINT		(1 << 5)
+#define		IMXUART_USR1_AWAKE		(1 << 4)
+/* 6040 5008 XXX */
+
+#define	IMXUART_USR2_REG	0x0098 /* UART Status Register 2 */
+#define		IMXUART_USR2_ADET		(1 << 15)
+#define		IMXUART_USR2_TXFE		(1 << 14)
+#define		IMXUART_USR2_DTRF		(1 << 13)
+#define		IMXUART_USR2_IDLE		(1 << 12)
+#define		IMXUART_USR2_ACST		(1 << 11)
+#define		IMXUART_USR2_RIDELT		(1 << 10)
+#define		IMXUART_USR2_RIIN		(1 << 9)
+#define		IMXUART_USR2_IRINT		(1 << 8)
+#define		IMXUART_USR2_WAKE		(1 << 7)
+#define		IMXUART_USR2_DCDDELT		(1 << 6)
+#define		IMXUART_USR2_DCDIN		(1 << 5)
+#define		IMXUART_USR2_RTSF		(1 << 4)
+#define		IMXUART_USR2_TXDC		(1 << 3)
+#define		IMXUART_USR2_BRCD		(1 << 2)
+#define		IMXUART_USR2_ORE		(1 << 1)
+#define		IMXUART_USR2_RDR		(1 << 0)
+
+#define	IMXUART_UESC_REG	0x009c /* UART Escape Character Register */
+#define		IMXUART_UESC_ESC_CHAR_MASK	0x000000ff
+
+#define	IMXUART_UTIM_REG	0x00a0 /* UART Escape Timer Register */
+#define		IMXUART_UTIM_TIM_MASK		0x00000fff
+
+#define	IMXUART_UBIR_REG	0x00a4 /* UART BRM Incremental Register */
+#define		IMXUART_UBIR_INC_MASK		0x0000ffff
+
+#define	IMXUART_UBMR_REG	0x00a8 /* UART BRM Modulator Register */
+#define		IMXUART_UBMR_MOD_MASK		0x0000ffff
+
+#define	IMXUART_UBRC_REG	0x00ac /* UART Baud Rate Count Register */
+#define		IMXUART_UBRC_BCNT_MASK		0x0000ffff
+
+#define	IMXUART_ONEMS_REG	0x00b0 /* UART One Millisecond Register */
+#define		IMXUART_ONEMS_ONEMS_MASK	0x00ffffff
+
+#define	IMXUART_UTS_REG		0x00b4 /* UART Test Register */
+#define		IMXUART_UTS_FRCPERR		(1 << 13)
+#define		IMXUART_UTS_LOOP		(1 << 12)
+#define		IMXUART_UTS_DBGEN		(1 << 11)
+#define		IMXUART_UTS_LOOPIR		(1 << 10)
+#define		IMXUART_UTS_RXDBG		(1 << 9)
+#define		IMXUART_UTS_TXEMPTY		(1 << 6)
+#define		IMXUART_UTS_RXEMPTY		(1 << 5)
+#define		IMXUART_UTS_TXFULL		(1 << 4)
+#define		IMXUART_UTS_RXFULL		(1 << 3)
+#define		IMXUART_UTS_SOFTRST		(1 << 0)
+
+#define	REG(_r)		IMXUART_ ## _r ## _REG
+#define	FLD(_r, _v)	IMXUART_ ## _r ## _ ## _v
+
+#define	GETREG(bas, reg)						\
+		bus_space_read_4((bas)->bst, (bas)->bsh, (reg))
+#define	SETREG(bas, reg, value)						\
+		bus_space_write_4((bas)->bst, (bas)->bsh, (reg), (value))
+
+#define	CLR(_bas, _r, _b)						\
+		SETREG((_bas), (_r), GETREG((_bas), (_r)) & ~(_b))
+#define	SET(_bas, _r, _b)						\
+		SETREG((_bas), (_r), GETREG((_bas), (_r)) | (_b))
+#define	IS_SET(_bas, _r, _b)						\
+		((GETREG((_bas), (_r)) & (_b)) ? 1 : 0)
+
+#define	ENA(_bas, _r, _b)	SET((_bas), REG(_r), FLD(_r, _b))
+#define	DIS(_bas, _r, _b)	CLR((_bas), REG(_r), FLD(_r, _b))
+#define	IS(_bas, _r, _b)	IS_SET((_bas), REG(_r), FLD(_r, _b))
+
+
+#endif	/* _UART_DEV_IMX5XX_H */


Property changes on: trunk/sys/dev/uart/uart_dev_imx.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/dev/uart/uart_dev_lpc.c
===================================================================
--- trunk/sys/dev/uart/uart_dev_lpc.c	                        (rev 0)
+++ trunk/sys/dev/uart/uart_dev_lpc.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -0,0 +1,935 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_dev_lpc.c 283327 2015-05-23 20:54:25Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_cpu_fdt.h>
+#include <dev/uart/uart_bus.h>
+
+#include <dev/ic/ns16550.h>
+#include <arm/lpc/lpcreg.h>
+
+#include "uart_if.h"
+
+#define	DEFAULT_RCLK		(13 * 1000 * 1000)
+
+static bus_space_handle_t bsh_clkpwr;
+
+#define	lpc_ns8250_get_clkreg(_bas, _reg)	\
+    bus_space_read_4(fdtbus_bs_tag, bsh_clkpwr, (_reg))
+#define	lpc_ns8250_set_clkreg(_bas, _reg, _val)	\
+    bus_space_write_4(fdtbus_bs_tag, bsh_clkpwr, (_reg), (_val))
+
+/*
+ * Clear pending interrupts. THRE is cleared by reading IIR. Data
+ * that may have been received gets lost here.
+ */
+static void
+lpc_ns8250_clrint(struct uart_bas *bas)
+{
+	uint8_t iir, lsr;
+
+	iir = uart_getreg(bas, REG_IIR);
+	while ((iir & IIR_NOPEND) == 0) {
+		iir &= IIR_IMASK;
+		if (iir == IIR_RLS) {
+			lsr = uart_getreg(bas, REG_LSR);
+			if (lsr & (LSR_BI|LSR_FE|LSR_PE))
+				(void)uart_getreg(bas, REG_DATA);
+		} else if (iir == IIR_RXRDY || iir == IIR_RXTOUT)
+			(void)uart_getreg(bas, REG_DATA);
+		else if (iir == IIR_MLSC)
+			(void)uart_getreg(bas, REG_MSR);
+		uart_barrier(bas);
+		iir = uart_getreg(bas, REG_IIR);
+	}
+}
+
+static int
+lpc_ns8250_delay(struct uart_bas *bas)
+{
+	uint32_t uclk;
+	int x, y;
+
+	uclk = lpc_ns8250_get_clkreg(bas, LPC_CLKPWR_UART_U5CLK);
+	
+	x = (uclk >> 8) & 0xff;
+	y = uclk & 0xff;
+
+	return (16000000 / (bas->rclk * x / y));
+}
+
+static void
+lpc_ns8250_divisor(int rclk, int baudrate, int *x, int *y)
+{
+
+	switch (baudrate) {
+	case 2400:
+		*x = 1;
+		*y = 255;
+		return;
+	case 4800:
+		*x = 1;
+		*y = 169;
+		return;
+	case 9600:
+		*x = 3;
+		*y = 254;
+		return;
+	case 19200:
+		*x = 3;
+		*y = 127;
+		return;
+	case 38400:
+		*x = 6;
+		*y = 127;
+		return;
+	case 57600:
+		*x = 9;
+		*y = 127;
+		return;
+	default:
+	case 115200:
+		*x = 19;
+		*y = 134;
+		return;
+	case 230400:
+		*x = 19;
+		*y = 67;
+		return;	
+	case 460800:
+		*x = 38;
+		*y = 67;
+		return;
+	}
+}
+
+static int
+lpc_ns8250_drain(struct uart_bas *bas, int what)
+{
+	int delay, limit;
+
+	delay = lpc_ns8250_delay(bas);
+
+	if (what & UART_DRAIN_TRANSMITTER) {
+		/*
+		 * Pick an arbitrary high limit to avoid getting stuck in
+		 * an infinite loop when the hardware is broken. Make the
+		 * limit high enough to handle large FIFOs.
+		 */
+		limit = 10*1024;
+		while ((uart_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit)
+			DELAY(delay);
+		if (limit == 0) {
+			/* printf("lpc_ns8250: transmitter appears stuck... "); */
+			return (EIO);
+		}
+	}
+
+	if (what & UART_DRAIN_RECEIVER) {
+		/*
+		 * Pick an arbitrary high limit to avoid getting stuck in
+		 * an infinite loop when the hardware is broken. Make the
+		 * limit high enough to handle large FIFOs and integrated
+		 * UARTs. The HP rx2600 for example has 3 UARTs on the
+		 * management board that tend to get a lot of data send
+		 * to it when the UART is first activated.
+		 */
+		limit=10*4096;
+		while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) && --limit) {
+			(void)uart_getreg(bas, REG_DATA);
+			uart_barrier(bas);
+			DELAY(delay << 2);
+		}
+		if (limit == 0) {
+			/* printf("lpc_ns8250: receiver appears broken... "); */
+			return (EIO);
+		}
+	}
+
+	return (0);
+}
+
+/*
+ * We can only flush UARTs with FIFOs. UARTs without FIFOs should be
+ * drained. WARNING: this function clobbers the FIFO setting!
+ */
+static void
+lpc_ns8250_flush(struct uart_bas *bas, int what)
+{
+	uint8_t fcr;
+
+	fcr = FCR_ENABLE;
+	if (what & UART_FLUSH_TRANSMITTER)
+		fcr |= FCR_XMT_RST;
+	if (what & UART_FLUSH_RECEIVER)
+		fcr |= FCR_RCV_RST;
+	uart_setreg(bas, REG_FCR, fcr);
+	uart_barrier(bas);
+}
+
+static int
+lpc_ns8250_param(struct uart_bas *bas, int baudrate, int databits, int stopbits,
+    int parity)
+{
+	int xdiv, ydiv;
+	uint8_t lcr;
+
+	lcr = 0;
+	if (databits >= 8)
+		lcr |= LCR_8BITS;
+	else if (databits == 7)
+		lcr |= LCR_7BITS;
+	else if (databits == 6)
+		lcr |= LCR_6BITS;
+	else
+		lcr |= LCR_5BITS;
+	if (stopbits > 1)
+		lcr |= LCR_STOPB;
+	lcr |= parity << 3;
+
+	/* Set baudrate. */
+	if (baudrate > 0) {
+		uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
+		uart_barrier(bas);
+		uart_setreg(bas, REG_DLL, 0x00);
+		uart_setreg(bas, REG_DLH, 0x00);
+		uart_barrier(bas);
+
+		lpc_ns8250_divisor(bas->rclk, baudrate, &xdiv, &ydiv);
+		lpc_ns8250_set_clkreg(bas,
+		    LPC_CLKPWR_UART_U5CLK,
+		    LPC_CLKPWR_UART_UCLK_X(xdiv) |
+		    LPC_CLKPWR_UART_UCLK_Y(ydiv));
+	}
+
+	/* Set LCR and clear DLAB. */
+	uart_setreg(bas, REG_LCR, lcr);
+	uart_barrier(bas);
+	return (0);
+}
+
+/*
+ * Low-level UART interface.
+ */
+static int lpc_ns8250_probe(struct uart_bas *bas);
+static void lpc_ns8250_init(struct uart_bas *bas, int, int, int, int);
+static void lpc_ns8250_term(struct uart_bas *bas);
+static void lpc_ns8250_putc(struct uart_bas *bas, int);
+static int lpc_ns8250_rxready(struct uart_bas *bas);
+static int lpc_ns8250_getc(struct uart_bas *bas, struct mtx *);
+
+static struct uart_ops uart_lpc_ns8250_ops = {
+	.probe = lpc_ns8250_probe,
+	.init = lpc_ns8250_init,
+	.term = lpc_ns8250_term,
+	.putc = lpc_ns8250_putc,
+	.rxready = lpc_ns8250_rxready,
+	.getc = lpc_ns8250_getc,
+};
+
+static int
+lpc_ns8250_probe(struct uart_bas *bas)
+{
+#if 0
+	u_char val;
+
+	/* Check known 0 bits that don't depend on DLAB. */
+	val = uart_getreg(bas, REG_IIR);
+	if (val & 0x30)
+		return (ENXIO);
+	/*
+	 * Bit 6 of the MCR (= 0x40) appears to be 1 for the Sun1699
+	 * chip, but otherwise doesn't seem to have a function. In
+	 * other words, uart(4) works regardless. Ignore that bit so
+	 * the probe succeeds.
+	 */
+	val = uart_getreg(bas, REG_MCR);
+	if (val & 0xa0)
+		return (ENXIO);
+#endif
+	return (0);
+}
+
+static void
+lpc_ns8250_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
+    int parity)
+{
+	u_char	ier;
+	u_long	clkmode;
+	
+	/* Enable UART clock */
+	bus_space_map(fdtbus_bs_tag, LPC_CLKPWR_PHYS_BASE, LPC_CLKPWR_SIZE, 0,
+	    &bsh_clkpwr);
+	clkmode = lpc_ns8250_get_clkreg(bas, LPC_UART_CLKMODE);
+	lpc_ns8250_set_clkreg(bas, LPC_UART_CLKMODE, clkmode | 
+	    LPC_UART_CLKMODE_UART5(1));
+
+#if 0
+	/* Work around H/W bug */
+	uart_setreg(bas, REG_DATA, 0x00);
+#endif
+	if (bas->rclk == 0)
+		bas->rclk = DEFAULT_RCLK;
+	lpc_ns8250_param(bas, baudrate, databits, stopbits, parity);
+
+	/* Disable all interrupt sources. */
+	/*
+	 * 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);
+
+	/* Disable the FIFO (if present). */
+	uart_setreg(bas, REG_FCR, 0);
+	uart_barrier(bas);
+
+	/* Set RTS & DTR. */
+	uart_setreg(bas, REG_MCR, MCR_IE | MCR_RTS | MCR_DTR);
+	uart_barrier(bas);
+
+	lpc_ns8250_clrint(bas);
+}
+
+static void
+lpc_ns8250_term(struct uart_bas *bas)
+{
+
+	/* Clear RTS & DTR. */
+	uart_setreg(bas, REG_MCR, MCR_IE);
+	uart_barrier(bas);
+}
+
+static void
+lpc_ns8250_putc(struct uart_bas *bas, int c)
+{
+	int limit;
+
+	limit = 250000;
+	while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0 && --limit)
+		DELAY(4);
+	uart_setreg(bas, REG_DATA, c);
+	uart_barrier(bas);
+	limit = 250000;
+	while ((uart_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit)
+		DELAY(4);
+}
+
+static int
+lpc_ns8250_rxready(struct uart_bas *bas)
+{
+
+	return ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) != 0 ? 1 : 0);
+}
+
+static int
+lpc_ns8250_getc(struct uart_bas *bas, struct mtx *hwmtx)
+{
+	int c;
+
+	uart_lock(hwmtx);
+
+	while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) == 0) {
+		uart_unlock(hwmtx);
+		DELAY(4);
+		uart_lock(hwmtx);
+	}
+
+	c = uart_getreg(bas, REG_DATA);
+
+	uart_unlock(hwmtx);
+
+	return (c);
+}
+
+/*
+ * High-level UART interface.
+ */
+struct lpc_ns8250_softc {
+	struct uart_softc base;
+	uint8_t		fcr;
+	uint8_t		ier;
+	uint8_t		mcr;
+	
+	uint8_t		ier_mask;
+	uint8_t		ier_rxbits;
+};
+
+static int lpc_ns8250_bus_attach(struct uart_softc *);
+static int lpc_ns8250_bus_detach(struct uart_softc *);
+static int lpc_ns8250_bus_flush(struct uart_softc *, int);
+static int lpc_ns8250_bus_getsig(struct uart_softc *);
+static int lpc_ns8250_bus_ioctl(struct uart_softc *, int, intptr_t);
+static int lpc_ns8250_bus_ipend(struct uart_softc *);
+static int lpc_ns8250_bus_param(struct uart_softc *, int, int, int, int);
+static int lpc_ns8250_bus_probe(struct uart_softc *);
+static int lpc_ns8250_bus_receive(struct uart_softc *);
+static int lpc_ns8250_bus_setsig(struct uart_softc *, int);
+static int lpc_ns8250_bus_transmit(struct uart_softc *);
+static void lpc_ns8250_bus_grab(struct uart_softc *);
+static void lpc_ns8250_bus_ungrab(struct uart_softc *);
+
+static kobj_method_t lpc_ns8250_methods[] = {
+	KOBJMETHOD(uart_attach,		lpc_ns8250_bus_attach),
+	KOBJMETHOD(uart_detach,		lpc_ns8250_bus_detach),
+	KOBJMETHOD(uart_flush,		lpc_ns8250_bus_flush),
+	KOBJMETHOD(uart_getsig,		lpc_ns8250_bus_getsig),
+	KOBJMETHOD(uart_ioctl,		lpc_ns8250_bus_ioctl),
+	KOBJMETHOD(uart_ipend,		lpc_ns8250_bus_ipend),
+	KOBJMETHOD(uart_param,		lpc_ns8250_bus_param),
+	KOBJMETHOD(uart_probe,		lpc_ns8250_bus_probe),
+	KOBJMETHOD(uart_receive,	lpc_ns8250_bus_receive),
+	KOBJMETHOD(uart_setsig,		lpc_ns8250_bus_setsig),
+	KOBJMETHOD(uart_transmit,	lpc_ns8250_bus_transmit),
+	KOBJMETHOD(uart_grab,		lpc_ns8250_bus_grab),
+	KOBJMETHOD(uart_ungrab,		lpc_ns8250_bus_ungrab),
+	{ 0, 0 }
+};
+
+static struct uart_class uart_lpc_class = {
+	"lpc_ns8250",
+	lpc_ns8250_methods,
+	sizeof(struct lpc_ns8250_softc),
+	.uc_ops = &uart_lpc_ns8250_ops,
+	.uc_range = 8,
+	.uc_rclk = DEFAULT_RCLK
+};
+
+static struct ofw_compat_data compat_data[] = {
+	{"lpc,uart",		(uintptr_t)&uart_lpc_class},
+	{NULL,			(uintptr_t)NULL},
+};
+UART_FDT_CLASS_AND_DEVICE(compat_data);
+
+#define	SIGCHG(c, i, s, d)				\
+	if (c) {					\
+		i |= (i & s) ? s : s | d;		\
+	} else {					\
+		i = (i & s) ? (i & ~s) | d : i;		\
+	}
+
+static int
+lpc_ns8250_bus_attach(struct uart_softc *sc)
+{
+	struct lpc_ns8250_softc *lpc_ns8250 = (struct lpc_ns8250_softc*)sc;
+	struct uart_bas *bas;
+	unsigned int ivar;
+
+	bas = &sc->sc_bas;
+
+	lpc_ns8250->mcr = uart_getreg(bas, REG_MCR);
+	lpc_ns8250->fcr = FCR_ENABLE | FCR_DMA;
+	if (!resource_int_value("uart", device_get_unit(sc->sc_dev), "flags",
+	    &ivar)) {
+		if (UART_FLAGS_FCR_RX_LOW(ivar)) 
+			lpc_ns8250->fcr |= FCR_RX_LOW;
+		else if (UART_FLAGS_FCR_RX_MEDL(ivar)) 
+			lpc_ns8250->fcr |= FCR_RX_MEDL;
+		else if (UART_FLAGS_FCR_RX_HIGH(ivar)) 
+			lpc_ns8250->fcr |= FCR_RX_HIGH;
+		else
+			lpc_ns8250->fcr |= FCR_RX_MEDH;
+	} else 
+		lpc_ns8250->fcr |= FCR_RX_HIGH;
+	
+	/* Get IER mask */
+	ivar = 0xf0;
+	resource_int_value("uart", device_get_unit(sc->sc_dev), "ier_mask",
+	    &ivar);
+	lpc_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);
+	lpc_ns8250->ier_rxbits = (uint8_t)(ivar & 0xff);
+	
+	uart_setreg(bas, REG_FCR, lpc_ns8250->fcr);
+	uart_barrier(bas);
+	lpc_ns8250_bus_flush(sc, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER);
+
+	if (lpc_ns8250->mcr & MCR_DTR)
+		sc->sc_hwsig |= SER_DTR;
+	if (lpc_ns8250->mcr & MCR_RTS)
+		sc->sc_hwsig |= SER_RTS;
+	lpc_ns8250_bus_getsig(sc);
+
+	lpc_ns8250_clrint(bas);
+	lpc_ns8250->ier = uart_getreg(bas, REG_IER) & lpc_ns8250->ier_mask;
+	lpc_ns8250->ier |= lpc_ns8250->ier_rxbits;
+	uart_setreg(bas, REG_IER, lpc_ns8250->ier);
+	uart_barrier(bas);
+	
+	return (0);
+}
+
+static int
+lpc_ns8250_bus_detach(struct uart_softc *sc)
+{
+	struct lpc_ns8250_softc *lpc_ns8250;
+	struct uart_bas *bas;
+	u_char ier;
+
+	lpc_ns8250 = (struct lpc_ns8250_softc *)sc;
+	bas = &sc->sc_bas;
+	ier = uart_getreg(bas, REG_IER) & lpc_ns8250->ier_mask;
+	uart_setreg(bas, REG_IER, ier);
+	uart_barrier(bas);
+	lpc_ns8250_clrint(bas);
+	return (0);
+}
+
+static int
+lpc_ns8250_bus_flush(struct uart_softc *sc, int what)
+{
+	struct lpc_ns8250_softc *lpc_ns8250 = (struct lpc_ns8250_softc*)sc;
+	struct uart_bas *bas;
+	int error;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+	if (sc->sc_rxfifosz > 1) {
+		lpc_ns8250_flush(bas, what);
+		uart_setreg(bas, REG_FCR, lpc_ns8250->fcr);
+		uart_barrier(bas);
+		error = 0;
+	} else
+		error = lpc_ns8250_drain(bas, what);
+	uart_unlock(sc->sc_hwmtx);
+	return (error);
+}
+
+static int
+lpc_ns8250_bus_getsig(struct uart_softc *sc)
+{
+	uint32_t new, old, sig;
+	uint8_t msr;
+
+	do {
+		old = sc->sc_hwsig;
+		sig = old;
+		uart_lock(sc->sc_hwmtx);
+		msr = uart_getreg(&sc->sc_bas, REG_MSR);
+		uart_unlock(sc->sc_hwmtx);
+		SIGCHG(msr & MSR_DSR, sig, SER_DSR, SER_DDSR);
+		SIGCHG(msr & MSR_CTS, sig, SER_CTS, SER_DCTS);
+		SIGCHG(msr & MSR_DCD, sig, SER_DCD, SER_DDCD);
+		SIGCHG(msr & MSR_RI,  sig, SER_RI,  SER_DRI);
+		new = sig & ~SER_MASK_DELTA;
+	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
+	return (sig);
+}
+
+static int
+lpc_ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+	struct uart_bas *bas;
+	int baudrate, divisor, error;
+	uint8_t efr, lcr;
+
+	bas = &sc->sc_bas;
+	error = 0;
+	uart_lock(sc->sc_hwmtx);
+	switch (request) {
+	case UART_IOCTL_BREAK:
+		lcr = uart_getreg(bas, REG_LCR);
+		if (data)
+			lcr |= LCR_SBREAK;
+		else
+			lcr &= ~LCR_SBREAK;
+		uart_setreg(bas, REG_LCR, lcr);
+		uart_barrier(bas);
+		break;
+	case UART_IOCTL_IFLOW:
+		lcr = uart_getreg(bas, REG_LCR);
+		uart_barrier(bas);
+		uart_setreg(bas, REG_LCR, 0xbf);
+		uart_barrier(bas);
+		efr = uart_getreg(bas, REG_EFR);
+		if (data)
+			efr |= EFR_RTS;
+		else
+			efr &= ~EFR_RTS;
+		uart_setreg(bas, REG_EFR, efr);
+		uart_barrier(bas);
+		uart_setreg(bas, REG_LCR, lcr);
+		uart_barrier(bas);
+		break;
+	case UART_IOCTL_OFLOW:
+		lcr = uart_getreg(bas, REG_LCR);
+		uart_barrier(bas);
+		uart_setreg(bas, REG_LCR, 0xbf);
+		uart_barrier(bas);
+		efr = uart_getreg(bas, REG_EFR);
+		if (data)
+			efr |= EFR_CTS;
+		else
+			efr &= ~EFR_CTS;
+		uart_setreg(bas, REG_EFR, efr);
+		uart_barrier(bas);
+		uart_setreg(bas, REG_LCR, lcr);
+		uart_barrier(bas);
+		break;
+	case UART_IOCTL_BAUD:
+		lcr = uart_getreg(bas, REG_LCR);
+		uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
+		uart_barrier(bas);
+		divisor = uart_getreg(bas, REG_DLL) |
+		    (uart_getreg(bas, REG_DLH) << 8);
+		uart_barrier(bas);
+		uart_setreg(bas, REG_LCR, lcr);
+		uart_barrier(bas);
+		baudrate = (divisor > 0) ? bas->rclk / divisor / 16 : 0;
+		if (baudrate > 0)
+			*(int*)data = baudrate;
+		else
+			error = ENXIO;
+		break;
+	default:
+		error = EINVAL;
+		break;
+	}
+	uart_unlock(sc->sc_hwmtx);
+	return (error);
+}
+
+static int
+lpc_ns8250_bus_ipend(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	struct lpc_ns8250_softc *lpc_ns8250;
+	int ipend;
+	uint8_t iir, lsr;
+
+	lpc_ns8250 = (struct lpc_ns8250_softc *)sc;
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+	iir = uart_getreg(bas, REG_IIR);
+	if (iir & IIR_NOPEND) {
+		uart_unlock(sc->sc_hwmtx);
+		return (0);
+	}
+	ipend = 0;
+	if (iir & IIR_RXRDY) {
+		lsr = uart_getreg(bas, REG_LSR);
+		if (lsr & LSR_OE)
+			ipend |= SER_INT_OVERRUN;
+		if (lsr & LSR_BI)
+			ipend |= SER_INT_BREAK;
+		if (lsr & LSR_RXRDY)
+			ipend |= SER_INT_RXREADY;
+	} else {
+		if (iir & IIR_TXRDY) {
+			ipend |= SER_INT_TXIDLE;
+			uart_setreg(bas, REG_IER, lpc_ns8250->ier);
+		} else
+			ipend |= SER_INT_SIGCHG;
+	}
+	if (ipend == 0)
+		lpc_ns8250_clrint(bas);
+	uart_unlock(sc->sc_hwmtx);
+	return (ipend);
+}
+
+static int
+lpc_ns8250_bus_param(struct uart_softc *sc, int baudrate, int databits,
+    int stopbits, int parity)
+{
+	struct uart_bas *bas;
+	int error;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+	error = lpc_ns8250_param(bas, baudrate, databits, stopbits, parity);
+	uart_unlock(sc->sc_hwmtx);
+	return (error);
+}
+
+static int
+lpc_ns8250_bus_probe(struct uart_softc *sc)
+{
+	struct lpc_ns8250_softc *lpc_ns8250;
+	struct uart_bas *bas;
+	int count, delay, error, limit;
+	uint8_t lsr, mcr, ier;
+
+	lpc_ns8250 = (struct lpc_ns8250_softc *)sc;
+	bas = &sc->sc_bas;
+
+	error = lpc_ns8250_probe(bas);
+	if (error)
+		return (error);
+
+	mcr = MCR_IE;
+	if (sc->sc_sysdev == NULL) {
+		/* By using lpc_ns8250_init() we also set DTR and RTS. */
+		lpc_ns8250_init(bas, 115200, 8, 1, UART_PARITY_NONE);
+	} else
+		mcr |= MCR_DTR | MCR_RTS;
+
+	error = lpc_ns8250_drain(bas, UART_DRAIN_TRANSMITTER);
+	if (error)
+		return (error);
+
+	/*
+	 * Set loopback mode. This avoids having garbage on the wire and
+	 * also allows us send and receive data. We set DTR and RTS to
+	 * avoid the possibility that automatic flow-control prevents
+	 * any data from being sent.
+	 */
+	uart_setreg(bas, REG_MCR, MCR_LOOPBACK | MCR_IE | MCR_DTR | MCR_RTS);
+	uart_barrier(bas);
+
+	/*
+	 * Enable FIFOs. And check that the UART has them. If not, we're
+	 * done. Since this is the first time we enable the FIFOs, we reset
+	 * them.
+	 */
+	uart_setreg(bas, REG_FCR, FCR_ENABLE);
+	uart_barrier(bas);
+	if (!(uart_getreg(bas, REG_IIR) & IIR_FIFO_MASK)) {
+		/*
+		 * NS16450 or INS8250. We don't bother to differentiate
+		 * between them. They're too old to be interesting.
+		 */
+		uart_setreg(bas, REG_MCR, mcr);
+		uart_barrier(bas);
+		sc->sc_rxfifosz = sc->sc_txfifosz = 1;
+		device_set_desc(sc->sc_dev, "8250 or 16450 or compatible");
+		return (0);
+	}
+
+	uart_setreg(bas, REG_FCR, FCR_ENABLE | FCR_XMT_RST | FCR_RCV_RST);
+	uart_barrier(bas);
+
+	count = 0;
+	delay = lpc_ns8250_delay(bas);
+
+	/* We have FIFOs. Drain the transmitter and receiver. */
+	error = lpc_ns8250_drain(bas, UART_DRAIN_RECEIVER|UART_DRAIN_TRANSMITTER);
+	if (error) {
+		uart_setreg(bas, REG_MCR, mcr);
+		uart_setreg(bas, REG_FCR, 0);
+		uart_barrier(bas);
+		goto done;
+	}
+
+	/*
+	 * We should have a sufficiently clean "pipe" to determine the
+	 * size of the FIFOs. We send as much characters as is reasonable
+	 * and wait for the overflow bit in the LSR register to be
+	 * asserted, counting the characters as we send them. Based on
+	 * that count we know the FIFO size.
+	 */
+	do {
+		uart_setreg(bas, REG_DATA, 0);
+		uart_barrier(bas);
+		count++;
+
+		limit = 30;
+		lsr = 0;
+		/*
+		 * LSR bits are cleared upon read, so we must accumulate
+		 * them to be able to test LSR_OE below.
+		 */
+		while (((lsr |= uart_getreg(bas, REG_LSR)) & LSR_TEMT) == 0 &&
+		    --limit)
+			DELAY(delay);
+		if (limit == 0) {
+			ier = uart_getreg(bas, REG_IER) & lpc_ns8250->ier_mask;
+			uart_setreg(bas, REG_IER, ier);
+			uart_setreg(bas, REG_MCR, mcr);
+			uart_setreg(bas, REG_FCR, 0);
+			uart_barrier(bas);
+			count = 0;
+			goto done;
+		}
+	} while ((lsr & LSR_OE) == 0 && count < 130);
+	count--;
+
+	uart_setreg(bas, REG_MCR, mcr);
+
+	/* Reset FIFOs. */
+	lpc_ns8250_flush(bas, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER);
+
+done:
+	sc->sc_rxfifosz = 64;
+	device_set_desc(sc->sc_dev, "LPC32x0 UART with FIFOs");
+
+	/*
+	 * Force the Tx FIFO size to 16 bytes for now. We don't program the
+	 * Tx trigger. Also, we assume that all data has been sent when the
+	 * interrupt happens.
+	 */
+	sc->sc_txfifosz = 16;
+
+#if 0
+	/*
+	 * XXX there are some issues related to hardware flow control and
+	 * it's likely that uart(4) is the cause. This basicly needs more
+	 * investigation, but we avoid using for hardware flow control
+	 * until then.
+	 */
+	/* 16650s or higher have automatic flow control. */
+	if (sc->sc_rxfifosz > 16) {
+		sc->sc_hwiflow = 1;
+		sc->sc_hwoflow = 1;
+	}
+#endif
+	return (0);
+}
+
+static int
+lpc_ns8250_bus_receive(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	int xc;
+	uint8_t lsr;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+	lsr = uart_getreg(bas, REG_LSR);
+	while (lsr & LSR_RXRDY) {
+		if (uart_rx_full(sc)) {
+			sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
+			break;
+		}
+		xc = uart_getreg(bas, REG_DATA);
+		if (lsr & LSR_FE)
+			xc |= UART_STAT_FRAMERR;
+		if (lsr & LSR_PE)
+			xc |= UART_STAT_PARERR;
+		uart_rx_put(sc, xc);
+		lsr = uart_getreg(bas, REG_LSR);
+	}
+	/* Discard everything left in the Rx FIFO. */
+	while (lsr & LSR_RXRDY) {
+		(void)uart_getreg(bas, REG_DATA);
+		uart_barrier(bas);
+		lsr = uart_getreg(bas, REG_LSR);
+	}
+	uart_unlock(sc->sc_hwmtx);
+ 	return (0);
+}
+
+static int
+lpc_ns8250_bus_setsig(struct uart_softc *sc, int sig)
+{
+	struct lpc_ns8250_softc *lpc_ns8250 = (struct lpc_ns8250_softc*)sc;
+	struct uart_bas *bas;
+	uint32_t new, old;
+
+	bas = &sc->sc_bas;
+	do {
+		old = sc->sc_hwsig;
+		new = old;
+		if (sig & SER_DDTR) {
+			SIGCHG(sig & SER_DTR, new, SER_DTR,
+			    SER_DDTR);
+		}
+		if (sig & SER_DRTS) {
+			SIGCHG(sig & SER_RTS, new, SER_RTS,
+			    SER_DRTS);
+		}
+	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
+	uart_lock(sc->sc_hwmtx);
+	lpc_ns8250->mcr &= ~(MCR_DTR|MCR_RTS);
+	if (new & SER_DTR)
+		lpc_ns8250->mcr |= MCR_DTR;
+	if (new & SER_RTS)
+		lpc_ns8250->mcr |= MCR_RTS;
+	uart_setreg(bas, REG_MCR, lpc_ns8250->mcr);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+	return (0);
+}
+
+static int
+lpc_ns8250_bus_transmit(struct uart_softc *sc)
+{
+	struct lpc_ns8250_softc *lpc_ns8250 = (struct lpc_ns8250_softc*)sc;
+	struct uart_bas *bas;
+	int i;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+	while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0)
+		;
+	uart_setreg(bas, REG_IER, lpc_ns8250->ier | IER_ETXRDY);
+	uart_barrier(bas);
+	for (i = 0; i < sc->sc_txdatasz; i++) {
+		uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]);
+		uart_barrier(bas);
+	}
+	sc->sc_txbusy = 1;
+	uart_unlock(sc->sc_hwmtx);
+	return (0);
+}
+
+void
+lpc_ns8250_bus_grab(struct uart_softc *sc)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+
+	/*
+	 * turn off all interrupts to enter polling mode. Leave the
+	 * saved mask alone. We'll restore whatever it was in ungrab.
+	 * All pending interupt signals are reset when IER is set to 0.
+	 */
+	uart_lock(sc->sc_hwmtx);
+	uart_setreg(bas, REG_IER, 0);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+void
+lpc_ns8250_bus_ungrab(struct uart_softc *sc)
+{
+	struct lpc_ns8250_softc *lpc_ns8250 = (struct lpc_ns8250_softc*)sc;
+	struct uart_bas *bas = &sc->sc_bas;
+
+	/*
+	 * Restore previous interrupt mask
+	 */
+	uart_lock(sc->sc_hwmtx);
+	uart_setreg(bas, REG_IER, lpc_ns8250->ier);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+}


Property changes on: trunk/sys/dev/uart/uart_dev_lpc.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/dev/uart/uart_dev_msm.c
===================================================================
--- trunk/sys/dev/uart/uart_dev_msm.c	                        (rev 0)
+++ trunk/sys/dev/uart/uart_dev_msm.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -0,0 +1,576 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Qualcomm MSM7K/8K uart driver */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_dev_msm.c 283327 2015-05-23 20:54:25Z ian $");
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kdb.h>
+#include <machine/bus.h>
+#include <machine/fdt.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_cpu_fdt.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_dev_msm.h>
+
+#include "uart_if.h"
+
+#define	DEF_CLK		7372800
+
+#define	GETREG(bas, reg)	\
+    bus_space_read_4((bas)->bst, (bas)->bsh, (reg))
+#define	SETREG(bas, reg, value)	\
+    bus_space_write_4((bas)->bst, (bas)->bsh, (reg), (value))
+
+static int msm_uart_param(struct uart_bas *, int, int, int, int);
+
+/*
+ * Low-level UART interface.
+ */
+static int	msm_probe(struct uart_bas *bas);
+static void	msm_init(struct uart_bas *bas, int, int, int, int);
+static void	msm_term(struct uart_bas *bas);
+static void	msm_putc(struct uart_bas *bas, int);
+static int	msm_rxready(struct uart_bas *bas);
+static int	msm_getc(struct uart_bas *bas, struct mtx *mtx);
+
+extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
+
+static int
+msm_uart_param(struct uart_bas *bas, int baudrate, int databits,
+    int stopbits, int parity)
+{
+	int ulcon;
+
+	ulcon = 0;
+
+	switch (databits) {
+	case 5:
+		ulcon |= (UART_DM_5_BPS << 4);
+		break;
+	case 6:
+		ulcon |= (UART_DM_6_BPS << 4);
+		break;
+	case 7:
+		ulcon |= (UART_DM_7_BPS << 4);
+		break;
+	case 8:
+		ulcon |= (UART_DM_8_BPS << 4);
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	switch (parity) {
+	case UART_PARITY_NONE:
+		ulcon |= UART_DM_NO_PARITY;
+		break;
+	case UART_PARITY_ODD:
+		ulcon |= UART_DM_ODD_PARITY;
+		break;
+	case UART_PARITY_EVEN:
+		ulcon |= UART_DM_EVEN_PARITY;
+		break;
+	case UART_PARITY_SPACE:
+		ulcon |= UART_DM_SPACE_PARITY;
+		break;
+	case UART_PARITY_MARK:
+	default:
+		return (EINVAL);
+	}
+
+	switch (stopbits) {
+	case 1:
+		ulcon |= (UART_DM_SBL_1 << 2);
+		break;
+	case 2:
+		ulcon |= (UART_DM_SBL_2 << 2);
+		break;
+	default:
+		return (EINVAL);
+	}
+	uart_setreg(bas, UART_DM_MR2, ulcon);
+
+	/* Set 115200 for both TX and RX. */;
+	uart_setreg(bas, UART_DM_CSR, UART_DM_CSR_115200);
+	uart_barrier(bas);
+
+	return (0);
+}
+
+struct uart_ops uart_msm_ops = {
+	.probe = msm_probe,
+	.init = msm_init,
+	.term = msm_term,
+	.putc = msm_putc,
+	.rxready = msm_rxready,
+	.getc = msm_getc,
+};
+
+static int
+msm_probe(struct uart_bas *bas)
+{
+
+	return (0);
+}
+
+static void
+msm_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
+    int parity)
+{
+
+	if (bas->rclk == 0)
+		bas->rclk = DEF_CLK;
+
+	KASSERT(bas->rclk != 0, ("msm_init: Invalid rclk"));
+
+	/* Set default parameters */
+	msm_uart_param(bas, baudrate, databits, stopbits, parity);
+
+	/*
+	 * Configure UART mode registers MR1 and MR2.
+	 * Hardware flow control isn't supported.
+	 */
+	uart_setreg(bas, UART_DM_MR1, 0x0);
+
+	/* Reset interrupt mask register. */
+	uart_setreg(bas, UART_DM_IMR, 0);
+
+	/*
+	 * Configure Tx and Rx watermarks configuration registers.
+	 * TX watermark value is set to 0 - interrupt is generated when
+	 * FIFO level is less than or equal to 0.
+	 */
+	uart_setreg(bas, UART_DM_TFWR, UART_DM_TFW_VALUE);
+
+	/* Set RX watermark value */
+	uart_setreg(bas, UART_DM_RFWR, UART_DM_RFW_VALUE);
+
+	/*
+	 * Configure Interrupt Programming Register.
+	 * Set initial Stale timeout value.
+	 */
+	uart_setreg(bas, UART_DM_IPR, UART_DM_STALE_TIMEOUT_LSB);
+
+	/* Disable IRDA mode */
+	uart_setreg(bas, UART_DM_IRDA, 0x0);
+
+	/*
+	 * Configure and enable sim interface if required.
+	 * Configure hunt character value in HCR register.
+	 * Keep it in reset state.
+	 */
+	uart_setreg(bas, UART_DM_HCR, 0x0);
+
+	/* Issue soft reset command */
+	SETREG(bas, UART_DM_CR, UART_DM_RESET_TX);
+	SETREG(bas, UART_DM_CR, UART_DM_RESET_RX);
+	SETREG(bas, UART_DM_CR, UART_DM_RESET_ERROR_STATUS);
+	SETREG(bas, UART_DM_CR, UART_DM_RESET_BREAK_INT);
+	SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT);
+
+	/* Enable/Disable Rx/Tx DM interfaces */
+	/* Disable Data Mover for now. */
+	uart_setreg(bas, UART_DM_DMEN, 0x0);
+
+	/* Enable transmitter and receiver */
+	uart_setreg(bas, UART_DM_CR, UART_DM_CR_RX_ENABLE);
+	uart_setreg(bas, UART_DM_CR, UART_DM_CR_TX_ENABLE);
+
+	uart_barrier(bas);
+}
+
+static void
+msm_term(struct uart_bas *bas)
+{
+
+	/* XXX */
+}
+
+static void
+msm_putc(struct uart_bas *bas, int c)
+{
+	int limit;
+
+	/*
+	 * Write to NO_CHARS_FOR_TX register the number of characters
+	 * to be transmitted. However, before writing TX_FIFO must
+	 * be empty as indicated by TX_READY interrupt in IMR register
+	 */
+
+	/*
+	 * Check if transmit FIFO is empty.
+	 * If not wait for TX_READY interrupt.
+	 */
+	limit = 1000;
+	if (!(uart_getreg(bas, UART_DM_SR) & UART_DM_SR_TXEMT)) {
+		while ((uart_getreg(bas, UART_DM_ISR) & UART_DM_TX_READY) == 0
+		    && --limit)
+			DELAY(4);
+	}
+	/* FIFO is ready, write number of characters to be written */
+	uart_setreg(bas, UART_DM_NO_CHARS_FOR_TX, 1);
+
+	/* Wait till TX FIFO has space */
+	while ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_TXRDY) == 0)
+		DELAY(4);
+
+	/* TX FIFO has space. Write char */
+	SETREG(bas, UART_DM_TF(0), (c & 0xff));
+}
+
+static int
+msm_rxready(struct uart_bas *bas)
+{
+
+	/* Wait for a character to come ready */
+	return ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_RXRDY) ==
+	    UART_DM_SR_RXRDY);
+}
+
+static int
+msm_getc(struct uart_bas *bas, struct mtx *mtx)
+{
+	int c;
+
+	uart_lock(mtx);
+
+	/* Wait for a character to come ready */
+	while ((uart_getreg(bas, UART_DM_SR) & UART_DM_SR_RXRDY) !=
+	    UART_DM_SR_RXRDY)
+		DELAY(4);
+
+	/* Check for Overrun error. If so reset Error Status */
+	if (uart_getreg(bas, UART_DM_SR) & UART_DM_SR_UART_OVERRUN)
+		uart_setreg(bas, UART_DM_CR, UART_DM_RESET_ERROR_STATUS);
+
+	/* Read char */
+	c = uart_getreg(bas, UART_DM_RF(0));
+
+	uart_unlock(mtx);
+
+	return (c);
+}
+
+/*
+ * High-level UART interface.
+ */
+struct msm_uart_softc {
+	struct uart_softc base;
+	uint32_t ier;
+};
+
+static int	msm_bus_probe(struct uart_softc *sc);
+static int	msm_bus_attach(struct uart_softc *sc);
+static int	msm_bus_flush(struct uart_softc *, int);
+static int	msm_bus_getsig(struct uart_softc *);
+static int	msm_bus_ioctl(struct uart_softc *, int, intptr_t);
+static int	msm_bus_ipend(struct uart_softc *);
+static int	msm_bus_param(struct uart_softc *, int, int, int, int);
+static int	msm_bus_receive(struct uart_softc *);
+static int	msm_bus_setsig(struct uart_softc *, int);
+static int	msm_bus_transmit(struct uart_softc *);
+static void	msm_bus_grab(struct uart_softc *);
+static void	msm_bus_ungrab(struct uart_softc *);
+
+static kobj_method_t msm_methods[] = {
+	KOBJMETHOD(uart_probe,		msm_bus_probe),
+	KOBJMETHOD(uart_attach, 	msm_bus_attach),
+	KOBJMETHOD(uart_flush,		msm_bus_flush),
+	KOBJMETHOD(uart_getsig,		msm_bus_getsig),
+	KOBJMETHOD(uart_ioctl,		msm_bus_ioctl),
+	KOBJMETHOD(uart_ipend,		msm_bus_ipend),
+	KOBJMETHOD(uart_param,		msm_bus_param),
+	KOBJMETHOD(uart_receive,	msm_bus_receive),
+	KOBJMETHOD(uart_setsig,		msm_bus_setsig),
+	KOBJMETHOD(uart_transmit,	msm_bus_transmit),
+	KOBJMETHOD(uart_grab,		msm_bus_grab),
+	KOBJMETHOD(uart_ungrab,		msm_bus_ungrab),
+	{0, 0 }
+};
+
+int
+msm_bus_probe(struct uart_softc *sc)
+{
+
+	sc->sc_txfifosz = 64;
+	sc->sc_rxfifosz = 64;
+
+	device_set_desc(sc->sc_dev, "Qualcomm HSUART");
+
+	return (0);
+}
+
+static int
+msm_bus_attach(struct uart_softc *sc)
+{
+	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
+	struct uart_bas *bas = &sc->sc_bas;
+
+	sc->sc_hwiflow = 0;
+	sc->sc_hwoflow = 0;
+
+	/* Set TX_READY, TXLEV, RXLEV, RXSTALE */
+	u->ier = UART_DM_IMR_ENABLED;
+
+	/* Configure Interrupt Mask register IMR */
+	uart_setreg(bas, UART_DM_IMR, u->ier);
+
+	return (0);
+}
+
+/*
+ * Write the current transmit buffer to the TX FIFO. 
+ */
+static int
+msm_bus_transmit(struct uart_softc *sc)
+{
+	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
+	struct uart_bas *bas = &sc->sc_bas;
+	int i;
+
+	uart_lock(sc->sc_hwmtx);
+
+	/* Write some data */
+	for (i = 0; i < sc->sc_txdatasz; i++) {
+		/* Write TX data */
+		msm_putc(bas, sc->sc_txbuf[i]);
+		uart_barrier(bas);
+	}
+
+	/* TX FIFO is empty now, enable TX_READY interrupt */
+	u->ier |= UART_DM_TX_READY;
+	SETREG(bas, UART_DM_IMR, u->ier);
+	uart_barrier(bas);
+
+	/*
+	 * Inform upper layer that it is transmitting data to hardware,
+	 * this will be cleared when TXIDLE interrupt occurs.
+	 */
+	sc->sc_txbusy = 1;
+	uart_unlock(sc->sc_hwmtx);
+
+	return (0);
+}
+
+static int
+msm_bus_setsig(struct uart_softc *sc, int sig)
+{
+
+	return (0);
+}
+
+static int
+msm_bus_receive(struct uart_softc *sc)
+{
+	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
+	struct uart_bas *bas;
+	int c;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+
+	/* Initialize Receive Path and interrupt */
+	SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT);
+	SETREG(bas, UART_DM_CR, UART_DM_STALE_EVENT_ENABLE);
+	u->ier |= UART_DM_RXLEV;
+	SETREG(bas, UART_DM_IMR, u->ier);
+
+	/* Loop over until we are full, or no data is available */
+	while (uart_getreg(bas, UART_DM_SR) & UART_DM_SR_RXRDY) {
+		if (uart_rx_full(sc)) {
+			/* No space left in input buffer */
+			sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
+			break;
+		}
+
+		/* Read RX FIFO */
+		c = uart_getreg(bas, UART_DM_RF(0));
+		uart_barrier(bas);
+
+		uart_rx_put(sc, c);
+	}
+
+	uart_unlock(sc->sc_hwmtx);
+
+	return (0);
+}
+
+static int
+msm_bus_param(struct uart_softc *sc, int baudrate, int databits,
+    int stopbits, int parity)
+{
+	int error;
+
+	if (sc->sc_bas.rclk == 0)
+		sc->sc_bas.rclk = DEF_CLK;
+
+	KASSERT(sc->sc_bas.rclk != 0, ("msm_init: Invalid rclk"));
+
+	uart_lock(sc->sc_hwmtx);
+	error = msm_uart_param(&sc->sc_bas, baudrate, databits, stopbits,
+	    parity);
+	uart_unlock(sc->sc_hwmtx);
+
+	return (error);
+}
+
+static int
+msm_bus_ipend(struct uart_softc *sc)
+{
+	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
+	struct uart_bas *bas = &sc->sc_bas;
+	uint32_t isr;
+	int ipend;
+
+	uart_lock(sc->sc_hwmtx);
+
+	/* Get ISR status */
+	isr = GETREG(bas, UART_DM_MISR);
+
+	ipend = 0;
+
+	/* Uart RX starting, notify upper layer */
+	if (isr & UART_DM_RXLEV) {
+		u->ier &= ~UART_DM_RXLEV;
+		SETREG(bas, UART_DM_IMR, u->ier);
+		uart_barrier(bas);
+		ipend |= SER_INT_RXREADY;
+	}
+
+	/* Stale RX interrupt */
+	if (isr & UART_DM_RXSTALE) {
+		/* Disable and reset it */
+		SETREG(bas, UART_DM_CR, UART_DM_STALE_EVENT_DISABLE);
+		SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT);
+		uart_barrier(bas);
+		ipend |= SER_INT_RXREADY;
+	}
+
+	/* TX READY interrupt */
+	if (isr & UART_DM_TX_READY) {
+		/* Clear  TX Ready */
+		SETREG(bas, UART_DM_CR, UART_DM_CLEAR_TX_READY);
+
+		/* Disable TX_READY */
+		u->ier &= ~UART_DM_TX_READY;
+		SETREG(bas, UART_DM_IMR, u->ier);
+		uart_barrier(bas);
+
+		if (sc->sc_txbusy != 0)
+			ipend |= SER_INT_TXIDLE;
+	}
+
+	if (isr & UART_DM_TXLEV) {
+		/* TX FIFO is empty */
+		u->ier &= ~UART_DM_TXLEV;
+		SETREG(bas, UART_DM_IMR, u->ier);
+		uart_barrier(bas);
+
+		if (sc->sc_txbusy != 0)
+			ipend |= SER_INT_TXIDLE;
+	}
+
+	uart_unlock(sc->sc_hwmtx);
+	return (ipend);
+}
+
+static int
+msm_bus_flush(struct uart_softc *sc, int what)
+{
+
+	return (0);
+}
+
+static int
+msm_bus_getsig(struct uart_softc *sc)
+{
+
+	return (0);
+}
+
+static int
+msm_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+
+	return (EINVAL);
+}
+
+static void
+msm_bus_grab(struct uart_softc *sc)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+
+	/*
+	 * XXX: Turn off all interrupts to enter polling mode. Leave the
+	 * saved mask alone. We'll restore whatever it was in ungrab.
+	 */
+	uart_lock(sc->sc_hwmtx);
+	SETREG(bas, UART_DM_CR, UART_DM_RESET_STALE_INT);
+	SETREG(bas, UART_DM_IMR, 0);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+static void
+msm_bus_ungrab(struct uart_softc *sc)
+{
+	struct msm_uart_softc *u = (struct msm_uart_softc *)sc;
+	struct uart_bas *bas = &sc->sc_bas;
+
+	/*
+	 * Restore previous interrupt mask
+	 */
+	uart_lock(sc->sc_hwmtx);
+	SETREG(bas, UART_DM_IMR, u->ier);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+static struct uart_class uart_msm_class = {
+	"msm",
+	msm_methods,
+	sizeof(struct msm_uart_softc),
+	.uc_ops = &uart_msm_ops,
+	.uc_range = 8,
+	.uc_rclk = DEF_CLK,
+};
+
+static struct ofw_compat_data compat_data[] = {
+	{"qcom,msm-uartdm",	(uintptr_t)&uart_msm_class},
+	{NULL,			(uintptr_t)NULL},
+};
+UART_FDT_CLASS_AND_DEVICE(compat_data);


Property changes on: trunk/sys/dev/uart/uart_dev_msm.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/dev/uart/uart_dev_msm.h
===================================================================
--- trunk/sys/dev/uart/uart_dev_msm.h	                        (rev 0)
+++ trunk/sys/dev/uart/uart_dev_msm.h	2018-05-27 22:53:06 UTC (rev 10057)
@@ -0,0 +1,230 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2014 Ganbold Tsagaankhuu <ganbold at freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: stable/10/sys/dev/uart/uart_dev_msm.h 283321 2015-05-23 19:27:04Z ian $
+ */
+
+#ifndef	_UART_DM_H_
+#define	_UART_DM_H_
+
+#define	UART_DM_EXTR_BITS(value, start_pos, end_pos) \
+	    ((value << (32 - end_pos)) >> (32 - (end_pos - start_pos)))
+
+/* UART Parity Mode */
+enum UART_DM_PARITY_MODE {
+	UART_DM_NO_PARITY,
+	UART_DM_ODD_PARITY,
+	UART_DM_EVEN_PARITY,
+	UART_DM_SPACE_PARITY
+};
+
+/* UART Stop Bit Length */
+enum UART_DM_STOP_BIT_LEN {
+	UART_DM_SBL_9_16,
+	UART_DM_SBL_1,
+	UART_DM_SBL_1_9_16,
+	UART_DM_SBL_2
+};
+
+/* UART Bits per Char */
+enum UART_DM_BITS_PER_CHAR {
+	UART_DM_5_BPS,
+	UART_DM_6_BPS,
+	UART_DM_7_BPS,
+	UART_DM_8_BPS
+};
+
+/* 8-N-1 Configuration */
+#define	UART_DM_8_N_1_MODE			(UART_DM_NO_PARITY | \
+						(UART_DM_SBL_1 << 2) | \
+						(UART_DM_8_BPS << 4))
+
+/* UART_DM Registers */
+
+/* UART Operational Mode Registers (HSUART) */
+#define	UART_DM_MR1				0x00
+#define	 UART_DM_MR1_AUTO_RFR_LEVEL1_BMSK	0xffffff00
+#define	 UART_DM_MR1_AUTO_RFR_LEVEL0_BMSK	0x3f
+#define	 UART_DM_MR1_CTS_CTL_BMSK		0x40
+#define	 UART_DM_MR1_RX_RDY_CTL_BMSK		0x80
+
+#define	UART_DM_MR2				0x04
+#define	 UART_DM_MR2_ERROR_MODE_BMSK		0x40
+#define	 UART_DM_MR2_BITS_PER_CHAR_BMSK		0x30
+#define	 UART_DM_MR2_STOP_BIT_LEN_BMSK		0x0c
+#define	 UART_DM_MR2_PARITY_MODE_BMSK		0x03
+#define	 UART_DM_RXBRK_ZERO_CHAR_OFF		(1 << 8)
+#define	 UART_DM_LOOPBACK			(1 << 7)
+
+/* UART Clock Selection Register, write only */
+#define	UART_DM_CSR				0x08
+#define	 UART_DM_CSR_115200			0xff
+#define	 UART_DM_CSR_57600			0xee
+#define	 UART_DM_CSR_38400			0xdd
+#define	 UART_DM_CSR_28800			0xcc
+#define	 UART_DM_CSR_19200			0xbb
+#define	 UART_DM_CSR_14400			0xaa
+#define	 UART_DM_CSR_9600			0x99
+#define	 UART_DM_CSR_7200			0x88
+#define	 UART_DM_CSR_4800			0x77
+#define	 UART_DM_CSR_3600			0x66
+#define	 UART_DM_CSR_2400			0x55
+#define	 UART_DM_CSR_1200			0x44
+#define	 UART_DM_CSR_600			0x33
+#define	 UART_DM_CSR_300			0x22
+#define	 UART_DM_CSR_150			0x11
+#define	 UART_DM_CSR_75				0x00
+
+/* UART DM TX FIFO Registers - 4, write only */
+#define	UART_DM_TF(x)				(0x70 + (4 * (x)))
+
+/* UART Command Register, write only */
+#define	UART_DM_CR				0x10
+#define	 UART_DM_CR_RX_ENABLE			(1 << 0)
+#define	 UART_DM_CR_RX_DISABLE			(1 << 1)
+#define	 UART_DM_CR_TX_ENABLE			(1 << 2)
+#define	 UART_DM_CR_TX_DISABLE			(1 << 3)
+
+/* UART_DM_CR channel command bit value (register field is bits 8:4) */
+#define	UART_DM_RESET_RX			0x10
+#define	UART_DM_RESET_TX			0x20
+#define	UART_DM_RESET_ERROR_STATUS		0x30
+#define	UART_DM_RESET_BREAK_INT			0x40
+#define	UART_DM_START_BREAK			0x50
+#define	UART_DM_STOP_BREAK			0x60
+#define	UART_DM_RESET_CTS			0x70
+#define	UART_DM_RESET_STALE_INT			0x80
+#define	UART_DM_RFR_LOW				0xD0
+#define	UART_DM_RFR_HIGH			0xE0
+#define	UART_DM_CR_PROTECTION_EN		0x100
+#define	UART_DM_STALE_EVENT_ENABLE		0x500
+#define	UART_DM_STALE_EVENT_DISABLE		0x600
+#define	UART_DM_FORCE_STALE_EVENT		0x400
+#define	UART_DM_CLEAR_TX_READY			0x300
+#define	UART_DM_RESET_TX_ERROR			0x800
+#define	UART_DM_RESET_TX_DONE			0x810
+
+/* UART Interrupt Mask Register */
+#define	UART_DM_IMR				0x14
+/* these can be used for both ISR and IMR registers */
+#define	UART_DM_TXLEV				(1 << 0)
+#define	UART_DM_RXHUNT				(1 << 1)
+#define	UART_DM_RXBRK_CHNG			(1 << 2)
+#define	UART_DM_RXSTALE				(1 << 3)
+#define	UART_DM_RXLEV				(1 << 4)
+#define	UART_DM_DELTA_CTS			(1 << 5)
+#define	UART_DM_CURRENT_CTS			(1 << 6)
+#define	UART_DM_TX_READY			(1 << 7)
+#define	UART_DM_TX_ERROR			(1 << 8)
+#define	UART_DM_TX_DONE				(1 << 9)
+#define	UART_DM_RXBREAK_START			(1 << 10)
+#define	UART_DM_RXBREAK_END			(1 << 11)
+#define	UART_DM_PAR_FRAME_ERR_IRQ		(1 << 12)
+
+#define	UART_DM_IMR_ENABLED			(UART_DM_TX_READY | \
+						UART_DM_TXLEV | \
+						UART_DM_RXLEV | \
+						UART_DM_RXSTALE)
+
+/* UART Interrupt Programming Register */
+#define	UART_DM_IPR				0x18
+#define	UART_DM_STALE_TIMEOUT_LSB		0x0f
+#define	UART_DM_STALE_TIMEOUT_MSB		0x00
+#define	UART_DM_IPR_STALE_TIMEOUT_MSB_BMSK	0xffffff80
+#define	UART_DM_IPR_STALE_LSB_BMSK		0x1f
+
+/* UART Transmit/Receive FIFO Watermark Register */
+#define	UART_DM_TFWR				0x1c
+/* Interrupt is generated when FIFO level is less than or equal to this value */
+#define	UART_DM_TFW_VALUE			0
+
+#define	UART_DM_RFWR				0x20
+/* Interrupt generated when no of words in RX FIFO is greater than this value */
+#define	UART_DM_RFW_VALUE			0
+
+/* UART Hunt Character Register */
+#define	UART_DM_HCR				0x24
+
+/* Used for RX transfer initialization */
+#define	UART_DM_DMRX				0x34
+/* Default DMRX value - any value bigger than FIFO size would be fine */
+#define	UART_DM_DMRX_DEF_VALUE			0x220
+
+/* Register to enable IRDA function */
+#define	UART_DM_IRDA				0x38
+
+/* UART Data Mover Enable Register */
+#define	UART_DM_DMEN				0x3c
+
+/* Number of characters for Transmission */
+#define	UART_DM_NO_CHARS_FOR_TX			0x40
+
+/* UART RX FIFO Base Address */
+#define	UART_DM_BADR				0x44
+
+#define	UART_DM_SIM_CFG_ADDR			0x80
+
+/* Read only registers */
+/* UART Status Register */
+#define	UART_DM_SR				0x08
+/* register field mask mapping */
+#define	 UART_DM_SR_RXRDY			(1 << 0)
+#define	 UART_DM_SR_RXFULL			(1 << 1)
+#define	 UART_DM_SR_TXRDY			(1 << 2)
+#define	 UART_DM_SR_TXEMT			(1 << 3)
+#define	 UART_DM_SR_UART_OVERRUN		(1 << 4)
+#define	 UART_DM_SR_PAR_FRAME_ERR		(1 << 5)
+#define	 UART_DM_RX_BREAK			(1 << 6)
+#define	 UART_DM_HUNT_CHAR			(1 << 7)
+#define	 UART_DM_RX_BRK_START_LAST		(1 << 8)
+
+/* UART Receive FIFO Registers - 4 in numbers */
+#define	UART_DM_RF(x)				(0x70 + (4 * (x)))
+
+/* UART Masked Interrupt Status Register */
+#define	UART_DM_MISR				0x10
+
+/* UART Interrupt Status Register */
+#define	UART_DM_ISR				0x14
+
+/* Number of characters received since the end of last RX transfer */
+#define	UART_DM_RX_TOTAL_SNAP			0x38
+
+/* UART TX FIFO Status Register */
+#define	UART_DM_TXFS				0x4c
+#define	 UART_DM_TXFS_STATE_LSB(x)		UART_DM_EXTR_BITS(x,0,6)
+#define	 UART_DM_TXFS_STATE_MSB(x)		UART_DM_EXTR_BITS(x,14,31)
+#define	 UART_DM_TXFS_BUF_STATE(x)		UART_DM_EXTR_BITS(x,7,9)
+#define	 UART_DM_TXFS_ASYNC_STATE(x)		UART_DM_EXTR_BITS(x,10,13)
+
+/* UART RX FIFO Status Register */
+#define	UART_DM_RXFS				0x50
+#define	 UART_DM_RXFS_STATE_LSB(x)		UART_DM_EXTR_BITS(x,0,6)
+#define	 UART_DM_RXFS_STATE_MSB(x)		UART_DM_EXTR_BITS(x,14,31)
+#define	 UART_DM_RXFS_BUF_STATE(x)		UART_DM_EXTR_BITS(x,7,9)
+#define	 UART_DM_RXFS_ASYNC_STATE(x)		UART_DM_EXTR_BITS(x,10,13)
+
+#endif	/* _UART_DM_H_ */


Property changes on: trunk/sys/dev/uart/uart_dev_msm.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/dev/uart/uart_dev_ns8250.c
===================================================================
--- trunk/sys/dev/uart/uart_dev_ns8250.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_dev_ns8250.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 Marcel Moolenaar
  * All rights reserved.
@@ -24,8 +25,10 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "opt_platform.h"
+
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_dev_ns8250.c 294229 2016-01-17 18:18:01Z ian $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -35,9 +38,20 @@
 #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>
+#ifdef FDT
+#include <dev/uart/uart_cpu_fdt.h>
+#endif
 #include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_dev_ns8250.h>
+#include <dev/uart/uart_ppstypes.h>
 
 #include <dev/ic/ns16550.h>
 
@@ -45,6 +59,11 @@
 
 #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.
@@ -226,7 +245,7 @@
 static int ns8250_rxready(struct uart_bas *bas);
 static int ns8250_getc(struct uart_bas *bas, struct mtx *);
 
-static struct uart_ops uart_ns8250_ops = {
+struct uart_ops uart_ns8250_ops = {
 	.probe = ns8250_probe,
 	.init = ns8250_init,
 	.term = ns8250_term,
@@ -339,31 +358,6 @@
 	return (c);
 }
 
-/*
- * High-level UART interface.
- */
-struct ns8250_softc {
-	struct uart_softc base;
-	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 *);
-static int ns8250_bus_detach(struct uart_softc *);
-static int ns8250_bus_flush(struct uart_softc *, int);
-static int ns8250_bus_getsig(struct uart_softc *);
-static int ns8250_bus_ioctl(struct uart_softc *, int, intptr_t);
-static int ns8250_bus_ipend(struct uart_softc *);
-static int ns8250_bus_param(struct uart_softc *, int, int, int, int);
-static int ns8250_bus_probe(struct uart_softc *);
-static int ns8250_bus_receive(struct uart_softc *);
-static int ns8250_bus_setsig(struct uart_softc *, int);
-static int ns8250_bus_transmit(struct uart_softc *);
-
 static kobj_method_t ns8250_methods[] = {
 	KOBJMETHOD(uart_attach,		ns8250_bus_attach),
 	KOBJMETHOD(uart_detach,		ns8250_bus_detach),
@@ -376,6 +370,8 @@
 	KOBJMETHOD(uart_receive,	ns8250_bus_receive),
 	KOBJMETHOD(uart_setsig,		ns8250_bus_setsig),
 	KOBJMETHOD(uart_transmit,	ns8250_bus_transmit),
+	KOBJMETHOD(uart_grab,		ns8250_bus_grab),
+	KOBJMETHOD(uart_ungrab,		ns8250_bus_ungrab),
 	{ 0, 0 }
 };
 
@@ -388,20 +384,75 @@
 	.uc_rclk = DEFAULT_RCLK
 };
 
-#define	SIGCHG(c, i, s, d)				\
-	if (c) {					\
-		i |= (i & s) ? s : s | d;		\
-	} else {					\
-		i = (i & s) ? (i & ~s) | d : i;		\
+#ifdef FDT
+static struct ofw_compat_data compat_data[] = {
+	{"ns16550",		(uintptr_t)&uart_ns8250_class},
+	{NULL,			(uintptr_t)NULL},
+};
+UART_FDT_CLASS_AND_DEVICE(compat_data);
+#endif
+
+/* Use token-pasting to form SER_ and MSR_ named constants. */
+#define	SER(sig)	SER_##sig
+#define	SERD(sig)	SER_D##sig
+#define	MSR(sig)	MSR_##sig
+#define	MSRD(sig)	MSR_D##sig
+
+/*
+ * Detect signal changes using software delta detection.  The previous state of
+ * the signals is in 'var' the new hardware state is in 'msr', and 'sig' is the
+ * short name (DCD, CTS, etc) of the signal bit being processed; 'var' gets the
+ * new state of both the signal and the delta bits.
+ */
+#define SIGCHGSW(var, msr, sig)					\
+	if ((msr) & MSR(sig)) {					\
+		if ((var & SER(sig)) == 0)			\
+			var |= SERD(sig) | SER(sig);		\
+	} else {						\
+		if ((var & SER(sig)) != 0)			\
+			var = SERD(sig) | (var & ~SER(sig));	\
 	}
 
-static int
+/*
+ * Detect signal changes using the hardware msr delta bits.  This is currently
+ * used only when PPS timing information is being captured using the "narrow
+ * pulse" option.  With a narrow PPS pulse the signal may not still be asserted
+ * by time the interrupt handler is invoked.  The hardware will latch the fact
+ * that it changed in the delta bits.
+ */
+#define SIGCHGHW(var, msr, sig)					\
+	if ((msr) & MSRD(sig)) {				\
+		if (((msr) & MSR(sig)) != 0)			\
+			var |= SERD(sig) | SER(sig);		\
+		else						\
+			var = SERD(sig) | (var & ~SER(sig));	\
+	}
+
+int
 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;
 
 	ns8250->mcr = uart_getreg(bas, REG_MCR);
@@ -446,11 +497,23 @@
 	ns8250->ier |= ns8250->ier_rxbits;
 	uart_setreg(bas, REG_IER, ns8250->ier);
 	uart_barrier(bas);
-	
+
+	/*
+	 * Timing of the H/W access was changed with r253161 of uart_core.c
+	 * It has been observed that an ITE IT8513E would signal a break
+	 * condition with pretty much every character it received, unless
+	 * it had enough time to settle between ns8250_bus_attach() and
+	 * ns8250_bus_ipend() -- which it accidentally had before r253161.
+	 * It's not understood why the UART chip behaves this way and it
+	 * could very well be that the DELAY make the H/W work in the same
+	 * accidental manner as before. More analysis is warranted, but
+	 * at least now we fixed a known regression.
+	 */
+	DELAY(200);
 	return (0);
 }
 
-static int
+int
 ns8250_bus_detach(struct uart_softc *sc)
 {
 	struct ns8250_softc *ns8250;
@@ -466,7 +529,7 @@
 	return (0);
 }
 
-static int
+int
 ns8250_bus_flush(struct uart_softc *sc, int what)
 {
 	struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
@@ -486,12 +549,23 @@
 	return (error);
 }
 
-static int
+int
 ns8250_bus_getsig(struct uart_softc *sc)
 {
-	uint32_t new, old, sig;
+	uint32_t old, sig;
 	uint8_t msr;
 
+	/*
+	 * The delta bits are reputed to be broken on some hardware, so use
+	 * software delta detection by default.  Use the hardware delta bits
+	 * when capturing PPS pulses which are too narrow for software detection
+	 * to see the edges.  Hardware delta for RI doesn't work like the
+	 * others, so always use software for it.  Other threads may be changing
+	 * other (non-MSR) bits in sc_hwsig, so loop until it can succesfully
+	 * update without other changes happening.  Note that the SIGCHGxx()
+	 * macros carefully preserve the delta bits when we have to loop several
+	 * times and a signal transitions between iterations.
+	 */
 	do {
 		old = sc->sc_hwsig;
 		sig = old;
@@ -498,16 +572,21 @@
 		uart_lock(sc->sc_hwmtx);
 		msr = uart_getreg(&sc->sc_bas, REG_MSR);
 		uart_unlock(sc->sc_hwmtx);
-		SIGCHG(msr & MSR_DSR, sig, SER_DSR, SER_DDSR);
-		SIGCHG(msr & MSR_CTS, sig, SER_CTS, SER_DCTS);
-		SIGCHG(msr & MSR_DCD, sig, SER_DCD, SER_DDCD);
-		SIGCHG(msr & MSR_RI,  sig, SER_RI,  SER_DRI);
-		new = sig & ~SER_MASK_DELTA;
-	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
+		if (sc->sc_pps_mode & UART_PPS_NARROW_PULSE) {
+			SIGCHGHW(sig, msr, DSR);
+			SIGCHGHW(sig, msr, CTS);
+			SIGCHGHW(sig, msr, DCD);
+		} else {
+			SIGCHGSW(sig, msr, DSR);
+			SIGCHGSW(sig, msr, CTS);
+			SIGCHGSW(sig, msr, DCD);
+		}
+		SIGCHGSW(sig, msr, RI);
+	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, sig & ~SER_MASK_DELTA));
 	return (sig);
 }
 
-static int
+int
 ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
 {
 	struct uart_bas *bas;
@@ -580,16 +659,24 @@
 	return (error);
 }
 
-static int
+int
 ns8250_bus_ipend(struct uart_softc *sc)
 {
 	struct uart_bas *bas;
+	struct ns8250_softc *ns8250;
 	int ipend;
 	uint8_t iir, lsr;
 
+	ns8250 = (struct ns8250_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);
@@ -604,9 +691,10 @@
 		if (lsr & LSR_RXRDY)
 			ipend |= SER_INT_RXREADY;
 	} else {
-		if (iir & IIR_TXRDY)
+		if (iir & IIR_TXRDY) {
 			ipend |= SER_INT_TXIDLE;
-		else
+			uart_setreg(bas, REG_IER, ns8250->ier);
+		} else
 			ipend |= SER_INT_SIGCHG;
 	}
 	if (ipend == 0)
@@ -615,21 +703,45 @@
 	return (ipend);
 }
 
-static int
+int
 ns8250_bus_param(struct uart_softc *sc, int baudrate, int databits,
     int stopbits, int parity)
 {
+	struct ns8250_softc *ns8250;
 	struct uart_bas *bas;
-	int error;
+	int error, limit;
 
+	ns8250 = (struct ns8250_softc*)sc;
 	bas = &sc->sc_bas;
 	uart_lock(sc->sc_hwmtx);
+	/*
+	 * When using DW UART with BUSY detection it is necessary to wait
+	 * until all serial transfers are finished before manipulating the
+	 * line control. LCR will not be affected when UART is busy.
+	 */
+	if (ns8250->busy_detect != 0) {
+		/*
+		 * Pick an arbitrary high limit to avoid getting stuck in
+		 * an infinite loop in case when the hardware is broken.
+		 */
+		limit = 10 * 1024;
+		while (((uart_getreg(bas, DW_REG_USR) & USR_BUSY) != 0) &&
+		    --limit)
+			DELAY(4);
+
+		if (limit <= 0) {
+			/* UART appears to be stuck */
+			uart_unlock(sc->sc_hwmtx);
+			return (EIO);
+		}
+	}
+
 	error = ns8250_param(bas, baudrate, databits, stopbits, parity);
 	uart_unlock(sc->sc_hwmtx);
 	return (error);
 }
 
-static int
+int
 ns8250_bus_probe(struct uart_softc *sc)
 {
 	struct ns8250_softc *ns8250;
@@ -779,7 +891,7 @@
 	return (0);
 }
 
-static int
+int
 ns8250_bus_receive(struct uart_softc *sc)
 {
 	struct uart_bas *bas;
@@ -812,7 +924,7 @@
  	return (0);
 }
 
-static int
+int
 ns8250_bus_setsig(struct uart_softc *sc, int sig)
 {
 	struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
@@ -824,12 +936,10 @@
 		old = sc->sc_hwsig;
 		new = old;
 		if (sig & SER_DDTR) {
-			SIGCHG(sig & SER_DTR, new, SER_DTR,
-			    SER_DDTR);
+			new = (new & ~SER_DTR) | (sig & (SER_DTR | SER_DDTR));
 		}
 		if (sig & SER_DRTS) {
-			SIGCHG(sig & SER_RTS, new, SER_RTS,
-			    SER_DRTS);
+			new = (new & ~SER_RTS) | (sig & (SER_RTS | SER_DRTS));
 		}
 	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
 	uart_lock(sc->sc_hwmtx);
@@ -844,12 +954,7 @@
 	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
+int
 ns8250_bus_transmit(struct uart_softc *sc)
 {
 	struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
@@ -875,3 +980,34 @@
 		uart_sched_softih(sc, SER_INT_TXIDLE);
 	return (0);
 }
+
+void
+ns8250_bus_grab(struct uart_softc *sc)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+
+	/*
+	 * turn off all interrupts to enter polling mode. Leave the
+	 * saved mask alone. We'll restore whatever it was in ungrab.
+	 * All pending interupt signals are reset when IER is set to 0.
+	 */
+	uart_lock(sc->sc_hwmtx);
+	uart_setreg(bas, REG_IER, 0);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+void
+ns8250_bus_ungrab(struct uart_softc *sc)
+{
+	struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
+	struct uart_bas *bas = &sc->sc_bas;
+
+	/*
+	 * Restore previous interrupt mask
+	 */
+	uart_lock(sc->sc_hwmtx);
+	uart_setreg(bas, REG_IER, ns8250->ier);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+}

Added: trunk/sys/dev/uart/uart_dev_ns8250.h
===================================================================
--- trunk/sys/dev/uart/uart_dev_ns8250.h	                        (rev 0)
+++ trunk/sys/dev/uart/uart_dev_ns8250.h	2018-05-27 22:53:06 UTC (rev 10057)
@@ -0,0 +1,63 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2003 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD: stable/10/sys/dev/uart/uart_dev_ns8250.h 262649 2014-03-01 04:16:54Z imp $
+ */
+
+#ifndef _DEV_UART_DEV_NS8250_H_
+#define _DEV_UART_DEV_NS8250_H_
+
+/*
+ * High-level UART interface.
+ */
+struct ns8250_softc {
+	struct uart_softc base;
+	uint8_t		fcr;
+	uint8_t		ier;
+	uint8_t		mcr;
+	
+	uint8_t		ier_mask;
+	uint8_t		ier_rxbits;
+	uint8_t		busy_detect;
+};
+
+extern struct uart_ops uart_ns8250_ops;
+
+int ns8250_bus_attach(struct uart_softc *);
+int ns8250_bus_detach(struct uart_softc *);
+int ns8250_bus_flush(struct uart_softc *, int);
+int ns8250_bus_getsig(struct uart_softc *);
+int ns8250_bus_ioctl(struct uart_softc *, int, intptr_t);
+int ns8250_bus_ipend(struct uart_softc *);
+int ns8250_bus_param(struct uart_softc *, int, int, int, int);
+int ns8250_bus_probe(struct uart_softc *);
+int ns8250_bus_receive(struct uart_softc *);
+int ns8250_bus_setsig(struct uart_softc *, int);
+int ns8250_bus_transmit(struct uart_softc *);
+void ns8250_bus_grab(struct uart_softc *);
+void ns8250_bus_ungrab(struct uart_softc *);
+
+#endif /* _DEV_UART_DEV_NS8250_H_ */


Property changes on: trunk/sys/dev/uart/uart_dev_ns8250.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/dev/uart/uart_dev_pl011.c
===================================================================
--- trunk/sys/dev/uart/uart_dev_pl011.c	                        (rev 0)
+++ trunk/sys/dev/uart/uart_dev_pl011.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -0,0 +1,497 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2012 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_dev_pl011.c 283327 2015-05-23 20:54:25Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_cpu_fdt.h>
+#include <dev/uart/uart_bus.h>
+#include "uart_if.h"
+
+#include <sys/kdb.h>
+
+/* PL011 UART registers and masks*/
+#define	UART_DR		0x00		/* Data register */
+#define	DR_FE		(1 << 8)	/* Framing error */
+#define	DR_PE		(1 << 9)	/* Parity error */
+#define	DR_BE		(1 << 10)	/* Break error */
+#define	DR_OE		(1 << 11)	/* Overrun error */
+
+#define	UART_FR		0x06		/* Flag register */
+#define	FR_TXFF		(1 << 5)	/* Transmit FIFO/reg full */
+#define	FR_RXFF		(1 << 6)	/* Receive FIFO/reg full */
+#define	FR_TXFE		(1 << 7)	/* Transmit FIFO/reg empty */
+
+#define	UART_IBRD	0x09		/* Integer baud rate register */
+#define	IBRD_BDIVINT	0xffff	/* Significant part of int. divisor value */
+
+#define	UART_FBRD	0x0a		/* Fractional baud rate register */
+#define	FBRD_BDIVFRAC	0x3f	/* Significant part of frac. divisor value */
+
+#define	UART_LCR_H	0x0b		/* Line control register */
+#define	LCR_H_WLEN8	(0x3 << 5)
+#define	LCR_H_WLEN7	(0x2 << 5)
+#define	LCR_H_WLEN6	(0x1 << 5)
+#define	LCR_H_FEN	(1 << 4)	/* FIFO mode enable */
+#define	LCR_H_STP2	(1 << 3)	/* 2 stop frames at the end */
+#define	LCR_H_EPS	(1 << 2)	/* Even parity select */
+#define	LCR_H_PEN	(1 << 1)	/* Parity enable */
+
+#define	UART_CR		0x0c		/* Control register */
+#define	CR_RXE		(1 << 9)	/* Receive enable */
+#define	CR_TXE		(1 << 8)	/* Transmit enable */
+#define	CR_UARTEN	(1 << 0)	/* UART enable */
+
+#define	UART_IMSC	0x0e		/* Interrupt mask set/clear register */
+#define	IMSC_MASK_ALL	0x7ff		/* Mask all interrupts */
+
+#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 */
+#define	RIS_OE		(1 << 10)	/* Overrun interrupt status */
+
+#define	UART_MIS	0x10		/* Masked interrupt status register */
+#define	UART_ICR	0x11		/* Interrupt clear register */
+
+/*
+ * FIXME: actual register size is SoC-dependent, we need to handle it
+ */
+#define	__uart_getreg(bas, reg)		\
+	bus_space_read_4((bas)->bst, (bas)->bsh, uart_regofs(bas, reg))
+#define	__uart_setreg(bas, reg, value)	\
+	bus_space_write_4((bas)->bst, (bas)->bsh, uart_regofs(bas, reg), value)
+
+/*
+ * Low-level UART interface.
+ */
+static int uart_pl011_probe(struct uart_bas *bas);
+static void uart_pl011_init(struct uart_bas *bas, int, int, int, int);
+static void uart_pl011_term(struct uart_bas *bas);
+static void uart_pl011_putc(struct uart_bas *bas, int);
+static int uart_pl011_rxready(struct uart_bas *bas);
+static int uart_pl011_getc(struct uart_bas *bas, struct mtx *);
+
+static struct uart_ops uart_pl011_ops = {
+	.probe = uart_pl011_probe,
+	.init = uart_pl011_init,
+	.term = uart_pl011_term,
+	.putc = uart_pl011_putc,
+	.rxready = uart_pl011_rxready,
+	.getc = uart_pl011_getc,
+};
+
+static int
+uart_pl011_probe(struct uart_bas *bas)
+{
+
+	return (0);
+}
+
+static void
+uart_pl011_param(struct uart_bas *bas, int baudrate, int databits, int stopbits,
+    int parity)
+{
+	uint32_t ctrl, line;
+	uint32_t baud;
+
+	/*
+	 * Zero all settings to make sure
+	 * UART is disabled and not configured
+	 */
+	ctrl = line = 0x0;
+	__uart_setreg(bas, UART_CR, ctrl);
+
+	/* As we know UART is disabled we may setup the line */
+	switch (databits) {
+	case 7:
+		line |= LCR_H_WLEN7;
+		break;
+	case 6:
+		line |= LCR_H_WLEN6;
+		break;
+	case 8:
+	default:
+		line |= LCR_H_WLEN8;
+		break;
+	}
+
+	if (stopbits == 2)
+		line |= LCR_H_STP2;
+	else
+		line &= ~LCR_H_STP2;
+
+	if (parity)
+		line |= LCR_H_PEN;
+	else
+		line &= ~LCR_H_PEN;
+
+	/* Configure the rest */
+	line &=  ~LCR_H_FEN;
+	ctrl |= (CR_RXE | CR_TXE | CR_UARTEN);
+
+	if (bas->rclk != 0 && baudrate != 0) {
+		baud = bas->rclk * 4 / baudrate;
+		__uart_setreg(bas, UART_IBRD, ((uint32_t)(baud >> 6)) & IBRD_BDIVINT);
+		__uart_setreg(bas, UART_FBRD, (uint32_t)(baud & 0x3F) & FBRD_BDIVFRAC);
+	}
+
+	/* Add config. to line before reenabling UART */
+	__uart_setreg(bas, UART_LCR_H, (__uart_getreg(bas, UART_LCR_H) &
+	    ~0xff) | line);
+
+	__uart_setreg(bas, UART_CR, ctrl);
+}
+
+static void
+uart_pl011_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
+    int parity)
+{
+	/* Mask all interrupts */
+	__uart_setreg(bas, UART_IMSC, __uart_getreg(bas, UART_IMSC) &
+	    ~IMSC_MASK_ALL);
+	
+	uart_pl011_param(bas, baudrate, databits, stopbits, parity);
+}
+
+static void
+uart_pl011_term(struct uart_bas *bas)
+{
+}
+
+static void
+uart_pl011_putc(struct uart_bas *bas, int c)
+{
+
+	/* Wait when TX FIFO full. Push character otherwise. */
+	while (__uart_getreg(bas, UART_FR) & FR_TXFF)
+		;
+	__uart_setreg(bas, UART_DR, c & 0xff);
+}
+
+static int
+uart_pl011_rxready(struct uart_bas *bas)
+{
+
+	return (__uart_getreg(bas, UART_FR) & FR_RXFF);
+}
+
+static int
+uart_pl011_getc(struct uart_bas *bas, struct mtx *hwmtx)
+{
+	int c;
+
+	while (!uart_pl011_rxready(bas))
+		;
+	c = __uart_getreg(bas, UART_DR) & 0xff;
+
+	return (c);
+}
+
+/*
+ * High-level UART interface.
+ */
+struct uart_pl011_softc {
+	struct uart_softc base;
+	uint8_t		fcr;
+	uint8_t		ier;
+	uint8_t		mcr;
+
+	uint8_t		ier_mask;
+	uint8_t		ier_rxbits;
+};
+
+static int uart_pl011_bus_attach(struct uart_softc *);
+static int uart_pl011_bus_detach(struct uart_softc *);
+static int uart_pl011_bus_flush(struct uart_softc *, int);
+static int uart_pl011_bus_getsig(struct uart_softc *);
+static int uart_pl011_bus_ioctl(struct uart_softc *, int, intptr_t);
+static int uart_pl011_bus_ipend(struct uart_softc *);
+static int uart_pl011_bus_param(struct uart_softc *, int, int, int, int);
+static int uart_pl011_bus_probe(struct uart_softc *);
+static int uart_pl011_bus_receive(struct uart_softc *);
+static int uart_pl011_bus_setsig(struct uart_softc *, int);
+static int uart_pl011_bus_transmit(struct uart_softc *);
+static void uart_pl011_bus_grab(struct uart_softc *);
+static void uart_pl011_bus_ungrab(struct uart_softc *);
+
+static kobj_method_t uart_pl011_methods[] = {
+	KOBJMETHOD(uart_attach,		uart_pl011_bus_attach),
+	KOBJMETHOD(uart_detach,		uart_pl011_bus_detach),
+	KOBJMETHOD(uart_flush,		uart_pl011_bus_flush),
+	KOBJMETHOD(uart_getsig,		uart_pl011_bus_getsig),
+	KOBJMETHOD(uart_ioctl,		uart_pl011_bus_ioctl),
+	KOBJMETHOD(uart_ipend,		uart_pl011_bus_ipend),
+	KOBJMETHOD(uart_param,		uart_pl011_bus_param),
+	KOBJMETHOD(uart_probe,		uart_pl011_bus_probe),
+	KOBJMETHOD(uart_receive,	uart_pl011_bus_receive),
+	KOBJMETHOD(uart_setsig,		uart_pl011_bus_setsig),
+	KOBJMETHOD(uart_transmit,	uart_pl011_bus_transmit),
+	KOBJMETHOD(uart_grab,		uart_pl011_bus_grab),
+	KOBJMETHOD(uart_ungrab,		uart_pl011_bus_ungrab),
+
+	{ 0, 0 }
+};
+
+static struct uart_class uart_pl011_class = {
+	"uart_pl011",
+	uart_pl011_methods,
+	sizeof(struct uart_pl011_softc),
+	.uc_ops = &uart_pl011_ops,
+	.uc_range = 0x48,
+	.uc_rclk = 0
+};
+
+static struct ofw_compat_data compat_data[] = {
+	{"arm,pl011",		(uintptr_t)&uart_pl011_class},
+	{NULL,			(uintptr_t)NULL},
+};
+UART_FDT_CLASS_AND_DEVICE(compat_data);
+
+static int
+uart_pl011_bus_attach(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	int reg;
+
+	bas = &sc->sc_bas;
+
+	/* 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);
+}
+
+static int
+uart_pl011_bus_detach(struct uart_softc *sc)
+{
+
+	return (0);
+}
+
+static int
+uart_pl011_bus_flush(struct uart_softc *sc, int what)
+{
+
+	return (0);
+}
+
+static int
+uart_pl011_bus_getsig(struct uart_softc *sc)
+{
+
+	return (0);
+}
+
+static int
+uart_pl011_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
+{
+	struct uart_bas *bas;
+	int error;
+
+	bas = &sc->sc_bas;
+	error = 0;
+	uart_lock(sc->sc_hwmtx);
+	switch (request) {
+	case UART_IOCTL_BREAK:
+		break;
+	case UART_IOCTL_BAUD:
+		*(int*)data = 115200;
+		break;
+	default:
+		error = EINVAL;
+		break;
+	}
+	uart_unlock(sc->sc_hwmtx);
+
+	return (error);
+}
+
+static int
+uart_pl011_bus_ipend(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	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 | RIS_RTIM))
+		ipend |= SER_INT_RXREADY;
+	if (ints & RIS_BE)
+		ipend |= SER_INT_BREAK;
+	if (ints & RIS_OE)
+		ipend |= SER_INT_OVERRUN;
+	if (ints & UART_TXEMPTY) {
+		if (sc->sc_txbusy)
+			ipend |= SER_INT_TXIDLE;
+
+		/* Disable TX interrupt */
+		reg = __uart_getreg(bas, UART_IMSC);
+		reg &= ~(UART_TXEMPTY);
+		__uart_setreg(bas, UART_IMSC, reg);
+	}
+
+	uart_unlock(sc->sc_hwmtx);
+
+	return (ipend);
+}
+
+static int
+uart_pl011_bus_param(struct uart_softc *sc, int baudrate, int databits,
+    int stopbits, int parity)
+{
+
+	uart_lock(sc->sc_hwmtx);
+	uart_pl011_param(&sc->sc_bas, baudrate, databits, stopbits, parity);
+	uart_unlock(sc->sc_hwmtx);
+
+	return (0);
+}
+
+static int
+uart_pl011_bus_probe(struct uart_softc *sc)
+{
+
+	device_set_desc(sc->sc_dev, "PrimeCell UART (PL011)");
+
+	sc->sc_rxfifosz = 1;
+	sc->sc_txfifosz = 1;
+
+	return (0);
+}
+
+static int
+uart_pl011_bus_receive(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	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 | RIS_RTIM)) {
+		if (uart_rx_full(sc)) {
+			sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
+			break;
+		}
+		xc = __uart_getreg(bas, UART_DR);
+		rx = xc & 0xff;
+
+		if (xc & DR_FE)
+			rx |= UART_STAT_FRAMERR;
+		if (xc & DR_PE)
+			rx |= UART_STAT_PARERR;
+
+		__uart_setreg(bas, UART_ICR, (UART_RXREADY | RIS_RTIM));
+
+		uart_rx_put(sc, rx);
+		ints = __uart_getreg(bas, UART_MIS);
+	}
+
+	uart_unlock(sc->sc_hwmtx);
+
+	return (0);
+}
+
+static int
+uart_pl011_bus_setsig(struct uart_softc *sc, int sig)
+{
+
+	return (0);
+}
+
+static int
+uart_pl011_bus_transmit(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	int reg;
+	int i;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+
+	for (i = 0; i < sc->sc_txdatasz; i++) {
+		__uart_setreg(bas, UART_DR, sc->sc_txbuf[i]);
+		uart_barrier(bas);
+	}
+	sc->sc_txbusy = 1;
+
+	/* 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);
+}
+
+static void
+uart_pl011_bus_grab(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+	__uart_setreg(bas, UART_IMSC, 	/* Switch to RX polling while grabbed */
+	    ~UART_RXREADY & __uart_getreg(bas, UART_IMSC));
+	uart_unlock(sc->sc_hwmtx);
+}
+
+static void
+uart_pl011_bus_ungrab(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+	__uart_setreg(bas, UART_IMSC,	/* Switch to RX interrupts while not grabbed */
+	    UART_RXREADY | __uart_getreg(bas, UART_IMSC));
+	uart_unlock(sc->sc_hwmtx);
+}


Property changes on: trunk/sys/dev/uart/uart_dev_pl011.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/dev/uart/uart_dev_quicc.c
===================================================================
--- trunk/sys/dev/uart/uart_dev_quicc.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_dev_quicc.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2006 Juniper Networks
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_dev_quicc.c 262649 2014-03-01 04:16:54Z imp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -245,6 +246,8 @@
 static int quicc_bus_receive(struct uart_softc *);
 static int quicc_bus_setsig(struct uart_softc *, int);
 static int quicc_bus_transmit(struct uart_softc *);
+static void quicc_bus_grab(struct uart_softc *);
+static void quicc_bus_ungrab(struct uart_softc *);
 
 static kobj_method_t quicc_methods[] = {
 	KOBJMETHOD(uart_attach,		quicc_bus_attach),
@@ -258,6 +261,8 @@
 	KOBJMETHOD(uart_receive,	quicc_bus_receive),
 	KOBJMETHOD(uart_setsig,		quicc_bus_setsig),
 	KOBJMETHOD(uart_transmit,	quicc_bus_transmit),
+	KOBJMETHOD(uart_grab,		quicc_bus_grab),
+	KOBJMETHOD(uart_ungrab,		quicc_bus_ungrab),
 	{ 0, 0 }
 };
 
@@ -293,9 +298,6 @@
 		quicc_setup(bas, 9600, 8, 1, UART_PARITY_NONE);
 	}
 
-	sc->sc_rxfifosz = 1;
-	sc->sc_txfifosz = 1;
-
 	/* Enable interrupts on the receive buffer. */
 	rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1));
 	st = quicc_read2(bas, rb);
@@ -417,6 +419,9 @@
 	if (error)
 		return (error);
 
+	sc->sc_rxfifosz = 1;
+	sc->sc_txfifosz = 1;
+
 	snprintf(buf, sizeof(buf), "quicc, channel %d", sc->sc_bas.chan);
 	device_set_desc_copy(sc->sc_dev, buf);
 	return (0);
@@ -485,3 +490,34 @@
 	uart_unlock(sc->sc_hwmtx);
 	return (0);
 }
+
+static void
+quicc_bus_grab(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	uint16_t st, rb;
+
+	/* Disable interrupts on the receive buffer. */
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+	rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1));
+	st = quicc_read2(bas, rb);
+	quicc_write2(bas, rb, st & ~0x9000);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+static void
+quicc_bus_ungrab(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	uint16_t st, rb;
+
+	/* Enable interrupts on the receive buffer. */
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+	rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1));
+	st = quicc_read2(bas, rb);
+	quicc_write2(bas, rb, st | 0x9000);
+	uart_unlock(sc->sc_hwmtx);
+}
+

Modified: trunk/sys/dev/uart/uart_dev_sab82532.c
===================================================================
--- trunk/sys/dev/uart/uart_dev_sab82532.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_dev_sab82532.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 Marcel Moolenaar
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_dev_sab82532.c 262649 2014-03-01 04:16:54Z imp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -365,6 +366,8 @@
 static int sab82532_bus_receive(struct uart_softc *);
 static int sab82532_bus_setsig(struct uart_softc *, int);
 static int sab82532_bus_transmit(struct uart_softc *);
+static void sab82532_bus_grab(struct uart_softc *);
+static void sab82532_bus_ungrab(struct uart_softc *);
 
 static kobj_method_t sab82532_methods[] = {
 	KOBJMETHOD(uart_attach,		sab82532_bus_attach),
@@ -378,6 +381,8 @@
 	KOBJMETHOD(uart_receive,	sab82532_bus_receive),
 	KOBJMETHOD(uart_setsig,		sab82532_bus_setsig),
 	KOBJMETHOD(uart_transmit,	sab82532_bus_transmit),
+	KOBJMETHOD(uart_grab,		sab82532_bus_grab),
+	KOBJMETHOD(uart_ungrab,		sab82532_bus_ungrab),
 	{ 0, 0 }
 };
 
@@ -407,9 +412,6 @@
 	if (sc->sc_sysdev == NULL)
 		sab82532_init(bas, 9600, 8, 1, UART_PARITY_NONE);
 
-	sc->sc_rxfifosz = 32;
-	sc->sc_txfifosz = 32;
-
 	imr0 = SAB_IMR0_TCD|SAB_IMR0_TIME|SAB_IMR0_CDSC|SAB_IMR0_RFO|
 	    SAB_IMR0_RPF;
 	uart_setreg(bas, SAB_IMR0, 0xff & ~imr0);
@@ -592,6 +594,9 @@
 	if (error)
 		return (error);
 
+	sc->sc_rxfifosz = 32;
+	sc->sc_txfifosz = 32;
+
 	ch = sc->sc_bas.chan - 1 + 'A';
 
 	switch (uart_getreg(&sc->sc_bas, SAB_VSTR) & SAB_VSTR_VMASK) {
@@ -724,3 +729,32 @@
 	uart_unlock(sc->sc_hwmtx);
 	return (0);
 }
+
+static void
+sab82532_bus_grab(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	uint8_t imr0;
+
+	bas = &sc->sc_bas;
+	imr0 = SAB_IMR0_TIME|SAB_IMR0_CDSC|SAB_IMR0_RFO; /* No TCD or RPF */
+	uart_lock(sc->sc_hwmtx);
+	uart_setreg(bas, SAB_IMR0, 0xff & ~imr0);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+static void
+sab82532_bus_ungrab(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+	uint8_t imr0;
+
+	bas = &sc->sc_bas;
+	imr0 = SAB_IMR0_TCD|SAB_IMR0_TIME|SAB_IMR0_CDSC|SAB_IMR0_RFO|
+	    SAB_IMR0_RPF;
+	uart_lock(sc->sc_hwmtx);
+	uart_setreg(bas, SAB_IMR0, 0xff & ~imr0);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+}

Added: trunk/sys/dev/uart/uart_dev_ti8250.c
===================================================================
--- trunk/sys/dev/uart/uart_dev_ti8250.c	                        (rev 0)
+++ trunk/sys/dev/uart/uart_dev_ti8250.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -0,0 +1,147 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2013 Ian Lepore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opt_platform.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_dev_ti8250.c 283327 2015-05-23 20:54:25Z ian $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <machine/bus.h>
+
+#include <arm/ti/ti_prcm.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_cpu.h>
+#include <dev/uart/uart_cpu_fdt.h>
+#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_dev_ns8250.h>
+
+#include "uart_if.h"
+
+/*
+ * High-level UART interface.
+ */
+struct ti8250_softc {
+	struct ns8250_softc ns8250_base;
+	/*uint32_t	mystuff;*/
+};
+
+#define	MDR1_REG		8
+#define	  MDR1_MODE_UART	0
+#define	  MDR1_MODE_DISABLE	7
+#define	SYSCC_REG		15
+#define	  SYSCC_SOFTRESET	(1 << 1)
+#define	SYSS_REG		16
+#define	  SYSS_STATUS_RESETDONE	(1 << 0)
+
+static int
+ti8250_bus_probe(struct uart_softc *sc)
+{
+	int status;
+	int devid;
+	clk_ident_t clkid;
+	pcell_t prop;
+	phandle_t node;
+
+	/*
+	 * Get the device id from FDT.  If it's not there we can't turn on the
+	 * right clocks, so bail, unless we're doing unit 0.  We assume that's
+	 * the serial console, whose clock isn't controllable anyway, and we
+	 * sure don't want to break the console because of a config error.
+	 */
+	node = ofw_bus_get_node(sc->sc_dev);
+	if ((OF_getprop(node, "uart-device-id", &prop, sizeof(prop))) <= 0) {
+		device_printf(sc->sc_dev, 
+		    "missing uart-device-id attribute in FDT\n");
+		if (device_get_unit(sc->sc_dev) != 0)
+			return (ENXIO);
+		devid = 0;
+	} else
+		devid = fdt32_to_cpu(prop);
+
+	/* Enable clocks for this device.  We can't continue if that fails.  */
+	clkid = UART0_CLK + devid;
+	if ((status = ti_prcm_clk_enable(clkid)) != 0)
+		return (status);
+
+	/*
+	 * Set the hardware to disabled mode, do a full device reset, then set
+	 * it to uart mode.  Most devices will be reset-and-disabled already,
+	 * but you never know what a bootloader might have done.
+	 */
+	uart_setreg(&sc->sc_bas, MDR1_REG, MDR1_MODE_DISABLE);
+	uart_setreg(&sc->sc_bas, SYSCC_REG, SYSCC_SOFTRESET);
+	while (uart_getreg(&sc->sc_bas, SYSS_REG) & SYSS_STATUS_RESETDONE)
+		continue;
+	uart_setreg(&sc->sc_bas, MDR1_REG, MDR1_MODE_UART);
+
+	status = ns8250_bus_probe(sc); 
+	if (status == 0)
+		device_set_desc(sc->sc_dev, "TI UART (16550 compatible)");
+
+	return (status);
+}
+
+static kobj_method_t ti8250_methods[] = {
+	KOBJMETHOD(uart_probe,		ti8250_bus_probe),
+
+	KOBJMETHOD(uart_attach,		ns8250_bus_attach),
+	KOBJMETHOD(uart_detach,		ns8250_bus_detach),
+	KOBJMETHOD(uart_flush,		ns8250_bus_flush),
+	KOBJMETHOD(uart_getsig,		ns8250_bus_getsig),
+	KOBJMETHOD(uart_ioctl,		ns8250_bus_ioctl),
+	KOBJMETHOD(uart_ipend,		ns8250_bus_ipend),
+	KOBJMETHOD(uart_param,		ns8250_bus_param),
+	KOBJMETHOD(uart_receive,	ns8250_bus_receive),
+	KOBJMETHOD(uart_setsig,		ns8250_bus_setsig),
+	KOBJMETHOD(uart_transmit,	ns8250_bus_transmit),
+	KOBJMETHOD_END
+};
+
+static struct uart_class uart_ti8250_class = {
+	"ti8250",
+	ti8250_methods,
+	sizeof(struct ti8250_softc),
+	.uc_ops = &uart_ns8250_ops,
+	.uc_range = 0x88,
+	.uc_rclk = 48000000
+};
+static struct ofw_compat_data compat_data[] = {
+	{"ti,ns16550",		(uintptr_t)&uart_ti8250_class},
+	{NULL,			(uintptr_t)NULL},
+};
+UART_FDT_CLASS_AND_DEVICE(compat_data);


Property changes on: trunk/sys/dev/uart/uart_dev_ti8250.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/dev/uart/uart_dev_z8530.c
===================================================================
--- trunk/sys/dev/uart/uart_dev_z8530.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_dev_z8530.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 Marcel Moolenaar
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_dev_z8530.c 262649 2014-03-01 04:16:54Z imp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -281,6 +282,8 @@
 static int z8530_bus_receive(struct uart_softc *);
 static int z8530_bus_setsig(struct uart_softc *, int);
 static int z8530_bus_transmit(struct uart_softc *);
+static void z8530_bus_grab(struct uart_softc *);
+static void z8530_bus_ungrab(struct uart_softc *);
 
 static kobj_method_t z8530_methods[] = {
 	KOBJMETHOD(uart_attach,		z8530_bus_attach),
@@ -294,6 +297,8 @@
 	KOBJMETHOD(uart_receive,	z8530_bus_receive),
 	KOBJMETHOD(uart_setsig,		z8530_bus_setsig),
 	KOBJMETHOD(uart_transmit,	z8530_bus_transmit),
+	KOBJMETHOD(uart_grab,		z8530_bus_grab),
+	KOBJMETHOD(uart_ungrab,		z8530_bus_ungrab),
 	{ 0, 0 }
 };
 
@@ -332,9 +337,6 @@
 	}
 	z8530->txidle = 1;	/* Report SER_INT_TXIDLE. */
 
-	sc->sc_rxfifosz = 3;
-	sc->sc_txfifosz = 1;
-
 	(void)z8530_bus_getsig(sc);
 
 	uart_setmreg(bas, WR_IC, IC_BRK | IC_CTS | IC_DCD);
@@ -515,6 +517,9 @@
 	if (error)
 		return (error);
 
+	sc->sc_rxfifosz = 3;
+	sc->sc_txfifosz = 1;
+
 	ch = sc->sc_bas.chan - 1 + 'A';
 
 	snprintf(buf, sizeof(buf), "z8530, channel %c", ch);
@@ -621,3 +626,27 @@
 	uart_unlock(sc->sc_hwmtx);
 	return (0);
 }
+
+static void
+z8530_bus_grab(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+	uart_setmreg(bas, WR_IDT, IDT_XIE | IDT_TIE);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+static void
+z8530_bus_ungrab(struct uart_softc *sc)
+{
+	struct uart_bas *bas;
+
+	bas = &sc->sc_bas;
+	uart_lock(sc->sc_hwmtx);
+	uart_setmreg(bas, WR_IDT, IDT_XIE | IDT_TIE | IDT_RIA);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+}

Modified: trunk/sys/dev/uart/uart_if.m
===================================================================
--- trunk/sys/dev/uart/uart_if.m	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_if.m	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 #-
 # Copyright (c) 2003 Marcel Moolenaar
 # All rights reserved.
@@ -23,9 +24,10 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #
-# $MidnightBSD$
+# $FreeBSD: stable/10/sys/dev/uart/uart_if.m 262649 2014-03-01 04:16:54Z imp $
 
 #include <sys/param.h>
+#include <sys/systm.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/bus.h>
@@ -140,3 +142,19 @@
 METHOD int transmit {
 	struct uart_softc *this;
 };
+
+# grab() - Up call from the console to the upper layers of the driver when
+# the kernel asks to grab the console. This is valid only for console
+# drivers. This method is responsible for transitioning the hardware
+# from an interrupt driven state to a polled state that works with the
+# low-level console interface defined for this device. The kernel
+# currently only calls this when it wants to grab input from the
+# console. Output can still happen asyncrhonously to these calls.
+METHOD void grab {
+	struct uart_softc *this;
+};
+
+# ungrab() - Undoes the effects of grab().
+METHOD void ungrab {
+	struct uart_softc *this;
+};


Property changes on: trunk/sys/dev/uart/uart_if.m
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Modified: trunk/sys/dev/uart/uart_kbd_sun.c
===================================================================
--- trunk/sys/dev/uart/uart_kbd_sun.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_kbd_sun.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 Jake Burkholder.
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_kbd_sun.c 224126 2011-07-17 08:19:19Z ed $");
 
 #include "opt_compat.h"
 #include "opt_kbd.h"

Modified: trunk/sys/dev/uart/uart_kbd_sun.h
===================================================================
--- trunk/sys/dev/uart/uart_kbd_sun.h	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_kbd_sun.h	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2002 Jason L. Wright (jason at thought.net)
  * All rights reserved.
@@ -32,7 +33,7 @@
  * Agency (DARPA) and Air Force Research Laboratory, Air Force
  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/uart/uart_kbd_sun.h 163890 2006-11-02 00:01:15Z marius $
  */
 
 /* keyboard commands (host->kbd) */

Modified: trunk/sys/dev/uart/uart_kbd_sun_tables.h
===================================================================
--- trunk/sys/dev/uart/uart_kbd_sun_tables.h	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_kbd_sun_tables.h	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,8 +1,9 @@
+/* $MidnightBSD$ */
 /*
  * Automatically generated from sun.us.unix.kbd.
  * DO NOT EDIT!
  *
- * $MidnightBSD$
+ * $FreeBSD: stable/10/sys/dev/uart/uart_kbd_sun_tables.h 122470 2003-11-11 07:33:24Z jake $
  */
 static keymap_t keymap_sun_us_unix_kbd = { 0x80, {
 /*                                                         alt

Added: trunk/sys/dev/uart/uart_ppstypes.h
===================================================================
--- trunk/sys/dev/uart/uart_ppstypes.h	                        (rev 0)
+++ trunk/sys/dev/uart/uart_ppstypes.h	2018-05-27 22:53:06 UTC (rev 10057)
@@ -0,0 +1,47 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2015 	Ian Lepore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD: stable/10/sys/dev/uart/uart_ppstypes.h 294229 2016-01-17 18:18:01Z ian $
+ */
+
+#ifndef _DEV_UART_PPSTYPES_H_
+#define _DEV_UART_PPSTYPES_H_
+
+/*
+ * These constants are shared by several drivers including uart and usb_serial.
+ */
+
+#define	UART_PPS_SIGNAL_MASK	0x0f
+#define	UART_PPS_OPTION_MASK	0xf0
+
+#define	UART_PPS_DISABLED	0x00
+#define	UART_PPS_CTS		0x01
+#define	UART_PPS_DCD		0x02
+
+#define	UART_PPS_INVERT_PULSE	0x10
+#define	UART_PPS_NARROW_PULSE	0x20
+
+#endif /* _DEV_UART_PPSTYPES_H_ */


Property changes on: trunk/sys/dev/uart/uart_ppstypes.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/dev/uart/uart_subr.c
===================================================================
--- trunk/sys/dev/uart/uart_subr.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_subr.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2004 Marcel Moolenaar
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_subr.c 283327 2015-05-23 20:54:25Z ian $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -52,17 +53,20 @@
 	&uart_ns8250_class,
 	&uart_sab82532_class,
 	&uart_z8530_class,
+#if defined(__arm__)
+	&uart_s3c2410_class,
+#endif
 };
 static size_t uart_nclasses = sizeof(uart_classes) / sizeof(uart_classes[0]);
 
 static bus_addr_t
-uart_parse_addr(__const char **p)
+uart_parse_addr(const char **p)
 {
 	return (strtoul(*p, (char**)(uintptr_t)p, 0));
 }
 
 static struct uart_class *
-uart_parse_class(struct uart_class *class, __const char **p)
+uart_parse_class(struct uart_class *class, const char **p)
 {
 	struct uart_class *uc;
 	const char *nm;
@@ -84,13 +88,13 @@
 }
 
 static long
-uart_parse_long(__const char **p)
+uart_parse_long(const char **p)
 {
 	return (strtol(*p, (char**)(uintptr_t)p, 0));
 }
 
 static int
-uart_parse_parity(__const char **p)
+uart_parse_parity(const char **p)
 {
 	if (!strncmp(*p, "even", 4)) {
 		*p += 4;
@@ -116,7 +120,7 @@
 }
 
 static int
-uart_parse_tag(__const char **p)
+uart_parse_tag(const char **p)
 {
 	int tag;
 
@@ -192,7 +196,7 @@
 int
 uart_getenv(int devtype, struct uart_devinfo *di, struct uart_class *class)
 {
-	__const char *spec;
+	const char *spec;
 	bus_addr_t addr = ~0U;
 	int error;
 

Modified: trunk/sys/dev/uart/uart_tty.c
===================================================================
--- trunk/sys/dev/uart/uart_tty.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/uart/uart_tty.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 Marcel Moolenaar
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/uart/uart_tty.c 294959 2016-01-27 22:48:04Z marius $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -57,6 +58,16 @@
 static cn_grab_t uart_cngrab;
 static cn_ungrab_t uart_cnungrab;
 
+static tsw_open_t uart_tty_open;
+static tsw_close_t uart_tty_close;
+static tsw_outwakeup_t uart_tty_outwakeup;
+static tsw_inwakeup_t uart_tty_inwakeup;
+static tsw_ioctl_t uart_tty_ioctl;
+static tsw_param_t uart_tty_param;
+static tsw_modem_t uart_tty_modem;
+static tsw_free_t uart_tty_free;
+static tsw_busy_t uart_tty_busy;
+
 CONSOLE_DRIVER(uart);
 
 static struct uart_devinfo uart_console;
@@ -112,11 +123,15 @@
 static void
 uart_cngrab(struct consdev *cp)
 {
+
+	uart_grab(cp->cn_arg);
 }
 
 static void
 uart_cnungrab(struct consdev *cp)
 {
+
+	uart_ungrab(cp->cn_arg);
 }
 
 static void
@@ -153,7 +168,7 @@
 	struct uart_softc *sc;
 
 	sc = tty_softc(tp);
-	if (sc == NULL || sc->sc_leaving || !sc->sc_opened) 
+	if (sc == NULL || sc->sc_leaving || !sc->sc_opened)
 		return;
 
 	if (sc->sc_hwiflow)
@@ -165,7 +180,6 @@
 
 	wakeup(sc);
 	sc->sc_opened = 0;
-	return;
 }
 
 static void
@@ -211,7 +225,8 @@
 }
 
 static int
-uart_tty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
+uart_tty_ioctl(struct tty *tp, u_long cmd, caddr_t data,
+    struct thread *td __unused)
 {
 	struct uart_softc *sc;
 
@@ -258,8 +273,8 @@
 	}
 	stopbits = (t->c_cflag & CSTOPB) ? 2 : 1;
 	if (t->c_cflag & PARENB)
-		parity = (t->c_cflag & PARODD) ? UART_PARITY_ODD
-		    : UART_PARITY_EVEN;
+		parity = (t->c_cflag & PARODD) ? UART_PARITY_ODD :
+		    UART_PARITY_EVEN;
 	else
 		parity = UART_PARITY_NONE;
 	if (UART_PARAM(sc, t->c_ospeed, databits, stopbits, parity) != 0)
@@ -287,7 +302,7 @@
 
 	sc = tty_softc(tp);
 	if (biton != 0 || bitoff != 0)
-		UART_SETSIG(sc, SER_DELTA(bitoff|biton) | biton);
+		UART_SETSIG(sc, SER_DELTA(bitoff | biton) | biton);
 	return (sc->sc_hwsig);
 }
 
@@ -346,7 +361,7 @@
 }
 
 static void
-uart_tty_free(void *arg)
+uart_tty_free(void *arg __unused)
 {
 
 	/*
@@ -357,6 +372,18 @@
 	 */
 }
 
+static bool
+uart_tty_busy(struct tty *tp)
+{
+	struct uart_softc *sc;
+
+	sc = tty_softc(tp);
+	if (sc == NULL || sc->sc_leaving)
+                return (FALSE);
+
+	return (sc->sc_txbusy);
+}
+
 static struct ttydevsw uart_tty_class = {
 	.tsw_flags	= TF_INITLOCK|TF_CALLOUT,
 	.tsw_open	= uart_tty_open,
@@ -367,6 +394,7 @@
 	.tsw_param	= uart_tty_param,
 	.tsw_modem	= uart_tty_modem,
 	.tsw_free	= uart_tty_free,
+	.tsw_busy	= uart_tty_busy,
 };
 
 int
@@ -406,3 +434,13 @@
 
 	return (0);
 }
+
+struct mtx *
+uart_tty_getlock(struct uart_softc *sc)
+{
+
+	if (sc->sc_u.u_tty.tp != NULL)
+		return (tty_getlock(sc->sc_u.u_tty.tp));
+	else
+		return (NULL);
+}

Modified: trunk/sys/dev/ubsec/ubsec.c
===================================================================
--- trunk/sys/dev/ubsec/ubsec.c	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/ubsec/ubsec.c	2018-05-27 22:53:06 UTC (rev 10057)
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/dev/ubsec/ubsec.c 314667 2017-03-04 13:03:31Z avg $");
 
 /*
  * uBsec 5[56]01, 58xx hardware crypto accelerator
@@ -260,7 +260,7 @@
 static void
 default_harvest(struct rndtest_state *rsp, void *buf, u_int count)
 {
-	random_harvest(buf, count, count*NBBY, 0, RANDOM_PURE);
+	random_harvest(buf, count, count*NBBY/2, RANDOM_PURE_UBSEC);
 }
 
 static int
@@ -268,7 +268,7 @@
 {
 	struct ubsec_softc *sc = device_get_softc(dev);
 	struct ubsec_dma *dmap;
-	u_int32_t cmd, i;
+	u_int32_t i;
 	int rid;
 
 	bzero(sc, sizeof (*sc));
@@ -313,21 +313,8 @@
 		    UBS_FLAGS_LONGCTX | UBS_FLAGS_HWNORM | UBS_FLAGS_BIGKEY;
 	}
 
-	cmd = pci_read_config(dev, PCIR_COMMAND, 4);
-	cmd |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN;
-	pci_write_config(dev, PCIR_COMMAND, cmd, 4);
-	cmd = pci_read_config(dev, PCIR_COMMAND, 4);
+	pci_enable_busmaster(dev);
 
-	if (!(cmd & PCIM_CMD_MEMEN)) {
-		device_printf(dev, "failed to enable memory mapping\n");
-		goto bad;
-	}
-
-	if (!(cmd & PCIM_CMD_BUSMASTEREN)) {
-		device_printf(dev, "failed to enable bus mastering\n");
-		goto bad;
-	}
-
 	/*
 	 * Setup memory-mapping of PCI registers.
 	 */
@@ -470,7 +457,7 @@
 			sc->sc_rnghz = hz / 100;
 		else
 			sc->sc_rnghz = 1;
-		callout_init(&sc->sc_rngto, CALLOUT_MPSAFE);
+		callout_init(&sc->sc_rngto, 1);
 		callout_reset(&sc->sc_rngto, sc->sc_rnghz, ubsec_rng, sc);
 skip_rng:
 	;

Modified: trunk/sys/dev/ubsec/ubsecreg.h
===================================================================
--- trunk/sys/dev/ubsec/ubsecreg.h	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/ubsec/ubsecreg.h	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,5 +1,5 @@
-/* $MidnightBSD: src/sys/dev/ubsec/ubsecreg.h,v 1.2 2008/12/02 22:46:25 laffer1 Exp $ */
-/* $FreeBSD: src/sys/dev/ubsec/ubsecreg.h,v 1.6 2005/01/06 01:43:27 imp Exp $ */
+/* $MidnightBSD$ */
+/* $FreeBSD: stable/10/sys/dev/ubsec/ubsecreg.h 191894 2009-05-07 18:03:47Z philip $ */
 /*	$OpenBSD: ubsecreg.h,v 1.27 2002/09/11 22:40:31 jason Exp $	*/
 
 /*-

Modified: trunk/sys/dev/ubsec/ubsecvar.h
===================================================================
--- trunk/sys/dev/ubsec/ubsecvar.h	2018-05-27 22:50:50 UTC (rev 10056)
+++ trunk/sys/dev/ubsec/ubsecvar.h	2018-05-27 22:53:06 UTC (rev 10057)
@@ -1,5 +1,5 @@
 /* $MidnightBSD$ */
-/* $FreeBSD: src/sys/dev/ubsec/ubsecvar.h,v 1.9 2006/05/17 18:34:26 pjd Exp $ */
+/* $FreeBSD: stable/10/sys/dev/ubsec/ubsecvar.h 158705 2006-05-17 18:34:26Z pjd $ */
 /*	$OpenBSD: ubsecvar.h,v 1.35 2002/09/24 18:33:26 jason Exp $	*/
 
 /*-



More information about the Midnightbsd-cvs mailing list