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