Add support for scc(4).

This commit is contained in:
marcel 2006-03-30 18:37:03 +00:00
parent 0215f8085c
commit 11ffb007e1
6 changed files with 191 additions and 82 deletions

View File

@ -81,7 +81,8 @@ struct uart_softc {
struct uart_bas sc_bas;
device_t sc_dev;
struct mtx sc_hwmtx; /* Spinlock protecting hardware. */
struct mtx sc_hwmtx_s; /* Spinlock protecting hardware. */
struct mtx *sc_hwmtx;
struct resource *sc_rres; /* Register resource. */
int sc_rrid;
@ -139,7 +140,9 @@ extern char uart_driver_name[];
int uart_bus_attach(device_t dev);
int uart_bus_detach(device_t dev);
serdev_intr_t *uart_bus_ihand(device_t dev, int ipend);
int uart_bus_probe(device_t dev, int regshft, int rclk, int rid, int chan);
int uart_bus_sysdev(device_t dev);
int uart_tty_attach(struct uart_softc *);
int uart_tty_detach(struct uart_softc *);

View File

@ -70,6 +70,24 @@ uart_add_sysdev(struct uart_devinfo *di)
SLIST_INSERT_HEAD(&uart_sysdevs, di, next);
}
/*
* Schedule a soft interrupt. We do this on the 0 to !0 transition
* of the TTY pending interrupt status.
*/
static void
uart_sched_softih(struct uart_softc *sc, uint32_t ipend)
{
uint32_t new, old;
do {
old = sc->sc_ttypend;
new = old | ipend;
} while (!atomic_cmpset_32(&sc->sc_ttypend, old, new));
if ((old & SER_INT_MASK) == 0)
swi_sched(sc->sc_softih, 0);
}
/*
* A break condition has been detected. We treat the break condition as
* a special case that should not happen during normal operation. When
@ -79,18 +97,20 @@ uart_add_sysdev(struct uart_devinfo *di)
* the exceptional nature of the break condition, so we permit ourselves
* to be sloppy.
*/
static void
uart_intr_break(struct uart_softc *sc)
static __inline int
uart_intr_break(void *arg)
{
struct uart_softc *sc = arg;
#if defined(KDB) && defined(BREAK_TO_DEBUGGER)
if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
kdb_enter("Line break on console");
return;
return (0);
}
#endif
if (sc->sc_opened)
atomic_set_32(&sc->sc_ttypend, SER_INT_BREAK);
uart_sched_softih(sc, SER_INT_BREAK);
return (0);
}
/*
@ -108,25 +128,28 @@ uart_intr_break(struct uart_softc *sc)
* token represents the loss of at least one, but possible more bytes in
* the input stream.
*/
static void
uart_intr_overrun(struct uart_softc *sc)
static __inline int
uart_intr_overrun(void *arg)
{
struct uart_softc *sc = arg;
if (sc->sc_opened) {
UART_RECEIVE(sc);
if (uart_rx_put(sc, UART_STAT_OVERRUN))
sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
atomic_set_32(&sc->sc_ttypend, SER_INT_RXREADY);
uart_sched_softih(sc, SER_INT_RXREADY);
}
UART_FLUSH(sc, UART_FLUSH_RECEIVER);
return (0);
}
/*
* Received data ready.
*/
static void
uart_intr_rxready(struct uart_softc *sc)
static __inline int
uart_intr_rxready(void *arg)
{
struct uart_softc *sc = arg;
int rxp;
rxp = sc->sc_rxput;
@ -142,9 +165,10 @@ uart_intr_rxready(struct uart_softc *sc)
}
#endif
if (sc->sc_opened)
atomic_set_32(&sc->sc_ttypend, SER_INT_RXREADY);
uart_sched_softih(sc, SER_INT_RXREADY);
else
sc->sc_rxput = sc->sc_rxget; /* Ignore received data. */
return (1);
}
/*
@ -154,9 +178,10 @@ uart_intr_rxready(struct uart_softc *sc)
* bits. This is to avoid loosing state transitions due to having more
* than 1 hardware interrupt between software interrupts.
*/
static void
uart_intr_sigchg(struct uart_softc *sc)
static __inline int
uart_intr_sigchg(void *arg)
{
struct uart_softc *sc = arg;
int new, old, sig;
sig = UART_GETSIG(sc);
@ -169,24 +194,37 @@ uart_intr_sigchg(struct uart_softc *sc)
}
}
/*
* Keep track of signal changes, even when the device is not
* opened. This allows us to inform upper layers about a
* possible loss of DCD and thus the existence of a (possibly)
* different connection when we have DCD back, during the time
* that the device was closed.
*/
do {
old = sc->sc_ttypend;
new = old & ~SER_MASK_STATE;
new |= sig & SER_INT_SIGMASK;
new |= SER_INT_SIGCHG;
} while (!atomic_cmpset_32(&sc->sc_ttypend, old, new));
if (sc->sc_opened)
uart_sched_softih(sc, SER_INT_SIGCHG);
return (1);
}
/*
* The transmitter can accept more data.
*/
static void
uart_intr_txidle(struct uart_softc *sc)
static __inline int
uart_intr_txidle(void *arg)
{
struct uart_softc *sc = arg;
if (sc->sc_txbusy) {
sc->sc_txbusy = 0;
atomic_set_32(&sc->sc_ttypend, SER_INT_TXIDLE);
uart_sched_softih(sc, SER_INT_TXIDLE);
}
return (0);
}
static void
@ -195,13 +233,7 @@ uart_intr(void *arg)
struct uart_softc *sc = arg;
int ipend;
if (sc->sc_leaving)
return;
do {
ipend = UART_IPEND(sc);
if (ipend == 0)
break;
while (!sc->sc_leaving && (ipend = UART_IPEND(sc)) != 0) {
if (ipend & SER_INT_OVERRUN)
uart_intr_overrun(sc);
if (ipend & SER_INT_BREAK)
@ -212,10 +244,35 @@ uart_intr(void *arg)
uart_intr_sigchg(sc);
if (ipend & SER_INT_TXIDLE)
uart_intr_txidle(sc);
} while (1);
}
}
if (sc->sc_opened && sc->sc_ttypend != 0)
swi_sched(sc->sc_softih, 0);
serdev_intr_t *
uart_bus_ihand(device_t dev, int ipend)
{
switch (ipend) {
case SER_INT_BREAK:
return (uart_intr_break);
case SER_INT_OVERRUN:
return (uart_intr_overrun);
case SER_INT_RXREADY:
return (uart_intr_rxready);
case SER_INT_SIGCHG:
return (uart_intr_sigchg);
case SER_INT_TXIDLE:
return (uart_intr_txidle);
}
return (NULL);
}
int
uart_bus_sysdev(device_t dev)
{
struct uart_softc *sc;
sc = device_get_softc(dev);
return ((sc->sc_sysdev != NULL) ? 1 : 0);
}
int
@ -313,7 +370,9 @@ uart_bus_attach(device_t dev)
*/
sc->sc_leaving = 1;
mtx_init(&sc->sc_hwmtx, "uart_hwmtx", NULL, MTX_SPIN);
mtx_init(&sc->sc_hwmtx_s, "uart_hwmtx", NULL, MTX_SPIN);
if (sc->sc_hwmtx == NULL)
sc->sc_hwmtx = &sc->sc_hwmtx_s;
/*
* Re-allocate. We expect that the softc contains the information
@ -322,7 +381,7 @@ uart_bus_attach(device_t dev)
sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid,
0, ~0, sc->sc_class->uc_range, RF_ACTIVE);
if (sc->sc_rres == NULL) {
mtx_destroy(&sc->sc_hwmtx);
mtx_destroy(&sc->sc_hwmtx_s);
return (ENXIO);
}
sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
@ -425,6 +484,9 @@ uart_bus_attach(device_t dev)
if (error)
goto fail;
if (sc->sc_sysdev != NULL)
sc->sc_sysdev->hwmtx = sc->sc_hwmtx;
sc->sc_leaving = 0;
uart_intr(sc);
return (0);
@ -440,7 +502,7 @@ uart_bus_attach(device_t dev)
}
bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres);
mtx_destroy(&sc->sc_hwmtx);
mtx_destroy(&sc->sc_hwmtx_s);
return (error);
}
@ -454,6 +516,9 @@ uart_bus_detach(device_t dev)
sc->sc_leaving = 1;
if (sc->sc_sysdev != NULL)
sc->sc_sysdev->hwmtx = NULL;
UART_DETACH(sc);
if (sc->sc_sysdev != NULL && sc->sc_sysdev->detach != NULL)
@ -471,7 +536,7 @@ uart_bus_detach(device_t dev)
}
bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres);
mtx_destroy(&sc->sc_hwmtx);
mtx_destroy(&sc->sc_hwmtx_s);
if (sc->sc_class->size > sizeof(*sc)) {
device_set_softc(dev, NULL);

View File

@ -29,6 +29,10 @@
#ifndef _DEV_UART_CPU_H_
#define _DEV_UART_CPU_H_
#include <sys/kdb.h>
#include <sys/lock.h>
#include <sys/mutex.h>
/*
* Low-level operations for use by console and/or debug port support.
*/
@ -68,6 +72,7 @@ struct uart_devinfo {
int (*attach)(struct uart_softc*);
int (*detach)(struct uart_softc*);
void *cookie; /* Type dependent use. */
struct mtx *hwmtx;
};
int uart_cpu_eqres(struct uart_bas *, struct uart_bas *);
@ -80,41 +85,77 @@ void uart_add_sysdev(struct uart_devinfo *);
* Operations for low-level access to the UART. Primarily for use
* by console and debug port logic.
*/
static __inline void
uart_lock(struct mtx *hwmtx)
{
if (!kdb_active && hwmtx != NULL)
mtx_lock_spin(hwmtx);
}
static __inline void
uart_unlock(struct mtx *hwmtx)
{
if (!kdb_active && hwmtx != NULL)
mtx_unlock_spin(hwmtx);
}
static __inline int
uart_probe(struct uart_devinfo *di)
{
return (di->ops.probe(&di->bas));
int res;
uart_lock(di->hwmtx);
res = di->ops.probe(&di->bas);
uart_unlock(di->hwmtx);
return (res);
}
static __inline void
uart_init(struct uart_devinfo *di)
{
uart_lock(di->hwmtx);
di->ops.init(&di->bas, di->baudrate, di->databits, di->stopbits,
di->parity);
uart_unlock(di->hwmtx);
}
static __inline void
uart_term(struct uart_devinfo *di)
{
uart_lock(di->hwmtx);
di->ops.term(&di->bas);
uart_unlock(di->hwmtx);
}
static __inline void
uart_putc(struct uart_devinfo *di, int c)
{
uart_lock(di->hwmtx);
di->ops.putc(&di->bas, c);
uart_unlock(di->hwmtx);
}
static __inline int
uart_poll(struct uart_devinfo *di)
{
return (di->ops.poll(&di->bas));
int res;
uart_lock(di->hwmtx);
res = di->ops.poll(&di->bas);
uart_unlock(di->hwmtx);
return (res);
}
static __inline int
uart_getc(struct uart_devinfo *di)
{
return (di->ops.getc(&di->bas));
int res;
uart_lock(di->hwmtx);
res = di->ops.getc(&di->bas);
uart_unlock(di->hwmtx);
return (res);
}
#endif /* _DEV_UART_CPU_H_ */

