Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/samsung Make this driver MPSAFE
details: https://anonhg.NetBSD.org/src/rev/1007a2ba8fe2
branches: trunk
changeset: 433382:1007a2ba8fe2
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Tue Sep 11 10:05:31 2018 +0000
description:
Make this driver MPSAFE
diffstat:
sys/arch/arm/samsung/exynos_uart.c | 97 +++++++++++++++++++++----------------
1 files changed, 56 insertions(+), 41 deletions(-)
diffs (206 lines):
diff -r cfd24720686c -r 1007a2ba8fe2 sys/arch/arm/samsung/exynos_uart.c
--- a/sys/arch/arm/samsung/exynos_uart.c Tue Sep 11 08:05:18 2018 +0000
+++ b/sys/arch/arm/samsung/exynos_uart.c Tue Sep 11 10:05:31 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: exynos_uart.c,v 1.1 2018/07/05 13:11:58 jmcneill Exp $ */
+/* $NetBSD: exynos_uart.c,v 1.2 2018/09/11 10:05:31 jmcneill Exp $ */
/*-
* Copyright (c) 2013-2018 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exynos_uart.c,v 1.1 2018/07/05 13:11:58 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exynos_uart.c,v 1.2 2018/09/11 10:05:31 jmcneill Exp $");
#define cn_trap() \
do { \
@@ -77,6 +77,7 @@
device_t sc_dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
+ kmutex_t sc_lock;
u_int sc_freq;
void *sc_ih;
@@ -186,6 +187,7 @@
sc->sc_dev = self;
sc->sc_bst = faa->faa_bst;
+ mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH);
sc->sc_console = is_console;
if (is_console) {
sc->sc_bsh = exynos_uart_cnsc.sc_bsh;
@@ -259,13 +261,13 @@
exynos_uart_cngetc(dev_t dev)
{
struct exynos_uart_softc * const sc = &exynos_uart_cnsc;
- uint32_t status;
+ uint32_t ufstat;
int s, c;
s = splserial();
- status = RD4(sc, SSCOM_UTRSTAT);
- if ((status & UTRSTAT_RXREADY) == 0) {
+ ufstat = RD4(sc, SSCOM_UFSTAT);
+ if (__SHIFTOUT(ufstat, UFSTAT_RXCOUNT) == 0) {
splx(s);
return -1;
}
@@ -334,6 +336,8 @@
return EBUSY;
}
+ mutex_enter(&sc->sc_lock);
+
if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) {
tp->t_dev = dev;
ttychars(tp);
@@ -354,6 +358,8 @@
/* Enable RX and error interrupts */
WR4(sc, SSCOM_UINTM, ~0u & ~(UINT_RXD|UINT_ERROR));
+ mutex_exit(&sc->sc_lock);
+
return tp->t_linesw->l_open(dev, tp);
}
@@ -364,12 +370,16 @@
device_lookup_private(&exuart_cd, minor(dev));
struct tty *tp = sc->sc_tty;
+ mutex_enter(&sc->sc_lock);
+
tp->t_linesw->l_close(tp, flag);
ttyclose(tp);
/* Disable interrupts */
WR4(sc, SSCOM_UINTM, ~0u);
+ mutex_exit(&sc->sc_lock);
+
return 0;
}
@@ -447,8 +457,6 @@
}
tp->t_state |= TS_BUSY;
- splx(s);
-
for (brem = q_to_b(&tp->t_outq, sc->sc_buf, sizeof(sc->sc_buf));
brem > 0;
brem--, p++) {
@@ -459,7 +467,6 @@
SSCOM_UTXH, *p);
}
- s = spltty();
tp->t_state &= ~TS_BUSY;
if (ttypull(tp)) {
tp->t_state |= TS_TIMEOUT;
@@ -473,47 +480,51 @@
{
struct exynos_uart_softc *sc = tp->t_sc;
- if (tp->t_ospeed == t->c_ospeed &&
- tp->t_cflag == t->c_cflag)
- return 0;
+ mutex_enter(&sc->sc_lock);
- uint32_t ulcon = 0, ubrdiv;
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- ulcon |= ULCON_LENGTH_5;
- break;
- case CS6:
- ulcon |= ULCON_LENGTH_6;
- break;
- case CS7:
- ulcon |= ULCON_LENGTH_7;
- break;
- case CS8:
- ulcon |= ULCON_LENGTH_8;
- break;
+ if (tp->t_cflag != t->c_cflag) {
+ uint32_t ulcon = 0;
+ switch (ISSET(t->c_cflag, CSIZE)) {
+ case CS5:
+ ulcon |= ULCON_LENGTH_5;
+ break;
+ case CS6:
+ ulcon |= ULCON_LENGTH_6;
+ break;
+ case CS7:
+ ulcon |= ULCON_LENGTH_7;
+ break;
+ case CS8:
+ ulcon |= ULCON_LENGTH_8;
+ break;
+ }
+ switch (ISSET(t->c_cflag, PARENB|PARODD)) {
+ case PARENB|PARODD:
+ ulcon |= ULCON_PARITY_ODD;
+ break;
+ case PARENB:
+ ulcon |= ULCON_PARITY_EVEN;
+ break;
+ default:
+ ulcon |= ULCON_PARITY_NONE;
+ break;
+ }
+ if (ISSET(t->c_cflag, CSTOPB))
+ ulcon |= ULCON_STOP;
+ WR4(sc, SSCOM_ULCON, ulcon);
}
- switch (ISSET(t->c_cflag, PARENB|PARODD)) {
- case PARENB|PARODD:
- ulcon |= ULCON_PARITY_ODD;
- break;
- case PARENB:
- ulcon |= ULCON_PARITY_EVEN;
- break;
- default:
- ulcon |= ULCON_PARITY_NONE;
- break;
+
+ if (tp->t_ospeed != t->c_ospeed) {
+ const uint32_t ubrdiv = (sc->sc_freq / 16) / t->c_ospeed - 1;
+ WR4(sc, SSCOM_UBRDIV, ubrdiv);
}
- if (ISSET(t->c_cflag, CSTOPB))
- ulcon |= ULCON_STOP;
- WR4(sc, SSCOM_ULCON, ulcon);
-
- ubrdiv = (sc->sc_freq / 16) / t->c_ospeed - 1;
- WR4(sc, SSCOM_UBRDIV, ubrdiv);
tp->t_ispeed = t->c_ispeed;
tp->t_ospeed = t->c_ospeed;
tp->t_cflag = t->c_cflag;
+ mutex_exit(&sc->sc_lock);
+
return 0;
}
@@ -524,6 +535,8 @@
struct tty *tp = sc->sc_tty;
uint32_t uintp, uerstat, ufstat, c;
+ mutex_enter(&sc->sc_lock);
+
uintp = RD4(sc, SSCOM_UINTP);
for (;;) {
@@ -551,6 +564,8 @@
WR4(sc, SSCOM_UINTP, uintp);
+ mutex_exit(&sc->sc_lock);
+
return 1;
}
Home |
Main Index |
Thread Index |
Old Index