Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 1 Mar 2014 04:16:54 +0000 (UTC)
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r262649 - in stable/10/sys: arm/s3c2xx0 arm/sa11x0 arm/xilinx dev/uart mips/adm5120 mips/atheros mips/cavium mips/rt305x
Message-ID:  <201403010416.s214GsTq058579@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: imp
Date: Sat Mar  1 04:16:54 2014
New Revision: 262649
URL: http://svnweb.freebsd.org/changeset/base/262649

Log:
  MFC: r260889, r260890, r260911:
  
  	r260911 | imp | 2014-01-20 10:45:36 -0700 (Mon, 20 Jan 2014) | 5 lines
  
  	Don't lock in the generic grab just to lock again in the specific grabs.
  
  	r260890 | imp | 2014-01-19 12:39:13 -0700 (Sun, 19 Jan 2014) | 11 lines
  
  	Introduce grab and ungrab upcalls. When the kernel desires to grab the
  	console, it calls the grab functions. These functions should turn off
  	the RX interrupts, and any others that interfere. This makes mountroot
  	prompt work again. If there's more generalized need other than
  	prompting, many of these routines should be expanded to do those new
  	things.
  
  	Reviewed by:    bde (with reservations)

Modified:
  stable/10/sys/arm/s3c2xx0/uart_dev_s3c2410.c
  stable/10/sys/arm/sa11x0/uart_dev_sa1110.c
  stable/10/sys/arm/xilinx/uart_dev_cdnc.c
  stable/10/sys/dev/uart/uart_core.c
  stable/10/sys/dev/uart/uart_cpu.h
  stable/10/sys/dev/uart/uart_dev_imx.c
  stable/10/sys/dev/uart/uart_dev_lpc.c
  stable/10/sys/dev/uart/uart_dev_ns8250.c
  stable/10/sys/dev/uart/uart_dev_ns8250.h
  stable/10/sys/dev/uart/uart_dev_pl011.c
  stable/10/sys/dev/uart/uart_dev_quicc.c
  stable/10/sys/dev/uart/uart_dev_sab82532.c
  stable/10/sys/dev/uart/uart_dev_z8530.c
  stable/10/sys/dev/uart/uart_if.m
  stable/10/sys/mips/adm5120/uart_dev_adm5120.c
  stable/10/sys/mips/atheros/uart_dev_ar933x.c
  stable/10/sys/mips/cavium/uart_dev_oct16550.c
  stable/10/sys/mips/rt305x/uart_dev_rt305x.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/arm/s3c2xx0/uart_dev_s3c2410.c
==============================================================================
--- stable/10/sys/arm/s3c2xx0/uart_dev_s3c2410.c	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/arm/s3c2xx0/uart_dev_s3c2410.c	Sat Mar  1 04:16:54 2014	(r262649)
@@ -203,7 +203,6 @@ s3c2410_getc(struct uart_bas *bas, struc
 
 	return sscom_getc(bas->bst, bas->bsh);
 }
-
 static int s3c2410_bus_probe(struct uart_softc *sc);
 static int s3c2410_bus_attach(struct uart_softc *sc);
 static int s3c2410_bus_flush(struct uart_softc *, int);
