From e7bf55dd6682453694bfefefcf1a7ae0bd796de2 Mon Sep 17 00:00:00 2001 From: kettenis Date: Mon, 6 Apr 2026 10:27:53 +0000 Subject: [PATCH] Bring back the PXA2X0 variant; it resurfaced in the SpacemiT K1 SoC. Incorporate a fix inspired by NetBSD to keep the console enabled when userland closes the device. --- sys/dev/fdt/com_fdt.c | 7 ++++++- sys/dev/ic/com.c | 28 ++++++++++++++++++++++++++-- sys/dev/ic/comvar.h | 3 ++- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/sys/dev/fdt/com_fdt.c b/sys/dev/fdt/com_fdt.c index 9415b3165ae..6a3b72f4a01 100644 --- a/sys/dev/fdt/com_fdt.c +++ b/sys/dev/fdt/com_fdt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com_fdt.c,v 1.9 2024/01/31 01:01:10 hastings Exp $ */ +/* $OpenBSD: com_fdt.c,v 1.10 2026/04/06 10:27:53 kettenis Exp $ */ /* * Copyright (c) 2016 Patrick Wildt * @@ -54,6 +54,7 @@ com_fdt_init_cons(void) void *node; if ((node = fdt_find_cons("brcm,bcm2835-aux-uart")) == NULL && + (node = fdt_find_cons("intel,xscale-uart")) == NULL && (node = fdt_find_cons("marvell,armada-38x-uart")) == NULL && (node = fdt_find_cons("mediatek,mt6577-uart")) == NULL && (node = fdt_find_cons("ns16550a")) == NULL && @@ -96,6 +97,7 @@ com_fdt_match(struct device *parent, void *match, void *aux) struct fdt_attach_args *faa = aux; return (OF_is_compatible(faa->fa_node, "brcm,bcm2835-aux-uart") || + OF_is_compatible(faa->fa_node, "intel,xscale-uart") || OF_is_compatible(faa->fa_node, "marvell,armada-38x-uart") || OF_is_compatible(faa->fa_node, "mediatek,mt6577-uart") || OF_is_compatible(faa->fa_node, "ns16550a") || @@ -143,6 +145,9 @@ com_fdt_attach(struct device *parent, struct device *self, void *aux) sc->sc_reg_width = OF_getpropint(faa->fa_node, "reg-io-width", width); sc->sc_reg_shift = OF_getpropint(faa->fa_node, "reg-shift", shift); + if (OF_is_compatible(faa->fa_node, "intel,xscale-uart")) + sc->sc_uarttype = COM_UART_PXA2X0; + if (OF_is_compatible(faa->fa_node, "mediatek,mt6577-uart")) sc->sc_uarttype = COM_UART_16550A; diff --git a/sys/dev/ic/com.c b/sys/dev/ic/com.c index 13bbb5135ff..c5ceb956a67 100644 --- a/sys/dev/ic/com.c +++ b/sys/dev/ic/com.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com.c,v 1.180 2025/09/16 12:18:10 hshoexer Exp $ */ +/* $OpenBSD: com.c,v 1.181 2026/04/06 10:27:53 kettenis Exp $ */ /* $NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $ */ /* @@ -307,6 +307,9 @@ comopen(dev_t dev, int flag, int mode, struct proc *p) case COM_UART_XR17V35X: com_write_reg(sc, UART_EXAR_SLEEP, 0); break; + case COM_UART_PXA2X0: + com_write_reg(sc, com_ier, IER_EUART); + break; } } @@ -363,6 +366,8 @@ comopen(dev_t dev, int flag, int mode, struct proc *p) SET(sc->sc_mcr, MCR_IENABLE); com_write_reg(sc, com_mcr, sc->sc_mcr); sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC; + if (sc->sc_uarttype == COM_UART_PXA2X0) + sc->sc_ier |= IER_EUART | IER_ERXTOUT; com_write_reg(sc, com_ier, sc->sc_ier); sc->sc_msr = com_read_reg(sc, com_msr); @@ -465,10 +470,14 @@ void compwroff(struct com_softc *sc) { struct tty *tp = sc->sc_tty; + u_int8_t ier; CLR(sc->sc_lcr, LCR_SBREAK); com_write_reg(sc, com_lcr, sc->sc_lcr); - com_write_reg(sc, com_ier, 0); + ier = 0; + if (sc->sc_uarttype == COM_UART_PXA2X0) + ier |= IER_EUART; + com_write_reg(sc, com_ier, ier); if (ISSET(tp->t_cflag, HUPCL) && !ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) { /* XXX perhaps only clear DTR */ @@ -502,6 +511,9 @@ compwroff(struct com_softc *sc) case COM_UART_XR17V35X: com_write_reg(sc, UART_EXAR_SLEEP, 0xff); break; + case COM_UART_PXA2X0: + com_write_reg(sc, com_ier, 0); + break; } } } @@ -540,6 +552,9 @@ com_resume(struct com_softc *sc) case COM_UART_XR17V35X: com_write_reg(sc, UART_EXAR_SLEEP, 0); break; + case COM_UART_PXA2X0: + com_write_reg(sc, com_ier, IER_EUART); + break; } } @@ -1304,6 +1319,8 @@ com_attach_subr(struct com_softc *sc) u_int32_t cpr; sc->sc_ier = 0; + if (sc->sc_uarttype == COM_UART_PXA2X0) + sc->sc_ier |= IER_EUART; /* disable interrupts */ com_write_reg(sc, com_ier, sc->sc_ier); @@ -1502,6 +1519,11 @@ com_attach_subr(struct com_softc *sc) sc->sc_fifolen = 1; } break; + case COM_UART_PXA2X0: + printf(": pxa2x0, 32 byte fifo\n"); + SET(sc->sc_hwflags, COM_HW_FIFO); + sc->sc_fifolen = 32; + break; default: panic("comattach: bad fifo type"); } @@ -1575,6 +1597,8 @@ com_fifo_probe(struct com_softc *sc) return; ier = 0; + if (sc->sc_uarttype == COM_UART_PXA2X0) + ier |= IER_EUART; com_write_reg(sc, com_ier, ier); com_write_reg(sc, com_lcr, LCR_DLAB); com_write_reg(sc, com_dlbl, 3); diff --git a/sys/dev/ic/comvar.h b/sys/dev/ic/comvar.h index ff92e02d49d..81cf7ba3f27 100644 --- a/sys/dev/ic/comvar.h +++ b/sys/dev/ic/comvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: comvar.h,v 1.61 2024/05/29 00:48:15 jsg Exp $ */ +/* $OpenBSD: comvar.h,v 1.62 2026/04/06 10:27:53 kettenis Exp $ */ /* $NetBSD: comvar.h,v 1.5 1996/05/05 19:50:47 christos Exp $ */ /* @@ -105,6 +105,7 @@ struct com_softc { #define COM_UART_OX16C950 0x11 /* 128 byte fifo */ #define COM_UART_XR17V35X 0x12 /* 256 byte fifo */ #define COM_UART_DW_APB 0x13 /* configurable */ +#define COM_UART_PXA2X0 0x14 /* 32 byte fifo */ u_char sc_hwflags; #define COM_HW_NOIEN 0x01