View File

@ -432,7 +432,7 @@ ns8250_bus_flush(struct uart_softc *sc, int what)
int error;
bas = &sc->sc_bas;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
if (sc->sc_hasfifo) {
ns8250_flush(bas, what);
uart_setreg(bas, REG_FCR, ns8250->fcr);
@ -440,7 +440,7 @@ ns8250_bus_flush(struct uart_softc *sc, int what)
error = 0;
} else
error = ns8250_drain(bas, what);
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (error);
}
@ -453,9 +453,9 @@ ns8250_bus_getsig(struct uart_softc *sc)
do {
old = sc->sc_hwsig;
sig = old;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
msr = uart_getreg(&sc->sc_bas, REG_MSR);
mtx_unlock_spin(&sc->sc_hwmtx);
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);
@ -474,7 +474,7 @@ ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
bas = &sc->sc_bas;
error = 0;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
switch (request) {
case UART_IOCTL_BREAK:
lcr = uart_getreg(bas, REG_LCR);
@ -533,7 +533,7 @@ ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
error = EINVAL;
break;
}
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (error);
}
@ -545,16 +545,16 @@ ns8250_bus_ipend(struct uart_softc *sc)
uint8_t iir, lsr;
bas = &sc->sc_bas;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
iir = uart_getreg(bas, REG_IIR);
if (iir & IIR_NOPEND) {
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (0);
}
ipend = 0;
if (iir & IIR_RXRDY) {
lsr = uart_getreg(bas, REG_LSR);
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
if (lsr & LSR_OE)
ipend |= SER_INT_OVERRUN;
if (lsr & LSR_BI)
@ -562,7 +562,7 @@ ns8250_bus_ipend(struct uart_softc *sc)
if (lsr & LSR_RXRDY)
ipend |= SER_INT_RXREADY;
} else {
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
if (iir & IIR_TXRDY)
ipend |= SER_INT_TXIDLE;
else
@ -579,9 +579,9 @@ ns8250_bus_param(struct uart_softc *sc, int baudrate, int databits,
int error;
bas = &sc->sc_bas;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
error = ns8250_param(bas, baudrate, databits, stopbits, parity);
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (error);
}
@ -740,7 +740,7 @@ ns8250_bus_receive(struct uart_softc *sc)
uint8_t lsr;
bas = &sc->sc_bas;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
lsr = uart_getreg(bas, REG_LSR);
while (lsr & LSR_RXRDY) {
if (uart_rx_full(sc)) {
@ -761,7 +761,7 @@ ns8250_bus_receive(struct uart_softc *sc)
uart_barrier(bas);
lsr = uart_getreg(bas, REG_LSR);
}
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (0);
}
@ -785,7 +785,7 @@ ns8250_bus_setsig(struct uart_softc *sc, int sig)
SER_DRTS);
}
} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
ns8250->mcr &= ~(MCR_DTR|MCR_RTS);
if (new & SER_DTR)
ns8250->mcr |= MCR_DTR;
@ -793,7 +793,7 @@ ns8250_bus_setsig(struct uart_softc *sc, int sig)
ns8250->mcr |= MCR_RTS;
uart_setreg(bas, REG_MCR, ns8250->mcr);
uart_barrier(bas);
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (0);
}
@ -805,7 +805,7 @@ ns8250_bus_transmit(struct uart_softc *sc)
int i;
bas = &sc->sc_bas;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0)
;
uart_setreg(bas, REG_IER, ns8250->ier | IER_ETXRDY);
@ -815,6 +815,6 @@ ns8250_bus_transmit(struct uart_softc *sc)
uart_barrier(bas);
}
sc->sc_txbusy = 1;
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (0);
}

