svn commit: r260889 - in head/sys: arm/s3c2xx0 arm/sa11x0 arm/xilinx mips/adm5120 mips/atheros mips/cavium mips/rt305x

Warner Losh imp at FreeBSD.org
Sun Jan 19 19:36:13 UTC 2014


Author: imp
Date: Sun Jan 19 19:36:11 2014
New Revision: 260889
URL: http://svnweb.freebsd.org/changeset/base/260889

Log:
  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:
  head/sys/arm/s3c2xx0/uart_dev_s3c2410.c
  head/sys/arm/sa11x0/uart_dev_sa1110.c
  head/sys/arm/xilinx/uart_dev_cdnc.c
  head/sys/mips/adm5120/uart_dev_adm5120.c
  head/sys/mips/atheros/uart_dev_ar933x.c
  head/sys/mips/cavium/uart_dev_oct16550.c
  head/sys/mips/rt305x/uart_dev_rt305x.c

Modified: head/sys/arm/s3c2xx0/uart_dev_s3c2410.c
==============================================================================
--- head/sys/arm/s3c2xx0/uart_dev_s3c2410.c	Sun Jan 19 18:46:38 2014	(r260888)
+++ head/sys/arm/s3c2xx0/uart_dev_s3c2410.c	Sun Jan 19 19:36:11 2014	(r260889)
@@ -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: head/sys/arm/sa11x0/uart_dev_sa1110.c
==============================================================================
--- head/sys/arm/sa11x0/uart_dev_sa1110.c	Sun Jan 19 18:46:38 2014	(r260888)
+++ head/sys/arm/sa11x0/uart_dev_sa1110.c	Sun Jan 19 19:36:11 2014	(r260889)
@@ -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: head/sys/arm/xilinx/uart_dev_cdnc.c
==============================================================================
--- head/sys/arm/xilinx/uart_dev_cdnc.c	Sun Jan 19 18:46:38 2014	(r260888)
+++ head/sys/arm/xilinx/uart_dev_cdnc.c	Sun Jan 19 19:36:11 2014	(r260889)
@@ -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: head/sys/mips/adm5120/uart_dev_adm5120.c
==============================================================================
--- head/sys/mips/adm5120/uart_dev_adm5120.c	Sun Jan 19 18:46:38 2014	(r260888)
+++ head/sys/mips/adm5120/uart_dev_adm5120.c	Sun Jan 19 19:36:11 2014	(r260889)
@@ -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: head/sys/mips/atheros/uart_dev_ar933x.c
==============================================================================
--- head/sys/mips/atheros/uart_dev_ar933x.c	Sun Jan 19 18:46:38 2014	(r260888)
+++ head/sys/mips/atheros/uart_dev_ar933x.c	Sun Jan 19 19:36:11 2014	(r260889)
@@ -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: head/sys/mips/cavium/uart_dev_oct16550.c
==============================================================================
--- head/sys/mips/cavium/uart_dev_oct16550.c	Sun Jan 19 18:46:38 2014	(r260888)
+++ head/sys/mips/cavium/uart_dev_oct16550.c	Sun Jan 19 19:36:11 2014	(r260889)
@@ -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: head/sys/mips/rt305x/uart_dev_rt305x.c
==============================================================================
--- head/sys/mips/rt305x/uart_dev_rt305x.c	Sun Jan 19 18:46:38 2014	(r260888)
+++ head/sys/mips/rt305x/uart_dev_rt305x.c	Sun Jan 19 19:36:11 2014	(r260889)
@@ -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);
+}


More information about the svn-src-all mailing list