1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2013 Adrian Chadd <adrian@FreeBSD.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD: releng/12.0/sys/mips/atheros/uart_dev_ar933x.c 326259 2017-11-27 15:07:26Z pfg $");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35 #include <sys/conf.h>
36 #include <machine/bus.h>
37
38 #include <dev/uart/uart.h>
39 #include <dev/uart/uart_cpu.h>
40 #include <dev/uart/uart_bus.h>
41
42 #include <mips/atheros/ar933x_uart.h>
43
44 #include "uart_if.h"
45
46 /*
47 * Default system clock is 25MHz; see ar933x_chip.c for how
48 * the startup process determines whether it's 25MHz or 40MHz.
49 */
50 #define DEFAULT_RCLK (25 * 1000 * 1000)
51
52 #define ar933x_getreg(bas, reg) \
53 bus_space_read_4((bas)->bst, (bas)->bsh, reg)
54 #define ar933x_setreg(bas, reg, value) \
55 bus_space_write_4((bas)->bst, (bas)->bsh, reg, value)
56
57
58
59 static int
60 ar933x_drain(struct uart_bas *bas, int what)
61 {
62 int limit;
63
64 if (what & UART_DRAIN_TRANSMITTER) {
65 limit = 10*1024;
66
67 /* Loop over until the TX FIFO shows entirely clear */
68 while (--limit) {
69 if ((ar933x_getreg(bas, AR933X_UART_CS_REG)
70 & AR933X_UART_CS_TX_BUSY) == 0)
71 break;
72 }
73 if (limit == 0) {
74 return (EIO);
75 }
76 }
77
78 if (what & UART_DRAIN_RECEIVER) {
79 limit=10*4096;
80 while (--limit) {
81
82 /* XXX duplicated from ar933x_getc() */
83 /* XXX TODO: refactor! */
84
85 /* If there's nothing to read, stop! */
86 if ((ar933x_getreg(bas, AR933X_UART_DATA_REG) &
87 AR933X_UART_DATA_RX_CSR) == 0) {
88 break;
89 }
90
91 /* Read the top of the RX FIFO */
92 (void) ar933x_getreg(bas, AR933X_UART_DATA_REG);
93
94 /* Remove that entry from said RX FIFO */
95 ar933x_setreg(bas, AR933X_UART_DATA_REG,
96 AR933X_UART_DATA_RX_CSR);
97
98 uart_barrier(bas);
99 DELAY(2);
100 }
101 if (limit == 0) {
102 return (EIO);
103 }
104 }
105 return (0);
106 }
107
108 /*
109 * Calculate the baud from the given chip configuration parameters.
110 */
111 static unsigned long
112 ar933x_uart_get_baud(unsigned int clk, unsigned int scale,
113 unsigned int step)
114 {
115 uint64_t t;
116 uint32_t div;
117
118 div = (2 << 16) * (scale + 1);
119 t = clk;
120 t *= step;
121 t += (div / 2);
122 t = t / div;
123
124 return (t);
125 }
126
127 /*
128 * Calculate the scale/step with the lowest possible deviation from
129 * the target baudrate.
130 */
131 static void
132 ar933x_uart_get_scale_step(struct uart_bas *bas, unsigned int baud,
133 unsigned int *scale, unsigned int *step)
134 {
135 unsigned int tscale;
136 uint32_t clk;
137 long min_diff;
138
139 clk = bas->rclk;
140 *scale = 0;
141 *step = 0;
142
143 min_diff = baud;
144 for (tscale = 0; tscale < AR933X_UART_MAX_SCALE; tscale++) {
145 uint64_t tstep;
146 int diff;
147
148 tstep = baud * (tscale + 1);
149 tstep *= (2 << 16);
150 tstep = tstep / clk;
151
152 if (tstep > AR933X_UART_MAX_STEP)
153 break;
154
155 diff = abs(ar933x_uart_get_baud(clk, tscale, tstep) - baud);
156 if (diff < min_diff) {
157 min_diff = diff;
158 *scale = tscale;
159 *step = tstep;
160 }
161 }
162 }
163
164 static int
165 ar933x_param(struct uart_bas *bas, int baudrate, int databits, int stopbits,
166 int parity)
167 {
168 /* UART always 8 bits */
169
170 /* UART always 1 stop bit */
171
172 /* UART parity is controllable by bits 0:1, ignore for now */
173
174 /* Set baudrate if required. */
175 if (baudrate > 0) {
176 uint32_t clock_scale, clock_step;
177
178 /* Find the best fit for the given baud rate */
179 ar933x_uart_get_scale_step(bas, baudrate, &clock_scale,
180 &clock_step);
181
182 /*
183 * Program the clock register in its entirety - no need
184 * for Read-Modify-Write.
185 */
186 ar933x_setreg(bas, AR933X_UART_CLOCK_REG,
187 ((clock_scale & AR933X_UART_CLOCK_SCALE_M)
188 << AR933X_UART_CLOCK_SCALE_S) |
189 (clock_step & AR933X_UART_CLOCK_STEP_M));
190 }
191
192 uart_barrier(bas);
193 return (0);
194 }
195
196
197 /*
198 * Low-level UART interface.
199 */
200 static int ar933x_probe(struct uart_bas *bas);
201 static void ar933x_init(struct uart_bas *bas, int, int, int, int);
202 static void ar933x_term(struct uart_bas *bas);
203 static void ar933x_putc(struct uart_bas *bas, int);
204 static int ar933x_rxready(struct uart_bas *bas);
205 static int ar933x_getc(struct uart_bas *bas, struct mtx *);
206
207 static struct uart_ops uart_ar933x_ops = {
208 .probe = ar933x_probe,
209 .init = ar933x_init,
210 .term = ar933x_term,
211 .putc = ar933x_putc,
212 .rxready = ar933x_rxready,
213 .getc = ar933x_getc,
214 };
215
216 static int
217 ar933x_probe(struct uart_bas *bas)
218 {
219
220 /* We always know this will be here */
221 return (0);
222 }
223
224 static void
225 ar933x_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
226 int parity)
227 {
228 uint32_t reg;
229
230 /* Setup default parameters */
231 ar933x_param(bas, baudrate, databits, stopbits, parity);
232
233 /* XXX Force enable UART in case it was disabled */
234
235 /* Disable all interrupts */
236 ar933x_setreg(bas, AR933X_UART_INT_EN_REG, 0x00000000);
237
238 /* Disable the host interrupt */
239 reg = ar933x_getreg(bas, AR933X_UART_CS_REG);
240 reg &= ~AR933X_UART_CS_HOST_INT_EN;
241 ar933x_setreg(bas, AR933X_UART_CS_REG, reg);
242
243 uart_barrier(bas);
244
245 /* XXX Set RTS/DTR? */
246 }
247
248 /*
249 * Detach from console.
250 */
251 static void
252 ar933x_term(struct uart_bas *bas)
253 {
254
255 /* XXX TODO */
256 }
257
258 static void
259 ar933x_putc(struct uart_bas *bas, int c)
260 {
261 int limit;
262
263 limit = 250000;
264
265 /* Wait for space in the TX FIFO */
266 while ( ((ar933x_getreg(bas, AR933X_UART_DATA_REG) &
267 AR933X_UART_DATA_TX_CSR) == 0) && --limit)
268 DELAY(4);
269
270 /* Write the actual byte */
271 ar933x_setreg(bas, AR933X_UART_DATA_REG,
272 (c & 0xff) | AR933X_UART_DATA_TX_CSR);
273 }
274
275 static int
276 ar933x_rxready(struct uart_bas *bas)
277 {
278
279 /* Wait for a character to come ready */
280 return (!!(ar933x_getreg(bas, AR933X_UART_DATA_REG)
281 & AR933X_UART_DATA_RX_CSR));
282 }
283
284 static int
285 ar933x_getc(struct uart_bas *bas, struct mtx *hwmtx)
286 {
287 int c;
288
289 uart_lock(hwmtx);
290
291 /* Wait for a character to come ready */
292 while ((ar933x_getreg(bas, AR933X_UART_DATA_REG) &
293 AR933X_UART_DATA_RX_CSR) == 0) {
294 uart_unlock(hwmtx);
295 DELAY(4);
296 uart_lock(hwmtx);
297 }
298
299 /* Read the top of the RX FIFO */
300 c = ar933x_getreg(bas, AR933X_UART_DATA_REG) & 0xff;
301
302 /* Remove that entry from said RX FIFO */
303 ar933x_setreg(bas, AR933X_UART_DATA_REG, AR933X_UART_DATA_RX_CSR);
304
305 uart_unlock(hwmtx);
306
307 return (c);
308 }
309
310 /*
311 * High-level UART interface.
312 */
313 struct ar933x_softc {
314 struct uart_softc base;
315
316 uint32_t u_ier;
317 };
318
319 static int ar933x_bus_attach(struct uart_softc *);
320 static int ar933x_bus_detach(struct uart_softc *);
321 static int ar933x_bus_flush(struct uart_softc *, int);
322 static int ar933x_bus_getsig(struct uart_softc *);
323 static int ar933x_bus_ioctl(struct uart_softc *, int, intptr_t);
324 static int ar933x_bus_ipend(struct uart_softc *);
325 static int ar933x_bus_param(struct uart_softc *, int, int, int, int);
326 static int ar933x_bus_probe(struct uart_softc *);
327 static int ar933x_bus_receive(struct uart_softc *);
328 static int ar933x_bus_setsig(struct uart_softc *, int);
329 static int ar933x_bus_transmit(struct uart_softc *);
330 static void ar933x_bus_grab(struct uart_softc *);
331 static void ar933x_bus_ungrab(struct uart_softc *);
332
333 static kobj_method_t ar933x_methods[] = {
334 KOBJMETHOD(uart_attach, ar933x_bus_attach),
335 KOBJMETHOD(uart_detach, ar933x_bus_detach),
336 KOBJMETHOD(uart_flush, ar933x_bus_flush),
337 KOBJMETHOD(uart_getsig, ar933x_bus_getsig),
338 KOBJMETHOD(uart_ioctl, ar933x_bus_ioctl),
339 KOBJMETHOD(uart_ipend, ar933x_bus_ipend),
340 KOBJMETHOD(uart_param, ar933x_bus_param),
341 KOBJMETHOD(uart_probe, ar933x_bus_probe),
342 KOBJMETHOD(uart_receive, ar933x_bus_receive),
343 KOBJMETHOD(uart_setsig, ar933x_bus_setsig),
344 KOBJMETHOD(uart_transmit, ar933x_bus_transmit),
345 KOBJMETHOD(uart_grab, ar933x_bus_grab),
346 KOBJMETHOD(uart_ungrab, ar933x_bus_ungrab),
347 { 0, 0 }
348 };
349
350 struct uart_class uart_ar933x_class = {
351 "ar933x",
352 ar933x_methods,
353 sizeof(struct ar933x_softc),
354 .uc_ops = &uart_ar933x_ops,
355 .uc_range = 8,
356 .uc_rclk = DEFAULT_RCLK,
357 .uc_rshift = 0
358 };
359
360 #define SIGCHG(c, i, s, d) \
361 if (c) { \
362 i |= (i & s) ? s : s | d; \
363 } else { \
364 i = (i & s) ? (i & ~s) | d : i; \
365 }
366
367 static int
368 ar933x_bus_attach(struct uart_softc *sc)
369 {
370 struct ar933x_softc *u = (struct ar933x_softc *)sc;
371 struct uart_bas *bas = &sc->sc_bas;
372 uint32_t reg;
373
374 /* XXX TODO: flush transmitter */
375
376 /*
377 * Setup initial interrupt notifications.
378 *
379 * XXX for now, just RX FIFO valid.
380 * Later on (when they're handled), also handle
381 * RX errors/overflow.
382 */
383 u->u_ier = AR933X_UART_INT_RX_VALID;
384
385 /* Enable RX interrupts to kick-start things */
386 ar933x_setreg(bas, AR933X_UART_INT_EN_REG, u->u_ier);
387
388 /* Enable the host interrupt now */
389 reg = ar933x_getreg(bas, AR933X_UART_CS_REG);
390 reg |= AR933X_UART_CS_HOST_INT_EN;
391 ar933x_setreg(bas, AR933X_UART_CS_REG, reg);
392
393 return (0);
394 }
395
396 static int
397 ar933x_bus_detach(struct uart_softc *sc)
398 {
399 struct uart_bas *bas = &sc->sc_bas;
400 uint32_t reg;
401
402 /* Disable all interrupts */
403 ar933x_setreg(bas, AR933X_UART_INT_EN_REG, 0x00000000);
404
405 /* Disable the host interrupt */
406 reg = ar933x_getreg(bas, AR933X_UART_CS_REG);
407 reg &= ~AR933X_UART_CS_HOST_INT_EN;
408 ar933x_setreg(bas, AR933X_UART_CS_REG, reg);
409 uart_barrier(bas);
410
411 return (0);
412 }
413
414 static int
415 ar933x_bus_flush(struct uart_softc *sc, int what)
416 {
417 struct uart_bas *bas;
418
419 bas = &sc->sc_bas;
420 uart_lock(sc->sc_hwmtx);
421 ar933x_drain(bas, what);
422 uart_unlock(sc->sc_hwmtx);
423
424 return (0);
425 }
426
427 static int
428 ar933x_bus_getsig(struct uart_softc *sc)
429 {
430 uint32_t sig = sc->sc_hwsig;
431
432 /*
433 * For now, let's just return that DSR/DCD/CTS is asserted.
434 */
435 SIGCHG(1, sig, SER_DSR, SER_DDSR);
436 SIGCHG(1, sig, SER_CTS, SER_DCTS);
437 SIGCHG(1, sig, SER_DCD, SER_DDCD);
438 SIGCHG(1, sig, SER_RI, SER_DRI);
439
440 sc->sc_hwsig = sig & ~SER_MASK_DELTA;
441
442 return (sig);
443 }
444
445 /*
446 * XXX TODO: actually implement the rest of this!
447 */
448 static int
449 ar933x_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
450 {
451 int error = 0;
452
453 /* XXX lock */
454 switch (request) {
455 case UART_IOCTL_BREAK:
456 case UART_IOCTL_IFLOW:
457 case UART_IOCTL_OFLOW:
458 break;
459 case UART_IOCTL_BAUD:
460 *(int*)data = 115200;
461 break;
462 default:
463 error = EINVAL;
464 break;
465 }
466
467 /* XXX unlock */
468
469 return (error);
470 }
471
472 /*
473 * Bus interrupt handler.
474 *
475 * For now, system interrupts are disabled.
476 * So this is just called from a callout in uart_core.c
477 * to poll various state.
478 */
479 static int
480 ar933x_bus_ipend(struct uart_softc *sc)
481 {
482 struct ar933x_softc *u = (struct ar933x_softc *)sc;
483 struct uart_bas *bas = &sc->sc_bas;
484 int ipend = 0;
485 uint32_t isr;
486
487 uart_lock(sc->sc_hwmtx);
488
489 /*
490 * Fetch/ACK the ISR status.
491 */
492 isr = ar933x_getreg(bas, AR933X_UART_INT_REG);
493 ar933x_setreg(bas, AR933X_UART_INT_REG, isr);
494 uart_barrier(bas);
495
496 /*
497 * RX ready - notify upper layer.
498 */
499 if (isr & AR933X_UART_INT_RX_VALID) {
500 ipend |= SER_INT_RXREADY;
501 }
502
503 /*
504 * If we get this interrupt, we should disable
505 * it from the interrupt mask and inform the uart
506 * driver appropriately.
507 *
508 * We can't keep setting SER_INT_TXIDLE or SER_INT_SIGCHG
509 * all the time or IO stops working. So we will always
510 * clear this interrupt if we get it, then we only signal
511 * the upper layer if we were doing active TX in the
512 * first place.
513 *
514 * Also, the name is misleading. This actually means
515 * "the FIFO is almost empty." So if we just write some
516 * more data to the FIFO without checking whether it can
517 * take said data, we'll overflow the thing.
518 *
519 * Unfortunately the FreeBSD uart device has no concept of
520 * partial UART writes - it expects that the whole buffer
521 * is written to the hardware. Thus for now, ar933x_bus_transmit()
522 * will wait for the FIFO to finish draining before it pushes
523 * more frames into it.
524 */
525 if (isr & AR933X_UART_INT_TX_EMPTY) {
526 /*
527 * Update u_ier to disable TX notifications; update hardware
528 */
529 u->u_ier &= ~AR933X_UART_INT_TX_EMPTY;
530 ar933x_setreg(bas, AR933X_UART_INT_EN_REG, u->u_ier);
531 uart_barrier(bas);
532 }
533
534 /*
535 * Only signal TX idle if we're not busy transmitting.
536 *
537 * XXX I never get _out_ of txbusy? Debug that!
538 */
539 if (sc->sc_txbusy) {
540 if (isr & AR933X_UART_INT_TX_EMPTY) {
541 ipend |= SER_INT_TXIDLE;
542 } else {
543 ipend |= SER_INT_SIGCHG;
544 }
545 }
546
547 uart_unlock(sc->sc_hwmtx);
548 return (ipend);
549 }
550
551 static int
552 ar933x_bus_param(struct uart_softc *sc, int baudrate, int databits,
553 int stopbits, int parity)
554 {
555 struct uart_bas *bas;
556 int error;
557
558 bas = &sc->sc_bas;
559 uart_lock(sc->sc_hwmtx);
560 error = ar933x_param(bas, baudrate, databits, stopbits, parity);
561 uart_unlock(sc->sc_hwmtx);
562 return (error);
563 }
564
565 static int
566 ar933x_bus_probe(struct uart_softc *sc)
567 {
568 struct uart_bas *bas;
569 int error;
570
571 bas = &sc->sc_bas;
572
573 error = ar933x_probe(bas);
574 if (error)
575 return (error);
576
577 /* Reset FIFOs. */
578 ar933x_drain(bas, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER);
579
580 /* XXX TODO: actually find out what the FIFO depth is! */
581 sc->sc_rxfifosz = 16;
582 sc->sc_txfifosz = 16;
583
584 return (0);
585 }
586
587 static int
588 ar933x_bus_receive(struct uart_softc *sc)
589 {
590 struct uart_bas *bas = &sc->sc_bas;
591 int xc;
592
593 uart_lock(sc->sc_hwmtx);
594
595 /* Loop over until we are full, or no data is available */
596 while (ar933x_rxready(bas)) {
597 if (uart_rx_full(sc)) {
598 sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
599 break;
600 }
601
602 /* Read the top of the RX FIFO */
603 xc = ar933x_getreg(bas, AR933X_UART_DATA_REG) & 0xff;
604
605 /* Remove that entry from said RX FIFO */
606 ar933x_setreg(bas, AR933X_UART_DATA_REG,
607 AR933X_UART_DATA_RX_CSR);
608 uart_barrier(bas);
609
610 /* XXX frame, parity error */
611 uart_rx_put(sc, xc);
612 }
613
614 /*
615 * XXX TODO: Discard everything left in the Rx FIFO?
616 * XXX only if we've hit an overrun condition?
617 */
618
619 uart_unlock(sc->sc_hwmtx);
620
621 return (0);
622 }
623
624 static int
625 ar933x_bus_setsig(struct uart_softc *sc, int sig)
626 {
627 #if 0
628 struct ar933x_softc *ns8250 = (struct ar933x_softc*)sc;
629 struct uart_bas *bas;
630 uint32_t new, old;
631
632 bas = &sc->sc_bas;
633 do {
634 old = sc->sc_hwsig;
635 new = old;
636 if (sig & SER_DDTR) {
637 SIGCHG(sig & SER_DTR, new, SER_DTR,
638 SER_DDTR);
639 }
640 if (sig & SER_DRTS) {
641 SIGCHG(sig & SER_RTS, new, SER_RTS,
642 SER_DRTS);
643 }
644 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
645 uart_lock(sc->sc_hwmtx);
646 ns8250->mcr &= ~(MCR_DTR|MCR_RTS);
647 if (new & SER_DTR)
648 ns8250->mcr |= MCR_DTR;
649 if (new & SER_RTS)
650 ns8250->mcr |= MCR_RTS;
651 uart_setreg(bas, REG_MCR, ns8250->mcr);
652 uart_barrier(bas);
653 uart_unlock(sc->sc_hwmtx);
654 #endif
655 return (0);
656 }
657
658 /*
659 * Write the current transmit buffer to the TX FIFO.
660 *
661 * Unfortunately the FreeBSD uart device has no concept of
662 * partial UART writes - it expects that the whole buffer
663 * is written to the hardware. Thus for now, this will wait for
664 * the FIFO to finish draining before it pushes more frames into it.
665 *
666 * If non-blocking operation is truely needed here, either
667 * the FreeBSD uart device will need to handle partial writes
668 * in xxx_bus_transmit(), or we'll need to do TX FIFO buffering
669 * of our own here.
670 */
671 static int
672 ar933x_bus_transmit(struct uart_softc *sc)
673 {
674 struct uart_bas *bas = &sc->sc_bas;
675 struct ar933x_softc *u = (struct ar933x_softc *)sc;
676 int i;
677
678 uart_lock(sc->sc_hwmtx);
679
680 /* Wait for the FIFO to be clear - see above */
681 while (ar933x_getreg(bas, AR933X_UART_CS_REG) &
682 AR933X_UART_CS_TX_BUSY)
683 ;
684
685 /*
686 * Write some data!
687 */
688 for (i = 0; i < sc->sc_txdatasz; i++) {
689 /* Write the TX data */
690 ar933x_setreg(bas, AR933X_UART_DATA_REG,
691 (sc->sc_txbuf[i] & 0xff) | AR933X_UART_DATA_TX_CSR);
692 uart_barrier(bas);
693 }
694
695 /*
696 * Now that we're transmitting, get interrupt notification
697 * when the FIFO is (almost) empty - see above.
698 */
699 u->u_ier |= AR933X_UART_INT_TX_EMPTY;
700 ar933x_setreg(bas, AR933X_UART_INT_EN_REG, u->u_ier);
701 uart_barrier(bas);
702
703 /*
704 * Inform the upper layer that we are presently transmitting
705 * data to the hardware; this will be cleared when the
706 * TXIDLE interrupt occurs.
707 */
708 sc->sc_txbusy = 1;
709 uart_unlock(sc->sc_hwmtx);
710
711 return (0);
712 }
713
714 static void
715 ar933x_bus_grab(struct uart_softc *sc)
716 {
717 struct uart_bas *bas = &sc->sc_bas;
718 uint32_t reg;
719
720 /* Disable the host interrupt now */
721 uart_lock(sc->sc_hwmtx);
722 reg = ar933x_getreg(bas, AR933X_UART_CS_REG);
723 reg &= ~AR933X_UART_CS_HOST_INT_EN;
724 ar933x_setreg(bas, AR933X_UART_CS_REG, reg);
725 uart_unlock(sc->sc_hwmtx);
726 }
727
728 static void
729 ar933x_bus_ungrab(struct uart_softc *sc)
730 {
731 struct uart_bas *bas = &sc->sc_bas;
732 uint32_t reg;
733
734 /* Enable the host interrupt now */
735 uart_lock(sc->sc_hwmtx);
736 reg = ar933x_getreg(bas, AR933X_UART_CS_REG);
737 reg |= AR933X_UART_CS_HOST_INT_EN;
738 ar933x_setreg(bas, AR933X_UART_CS_REG, reg);
739 uart_unlock(sc->sc_hwmtx);
740 }
Cache object: 153b05266148e6e3a3feaca836abc51e
|