View File

@ -437,9 +437,9 @@ static int
sab82532_bus_flush(struct uart_softc *sc, int what)
{
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
sab82532_flush(&sc->sc_bas, what);
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (0);
}
@ -454,7 +454,7 @@ sab82532_bus_getsig(struct uart_softc *sc)
do {
old = sc->sc_hwsig;
sig = old;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
star = uart_getreg(bas, SAB_STAR);
SIGCHG(star & SAB_STAR_CTS, sig, SER_CTS, SER_DCTS);
vstr = uart_getreg(bas, SAB_VSTR);
@ -469,7 +469,7 @@ sab82532_bus_getsig(struct uart_softc *sc)
break;
}
SIGCHG(pvr, sig, SER_DSR, SER_DDSR);
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
new = sig & ~SER_MASK_DELTA;
} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
return (sig);
@ -484,7 +484,7 @@ sab82532_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
bas = &sc->sc_bas;
error = 0;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
switch (request) {
case UART_IOCTL_BREAK:
dafo = uart_getreg(bas, SAB_DAFO);
@ -520,7 +520,7 @@ sab82532_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
error = EINVAL;
break;
}
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (error);
}
@ -532,7 +532,7 @@ sab82532_bus_ipend(struct uart_softc *sc)
uint8_t isr0, isr1;
bas = &sc->sc_bas;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
isr0 = uart_getreg(bas, SAB_ISR0);
isr1 = uart_getreg(bas, SAB_ISR1);
uart_barrier(bas);
@ -542,7 +542,7 @@ sab82532_bus_ipend(struct uart_softc *sc)
uart_setreg(bas, SAB_CMDR, SAB_CMDR_RFRD);
uart_barrier(bas);
}
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
ipend = 0;
if (isr1 & SAB_ISR1_BRKT)
@ -567,9 +567,9 @@ sab82532_bus_param(struct uart_softc *sc, int baudrate, int databits,
int error;
bas = &sc->sc_bas;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
error = sab82532_param(bas, baudrate, databits, stopbits, parity);
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (error);
}
@ -617,7 +617,7 @@ sab82532_bus_receive(struct uart_softc *sc)
uint8_t s;
bas = &sc->sc_bas;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
if (uart_getreg(bas, SAB_STAR) & SAB_STAR_RFNE) {
rbcl = uart_getreg(bas, SAB_RBCL) & 31;
if (rbcl == 0)
@ -641,7 +641,7 @@ sab82532_bus_receive(struct uart_softc *sc)
;
uart_setreg(bas, SAB_CMDR, SAB_CMDR_RMC);
uart_barrier(bas);
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (0);
}
@ -666,7 +666,7 @@ sab82532_bus_setsig(struct uart_softc *sc, int sig)
}
} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
/* Set DTR pin. */
pvr = uart_getreg(bas, SAB_PVR);
switch (bas->chan) {
@ -693,7 +693,7 @@ sab82532_bus_setsig(struct uart_softc *sc, int sig)
mode |= SAB_MODE_FRTS;
uart_setreg(bas, SAB_MODE, mode);
uart_barrier(bas);
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (0);
}
@ -704,7 +704,7 @@ sab82532_bus_transmit(struct uart_softc *sc)
int i;
bas = &sc->sc_bas;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
while (!(uart_getreg(bas, SAB_STAR) & SAB_STAR_XFW))
;
for (i = 0; i < sc->sc_txdatasz; i++)
@ -714,6 +714,6 @@ sab82532_bus_transmit(struct uart_softc *sc)
;
uart_setreg(bas, SAB_CMDR, SAB_CMDR_XF);
sc->sc_txbusy = 1;
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (0);
}