@@ -214,6 +213,8 @@ static int s3c2410_bus_param(struct uart
 static int s3c2410_bus_receive(struct uart_softc *);
 static int s3c2410_bus_setsig(struct uart_softc *, int);
 static int s3c2410_bus_transmit(struct uart_softc *);
+static void s3c2410_bus_grab(struct uart_softc *);
+static void s3c2410_bus_ungrab(struct uart_softc *);
 
 static kobj_method_t s3c2410_methods[] = {
 	KOBJMETHOD(uart_probe,		s3c2410_bus_probe),
@@ -226,6 +227,8 @@ static kobj_method_t s3c2410_methods[] =
 	KOBJMETHOD(uart_receive,	s3c2410_bus_receive),
 	KOBJMETHOD(uart_setsig,		s3c2410_bus_setsig),
 	KOBJMETHOD(uart_transmit,	s3c2410_bus_transmit),
+	KOBJMETHOD(uart_grab,		s3c2410_bus_grab),
+	KOBJMETHOD(uart_ungrab,		s3c2410_bus_ungrab),
 	
 	{0, 0 }
 };
@@ -373,6 +376,25 @@ s3c2410_bus_ioctl(struct uart_softc *sc,
 	return (EINVAL);
 }
 
+
+static void
+s3c2410_bus_grab(struct uart_softc *sc)
+{
+	uintptr_t irq;
+
+	irq = rman_get_start(sc->sc_ires);
+	arm_mask_irq(get_sub_irq(irq, RX_OFF));
+}
+
+static void
+s3c2410_bus_ungrab(struct uart_softc *sc)
+{
+	uintptr_t irq;
+
+	irq = rman_get_start(sc->sc_ires);
+	arm_unmask_irq(get_sub_irq(irq, RX_OFF));
+}
+
 struct uart_class uart_s3c2410_class = {
 	"s3c2410 class",
 	s3c2410_methods,

Modified: stable/10/sys/arm/sa11x0/uart_dev_sa1110.c
==============================================================================
--- stable/10/sys/arm/sa11x0/uart_dev_sa1110.c	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/arm/sa11x0/uart_dev_sa1110.c	Sat Mar  1 04:16:54 2014	(r262649)
@@ -137,6 +137,8 @@ static int sa1110_bus_param(struct uart_
 static int sa1110_bus_receive(struct uart_softc *);
 static int sa1110_bus_setsig(struct uart_softc *, int);
 static int sa1110_bus_transmit(struct uart_softc *);
+static void sa1110_bus_grab(struct uart_softc *);
+static void sa1110_bus_ungrab(struct uart_softc *);
 
 static kobj_method_t sa1110_methods[] = {
 	KOBJMETHOD(uart_probe,		sa1110_bus_probe),
@@ -149,6 +151,8 @@ static kobj_method_t sa1110_methods[] = 
 	KOBJMETHOD(uart_receive,	sa1110_bus_receive),
 	KOBJMETHOD(uart_setsig,		sa1110_bus_setsig),
 	KOBJMETHOD(uart_transmit,	sa1110_bus_transmit),
+	KOBJMETHOD(uart_grab,		sa1110_bus_grab),
+	KOBJMETHOD(uart_ungrab,		sa1110_bus_ungrab),
 	
 	{0, 0 }
 };
@@ -164,10 +168,10 @@ sa1110_bus_probe(struct uart_softc *sc)
 static int
 sa1110_bus_attach(struct uart_softc *sc)
 {
-	 bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
+	bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
 
-	 sc->sc_hwiflow = 0;
-	 uart_setreg(&sc->sc_bas, SACOM_CR3, CR3_RXE | CR3_TXE | CR3_RIE | CR3_TIE);
+	sc->sc_hwiflow = 0;
+	uart_setreg(&sc->sc_bas, SACOM_CR3, CR3_RXE | CR3_TXE | CR3_RIE | CR3_TIE);
 	return (0);
 }
 static int
@@ -273,6 +277,26 @@ sa1110_bus_ioctl(struct uart_softc *sc, 
 	return (EINVAL);
 }
 
+static void
+sa1110_bus_grab(struct uart_softc *sc)
+{
+
+	/* Turn off Rx interrupts */
+	uart_lock(sc->sc_hwmtx);
+	uart_setreg(&sc->sc_bas, SACOM_CR3, CR3_TXE | CR3_TIE);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+static void
+sa1110_bus_ungrab(struct uart_softc *sc)
+{
+
+	/* Turn on Rx interrupts */
+	uart_lock(sc->sc_hwmtx);
+	uart_setreg(&sc->sc_bas, SACOM_CR3, CR3_RXE | CR3_TXE | CR3_RIE | CR3_TIE);
+	uart_unlock(sc->sc_hwmtx);
+}
+
 struct uart_class uart_sa1110_class = {
 	"sa1110",
 	sa1110_methods,

Modified: stable/10/sys/arm/xilinx/uart_dev_cdnc.c
==============================================================================
--- stable/10/sys/arm/xilinx/uart_dev_cdnc.c	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/arm/xilinx/uart_dev_cdnc.c	Sat Mar  1 04:16:54 2014	(r262649)
@@ -398,6 +398,8 @@ static int cdnc_uart_bus_param(struct ua
 static int cdnc_uart_bus_receive(struct uart_softc *);
 static int cdnc_uart_bus_setsig(struct uart_softc *, int);
 static int cdnc_uart_bus_transmit(struct uart_softc *);
+static void cdnc_uart_bus_grab(struct uart_softc *);
+static void cdnc_uart_bus_ungrab(struct uart_softc *);
 
 static kobj_method_t cdnc_uart_bus_methods[] = {
 	KOBJMETHOD(uart_probe,		cdnc_uart_bus_probe),
@@ -410,6 +412,8 @@ static kobj_method_t cdnc_uart_bus_metho
 	KOBJMETHOD(uart_receive,	cdnc_uart_bus_receive),
 	KOBJMETHOD(uart_setsig,		cdnc_uart_bus_setsig),
 	KOBJMETHOD(uart_transmit,	cdnc_uart_bus_transmit),
+	KOBJMETHOD(uart_grab,		cdnc_uart_bus_grab),
+	KOBJMETHOD(uart_ungrab,		cdnc_uart_bus_ungrab),
 	
 	KOBJMETHOD_END
 };
@@ -675,6 +679,27 @@ cdnc_uart_bus_ioctl(struct uart_softc *s
 	return (error);
 }
 
+static void
+cdnc_uart_bus_grab(struct uart_softc *sc)
+{
+
+	/* Enable interrupts. */
+	WR4(&sc->sc_bas, CDNC_UART_IEN_REG,
+	    CDNC_UART_INT_TXOVR | CDNC_UART_INT_RXOVR |
+	    CDNC_UART_INT_DMSI);
+}
+
+static void
+cdnc_uart_bus_ungrab(struct uart_softc *sc)
+{
+
+	/* Enable interrupts. */
+	WR4(&sc->sc_bas, CDNC_UART_IEN_REG,
+	    CDNC_UART_INT_RXTRIG | CDNC_UART_INT_RXTMOUT |
+	    CDNC_UART_INT_TXOVR | CDNC_UART_INT_RXOVR |
+	    CDNC_UART_INT_DMSI);
+}
+
 struct uart_class uart_cdnc_class = {
 	"cdnc_uart",
 	cdnc_uart_bus_methods,

Modified: stable/10/sys/dev/uart/uart_core.c
==============================================================================
--- stable/10/sys/dev/uart/uart_core.c	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/dev/uart/uart_core.c	Sat Mar  1 04:16:54 2014	(r262649)
@@ -412,6 +412,13 @@ uart_bus_attach(device_t dev)
 		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.
@@ -617,3 +624,19 @@ uart_bus_resume(device_t dev)
 	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: stable/10/sys/dev/uart/uart_cpu.h
==============================================================================
--- stable/10/sys/dev/uart/uart_cpu.h	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/dev/uart/uart_cpu.h	Sat Mar  1 04:16:54 2014	(r262649)
@@ -33,6 +33,8 @@
 #include <sys/lock.h>
 #include <sys/mutex.h>
 
+struct uart_softc;
+
 /*
  * Low-level operations for use by console and/or debug port support.
  */
@@ -43,8 +45,6 @@ struct uart_ops {
 	void (*putc)(struct uart_bas *, int);
 	int (*rxready)(struct uart_bas *);
 	int (*getc)(struct uart_bas *, struct mtx *);
-	void (*grab)(struct uart_bas *);
-	void (*ungrab)(struct uart_bas *);
 };
 
 extern bus_space_tag_t uart_bus_space_io;
@@ -53,7 +53,6 @@ extern bus_space_tag_t uart_bus_space_me
 /*
  * Console and debug port device info.
  */
-struct uart_softc;
 struct uart_devinfo {
 	SLIST_ENTRY(uart_devinfo) next;
 	struct uart_ops *ops;
@@ -70,6 +69,7 @@ struct uart_devinfo {
 	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 *);
@@ -137,27 +137,6 @@ uart_putc(struct uart_devinfo *di, int c
 	uart_unlock(di->hwmtx);
 }
 
-static __inline void
-uart_grab(struct uart_devinfo *di)
-{
-
-	uart_lock(di->hwmtx);
-	if (di->ops->grab)
-		di->ops->grab(&di->bas);
-	uart_unlock(di->hwmtx);
-}
-
-static __inline void
-uart_ungrab(struct uart_devinfo *di)
-{
-
-	uart_lock(di->hwmtx);
-	if (di->ops->ungrab)
-		di->ops->ungrab(&di->bas);
-	uart_unlock(di->hwmtx);
-}
-
-
 static __inline int
 uart_rxready(struct uart_devinfo *di)
 {
@@ -190,4 +169,7 @@ uart_getc(struct uart_devinfo *di)
 	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_ */

Modified: stable/10/sys/dev/uart/uart_dev_imx.c
==============================================================================
--- stable/10/sys/dev/uart/uart_dev_imx.c	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/dev/uart/uart_dev_imx.c	Sat Mar  1 04:16:54 2014	(r262649)
@@ -140,6 +140,8 @@ static int imx_uart_bus_probe(struct uar
 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),
@@ -153,6 +155,8 @@ static kobj_method_t imx_uart_methods[] 
 	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 }
 };
 
@@ -189,12 +193,7 @@ imx_uart_bus_attach(struct uart_softc *s
 
 	(void)imx_uart_bus_getsig(sc);
 
-	/* XXX workaround to have working console on manut prompt */
-	if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE){
-		DIS(bas, UCR4, DREN);
-	} else {
-		ENA(bas, UCR4, DREN);
-	}
+	ENA(bas, UCR4, DREN);
 	DIS(bas, UCR1, RRDYEN);
 	DIS(bas, UCR1, IDEN);
 	DIS(bas, UCR3, RXDSEN);
@@ -402,13 +401,6 @@ static int
 imx_uart_bus_setsig(struct uart_softc *sc, int sig)
 {
 
-	/* TODO: implement (?) */
-
-	/* XXX workaround to have working console on mount prompt */
-	/* Enable RX interrupt */
-	if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE)
-		if (!IS(&sc->sc_bas, UCR4, DREN))
-			ENA(&sc->sc_bas, UCR4, DREN);
 	return (0);
 }
 
@@ -434,3 +426,25 @@ imx_uart_bus_transmit(struct uart_softc 
 
 	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, UCR4, DREN);
+	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, UCR4, DREN);
+	uart_unlock(sc->sc_hwmtx);
+}

Modified: stable/10/sys/dev/uart/uart_dev_lpc.c
==============================================================================
--- stable/10/sys/dev/uart/uart_dev_lpc.c	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/dev/uart/uart_dev_lpc.c	Sat Mar  1 04:16:54 2014	(r262649)
@@ -400,6 +400,8 @@ static int lpc_ns8250_bus_probe(struct u
 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),
@@ -413,6 +415,8 @@ static kobj_method_t lpc_ns8250_methods[
 	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 }
 };
 
@@ -889,3 +893,34 @@ lpc_ns8250_bus_transmit(struct uart_soft
 	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);
+}

Modified: stable/10/sys/dev/uart/uart_dev_ns8250.c
==============================================================================
--- stable/10/sys/dev/uart/uart_dev_ns8250.c	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/dev/uart/uart_dev_ns8250.c	Sat Mar  1 04:16:54 2014	(r262649)
@@ -365,6 +365,8 @@ static kobj_method_t ns8250_methods[] = 
 	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 }
 };
 
