Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Driver for Zilog serial chips found on SGI workstations and
0004  * servers.  This driver could actually be made more generic.
0005  *
0006  * This is based on the drivers/serial/sunzilog.c code as of 2.6.0-test7 and the
0007  * old drivers/sgi/char/sgiserial.c code which itself is based of the original
0008  * drivers/sbus/char/zs.c code.  A lot of code has been simply moved over
0009  * directly from there but much has been rewritten.  Credits therefore go out
0010  * to David S. Miller, Eddie C. Dost, Pete Zaitcev, Ted Ts'o and Alex Buell
0011  * for their work there.
0012  *
0013  *  Copyright (C) 2002 Ralf Baechle (ralf@linux-mips.org)
0014  *  Copyright (C) 2002 David S. Miller (davem@redhat.com)
0015  */
0016 #include <linux/module.h>
0017 #include <linux/kernel.h>
0018 #include <linux/errno.h>
0019 #include <linux/delay.h>
0020 #include <linux/tty.h>
0021 #include <linux/tty_flip.h>
0022 #include <linux/major.h>
0023 #include <linux/string.h>
0024 #include <linux/ptrace.h>
0025 #include <linux/ioport.h>
0026 #include <linux/slab.h>
0027 #include <linux/circ_buf.h>
0028 #include <linux/serial.h>
0029 #include <linux/sysrq.h>
0030 #include <linux/console.h>
0031 #include <linux/spinlock.h>
0032 #include <linux/init.h>
0033 
0034 #include <linux/io.h>
0035 #include <asm/irq.h>
0036 #include <asm/sgialib.h>
0037 #include <asm/sgi/ioc.h>
0038 #include <asm/sgi/hpc3.h>
0039 #include <asm/sgi/ip22.h>
0040 
0041 #include <linux/serial_core.h>
0042 
0043 #include "ip22zilog.h"
0044 
0045 /*
0046  * On IP22 we need to delay after register accesses but we do not need to
0047  * flush writes.
0048  */
0049 #define ZSDELAY()       udelay(5)
0050 #define ZSDELAY_LONG()      udelay(20)
0051 #define ZS_WSYNC(channel)   do { } while (0)
0052 
0053 #define NUM_IP22ZILOG       1
0054 #define NUM_CHANNELS        (NUM_IP22ZILOG * 2)
0055 
0056 #define ZS_CLOCK        3672000 /* Zilog input clock rate. */
0057 #define ZS_CLOCK_DIVISOR    16      /* Divisor this driver uses. */
0058 
0059 /*
0060  * We wrap our port structure around the generic uart_port.
0061  */
0062 struct uart_ip22zilog_port {
0063     struct uart_port        port;
0064 
0065     /* IRQ servicing chain.  */
0066     struct uart_ip22zilog_port  *next;
0067 
0068     /* Current values of Zilog write registers.  */
0069     unsigned char           curregs[NUM_ZSREGS];
0070 
0071     unsigned int            flags;
0072 #define IP22ZILOG_FLAG_IS_CONS      0x00000004
0073 #define IP22ZILOG_FLAG_IS_KGDB      0x00000008
0074 #define IP22ZILOG_FLAG_MODEM_STATUS 0x00000010
0075 #define IP22ZILOG_FLAG_IS_CHANNEL_A 0x00000020
0076 #define IP22ZILOG_FLAG_REGS_HELD    0x00000040
0077 #define IP22ZILOG_FLAG_TX_STOPPED   0x00000080
0078 #define IP22ZILOG_FLAG_TX_ACTIVE    0x00000100
0079 #define IP22ZILOG_FLAG_RESET_DONE   0x00000200
0080 
0081     unsigned int            tty_break;
0082 
0083     unsigned char           parity_mask;
0084     unsigned char           prev_status;
0085 };
0086 
0087 #define ZILOG_CHANNEL_FROM_PORT(PORT)   ((struct zilog_channel *)((PORT)->membase))
0088 #define UART_ZILOG(PORT)        ((struct uart_ip22zilog_port *)(PORT))
0089 #define IP22ZILOG_GET_CURR_REG(PORT, REGNUM)        \
0090     (UART_ZILOG(PORT)->curregs[REGNUM])
0091 #define IP22ZILOG_SET_CURR_REG(PORT, REGNUM, REGVAL)    \
0092     ((UART_ZILOG(PORT)->curregs[REGNUM]) = (REGVAL))
0093 #define ZS_IS_CONS(UP)  ((UP)->flags & IP22ZILOG_FLAG_IS_CONS)
0094 #define ZS_IS_KGDB(UP)  ((UP)->flags & IP22ZILOG_FLAG_IS_KGDB)
0095 #define ZS_WANTS_MODEM_STATUS(UP)   ((UP)->flags & IP22ZILOG_FLAG_MODEM_STATUS)
0096 #define ZS_IS_CHANNEL_A(UP) ((UP)->flags & IP22ZILOG_FLAG_IS_CHANNEL_A)
0097 #define ZS_REGS_HELD(UP)    ((UP)->flags & IP22ZILOG_FLAG_REGS_HELD)
0098 #define ZS_TX_STOPPED(UP)   ((UP)->flags & IP22ZILOG_FLAG_TX_STOPPED)
0099 #define ZS_TX_ACTIVE(UP)    ((UP)->flags & IP22ZILOG_FLAG_TX_ACTIVE)
0100 
0101 /* Reading and writing Zilog8530 registers.  The delays are to make this
0102  * driver work on the IP22 which needs a settling delay after each chip
0103  * register access, other machines handle this in hardware via auxiliary
0104  * flip-flops which implement the settle time we do in software.
0105  *
0106  * The port lock must be held and local IRQs must be disabled
0107  * when {read,write}_zsreg is invoked.
0108  */
0109 static unsigned char read_zsreg(struct zilog_channel *channel,
0110                 unsigned char reg)
0111 {
0112     unsigned char retval;
0113 
0114     writeb(reg, &channel->control);
0115     ZSDELAY();
0116     retval = readb(&channel->control);
0117     ZSDELAY();
0118 
0119     return retval;
0120 }
0121 
0122 static void write_zsreg(struct zilog_channel *channel,
0123             unsigned char reg, unsigned char value)
0124 {
0125     writeb(reg, &channel->control);
0126     ZSDELAY();
0127     writeb(value, &channel->control);
0128     ZSDELAY();
0129 }
0130 
0131 static void ip22zilog_clear_fifo(struct zilog_channel *channel)
0132 {
0133     int i;
0134 
0135     for (i = 0; i < 32; i++) {
0136         unsigned char regval;
0137 
0138         regval = readb(&channel->control);
0139         ZSDELAY();
0140         if (regval & Rx_CH_AV)
0141             break;
0142 
0143         regval = read_zsreg(channel, R1);
0144         readb(&channel->data);
0145         ZSDELAY();
0146 
0147         if (regval & (PAR_ERR | Rx_OVR | CRC_ERR)) {
0148             writeb(ERR_RES, &channel->control);
0149             ZSDELAY();
0150             ZS_WSYNC(channel);
0151         }
0152     }
0153 }
0154 
0155 /* This function must only be called when the TX is not busy.  The UART
0156  * port lock must be held and local interrupts disabled.
0157  */
0158 static void __load_zsregs(struct zilog_channel *channel, unsigned char *regs)
0159 {
0160     int i;
0161 
0162     /* Let pending transmits finish.  */
0163     for (i = 0; i < 1000; i++) {
0164         unsigned char stat = read_zsreg(channel, R1);
0165         if (stat & ALL_SNT)
0166             break;
0167         udelay(100);
0168     }
0169 
0170     writeb(ERR_RES, &channel->control);
0171     ZSDELAY();
0172     ZS_WSYNC(channel);
0173 
0174     ip22zilog_clear_fifo(channel);
0175 
0176     /* Disable all interrupts.  */
0177     write_zsreg(channel, R1,
0178             regs[R1] & ~(RxINT_MASK | TxINT_ENAB | EXT_INT_ENAB));
0179 
0180     /* Set parity, sync config, stop bits, and clock divisor.  */
0181     write_zsreg(channel, R4, regs[R4]);
0182 
0183     /* Set misc. TX/RX control bits.  */
0184     write_zsreg(channel, R10, regs[R10]);
0185 
0186     /* Set TX/RX controls sans the enable bits.  */
0187     write_zsreg(channel, R3, regs[R3] & ~RxENAB);
0188     write_zsreg(channel, R5, regs[R5] & ~TxENAB);
0189 
0190     /* Synchronous mode config.  */
0191     write_zsreg(channel, R6, regs[R6]);
0192     write_zsreg(channel, R7, regs[R7]);
0193 
0194     /* Don't mess with the interrupt vector (R2, unused by us) and
0195      * master interrupt control (R9).  We make sure this is setup
0196      * properly at probe time then never touch it again.
0197      */
0198 
0199     /* Disable baud generator.  */
0200     write_zsreg(channel, R14, regs[R14] & ~BRENAB);
0201 
0202     /* Clock mode control.  */
0203     write_zsreg(channel, R11, regs[R11]);
0204 
0205     /* Lower and upper byte of baud rate generator divisor.  */
0206     write_zsreg(channel, R12, regs[R12]);
0207     write_zsreg(channel, R13, regs[R13]);
0208 
0209     /* Now rewrite R14, with BRENAB (if set).  */
0210     write_zsreg(channel, R14, regs[R14]);
0211 
0212     /* External status interrupt control.  */
0213     write_zsreg(channel, R15, regs[R15]);
0214 
0215     /* Reset external status interrupts.  */
0216     write_zsreg(channel, R0, RES_EXT_INT);
0217     write_zsreg(channel, R0, RES_EXT_INT);
0218 
0219     /* Rewrite R3/R5, this time without enables masked.  */
0220     write_zsreg(channel, R3, regs[R3]);
0221     write_zsreg(channel, R5, regs[R5]);
0222 
0223     /* Rewrite R1, this time without IRQ enabled masked.  */
0224     write_zsreg(channel, R1, regs[R1]);
0225 }
0226 
0227 /* Reprogram the Zilog channel HW registers with the copies found in the
0228  * software state struct.  If the transmitter is busy, we defer this update
0229  * until the next TX complete interrupt.  Else, we do it right now.
0230  *
0231  * The UART port lock must be held and local interrupts disabled.
0232  */
0233 static void ip22zilog_maybe_update_regs(struct uart_ip22zilog_port *up,
0234                        struct zilog_channel *channel)
0235 {
0236     if (!ZS_REGS_HELD(up)) {
0237         if (ZS_TX_ACTIVE(up)) {
0238             up->flags |= IP22ZILOG_FLAG_REGS_HELD;
0239         } else {
0240             __load_zsregs(channel, up->curregs);
0241         }
0242     }
0243 }
0244 
0245 #define Rx_BRK 0x0100                   /* BREAK event software flag.  */
0246 #define Rx_SYS 0x0200                   /* SysRq event software flag.  */
0247 
0248 static bool ip22zilog_receive_chars(struct uart_ip22zilog_port *up,
0249                           struct zilog_channel *channel)
0250 {
0251     unsigned char ch, flag;
0252     unsigned int r1;
0253     bool push = up->port.state != NULL;
0254 
0255     for (;;) {
0256         ch = readb(&channel->control);
0257         ZSDELAY();
0258         if (!(ch & Rx_CH_AV))
0259             break;
0260 
0261         r1 = read_zsreg(channel, R1);
0262         if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
0263             writeb(ERR_RES, &channel->control);
0264             ZSDELAY();
0265             ZS_WSYNC(channel);
0266         }
0267 
0268         ch = readb(&channel->data);
0269         ZSDELAY();
0270 
0271         ch &= up->parity_mask;
0272 
0273         /* Handle the null char got when BREAK is removed.  */
0274         if (!ch)
0275             r1 |= up->tty_break;
0276 
0277         /* A real serial line, record the character and status.  */
0278         flag = TTY_NORMAL;
0279         up->port.icount.rx++;
0280         if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | Rx_SYS | Rx_BRK)) {
0281             up->tty_break = 0;
0282 
0283             if (r1 & (Rx_SYS | Rx_BRK)) {
0284                 up->port.icount.brk++;
0285                 if (r1 & Rx_SYS)
0286                     continue;
0287                 r1 &= ~(PAR_ERR | CRC_ERR);
0288             }
0289             else if (r1 & PAR_ERR)
0290                 up->port.icount.parity++;
0291             else if (r1 & CRC_ERR)
0292                 up->port.icount.frame++;
0293             if (r1 & Rx_OVR)
0294                 up->port.icount.overrun++;
0295             r1 &= up->port.read_status_mask;
0296             if (r1 & Rx_BRK)
0297                 flag = TTY_BREAK;
0298             else if (r1 & PAR_ERR)
0299                 flag = TTY_PARITY;
0300             else if (r1 & CRC_ERR)
0301                 flag = TTY_FRAME;
0302         }
0303 
0304         if (uart_handle_sysrq_char(&up->port, ch))
0305             continue;
0306 
0307         if (push)
0308             uart_insert_char(&up->port, r1, Rx_OVR, ch, flag);
0309     }
0310     return push;
0311 }
0312 
0313 static void ip22zilog_status_handle(struct uart_ip22zilog_port *up,
0314                    struct zilog_channel *channel)
0315 {
0316     unsigned char status;
0317 
0318     status = readb(&channel->control);
0319     ZSDELAY();
0320 
0321     writeb(RES_EXT_INT, &channel->control);
0322     ZSDELAY();
0323     ZS_WSYNC(channel);
0324 
0325     if (up->curregs[R15] & BRKIE) {
0326         if ((status & BRK_ABRT) && !(up->prev_status & BRK_ABRT)) {
0327             if (uart_handle_break(&up->port))
0328                 up->tty_break = Rx_SYS;
0329             else
0330                 up->tty_break = Rx_BRK;
0331         }
0332     }
0333 
0334     if (ZS_WANTS_MODEM_STATUS(up)) {
0335         if (status & SYNC)
0336             up->port.icount.dsr++;
0337 
0338         /* The Zilog just gives us an interrupt when DCD/CTS/etc. change.
0339          * But it does not tell us which bit has changed, we have to keep
0340          * track of this ourselves.
0341          */
0342         if ((status ^ up->prev_status) ^ DCD)
0343             uart_handle_dcd_change(&up->port,
0344                            (status & DCD));
0345         if ((status ^ up->prev_status) ^ CTS)
0346             uart_handle_cts_change(&up->port,
0347                            (status & CTS));
0348 
0349         wake_up_interruptible(&up->port.state->port.delta_msr_wait);
0350     }
0351 
0352     up->prev_status = status;
0353 }
0354 
0355 static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up,
0356                     struct zilog_channel *channel)
0357 {
0358     struct circ_buf *xmit;
0359 
0360     if (ZS_IS_CONS(up)) {
0361         unsigned char status = readb(&channel->control);
0362         ZSDELAY();
0363 
0364         /* TX still busy?  Just wait for the next TX done interrupt.
0365          *
0366          * It can occur because of how we do serial console writes.  It would
0367          * be nice to transmit console writes just like we normally would for
0368          * a TTY line. (ie. buffered and TX interrupt driven).  That is not
0369          * easy because console writes cannot sleep.  One solution might be
0370          * to poll on enough port->xmit space becoming free.  -DaveM
0371          */
0372         if (!(status & Tx_BUF_EMP))
0373             return;
0374     }
0375 
0376     up->flags &= ~IP22ZILOG_FLAG_TX_ACTIVE;
0377 
0378     if (ZS_REGS_HELD(up)) {
0379         __load_zsregs(channel, up->curregs);
0380         up->flags &= ~IP22ZILOG_FLAG_REGS_HELD;
0381     }
0382 
0383     if (ZS_TX_STOPPED(up)) {
0384         up->flags &= ~IP22ZILOG_FLAG_TX_STOPPED;
0385         goto ack_tx_int;
0386     }
0387 
0388     if (up->port.x_char) {
0389         up->flags |= IP22ZILOG_FLAG_TX_ACTIVE;
0390         writeb(up->port.x_char, &channel->data);
0391         ZSDELAY();
0392         ZS_WSYNC(channel);
0393 
0394         up->port.icount.tx++;
0395         up->port.x_char = 0;
0396         return;
0397     }
0398 
0399     if (up->port.state == NULL)
0400         goto ack_tx_int;
0401     xmit = &up->port.state->xmit;
0402     if (uart_circ_empty(xmit))
0403         goto ack_tx_int;
0404     if (uart_tx_stopped(&up->port))
0405         goto ack_tx_int;
0406 
0407     up->flags |= IP22ZILOG_FLAG_TX_ACTIVE;
0408     writeb(xmit->buf[xmit->tail], &channel->data);
0409     ZSDELAY();
0410     ZS_WSYNC(channel);
0411 
0412     xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
0413     up->port.icount.tx++;
0414 
0415     if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
0416         uart_write_wakeup(&up->port);
0417 
0418     return;
0419 
0420 ack_tx_int:
0421     writeb(RES_Tx_P, &channel->control);
0422     ZSDELAY();
0423     ZS_WSYNC(channel);
0424 }
0425 
0426 static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id)
0427 {
0428     struct uart_ip22zilog_port *up = dev_id;
0429 
0430     while (up) {
0431         struct zilog_channel *channel
0432             = ZILOG_CHANNEL_FROM_PORT(&up->port);
0433         unsigned char r3;
0434         bool push = false;
0435 
0436         spin_lock(&up->port.lock);
0437         r3 = read_zsreg(channel, R3);
0438 
0439         /* Channel A */
0440         if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
0441             writeb(RES_H_IUS, &channel->control);
0442             ZSDELAY();
0443             ZS_WSYNC(channel);
0444 
0445             if (r3 & CHARxIP)
0446                 push = ip22zilog_receive_chars(up, channel);
0447             if (r3 & CHAEXT)
0448                 ip22zilog_status_handle(up, channel);
0449             if (r3 & CHATxIP)
0450                 ip22zilog_transmit_chars(up, channel);
0451         }
0452         spin_unlock(&up->port.lock);
0453 
0454         if (push)
0455             tty_flip_buffer_push(&up->port.state->port);
0456 
0457         /* Channel B */
0458         up = up->next;
0459         channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
0460         push = false;
0461 
0462         spin_lock(&up->port.lock);
0463         if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
0464             writeb(RES_H_IUS, &channel->control);
0465             ZSDELAY();
0466             ZS_WSYNC(channel);
0467 
0468             if (r3 & CHBRxIP)
0469                 push = ip22zilog_receive_chars(up, channel);
0470             if (r3 & CHBEXT)
0471                 ip22zilog_status_handle(up, channel);
0472             if (r3 & CHBTxIP)
0473                 ip22zilog_transmit_chars(up, channel);
0474         }
0475         spin_unlock(&up->port.lock);
0476 
0477         if (push)
0478             tty_flip_buffer_push(&up->port.state->port);
0479 
0480         up = up->next;
0481     }
0482 
0483     return IRQ_HANDLED;
0484 }
0485 
0486 /* A convenient way to quickly get R0 status.  The caller must _not_ hold the
0487  * port lock, it is acquired here.
0488  */
0489 static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port)
0490 {
0491     struct zilog_channel *channel;
0492     unsigned char status;
0493 
0494     channel = ZILOG_CHANNEL_FROM_PORT(port);
0495     status = readb(&channel->control);
0496     ZSDELAY();
0497 
0498     return status;
0499 }
0500 
0501 /* The port lock is not held.  */
0502 static unsigned int ip22zilog_tx_empty(struct uart_port *port)
0503 {
0504     unsigned long flags;
0505     unsigned char status;
0506     unsigned int ret;
0507 
0508     spin_lock_irqsave(&port->lock, flags);
0509 
0510     status = ip22zilog_read_channel_status(port);
0511 
0512     spin_unlock_irqrestore(&port->lock, flags);
0513 
0514     if (status & Tx_BUF_EMP)
0515         ret = TIOCSER_TEMT;
0516     else
0517         ret = 0;
0518 
0519     return ret;
0520 }
0521 
0522 /* The port lock is held and interrupts are disabled.  */
0523 static unsigned int ip22zilog_get_mctrl(struct uart_port *port)
0524 {
0525     unsigned char status;
0526     unsigned int ret;
0527 
0528     status = ip22zilog_read_channel_status(port);
0529 
0530     ret = 0;
0531     if (status & DCD)
0532         ret |= TIOCM_CAR;
0533     if (status & SYNC)
0534         ret |= TIOCM_DSR;
0535     if (status & CTS)
0536         ret |= TIOCM_CTS;
0537 
0538     return ret;
0539 }
0540 
0541 /* The port lock is held and interrupts are disabled.  */
0542 static void ip22zilog_set_mctrl(struct uart_port *port, unsigned int mctrl)
0543 {
0544     struct uart_ip22zilog_port *up =
0545         container_of(port, struct uart_ip22zilog_port, port);
0546     struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
0547     unsigned char set_bits, clear_bits;
0548 
0549     set_bits = clear_bits = 0;
0550 
0551     if (mctrl & TIOCM_RTS)
0552         set_bits |= RTS;
0553     else
0554         clear_bits |= RTS;
0555     if (mctrl & TIOCM_DTR)
0556         set_bits |= DTR;
0557     else
0558         clear_bits |= DTR;
0559 
0560     /* NOTE: Not subject to 'transmitter active' rule.  */
0561     up->curregs[R5] |= set_bits;
0562     up->curregs[R5] &= ~clear_bits;
0563     write_zsreg(channel, R5, up->curregs[R5]);
0564 }
0565 
0566 /* The port lock is held and interrupts are disabled.  */
0567 static void ip22zilog_stop_tx(struct uart_port *port)
0568 {
0569     struct uart_ip22zilog_port *up =
0570         container_of(port, struct uart_ip22zilog_port, port);
0571 
0572     up->flags |= IP22ZILOG_FLAG_TX_STOPPED;
0573 }
0574 
0575 /* The port lock is held and interrupts are disabled.  */
0576 static void ip22zilog_start_tx(struct uart_port *port)
0577 {
0578     struct uart_ip22zilog_port *up =
0579         container_of(port, struct uart_ip22zilog_port, port);
0580     struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
0581     unsigned char status;
0582 
0583     up->flags |= IP22ZILOG_FLAG_TX_ACTIVE;
0584     up->flags &= ~IP22ZILOG_FLAG_TX_STOPPED;
0585 
0586     status = readb(&channel->control);
0587     ZSDELAY();
0588 
0589     /* TX busy?  Just wait for the TX done interrupt.  */
0590     if (!(status & Tx_BUF_EMP))
0591         return;
0592 
0593     /* Send the first character to jump-start the TX done
0594      * IRQ sending engine.
0595      */
0596     if (port->x_char) {
0597         writeb(port->x_char, &channel->data);
0598         ZSDELAY();
0599         ZS_WSYNC(channel);
0600 
0601         port->icount.tx++;
0602         port->x_char = 0;
0603     } else {
0604         struct circ_buf *xmit = &port->state->xmit;
0605 
0606         if (uart_circ_empty(xmit))
0607             return;
0608         writeb(xmit->buf[xmit->tail], &channel->data);
0609         ZSDELAY();
0610         ZS_WSYNC(channel);
0611 
0612         xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
0613         port->icount.tx++;
0614 
0615         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
0616             uart_write_wakeup(&up->port);
0617     }
0618 }
0619 
0620 /* The port lock is held and interrupts are disabled.  */
0621 static void ip22zilog_stop_rx(struct uart_port *port)
0622 {
0623     struct uart_ip22zilog_port *up = UART_ZILOG(port);
0624     struct zilog_channel *channel;
0625 
0626     if (ZS_IS_CONS(up))
0627         return;
0628 
0629     channel = ZILOG_CHANNEL_FROM_PORT(port);
0630 
0631     /* Disable all RX interrupts.  */
0632     up->curregs[R1] &= ~RxINT_MASK;
0633     ip22zilog_maybe_update_regs(up, channel);
0634 }
0635 
0636 /* The port lock is held.  */
0637 static void ip22zilog_enable_ms(struct uart_port *port)
0638 {
0639     struct uart_ip22zilog_port *up =
0640         container_of(port, struct uart_ip22zilog_port, port);
0641     struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
0642     unsigned char new_reg;
0643 
0644     new_reg = up->curregs[R15] | (DCDIE | SYNCIE | CTSIE);
0645     if (new_reg != up->curregs[R15]) {
0646         up->curregs[R15] = new_reg;
0647 
0648         /* NOTE: Not subject to 'transmitter active' rule.  */
0649         write_zsreg(channel, R15, up->curregs[R15]);
0650     }
0651 }
0652 
0653 /* The port lock is not held.  */
0654 static void ip22zilog_break_ctl(struct uart_port *port, int break_state)
0655 {
0656     struct uart_ip22zilog_port *up =
0657         container_of(port, struct uart_ip22zilog_port, port);
0658     struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
0659     unsigned char set_bits, clear_bits, new_reg;
0660     unsigned long flags;
0661 
0662     set_bits = clear_bits = 0;
0663 
0664     if (break_state)
0665         set_bits |= SND_BRK;
0666     else
0667         clear_bits |= SND_BRK;
0668 
0669     spin_lock_irqsave(&port->lock, flags);
0670 
0671     new_reg = (up->curregs[R5] | set_bits) & ~clear_bits;
0672     if (new_reg != up->curregs[R5]) {
0673         up->curregs[R5] = new_reg;
0674 
0675         /* NOTE: Not subject to 'transmitter active' rule.  */
0676         write_zsreg(channel, R5, up->curregs[R5]);
0677     }
0678 
0679     spin_unlock_irqrestore(&port->lock, flags);
0680 }
0681 
0682 static void __ip22zilog_reset(struct uart_ip22zilog_port *up)
0683 {
0684     struct zilog_channel *channel;
0685     int i;
0686 
0687     if (up->flags & IP22ZILOG_FLAG_RESET_DONE)
0688         return;
0689 
0690     /* Let pending transmits finish.  */
0691     channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
0692     for (i = 0; i < 1000; i++) {
0693         unsigned char stat = read_zsreg(channel, R1);
0694         if (stat & ALL_SNT)
0695             break;
0696         udelay(100);
0697     }
0698 
0699     if (!ZS_IS_CHANNEL_A(up)) {
0700         up++;
0701         channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
0702     }
0703     write_zsreg(channel, R9, FHWRES);
0704     ZSDELAY_LONG();
0705     (void) read_zsreg(channel, R0);
0706 
0707     up->flags |= IP22ZILOG_FLAG_RESET_DONE;
0708     up->next->flags |= IP22ZILOG_FLAG_RESET_DONE;
0709 }
0710 
0711 static void __ip22zilog_startup(struct uart_ip22zilog_port *up)
0712 {
0713     struct zilog_channel *channel;
0714 
0715     channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
0716 
0717     __ip22zilog_reset(up);
0718 
0719     __load_zsregs(channel, up->curregs);
0720     /* set master interrupt enable */
0721     write_zsreg(channel, R9, up->curregs[R9]);
0722     up->prev_status = readb(&channel->control);
0723 
0724     /* Enable receiver and transmitter.  */
0725     up->curregs[R3] |= RxENAB;
0726     up->curregs[R5] |= TxENAB;
0727 
0728     up->curregs[R1] |= EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
0729     ip22zilog_maybe_update_regs(up, channel);
0730 }
0731 
0732 static int ip22zilog_startup(struct uart_port *port)
0733 {
0734     struct uart_ip22zilog_port *up = UART_ZILOG(port);
0735     unsigned long flags;
0736 
0737     if (ZS_IS_CONS(up))
0738         return 0;
0739 
0740     spin_lock_irqsave(&port->lock, flags);
0741     __ip22zilog_startup(up);
0742     spin_unlock_irqrestore(&port->lock, flags);
0743     return 0;
0744 }
0745 
0746 /*
0747  * The test for ZS_IS_CONS is explained by the following e-mail:
0748  *****
0749  * From: Russell King <rmk@arm.linux.org.uk>
0750  * Date: Sun, 8 Dec 2002 10:18:38 +0000
0751  *
0752  * On Sun, Dec 08, 2002 at 02:43:36AM -0500, Pete Zaitcev wrote:
0753  * > I boot my 2.5 boxes using "console=ttyS0,9600" argument,
0754  * > and I noticed that something is not right with reference
0755  * > counting in this case. It seems that when the console
0756  * > is open by kernel initially, this is not accounted
0757  * > as an open, and uart_startup is not called.
0758  *
0759  * That is correct.  We are unable to call uart_startup when the serial
0760  * console is initialised because it may need to allocate memory (as
0761  * request_irq does) and the memory allocators may not have been
0762  * initialised.
0763  *
0764  * 1. initialise the port into a state where it can send characters in the
0765  *    console write method.
0766  *
0767  * 2. don't do the actual hardware shutdown in your shutdown() method (but
0768  *    do the normal software shutdown - ie, free irqs etc)
0769  *****
0770  */
0771 static void ip22zilog_shutdown(struct uart_port *port)
0772 {
0773     struct uart_ip22zilog_port *up = UART_ZILOG(port);
0774     struct zilog_channel *channel;
0775     unsigned long flags;
0776 
0777     if (ZS_IS_CONS(up))
0778         return;
0779 
0780     spin_lock_irqsave(&port->lock, flags);
0781 
0782     channel = ZILOG_CHANNEL_FROM_PORT(port);
0783 
0784     /* Disable receiver and transmitter.  */
0785     up->curregs[R3] &= ~RxENAB;
0786     up->curregs[R5] &= ~TxENAB;
0787 
0788     /* Disable all interrupts and BRK assertion.  */
0789     up->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
0790     up->curregs[R5] &= ~SND_BRK;
0791     ip22zilog_maybe_update_regs(up, channel);
0792 
0793     spin_unlock_irqrestore(&port->lock, flags);
0794 }
0795 
0796 /* Shared by TTY driver and serial console setup.  The port lock is held
0797  * and local interrupts are disabled.
0798  */
0799 static void
0800 ip22zilog_convert_to_zs(struct uart_ip22zilog_port *up, unsigned int cflag,
0801                unsigned int iflag, int brg)
0802 {
0803 
0804     up->curregs[R10] = NRZ;
0805     up->curregs[R11] = TCBR | RCBR;
0806 
0807     /* Program BAUD and clock source. */
0808     up->curregs[R4] &= ~XCLK_MASK;
0809     up->curregs[R4] |= X16CLK;
0810     up->curregs[R12] = brg & 0xff;
0811     up->curregs[R13] = (brg >> 8) & 0xff;
0812     up->curregs[R14] = BRENAB;
0813 
0814     /* Character size, stop bits, and parity. */
0815     up->curregs[3] &= ~RxN_MASK;
0816     up->curregs[5] &= ~TxN_MASK;
0817     switch (cflag & CSIZE) {
0818     case CS5:
0819         up->curregs[3] |= Rx5;
0820         up->curregs[5] |= Tx5;
0821         up->parity_mask = 0x1f;
0822         break;
0823     case CS6:
0824         up->curregs[3] |= Rx6;
0825         up->curregs[5] |= Tx6;
0826         up->parity_mask = 0x3f;
0827         break;
0828     case CS7:
0829         up->curregs[3] |= Rx7;
0830         up->curregs[5] |= Tx7;
0831         up->parity_mask = 0x7f;
0832         break;
0833     case CS8:
0834     default:
0835         up->curregs[3] |= Rx8;
0836         up->curregs[5] |= Tx8;
0837         up->parity_mask = 0xff;
0838         break;
0839     }
0840     up->curregs[4] &= ~0x0c;
0841     if (cflag & CSTOPB)
0842         up->curregs[4] |= SB2;
0843     else
0844         up->curregs[4] |= SB1;
0845     if (cflag & PARENB)
0846         up->curregs[4] |= PAR_ENAB;
0847     else
0848         up->curregs[4] &= ~PAR_ENAB;
0849     if (!(cflag & PARODD))
0850         up->curregs[4] |= PAR_EVEN;
0851     else
0852         up->curregs[4] &= ~PAR_EVEN;
0853 
0854     up->port.read_status_mask = Rx_OVR;
0855     if (iflag & INPCK)
0856         up->port.read_status_mask |= CRC_ERR | PAR_ERR;
0857     if (iflag & (IGNBRK | BRKINT | PARMRK))
0858         up->port.read_status_mask |= BRK_ABRT;
0859 
0860     up->port.ignore_status_mask = 0;
0861     if (iflag & IGNPAR)
0862         up->port.ignore_status_mask |= CRC_ERR | PAR_ERR;
0863     if (iflag & IGNBRK) {
0864         up->port.ignore_status_mask |= BRK_ABRT;
0865         if (iflag & IGNPAR)
0866             up->port.ignore_status_mask |= Rx_OVR;
0867     }
0868 
0869     if ((cflag & CREAD) == 0)
0870         up->port.ignore_status_mask = 0xff;
0871 }
0872 
0873 /* The port lock is not held.  */
0874 static void
0875 ip22zilog_set_termios(struct uart_port *port, struct ktermios *termios,
0876               struct ktermios *old)
0877 {
0878     struct uart_ip22zilog_port *up =
0879         container_of(port, struct uart_ip22zilog_port, port);
0880     unsigned long flags;
0881     int baud, brg;
0882 
0883     baud = uart_get_baud_rate(port, termios, old, 1200, 76800);
0884 
0885     spin_lock_irqsave(&up->port.lock, flags);
0886 
0887     brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
0888 
0889     ip22zilog_convert_to_zs(up, termios->c_cflag, termios->c_iflag, brg);
0890 
0891     if (UART_ENABLE_MS(&up->port, termios->c_cflag))
0892         up->flags |= IP22ZILOG_FLAG_MODEM_STATUS;
0893     else
0894         up->flags &= ~IP22ZILOG_FLAG_MODEM_STATUS;
0895 
0896     ip22zilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port));
0897     uart_update_timeout(port, termios->c_cflag, baud);
0898 
0899     spin_unlock_irqrestore(&up->port.lock, flags);
0900 }
0901 
0902 static const char *ip22zilog_type(struct uart_port *port)
0903 {
0904     return "IP22-Zilog";
0905 }
0906 
0907 /* We do not request/release mappings of the registers here, this
0908  * happens at early serial probe time.
0909  */
0910 static void ip22zilog_release_port(struct uart_port *port)
0911 {
0912 }
0913 
0914 static int ip22zilog_request_port(struct uart_port *port)
0915 {
0916     return 0;
0917 }
0918 
0919 /* These do not need to do anything interesting either.  */
0920 static void ip22zilog_config_port(struct uart_port *port, int flags)
0921 {
0922 }
0923 
0924 /* We do not support letting the user mess with the divisor, IRQ, etc. */
0925 static int ip22zilog_verify_port(struct uart_port *port, struct serial_struct *ser)
0926 {
0927     return -EINVAL;
0928 }
0929 
0930 static const struct uart_ops ip22zilog_pops = {
0931     .tx_empty   =   ip22zilog_tx_empty,
0932     .set_mctrl  =   ip22zilog_set_mctrl,
0933     .get_mctrl  =   ip22zilog_get_mctrl,
0934     .stop_tx    =   ip22zilog_stop_tx,
0935     .start_tx   =   ip22zilog_start_tx,
0936     .stop_rx    =   ip22zilog_stop_rx,
0937     .enable_ms  =   ip22zilog_enable_ms,
0938     .break_ctl  =   ip22zilog_break_ctl,
0939     .startup    =   ip22zilog_startup,
0940     .shutdown   =   ip22zilog_shutdown,
0941     .set_termios    =   ip22zilog_set_termios,
0942     .type       =   ip22zilog_type,
0943     .release_port   =   ip22zilog_release_port,
0944     .request_port   =   ip22zilog_request_port,
0945     .config_port    =   ip22zilog_config_port,
0946     .verify_port    =   ip22zilog_verify_port,
0947 };
0948 
0949 static struct uart_ip22zilog_port *ip22zilog_port_table;
0950 static struct zilog_layout **ip22zilog_chip_regs;
0951 
0952 static struct uart_ip22zilog_port *ip22zilog_irq_chain;
0953 static int zilog_irq = -1;
0954 
0955 static void * __init alloc_one_table(unsigned long size)
0956 {
0957     return kzalloc(size, GFP_KERNEL);
0958 }
0959 
0960 static void __init ip22zilog_alloc_tables(void)
0961 {
0962     ip22zilog_port_table = (struct uart_ip22zilog_port *)
0963         alloc_one_table(NUM_CHANNELS * sizeof(struct uart_ip22zilog_port));
0964     ip22zilog_chip_regs = (struct zilog_layout **)
0965         alloc_one_table(NUM_IP22ZILOG * sizeof(struct zilog_layout *));
0966 
0967     if (ip22zilog_port_table == NULL || ip22zilog_chip_regs == NULL) {
0968         panic("IP22-Zilog: Cannot allocate IP22-Zilog tables.");
0969     }
0970 }
0971 
0972 /* Get the address of the registers for IP22-Zilog instance CHIP.  */
0973 static struct zilog_layout * __init get_zs(int chip)
0974 {
0975     unsigned long base;
0976 
0977     if (chip < 0 || chip >= NUM_IP22ZILOG) {
0978         panic("IP22-Zilog: Illegal chip number %d in get_zs.", chip);
0979     }
0980 
0981     /* Not probe-able, hard code it. */
0982     base = (unsigned long) &sgioc->uart;
0983 
0984     zilog_irq = SGI_SERIAL_IRQ;
0985     request_mem_region(base, 8, "IP22-Zilog");
0986 
0987     return (struct zilog_layout *) base;
0988 }
0989 
0990 #define ZS_PUT_CHAR_MAX_DELAY   2000    /* 10 ms */
0991 
0992 #ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLE
0993 static void ip22zilog_put_char(struct uart_port *port, unsigned char ch)
0994 {
0995     struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
0996     int loops = ZS_PUT_CHAR_MAX_DELAY;
0997 
0998     /* This is a timed polling loop so do not switch the explicit
0999      * udelay with ZSDELAY as that is a NOP on some platforms.  -DaveM
1000      */
1001     do {
1002         unsigned char val = readb(&channel->control);
1003         if (val & Tx_BUF_EMP) {
1004             ZSDELAY();
1005             break;
1006         }
1007         udelay(5);
1008     } while (--loops);
1009 
1010     writeb(ch, &channel->data);
1011     ZSDELAY();
1012     ZS_WSYNC(channel);
1013 }
1014 
1015 static void
1016 ip22zilog_console_write(struct console *con, const char *s, unsigned int count)
1017 {
1018     struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index];
1019     unsigned long flags;
1020 
1021     spin_lock_irqsave(&up->port.lock, flags);
1022     uart_console_write(&up->port, s, count, ip22zilog_put_char);
1023     udelay(2);
1024     spin_unlock_irqrestore(&up->port.lock, flags);
1025 }
1026 
1027 static int __init ip22zilog_console_setup(struct console *con, char *options)
1028 {
1029     struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index];
1030     unsigned long flags;
1031     int baud = 9600, bits = 8;
1032     int parity = 'n';
1033     int flow = 'n';
1034 
1035     up->flags |= IP22ZILOG_FLAG_IS_CONS;
1036 
1037     printk(KERN_INFO "Console: ttyS%d (IP22-Zilog)\n", con->index);
1038 
1039     spin_lock_irqsave(&up->port.lock, flags);
1040 
1041     up->curregs[R15] |= BRKIE;
1042 
1043     __ip22zilog_startup(up);
1044 
1045     spin_unlock_irqrestore(&up->port.lock, flags);
1046 
1047     if (options)
1048         uart_parse_options(options, &baud, &parity, &bits, &flow);
1049     return uart_set_options(&up->port, con, baud, parity, bits, flow);
1050 }
1051 
1052 static struct uart_driver ip22zilog_reg;
1053 
1054 static struct console ip22zilog_console = {
1055     .name   =   "ttyS",
1056     .write  =   ip22zilog_console_write,
1057     .device =   uart_console_device,
1058     .setup  =   ip22zilog_console_setup,
1059     .flags  =   CON_PRINTBUFFER,
1060     .index  =   -1,
1061     .data   =   &ip22zilog_reg,
1062 };
1063 #endif /* CONFIG_SERIAL_IP22_ZILOG_CONSOLE */
1064 
1065 static struct uart_driver ip22zilog_reg = {
1066     .owner      = THIS_MODULE,
1067     .driver_name    = "serial",
1068     .dev_name   = "ttyS",
1069     .major      = TTY_MAJOR,
1070     .minor      = 64,
1071     .nr     = NUM_CHANNELS,
1072 #ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLE
1073     .cons       = &ip22zilog_console,
1074 #endif
1075 };
1076 
1077 static void __init ip22zilog_prepare(void)
1078 {
1079     unsigned char sysrq_on = IS_ENABLED(CONFIG_SERIAL_IP22_ZILOG_CONSOLE);
1080     struct uart_ip22zilog_port *up;
1081     struct zilog_layout *rp;
1082     int channel, chip;
1083 
1084     /*
1085      * Temporary fix.
1086      */
1087     for (channel = 0; channel < NUM_CHANNELS; channel++)
1088         spin_lock_init(&ip22zilog_port_table[channel].port.lock);
1089 
1090     ip22zilog_irq_chain = &ip22zilog_port_table[NUM_CHANNELS - 1];
1091         up = &ip22zilog_port_table[0];
1092     for (channel = NUM_CHANNELS - 1 ; channel > 0; channel--)
1093         up[channel].next = &up[channel - 1];
1094     up[channel].next = NULL;
1095 
1096     for (chip = 0; chip < NUM_IP22ZILOG; chip++) {
1097         if (!ip22zilog_chip_regs[chip]) {
1098             ip22zilog_chip_regs[chip] = rp = get_zs(chip);
1099 
1100             up[(chip * 2) + 0].port.membase = (char *) &rp->channelB;
1101             up[(chip * 2) + 1].port.membase = (char *) &rp->channelA;
1102 
1103             /* In theory mapbase is the physical address ...  */
1104             up[(chip * 2) + 0].port.mapbase =
1105                 (unsigned long) ioremap((unsigned long) &rp->channelB, 8);
1106             up[(chip * 2) + 1].port.mapbase =
1107                 (unsigned long) ioremap((unsigned long) &rp->channelA, 8);
1108         }
1109 
1110         /* Channel A */
1111         up[(chip * 2) + 0].port.iotype = UPIO_MEM;
1112         up[(chip * 2) + 0].port.irq = zilog_irq;
1113         up[(chip * 2) + 0].port.uartclk = ZS_CLOCK;
1114         up[(chip * 2) + 0].port.fifosize = 1;
1115         up[(chip * 2) + 0].port.has_sysrq = sysrq_on;
1116         up[(chip * 2) + 0].port.ops = &ip22zilog_pops;
1117         up[(chip * 2) + 0].port.type = PORT_IP22ZILOG;
1118         up[(chip * 2) + 0].port.flags = 0;
1119         up[(chip * 2) + 0].port.line = (chip * 2) + 0;
1120         up[(chip * 2) + 0].flags = 0;
1121 
1122         /* Channel B */
1123         up[(chip * 2) + 1].port.iotype = UPIO_MEM;
1124         up[(chip * 2) + 1].port.irq = zilog_irq;
1125         up[(chip * 2) + 1].port.uartclk = ZS_CLOCK;
1126         up[(chip * 2) + 1].port.fifosize = 1;
1127         up[(chip * 2) + 1].port.has_sysrq = sysrq_on;
1128         up[(chip * 2) + 1].port.ops = &ip22zilog_pops;
1129         up[(chip * 2) + 1].port.type = PORT_IP22ZILOG;
1130         up[(chip * 2) + 1].port.line = (chip * 2) + 1;
1131         up[(chip * 2) + 1].flags |= IP22ZILOG_FLAG_IS_CHANNEL_A;
1132     }
1133 
1134     for (channel = 0; channel < NUM_CHANNELS; channel++) {
1135         struct uart_ip22zilog_port *up = &ip22zilog_port_table[channel];
1136         int brg;
1137 
1138         /* Normal serial TTY. */
1139         up->parity_mask = 0xff;
1140         up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
1141         up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
1142         up->curregs[R3] = RxENAB | Rx8;
1143         up->curregs[R5] = TxENAB | Tx8;
1144         up->curregs[R9] = NV | MIE;
1145         up->curregs[R10] = NRZ;
1146         up->curregs[R11] = TCBR | RCBR;
1147         brg = BPS_TO_BRG(9600, ZS_CLOCK / ZS_CLOCK_DIVISOR);
1148         up->curregs[R12] = (brg & 0xff);
1149         up->curregs[R13] = (brg >> 8) & 0xff;
1150         up->curregs[R14] = BRENAB;
1151     }
1152 }
1153 
1154 static int __init ip22zilog_ports_init(void)
1155 {
1156     int ret;
1157 
1158     printk(KERN_INFO "Serial: IP22 Zilog driver (%d chips).\n", NUM_IP22ZILOG);
1159 
1160     ip22zilog_prepare();
1161 
1162     if (request_irq(zilog_irq, ip22zilog_interrupt, 0,
1163             "IP22-Zilog", ip22zilog_irq_chain)) {
1164         panic("IP22-Zilog: Unable to register zs interrupt handler.\n");
1165     }
1166 
1167     ret = uart_register_driver(&ip22zilog_reg);
1168     if (ret == 0) {
1169         int i;
1170 
1171         for (i = 0; i < NUM_CHANNELS; i++) {
1172             struct uart_ip22zilog_port *up = &ip22zilog_port_table[i];
1173 
1174             uart_add_one_port(&ip22zilog_reg, &up->port);
1175         }
1176     }
1177 
1178     return ret;
1179 }
1180 
1181 static int __init ip22zilog_init(void)
1182 {
1183     /* IP22 Zilog setup is hard coded, no probing to do.  */
1184     ip22zilog_alloc_tables();
1185     ip22zilog_ports_init();
1186 
1187     return 0;
1188 }
1189 
1190 static void __exit ip22zilog_exit(void)
1191 {
1192     int i;
1193     struct uart_ip22zilog_port *up;
1194 
1195     for (i = 0; i < NUM_CHANNELS; i++) {
1196         up = &ip22zilog_port_table[i];
1197 
1198         uart_remove_one_port(&ip22zilog_reg, &up->port);
1199     }
1200 
1201     /* Free IO mem */
1202     up = &ip22zilog_port_table[0];
1203     for (i = 0; i < NUM_IP22ZILOG; i++) {
1204         if (up[(i * 2) + 0].port.mapbase) {
1205            iounmap((void*)up[(i * 2) + 0].port.mapbase);
1206            up[(i * 2) + 0].port.mapbase = 0;
1207         }
1208         if (up[(i * 2) + 1].port.mapbase) {
1209             iounmap((void*)up[(i * 2) + 1].port.mapbase);
1210             up[(i * 2) + 1].port.mapbase = 0;
1211         }
1212     }
1213 
1214     uart_unregister_driver(&ip22zilog_reg);
1215 }
1216 
1217 module_init(ip22zilog_init);
1218 module_exit(ip22zilog_exit);
1219 
1220 /* David wrote it but I'm to blame for the bugs ...  */
1221 MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
1222 MODULE_DESCRIPTION("SGI Zilog serial port driver");
1223 MODULE_LICENSE("GPL");