View File

@ -348,9 +348,9 @@ z8530_bus_getsig(struct uart_softc *sc)
do {
old = sc->sc_hwsig;
sig = old;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
bes = uart_getmreg(&sc->sc_bas, RR_BES);
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
SIGCHG(bes & BES_CTS, sig, SER_CTS, SER_DCTS);
SIGCHG(bes & BES_DCD, sig, SER_DCD, SER_DDCD);
SIGCHG(bes & BES_SYNC, sig, SER_DSR, SER_DDSR);
@ -368,7 +368,7 @@ z8530_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
bas = &sc->sc_bas;
error = 0;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
switch (request) {
case UART_IOCTL_BREAK:
if (data)
@ -382,7 +382,7 @@ z8530_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
error = EINVAL;
break;
}
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (error);
}
@ -398,7 +398,7 @@ z8530_bus_ipend(struct uart_softc *sc)
bas = &sc->sc_bas;
ipend = 0;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
switch (bas->chan) {
case 1:
ip = uart_getmreg(bas, RR_IP);
@ -454,7 +454,7 @@ z8530_bus_ipend(struct uart_softc *sc)
uart_barrier(bas);
}
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (ipend);
}
@ -466,10 +466,10 @@ z8530_bus_param(struct uart_softc *sc, int baudrate, int databits,
struct z8530_softc *z8530 = (struct z8530_softc*)sc;
int error;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
error = z8530_param(&sc->sc_bas, baudrate, databits, stopbits, parity,
&z8530->tpc);
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (error);
}
@ -499,7 +499,7 @@ z8530_bus_receive(struct uart_softc *sc)
uint8_t bes, src;
bas = &sc->sc_bas;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
bes = uart_getmreg(bas, RR_BES);
while (bes & BES_RXA) {
if (uart_rx_full(sc)) {
@ -533,7 +533,7 @@ z8530_bus_receive(struct uart_softc *sc)
}
bes = uart_getmreg(bas, RR_BES);
}
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (0);
}
@ -558,7 +558,7 @@ z8530_bus_setsig(struct uart_softc *sc, int sig)
}
} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
if (new & SER_DTR)
z8530->tpc |= TPC_DTR;
else
@ -569,7 +569,7 @@ z8530_bus_setsig(struct uart_softc *sc, int sig)
z8530->tpc &= ~TPC_RTS;
uart_setmreg(bas, WR_TPC, z8530->tpc);
uart_barrier(bas);
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (0);
}
@ -580,13 +580,13 @@ z8530_bus_transmit(struct uart_softc *sc)
struct uart_bas *bas;
bas = &sc->sc_bas;
mtx_lock_spin(&sc->sc_hwmtx);
uart_lock(sc->sc_hwmtx);
while (!(uart_getmreg(bas, RR_BES) & BES_TXE))
;
uart_setreg(bas, REG_DATA, sc->sc_txbuf[0]);
uart_barrier(bas);
sc->sc_txbusy = 1;
z8530->txidle = 1; /* Report SER_INT_TXIDLE again. */
mtx_unlock_spin(&sc->sc_hwmtx);
uart_unlock(sc->sc_hwmtx);
return (0);
}