@@ -898,3 +900,34 @@ ns8250_bus_transmit(struct uart_softc *s
 		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);
+}

Modified: stable/10/sys/dev/uart/uart_dev_ns8250.h
==============================================================================
--- stable/10/sys/dev/uart/uart_dev_ns8250.h	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/dev/uart/uart_dev_ns8250.h	Sat Mar  1 04:16:54 2014	(r262649)
@@ -56,5 +56,7 @@ 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_ */

Modified: stable/10/sys/dev/uart/uart_dev_pl011.c
==============================================================================
--- stable/10/sys/dev/uart/uart_dev_pl011.c	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/dev/uart/uart_dev_pl011.c	Sat Mar  1 04:16:54 2014	(r262649)
@@ -242,6 +242,8 @@ static int uart_pl011_bus_probe(struct u
 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),
@@ -255,6 +257,9 @@ static kobj_method_t uart_pl011_methods[
 	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 }
 };
 
@@ -441,3 +446,27 @@ uart_pl011_bus_transmit(struct uart_soft
 
 	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);
+}

Modified: stable/10/sys/dev/uart/uart_dev_quicc.c
==============================================================================
--- stable/10/sys/dev/uart/uart_dev_quicc.c	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/dev/uart/uart_dev_quicc.c	Sat Mar  1 04:16:54 2014	(r262649)
@@ -245,6 +245,8 @@ static int quicc_bus_probe(struct uart_s
 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 +260,8 @@ static kobj_method_t quicc_methods[] = {
 	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 }
 };
 
