The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/uart/uart_dev_z8530.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2003 Marcel Moolenaar
    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 <dev/ic/z8530.h>
   41 
   42 #include "uart_if.h"
   43 
   44 #define DEFAULT_RCLK    307200
   45 
   46 /* Hack! */
   47 #ifdef __powerpc__
   48 #define UART_PCLK       0
   49 #else
   50 #define UART_PCLK       MCB2_PCLK
   51 #endif
   52 
   53 /* Multiplexed I/O. */
   54 static __inline void
   55 uart_setmreg(struct uart_bas *bas, int reg, int val)
   56 {
   57 
   58         uart_setreg(bas, REG_CTRL, reg);
   59         uart_barrier(bas);
   60         uart_setreg(bas, REG_CTRL, val);
   61 }
   62 
   63 static __inline uint8_t
   64 uart_getmreg(struct uart_bas *bas, int reg)
   65 {
   66 
   67         uart_setreg(bas, REG_CTRL, reg);
   68         uart_barrier(bas);
   69         return (uart_getreg(bas, REG_CTRL));
   70 }
   71 
   72 static int
   73 z8530_divisor(int rclk, int baudrate)
   74 {
   75         int act_baud, divisor, error;
   76 
   77         if (baudrate == 0)
   78                 return (-1);
   79 
   80         divisor = (rclk + baudrate) / (baudrate << 1) - 2;
   81         if (divisor < 0 || divisor >= 65536)
   82                 return (-1);
   83         act_baud = rclk / 2 / (divisor + 2);
   84 
   85         /* 10 times error in percent: */
   86         error = ((act_baud - baudrate) * 2000 / baudrate + 1) >> 1;
   87 
   88         /* 3.0% maximum error tolerance: */
   89         if (error < -30 || error > 30)
   90                 return (-1);
   91 
   92         return (divisor);
   93 }
   94 
   95 static int
   96 z8530_param(struct uart_bas *bas, int baudrate, int databits, int stopbits,
   97     int parity, uint8_t *tpcp)
   98 {
   99         int divisor;
  100         uint8_t mpm, rpc, tpc;
  101 
  102         rpc = RPC_RXE;
  103         mpm = MPM_CM16;
  104         tpc = TPC_TXE | (*tpcp & (TPC_DTR | TPC_RTS));
  105 
  106         if (databits >= 8) {
  107                 rpc |= RPC_RB8;
  108                 tpc |= TPC_TB8;
  109         } else if (databits == 7) {
  110                 rpc |= RPC_RB7;
  111                 tpc |= TPC_TB7;
  112         } else if (databits == 6) {
  113                 rpc |= RPC_RB6;
  114                 tpc |= TPC_TB6;
  115         } else {
  116                 rpc |= RPC_RB5;
  117                 tpc |= TPC_TB5;
  118         }
  119         mpm |= (stopbits > 1) ? MPM_SB2 : MPM_SB1;
  120         switch (parity) {
  121         case UART_PARITY_EVEN:  mpm |= MPM_PE | MPM_EVEN; break;
  122         case UART_PARITY_NONE:  break;
  123         case UART_PARITY_ODD:   mpm |= MPM_PE; break;
  124         default:                return (EINVAL);
  125         }
  126 
  127         if (baudrate > 0) {
  128                 divisor = z8530_divisor(bas->rclk, baudrate);
  129                 if (divisor == -1)
  130                         return (EINVAL);
  131         } else
  132                 divisor = -1;
  133 
  134         uart_setmreg(bas, WR_MCB2, UART_PCLK);
  135         uart_barrier(bas);
  136 
  137         if (divisor >= 0) {
  138                 uart_setmreg(bas, WR_TCL, divisor & 0xff);
  139                 uart_barrier(bas);
  140                 uart_setmreg(bas, WR_TCH, (divisor >> 8) & 0xff);
  141                 uart_barrier(bas);
  142         }
  143 
  144         uart_setmreg(bas, WR_RPC, rpc);
  145         uart_barrier(bas);
  146         uart_setmreg(bas, WR_MPM, mpm);
  147         uart_barrier(bas);
  148         uart_setmreg(bas, WR_TPC, tpc);
  149         uart_barrier(bas);
  150         uart_setmreg(bas, WR_MCB2, UART_PCLK | MCB2_BRGE);
  151         uart_barrier(bas);
  152         *tpcp = tpc;
  153         return (0);
  154 }
  155 
  156 static int
  157 z8530_setup(struct uart_bas *bas, int baudrate, int databits, int stopbits,
  158     int parity)
  159 {
  160         uint8_t tpc;
  161 
  162         if (bas->rclk == 0)
  163                 bas->rclk = DEFAULT_RCLK;
  164 
  165         /* Assume we don't need to perform a full hardware reset. */
  166         switch (bas->chan) {
  167         case 1:
  168                 uart_setmreg(bas, WR_MIC, MIC_NV | MIC_CRA);
  169                 break;
  170         case 2:
  171                 uart_setmreg(bas, WR_MIC, MIC_NV | MIC_CRB);
  172                 break;
  173         }
  174         uart_barrier(bas);
  175         /* Set clock sources. */
  176         uart_setmreg(bas, WR_CMC, CMC_RC_BRG | CMC_TC_BRG);
  177         uart_setmreg(bas, WR_MCB2, UART_PCLK);
  178         uart_barrier(bas);
  179         /* Set data encoding. */
  180         uart_setmreg(bas, WR_MCB1, MCB1_NRZ);
  181         uart_barrier(bas);
  182 
  183         tpc = TPC_DTR | TPC_RTS;
  184         z8530_param(bas, baudrate, databits, stopbits, parity, &tpc);
  185         return (int)tpc;
  186 }
  187 
  188 /*
  189  * Low-level UART interface.
  190  */
  191 static int z8530_probe(struct uart_bas *bas);
  192 static void z8530_init(struct uart_bas *bas, int, int, int, int);
  193 static void z8530_term(struct uart_bas *bas);
  194 static void z8530_putc(struct uart_bas *bas, int);
  195 static int z8530_rxready(struct uart_bas *bas);
  196 static int z8530_getc(struct uart_bas *bas, struct mtx *);
  197 
  198 static struct uart_ops uart_z8530_ops = {
  199         .probe = z8530_probe,
  200         .init = z8530_init,
  201         .term = z8530_term,
  202         .putc = z8530_putc,
  203         .rxready = z8530_rxready,
  204         .getc = z8530_getc,
  205 };
  206 
  207 static int
  208 z8530_probe(struct uart_bas *bas)
  209 {
  210 
  211         return (0);
  212 }
  213 
  214 static void
  215 z8530_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
  216     int parity)
  217 {
  218 
  219         z8530_setup(bas, baudrate, databits, stopbits, parity);
  220 }
  221 
  222 static void
  223 z8530_term(struct uart_bas *bas)
  224 {
  225 }
  226 
  227 static void
  228 z8530_putc(struct uart_bas *bas, int c)
  229 {
  230 
  231         while (!(uart_getreg(bas, REG_CTRL) & BES_TXE))
  232                 ;
  233         uart_setreg(bas, REG_DATA, c);
  234         uart_barrier(bas);
  235 }
  236 
  237 static int
  238 z8530_rxready(struct uart_bas *bas)
  239 {
  240 
  241         return ((uart_getreg(bas, REG_CTRL) & BES_RXA) != 0 ? 1 : 0);
  242 }
  243 
  244 static int
  245 z8530_getc(struct uart_bas *bas, struct mtx *hwmtx)
  246 {
  247         int c;
  248 
  249         uart_lock(hwmtx);
  250 
  251         while (!(uart_getreg(bas, REG_CTRL) & BES_RXA)) {
  252                 uart_unlock(hwmtx);
  253                 DELAY(10);
  254                 uart_lock(hwmtx);
  255         }
  256 
  257         c = uart_getreg(bas, REG_DATA);
  258 
  259         uart_unlock(hwmtx);
  260 
  261         return (c);
  262 }
  263 
  264 /*
  265  * High-level UART interface.
  266  */
  267 struct z8530_softc {
  268         struct uart_softc base;
  269         uint8_t tpc;
  270         uint8_t txidle;
  271 };
  272 
  273 static int z8530_bus_attach(struct uart_softc *);
  274 static int z8530_bus_detach(struct uart_softc *);
  275 static int z8530_bus_flush(struct uart_softc *, int);
  276 static int z8530_bus_getsig(struct uart_softc *);
  277 static int z8530_bus_ioctl(struct uart_softc *, int, intptr_t);
  278 static int z8530_bus_ipend(struct uart_softc *);
  279 static int z8530_bus_param(struct uart_softc *, int, int, int, int);
  280 static int z8530_bus_probe(struct uart_softc *);
  281 static int z8530_bus_receive(struct uart_softc *);
  282 static int z8530_bus_setsig(struct uart_softc *, int);
  283 static int z8530_bus_transmit(struct uart_softc *);
  284 
  285 static kobj_method_t z8530_methods[] = {
  286         KOBJMETHOD(uart_attach,         z8530_bus_attach),
  287         KOBJMETHOD(uart_detach,         z8530_bus_detach),
  288         KOBJMETHOD(uart_flush,          z8530_bus_flush),
  289         KOBJMETHOD(uart_getsig,         z8530_bus_getsig),
  290         KOBJMETHOD(uart_ioctl,          z8530_bus_ioctl),
  291         KOBJMETHOD(uart_ipend,          z8530_bus_ipend),
  292         KOBJMETHOD(uart_param,          z8530_bus_param),
  293         KOBJMETHOD(uart_probe,          z8530_bus_probe),
  294         KOBJMETHOD(uart_receive,        z8530_bus_receive),
  295         KOBJMETHOD(uart_setsig,         z8530_bus_setsig),
  296         KOBJMETHOD(uart_transmit,       z8530_bus_transmit),
  297         { 0, 0 }
  298 };
  299 
  300 struct uart_class uart_z8530_class = {
  301         "z8530",
  302         z8530_methods,
  303         sizeof(struct z8530_softc),
  304         .uc_ops = &uart_z8530_ops,
  305         .uc_range = 2,
  306         .uc_rclk = DEFAULT_RCLK
  307 };
  308 
  309 #define SIGCHG(c, i, s, d)                              \
  310         if (c) {                                        \
  311                 i |= (i & s) ? s : s | d;               \
  312         } else {                                        \
  313                 i = (i & s) ? (i & ~s) | d : i;         \
  314         }
  315 
  316 static int
  317 z8530_bus_attach(struct uart_softc *sc)
  318 {
  319         struct z8530_softc *z8530 = (struct z8530_softc*)sc;
  320         struct uart_bas *bas;
  321         struct uart_devinfo *di;
  322 
  323         bas = &sc->sc_bas;
  324         if (sc->sc_sysdev != NULL) {
  325                 di = sc->sc_sysdev;
  326                 z8530->tpc = TPC_DTR|TPC_RTS;
  327                 z8530_param(bas, di->baudrate, di->databits, di->stopbits,
  328                     di->parity, &z8530->tpc);
  329         } else {
  330                 z8530->tpc = z8530_setup(bas, 9600, 8, 1, UART_PARITY_NONE);
  331                 z8530->tpc &= ~(TPC_DTR|TPC_RTS);
  332         }
  333         z8530->txidle = 1;      /* Report SER_INT_TXIDLE. */
  334 
  335         sc->sc_rxfifosz = 3;
  336         sc->sc_txfifosz = 1;
  337 
  338         (void)z8530_bus_getsig(sc);
  339 
  340         uart_setmreg(bas, WR_IC, IC_BRK | IC_CTS | IC_DCD);
  341         uart_barrier(bas);
  342         uart_setmreg(bas, WR_IDT, IDT_XIE | IDT_TIE | IDT_RIA);
  343         uart_barrier(bas);
  344         uart_setmreg(bas, WR_IV, 0);
  345         uart_barrier(bas);
  346         uart_setmreg(bas, WR_TPC, z8530->tpc);
  347         uart_barrier(bas);
  348         uart_setmreg(bas, WR_MIC, MIC_NV | MIC_MIE);
  349         uart_barrier(bas);
  350         return (0);
  351 }
  352 
  353 static int
  354 z8530_bus_detach(struct uart_softc *sc)
  355 {
  356 
  357         return (0);
  358 }
  359 
  360 static int
  361 z8530_bus_flush(struct uart_softc *sc, int what)
  362 {
  363 
  364         return (0);
  365 }
  366 
  367 static int
  368 z8530_bus_getsig(struct uart_softc *sc)
  369 {
  370         uint32_t new, old, sig;
  371         uint8_t bes;
  372 
  373         do {
  374                 old = sc->sc_hwsig;
  375                 sig = old;
  376                 uart_lock(sc->sc_hwmtx);
  377                 bes = uart_getmreg(&sc->sc_bas, RR_BES);
  378                 uart_unlock(sc->sc_hwmtx);
  379                 SIGCHG(bes & BES_CTS, sig, SER_CTS, SER_DCTS);
  380                 SIGCHG(bes & BES_DCD, sig, SER_DCD, SER_DDCD);
  381                 SIGCHG(bes & BES_SYNC, sig, SER_DSR, SER_DDSR);
  382                 new = sig & ~SER_MASK_DELTA;
  383         } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
  384         return (sig);
  385 }
  386 
  387 static int
  388 z8530_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
  389 {
  390         struct z8530_softc *z8530 = (struct z8530_softc*)sc;
  391         struct uart_bas *bas;
  392         int baudrate, divisor, error;
  393 
  394         bas = &sc->sc_bas;
  395         error = 0;
  396         uart_lock(sc->sc_hwmtx);
  397         switch (request) {
  398         case UART_IOCTL_BREAK:
  399                 if (data)
  400                         z8530->tpc |= TPC_BRK;
  401                 else
  402                         z8530->tpc &= ~TPC_BRK;
  403                 uart_setmreg(bas, WR_TPC, z8530->tpc);
  404                 uart_barrier(bas);
  405                 break;
  406         case UART_IOCTL_BAUD:
  407                 divisor = uart_getmreg(bas, RR_TCH);
  408                 divisor = (divisor << 8) | uart_getmreg(bas, RR_TCL);
  409                 baudrate = bas->rclk / 2 / (divisor + 2);
  410                 *(int*)data = baudrate;
  411                 break;
  412         default:
  413                 error = EINVAL;
  414                 break;
  415         }
  416         uart_unlock(sc->sc_hwmtx);
  417         return (error);
  418 }
  419 
  420 static int
  421 z8530_bus_ipend(struct uart_softc *sc)
  422 {
  423         struct z8530_softc *z8530 = (struct z8530_softc*)sc;
  424         struct uart_bas *bas;
  425         int ipend;
  426         uint32_t sig;
  427         uint8_t bes, ip, iv, src;
  428 
  429         bas = &sc->sc_bas;
  430         ipend = 0;
  431 
  432         uart_lock(sc->sc_hwmtx);
  433         switch (bas->chan) {
  434         case 1:
  435                 ip = uart_getmreg(bas, RR_IP);
  436                 break;
  437         case 2: /* XXX hack!!! */
  438                 iv = uart_getmreg(bas, RR_IV) & 0x0E;
  439                 switch (iv) {
  440                 case IV_TEB:    ip = IP_TIA; break;
  441                 case IV_XSB:    ip = IP_SIA; break;
  442                 case IV_RAB:    ip = IP_RIA; break;
  443                 default:        ip = 0; break;
  444                 }
  445                 break;
  446         default:
  447                 ip = 0;
  448                 break;
  449         }
  450 
  451         if (ip & IP_RIA)
  452                 ipend |= SER_INT_RXREADY;
  453 
  454         if (ip & IP_TIA) {
  455                 uart_setreg(bas, REG_CTRL, CR_RSTTXI);
  456                 uart_barrier(bas);
  457                 if (z8530->txidle) {
  458                         ipend |= SER_INT_TXIDLE;
  459                         z8530->txidle = 0;      /* Mask SER_INT_TXIDLE. */
  460                 }
  461         }
  462 
  463         if (ip & IP_SIA) {
  464                 uart_setreg(bas, REG_CTRL, CR_RSTXSI);
  465                 uart_barrier(bas);
  466                 bes = uart_getmreg(bas, RR_BES);
  467                 if (bes & BES_BRK)
  468                         ipend |= SER_INT_BREAK;
  469                 sig = sc->sc_hwsig;
  470                 SIGCHG(bes & BES_CTS, sig, SER_CTS, SER_DCTS);
  471                 SIGCHG(bes & BES_DCD, sig, SER_DCD, SER_DDCD);
  472                 SIGCHG(bes & BES_SYNC, sig, SER_DSR, SER_DDSR);
  473                 if (sig & SER_MASK_DELTA)
  474                         ipend |= SER_INT_SIGCHG;
  475                 src = uart_getmreg(bas, RR_SRC);
  476                 if (src & SRC_OVR) {
  477                         uart_setreg(bas, REG_CTRL, CR_RSTERR);
  478                         uart_barrier(bas);
  479                         ipend |= SER_INT_OVERRUN;
  480                 }
  481         }
  482 
  483         if (ipend) {
  484                 uart_setreg(bas, REG_CTRL, CR_RSTIUS);
  485                 uart_barrier(bas);
  486         }
  487 
  488         uart_unlock(sc->sc_hwmtx);
  489 
  490         return (ipend);
  491 }
  492 
  493 static int
  494 z8530_bus_param(struct uart_softc *sc, int baudrate, int databits,
  495     int stopbits, int parity)
  496 {
  497         struct z8530_softc *z8530 = (struct z8530_softc*)sc;
  498         int error;
  499 
  500         uart_lock(sc->sc_hwmtx);
  501         error = z8530_param(&sc->sc_bas, baudrate, databits, stopbits, parity,
  502             &z8530->tpc);
  503         uart_unlock(sc->sc_hwmtx);
  504         return (error);
  505 }
  506 
  507 static int
  508 z8530_bus_probe(struct uart_softc *sc)
  509 {
  510         char buf[80];
  511         int error;
  512         char ch;
  513 
  514         error = z8530_probe(&sc->sc_bas);
  515         if (error)
  516                 return (error);
  517 
  518         ch = sc->sc_bas.chan - 1 + 'A';
  519 
  520         snprintf(buf, sizeof(buf), "z8530, channel %c", ch);
  521         device_set_desc_copy(sc->sc_dev, buf);
  522         return (0);
  523 }
  524 
  525 static int
  526 z8530_bus_receive(struct uart_softc *sc)
  527 {
  528         struct uart_bas *bas;
  529         int xc;
  530         uint8_t bes, src;
  531 
  532         bas = &sc->sc_bas;
  533         uart_lock(sc->sc_hwmtx);
  534         bes = uart_getmreg(bas, RR_BES);
  535         while (bes & BES_RXA) {
  536                 if (uart_rx_full(sc)) {
  537                         sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
  538                         break;
  539                 }
  540                 xc = uart_getreg(bas, REG_DATA);
  541                 uart_barrier(bas);
  542                 src = uart_getmreg(bas, RR_SRC);
  543                 if (src & SRC_FE)
  544                         xc |= UART_STAT_FRAMERR;
  545                 if (src & SRC_PE)
  546                         xc |= UART_STAT_PARERR;
  547                 if (src & SRC_OVR)
  548                         xc |= UART_STAT_OVERRUN;
  549                 uart_rx_put(sc, xc);
  550                 if (src & (SRC_FE | SRC_PE | SRC_OVR)) {
  551                         uart_setreg(bas, REG_CTRL, CR_RSTERR);
  552                         uart_barrier(bas);
  553                 }
  554                 bes = uart_getmreg(bas, RR_BES);
  555         }
  556         /* Discard everything left in the Rx FIFO. */
  557         while (bes & BES_RXA) {
  558                 (void)uart_getreg(bas, REG_DATA);
  559                 uart_barrier(bas);
  560                 src = uart_getmreg(bas, RR_SRC);
  561                 if (src & (SRC_FE | SRC_PE | SRC_OVR)) {
  562                         uart_setreg(bas, REG_CTRL, CR_RSTERR);
  563                         uart_barrier(bas);
  564                 }
  565                 bes = uart_getmreg(bas, RR_BES);
  566         }
  567         uart_unlock(sc->sc_hwmtx);
  568         return (0);
  569 }
  570 
  571 static int
  572 z8530_bus_setsig(struct uart_softc *sc, int sig)
  573 {
  574         struct z8530_softc *z8530 = (struct z8530_softc*)sc;
  575         struct uart_bas *bas;
  576         uint32_t new, old;
  577 
  578         bas = &sc->sc_bas;
  579         do {
  580                 old = sc->sc_hwsig;
  581                 new = old;
  582                 if (sig & SER_DDTR) {
  583                         SIGCHG(sig & SER_DTR, new, SER_DTR,
  584                             SER_DDTR);
  585                 }
  586                 if (sig & SER_DRTS) {
  587                         SIGCHG(sig & SER_RTS, new, SER_RTS,
  588                             SER_DRTS);
  589                 }
  590         } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
  591 
  592         uart_lock(sc->sc_hwmtx);
  593         if (new & SER_DTR)
  594                 z8530->tpc |= TPC_DTR;
  595         else
  596                 z8530->tpc &= ~TPC_DTR;
  597         if (new & SER_RTS)
  598                 z8530->tpc |= TPC_RTS;
  599         else
  600                 z8530->tpc &= ~TPC_RTS;
  601         uart_setmreg(bas, WR_TPC, z8530->tpc);
  602         uart_barrier(bas);
  603         uart_unlock(sc->sc_hwmtx);
  604         return (0);
  605 }
  606 
  607 static int
  608 z8530_bus_transmit(struct uart_softc *sc)
  609 {
  610         struct z8530_softc *z8530 = (struct z8530_softc*)sc;
  611         struct uart_bas *bas;
  612 
  613         bas = &sc->sc_bas;
  614         uart_lock(sc->sc_hwmtx);
  615         while (!(uart_getmreg(bas, RR_BES) & BES_TXE))
  616                 ;
  617         uart_setreg(bas, REG_DATA, sc->sc_txbuf[0]);
  618         uart_barrier(bas);
  619         sc->sc_txbusy = 1;
  620         z8530->txidle = 1;      /* Report SER_INT_TXIDLE again. */
  621         uart_unlock(sc->sc_hwmtx);
  622         return (0);
  623 }

Cache object: 2e25cde9ece1946978e2fdbe772e06fd


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.