summaryrefslogtreecommitdiff
path: root/sys/arch/armv7
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2016-08-09 16:52:43 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2016-08-09 16:52:43 +0000
commit9ef0ba96819e1856e7d03f4e39915433c7258de4 (patch)
tree0210b2223723da38ffb3645550a8ff958265b6f7 /sys/arch/armv7
parent367e409ead98402f753f6650813d50c45a6da5d3 (diff)
Just re-set the line speed when required. This fixes a serial console
hang seen on the allwinner,sun5i-r8. ok kettenis
Diffstat (limited to 'sys/arch/armv7')
-rw-r--r--sys/arch/armv7/sunxi/sxiuart.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/sys/arch/armv7/sunxi/sxiuart.c b/sys/arch/armv7/sunxi/sxiuart.c
index 5d1b592c145..9702cb41457 100644
--- a/sys/arch/armv7/sunxi/sxiuart.c
+++ b/sys/arch/armv7/sunxi/sxiuart.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sxiuart.c,v 1.10 2016/08/05 19:00:25 kettenis Exp $ */
+/* $OpenBSD: sxiuart.c,v 1.11 2016/08/09 16:52:42 mglocker Exp $ */
/*
* Copyright (c) 2005 Dale Rahn <drahn@motorola.com>
* Copyright (c) 2013 Artturi Alm
@@ -377,30 +377,37 @@ sxiuart_param(struct tty *tp, struct termios *t)
bus_space_write_1(iot, ioh, SXIUART_MCR, sc->sc_mcr);
}
- if (ospeed != 0) { /* XXX sc_initialize? */
- while (ISSET(tp->t_state, TS_BUSY)) {
- ++sc->sc_halt;
- error = ttysleep(tp, &tp->t_outq,
- TTOPRI | PCATCH, "sxiuartprm", 0);
- --sc->sc_halt;
- if (error) {
- sxiuart_start(tp);
- return (error);
+ if (sc->sc_initialize || (tp->t_ispeed != t->c_ispeed)) {
+ sc->sc_initialize = 0;
+
+ if (ospeed != 0) {
+ while (ISSET(tp->t_state, TS_BUSY)) {
+ ++sc->sc_halt;
+ error = ttysleep(tp, &tp->t_outq,
+ TTOPRI | PCATCH, "sxiuartprm", 0);
+ --sc->sc_halt;
+ if (error) {
+ sxiuart_start(tp);
+ return (error);
+ }
}
- }
- bus_space_write_1(iot, ioh, SXIUART_LCR, lcr | LCR_DLAB);
- ratediv = 13;
- bus_space_write_1(iot, ioh, SXIUART_DLL, ratediv);
- bus_space_write_1(iot, ioh, SXIUART_DLH, ratediv >> 8);
- bus_space_write_1(iot, ioh, SXIUART_LCR, lcr);
- SET(sc->sc_mcr, MCR_DTR);
- bus_space_write_1(iot, ioh, SXIUART_MCR, sc->sc_mcr);
+
+ bus_space_write_1(iot, ioh, SXIUART_LCR,
+ lcr | LCR_DLAB);
+ ratediv = 13;
+ bus_space_write_1(iot, ioh, SXIUART_DLL, ratediv);
+ bus_space_write_1(iot, ioh, SXIUART_DLH, ratediv >> 8);
+ bus_space_write_1(iot, ioh, SXIUART_LCR, lcr);
+ SET(sc->sc_mcr, MCR_DTR);
+ bus_space_write_1(iot, ioh, SXIUART_MCR, sc->sc_mcr);
+ } else
+ bus_space_write_1(iot, ioh, SXIUART_LCR, lcr);
+
+ /* setup fifo */
+ bus_space_write_1(iot, ioh, SXIUART_FCR, FIFOE | FIFO_RXT0);
} else
bus_space_write_1(iot, ioh, SXIUART_LCR, lcr);
- /* setup fifo */
- bus_space_write_1(iot, ioh, SXIUART_FCR, FIFOE | FIFO_RXT0);
-
/* When not using CRTSCTS, RTS follows DTR. */
if (!ISSET(t->c_cflag, CRTSCTS)) {
if (ISSET(sc->sc_mcr, MCR_DTR)) {