@@ -485,3 +489,34 @@ quicc_bus_transmit(struct uart_softc *sc
 	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: stable/10/sys/dev/uart/uart_dev_sab82532.c
==============================================================================
--- stable/10/sys/dev/uart/uart_dev_sab82532.c	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/dev/uart/uart_dev_sab82532.c	Sat Mar  1 04:16:54 2014	(r262649)
@@ -365,6 +365,8 @@ static int sab82532_bus_probe(struct uar
 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 +380,8 @@ static kobj_method_t sab82532_methods[] 
 	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 }
 };
 
@@ -724,3 +728,32 @@ sab82532_bus_transmit(struct uart_softc 
 	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);
+}

Modified: stable/10/sys/dev/uart/uart_dev_z8530.c
==============================================================================
--- stable/10/sys/dev/uart/uart_dev_z8530.c	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/dev/uart/uart_dev_z8530.c	Sat Mar  1 04:16:54 2014	(r262649)
@@ -281,6 +281,8 @@ static int z8530_bus_probe(struct uart_s
 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 +296,8 @@ static kobj_method_t z8530_methods[] = {
 	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 }
 };
 
@@ -621,3 +625,27 @@ z8530_bus_transmit(struct uart_softc *sc
 	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: stable/10/sys/dev/uart/uart_if.m
==============================================================================
--- stable/10/sys/dev/uart/uart_if.m	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/dev/uart/uart_if.m	Sat Mar  1 04:16:54 2014	(r262649)
@@ -141,3 +141,19 @@ METHOD int setsig {
 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;
+};

Modified: stable/10/sys/mips/adm5120/uart_dev_adm5120.c
==============================================================================
--- stable/10/sys/mips/adm5120/uart_dev_adm5120.c	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/mips/adm5120/uart_dev_adm5120.c	Sat Mar  1 04:16:54 2014	(r262649)
@@ -149,6 +149,8 @@ static int adm5120_uart_bus_probe(struct
 static int adm5120_uart_bus_receive(struct uart_softc *);
 static int adm5120_uart_bus_setsig(struct uart_softc *, int);
 static int adm5120_uart_bus_transmit(struct uart_softc *);
+static void adm5120_uart_bus_grab(struct uart_softc *);
+static void adm5120_uart_bus_ungrab(struct uart_softc *);
 
 static kobj_method_t adm5120_uart_methods[] = {
 	KOBJMETHOD(uart_attach,		adm5120_uart_bus_attach),
@@ -162,6 +164,8 @@ static kobj_method_t adm5120_uart_method
 	KOBJMETHOD(uart_receive,	adm5120_uart_bus_receive),
 	KOBJMETHOD(uart_setsig,		adm5120_uart_bus_setsig),
 	KOBJMETHOD(uart_transmit,	adm5120_uart_bus_transmit),
+	KOBJMETHOD(uart_grab,		adm5120_uart_bus_grab),
+	KOBJMETHOD(uart_ungrab,		adm5120_uart_bus_ungrab),
 	{ 0, 0 }
 };
 
@@ -450,3 +454,26 @@ adm5120_uart_bus_transmit(struct uart_so
 	uart_unlock(sc->sc_hwmtx);
 	return (0);
 }
+
+static void
+adm5120_uart_bus_grab(struct uart_softc *sc)
+{
+
+	/* Enable interrupts - no RX_INT or RX_TIMEOUT */
+	uart_lock(sc->sc_hwmtx);
+	uart_setreg(&sc->sc_bas, UART_CR_REG,
+	    UART_CR_PORT_EN | UART_CR_MODEM_STATUS_INT_EN);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+static void
+adm5120_uart_bus_ungrab(struct uart_softc *sc)
+{
+
+	/* Enable interrupts */
+	uart_lock(sc->sc_hwmtx);
+	uart_setreg(&sc->sc_bas, UART_CR_REG,
+	    UART_CR_PORT_EN|UART_CR_RX_INT_EN|UART_CR_RX_TIMEOUT_INT_EN|
+	    UART_CR_MODEM_STATUS_INT_EN);
+	uart_unlock(sc->sc_hwmtx);
+}

Modified: stable/10/sys/mips/atheros/uart_dev_ar933x.c
==============================================================================
--- stable/10/sys/mips/atheros/uart_dev_ar933x.c	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/mips/atheros/uart_dev_ar933x.c	Sat Mar  1 04:16:54 2014	(r262649)
@@ -325,6 +325,8 @@ static int ar933x_bus_probe(struct uart_
 static int ar933x_bus_receive(struct uart_softc *);
 static int ar933x_bus_setsig(struct uart_softc *, int);
 static int ar933x_bus_transmit(struct uart_softc *);
+static void ar933x_bus_grab(struct uart_softc *);
+static void ar933x_bus_ungrab(struct uart_softc *);
 
 static kobj_method_t ar933x_methods[] = {
 	KOBJMETHOD(uart_attach,		ar933x_bus_attach),
@@ -338,6 +340,8 @@ static kobj_method_t ar933x_methods[] = 
 	KOBJMETHOD(uart_receive,	ar933x_bus_receive),
 	KOBJMETHOD(uart_setsig,		ar933x_bus_setsig),
 	KOBJMETHOD(uart_transmit,	ar933x_bus_transmit),
+	KOBJMETHOD(uart_grab,		ar933x_bus_grab),
+	KOBJMETHOD(uart_ungrab,		ar933x_bus_ungrab),
 	{ 0, 0 }
 };
 
@@ -752,3 +756,31 @@ ar933x_bus_transmit(struct uart_softc *s
 
 	return (0);
 }
+
+static void
+ar933x_bus_grab(struct uart_softc *sc)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+	uint32_t reg;
+
+	/* Disable the host interrupt now */
+	uart_lock(sc->sc_hwmtx);
+	reg = ar933x_getreg(bas, AR933X_UART_CS_REG);
+	reg &= ~AR933X_UART_CS_HOST_INT_EN;
+	ar933x_setreg(bas, AR933X_UART_CS_REG, reg);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+static void
+ar933x_bus_ungrab(struct uart_softc *sc)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+	uint32_t reg;
+
+	/* Enable the host interrupt now */
+	uart_lock(sc->sc_hwmtx);
+	reg = ar933x_getreg(bas, AR933X_UART_CS_REG);
+	reg |= AR933X_UART_CS_HOST_INT_EN;
+	ar933x_setreg(bas, AR933X_UART_CS_REG, reg);
+	uart_unlock(sc->sc_hwmtx);
+}

Modified: stable/10/sys/mips/cavium/uart_dev_oct16550.c
==============================================================================
--- stable/10/sys/mips/cavium/uart_dev_oct16550.c	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/mips/cavium/uart_dev_oct16550.c	Sat Mar  1 04:16:54 2014	(r262649)
@@ -398,6 +398,8 @@ static int oct16550_bus_probe(struct uar
 static int oct16550_bus_receive(struct uart_softc *);
 static int oct16550_bus_setsig(struct uart_softc *, int);
 static int oct16550_bus_transmit(struct uart_softc *);
+static void oct16550_bus_grab(struct uart_softc *);
+static void oct16550_bus_ungrab(struct uart_softc *);
 
 static kobj_method_t oct16550_methods[] = {
 	KOBJMETHOD(uart_attach,		oct16550_bus_attach),
@@ -411,6 +413,8 @@ static kobj_method_t oct16550_methods[] 
 	KOBJMETHOD(uart_receive,	oct16550_bus_receive),
 	KOBJMETHOD(uart_setsig,		oct16550_bus_setsig),
 	KOBJMETHOD(uart_transmit,	oct16550_bus_transmit),
+	KOBJMETHOD(uart_grab,		oct16550_bus_grab),
+	KOBJMETHOD(uart_ungrab,		oct16550_bus_ungrab),
 	{ 0, 0 }
 };
 
@@ -810,3 +814,34 @@ oct16550_bus_transmit (struct uart_softc
 	uart_unlock(sc->sc_hwmtx);
 	return (0);
 }
+
+static void
+oct16550_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);
+}
+
+static void
+oct16550_bus_ungrab(struct uart_softc *sc)
+{
+	struct oct16550_softc *oct16550 = (struct oct16550_softc*)sc;
+	struct uart_bas *bas = &sc->sc_bas;
+
+	/*
+	 * Restore previous interrupt mask
+	 */
+	uart_lock(sc->sc_hwmtx);
+	uart_setreg(bas, REG_IER, oct16550->ier);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+}

Modified: stable/10/sys/mips/rt305x/uart_dev_rt305x.c
==============================================================================
--- stable/10/sys/mips/rt305x/uart_dev_rt305x.c	Sat Mar  1 03:39:56 2014	(r262648)
+++ stable/10/sys/mips/rt305x/uart_dev_rt305x.c	Sat Mar  1 04:16:54 2014	(r262649)
@@ -195,6 +195,8 @@ static int rt305x_uart_bus_probe(struct 
 static int rt305x_uart_bus_receive(struct uart_softc *);
 static int rt305x_uart_bus_setsig(struct uart_softc *, int);
 static int rt305x_uart_bus_transmit(struct uart_softc *);
+static void rt305x_uart_bus_grab(struct uart_softc *);
+static void rt305x_uart_bus_ungrab(struct uart_softc *);
 
 static kobj_method_t rt305x_uart_methods[] = {
 	KOBJMETHOD(uart_attach,		rt305x_uart_bus_attach),
@@ -208,6 +210,8 @@ static kobj_method_t rt305x_uart_methods
 	KOBJMETHOD(uart_receive,	rt305x_uart_bus_receive),
 	KOBJMETHOD(uart_setsig,		rt305x_uart_bus_setsig),
 	KOBJMETHOD(uart_transmit,	rt305x_uart_bus_transmit),
+	KOBJMETHOD(uart_grab,		rt305x_uart_bus_grab),
+	KOBJMETHOD(uart_ungrab,		rt305x_uart_bus_ungrab),
 	{ 0, 0 }
 };
 
@@ -278,7 +282,7 @@ rt305x_uart_bus_attach(struct uart_softc
 	uart_setreg(bas, UART_FCR_REG, 
 	    uart_getreg(bas, UART_FCR_REG) | 
 	    UART_FCR_FIFOEN | UART_FCR_TXTGR_1 | UART_FCR_RXTGR_1);
-	uart_barrier(bas);
+ 	uart_barrier(bas);
 	/* Enable interrupts */
 	uart_setreg(bas, UART_IER_REG,
 	    UART_IER_EDSSI | UART_IER_ELSI | UART_IER_ERBFI);
@@ -505,3 +509,28 @@ rt305x_uart_bus_transmit(struct uart_sof
 	uart_unlock(sc->sc_hwmtx);
 	return (0);
 }
+
+static void
+rt305x_uart_bus_grab(struct uart_softc *sc)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+
+	/* disable interrupts -- XXX not sure which one is RX, so kill them all */
+	uart_lock(sc->sc_hwmtx);
+	uart_setreg(bas, UART_IER_REG, 0);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+}
+
+static void
+rt305x_uart_bus_ungrab(struct uart_softc *sc)
+{
+	struct uart_bas *bas = &sc->sc_bas;
+
+	/* Enable interrupts */
+	uart_lock(sc->sc_hwmtx);
+	uart_setreg(bas, UART_IER_REG,
+	    UART_IER_EDSSI | UART_IER_ELSI | UART_IER_ERBFI);
+	uart_barrier(bas);
+	uart_unlock(sc->sc_hwmtx);
+}



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