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