summaryrefslogtreecommitdiffstats
path: root/sys/dev/uart/uart_dev_sab82532.c
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2006-04-01 19:04:54 +0000
committermarcel <marcel@FreeBSD.org>2006-04-01 19:04:54 +0000
commit01ed5990aef062b97e91680895804b9689c8076b (patch)
treef866ed454b38b3e3ed100d7237faffef820e51f3 /sys/dev/uart/uart_dev_sab82532.c
parent6d14bcd43fdc1e895dd4255bb9f88dba939296ce (diff)
downloadFreeBSD-src-01ed5990aef062b97e91680895804b9689c8076b.zip
FreeBSD-src-01ed5990aef062b97e91680895804b9689c8076b.tar.gz
Don't hold the hardware mutex across getc(). It can wait indefinitely
for a character to be received. Instead let getc() do any necesary locking.
Diffstat (limited to 'sys/dev/uart/uart_dev_sab82532.c')
-rw-r--r--sys/dev/uart/uart_dev_sab82532.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/sys/dev/uart/uart_dev_sab82532.c b/sys/dev/uart/uart_dev_sab82532.c
index 927a681..9ef0bd1 100644
--- a/sys/dev/uart/uart_dev_sab82532.c
+++ b/sys/dev/uart/uart_dev_sab82532.c
@@ -174,7 +174,7 @@ static void sab82532_init(struct uart_bas *bas, int, int, int, int);
static void sab82532_term(struct uart_bas *bas);
static void sab82532_putc(struct uart_bas *bas, int);
static int sab82532_poll(struct uart_bas *bas);
-static int sab82532_getc(struct uart_bas *bas);
+static int sab82532_getc(struct uart_bas *bas, struct mtx *);
struct uart_ops uart_sab82532_ops = {
.probe = sab82532_probe,
@@ -307,20 +307,25 @@ sab82532_poll(struct uart_bas *bas)
{
if (uart_getreg(bas, SAB_STAR) & SAB_STAR_RFNE)
- return (sab82532_getc(bas));
+ return (sab82532_getc(bas, NULL));
return (-1);
}
static int
-sab82532_getc(struct uart_bas *bas)
+sab82532_getc(struct uart_bas *bas, struct mtx *hwmtx)
{
int c, delay;
+ uart_lock(hwmtx);
+
/* 1/10th the time to transmit 1 character (estimate). */
delay = sab82532_delay(bas);
- while (!(uart_getreg(bas, SAB_STAR) & SAB_STAR_RFNE))
+ while (!(uart_getreg(bas, SAB_STAR) & SAB_STAR_RFNE)) {
+ uart_unlock(hwmtx);
DELAY(delay);
+ uart_lock(hwmtx);
+ }
while (uart_getreg(bas, SAB_STAR) & SAB_STAR_CEC)
;
@@ -338,6 +343,9 @@ sab82532_getc(struct uart_bas *bas)
;
uart_setreg(bas, SAB_CMDR, SAB_CMDR_RMC);
uart_barrier(bas);
+
+ uart_unlock(hwmtx);
+
return (c);
}
OpenPOWER on IntegriCloud