linux-bk/drivers/serial/ip22zilog.c
<<
>>
Prefs
   1/*
   2 * Driver for Zilog serial chips found on SGI workstations and
   3 * servers.  This driver could actually be made more generic.
   4 *
   5 * This is based on the drivers/serial/sunzilog.c code as of 2.6.0-test7 and the
   6 * old drivers/sgi/char/sgiserial.c code which itself is based of the original
   7 * drivers/sbus/char/zs.c code.  A lot of code has been simply moved over
   8 * directly from there but much has been rewritten.  Credits therefore go out
   9 * to David S. Miller, Eddie C. Dost, Pete Zaitcev, Ted Ts'o and Alex Buell
  10 * for their work there.
  11 *
  12 *  Copyright (C) 2002 Ralf Baechle (ralf@linux-mips.org)
  13 *  Copyright (C) 2002 David S. Miller (davem@redhat.com)
  14 */
  15#include <linux/config.h>
  16#include <linux/module.h>
  17#include <linux/kernel.h>
  18#include <linux/sched.h>
  19#include <linux/errno.h>
  20#include <linux/delay.h>
  21#include <linux/tty.h>
  22#include <linux/tty_flip.h>
  23#include <linux/major.h>
  24#include <linux/string.h>
  25#include <linux/ptrace.h>
  26#include <linux/ioport.h>
  27#include <linux/slab.h>
  28#include <linux/circ_buf.h>
  29#include <linux/serial.h>
  30#include <linux/sysrq.h>
  31#include <linux/console.h>
  32#include <linux/spinlock.h>
  33#include <linux/init.h>
  34
  35#include <asm/io.h>
  36#include <asm/irq.h>
  37#include <asm/sgialib.h>
  38#include <asm/sgi/ioc.h>
  39#include <asm/sgi/hpc3.h>
  40#include <asm/sgi/ip22.h>
  41
  42#if defined(CONFIG_SERIAL_IP22_ZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
  43#define SUPPORT_SYSRQ
  44#endif
  45
  46#include <linux/serial_core.h>
  47
  48#include "ip22zilog.h"
  49
  50void ip22_do_break(void);
  51
  52/*
  53 * On IP22 we need to delay after register accesses but we do not need to
  54 * flush writes.
  55 */
  56#define ZSDELAY()               udelay(5)
  57#define ZSDELAY_LONG()          udelay(20)
  58#define ZS_WSYNC(channel)       do { } while (0)
  59
  60#define NUM_IP22ZILOG           1
  61#define NUM_CHANNELS            (NUM_IP22ZILOG * 2)
  62
  63#define ZS_CLOCK                3672000 /* Zilog input clock rate. */
  64#define ZS_CLOCK_DIVISOR        16      /* Divisor this driver uses. */
  65
  66/*
  67 * We wrap our port structure around the generic uart_port.
  68 */
  69struct uart_ip22zilog_port {
  70        struct uart_port                port;
  71
  72        /* IRQ servicing chain.  */
  73        struct uart_ip22zilog_port      *next;
  74
  75        /* Current values of Zilog write registers.  */
  76        unsigned char                   curregs[NUM_ZSREGS];
  77
  78        unsigned int                    flags;
  79#define IP22ZILOG_FLAG_IS_CONS          0x00000004
  80#define IP22ZILOG_FLAG_IS_KGDB          0x00000008
  81#define IP22ZILOG_FLAG_MODEM_STATUS     0x00000010
  82#define IP22ZILOG_FLAG_IS_CHANNEL_A     0x00000020
  83#define IP22ZILOG_FLAG_REGS_HELD        0x00000040
  84#define IP22ZILOG_FLAG_TX_STOPPED       0x00000080
  85#define IP22ZILOG_FLAG_TX_ACTIVE        0x00000100
  86
  87        unsigned int                    cflag;
  88
  89        /* L1-A keyboard break state.  */
  90        int                             kbd_id;
  91        int                             l1_down;
  92
  93        unsigned char                   parity_mask;
  94        unsigned char                   prev_status;
  95};
  96
  97#define ZILOG_CHANNEL_FROM_PORT(PORT)   ((struct zilog_channel *)((PORT)->membase))
  98#define UART_ZILOG(PORT)                ((struct uart_ip22zilog_port *)(PORT))
  99#define IP22ZILOG_GET_CURR_REG(PORT, REGNUM)            \
 100        (UART_ZILOG(PORT)->curregs[REGNUM])
 101#define IP22ZILOG_SET_CURR_REG(PORT, REGNUM, REGVAL)    \
 102        ((UART_ZILOG(PORT)->curregs[REGNUM]) = (REGVAL))
 103#define ZS_IS_CONS(UP)  ((UP)->flags & IP22ZILOG_FLAG_IS_CONS)
 104#define ZS_IS_KGDB(UP)  ((UP)->flags & IP22ZILOG_FLAG_IS_KGDB)
 105#define ZS_WANTS_MODEM_STATUS(UP)       ((UP)->flags & IP22ZILOG_FLAG_MODEM_STATUS)
 106#define ZS_IS_CHANNEL_A(UP)     ((UP)->flags & IP22ZILOG_FLAG_IS_CHANNEL_A)
 107#define ZS_REGS_HELD(UP)        ((UP)->flags & IP22ZILOG_FLAG_REGS_HELD)
 108#define ZS_TX_STOPPED(UP)       ((UP)->flags & IP22ZILOG_FLAG_TX_STOPPED)
 109#define ZS_TX_ACTIVE(UP)        ((UP)->flags & IP22ZILOG_FLAG_TX_ACTIVE)
 110
 111/* Reading and writing Zilog8530 registers.  The delays are to make this
 112 * driver work on the IP22 which needs a settling delay after each chip
 113 * register access, other machines handle this in hardware via auxiliary
 114 * flip-flops which implement the settle time we do in software.
 115 *
 116 * The port lock must be held and local IRQs must be disabled
 117 * when {read,write}_zsreg is invoked.
 118 */
 119static unsigned char read_zsreg(struct zilog_channel *channel,
 120                                unsigned char reg)
 121{
 122        unsigned char retval;
 123
 124        writeb(reg, &channel->control);
 125        ZSDELAY();
 126        retval = readb(&channel->control);
 127        ZSDELAY();
 128
 129        return retval;
 130}
 131
 132static void write_zsreg(struct zilog_channel *channel,
 133                        unsigned char reg, unsigned char value)
 134{
 135        writeb(reg, &channel->control);
 136        ZSDELAY();
 137        writeb(value, &channel->control);
 138        ZSDELAY();
 139}
 140
 141static void ip22zilog_clear_fifo(struct zilog_channel *channel)
 142{
 143        int i;
 144
 145        for (i = 0; i < 32; i++) {
 146                unsigned char regval;
 147
 148                regval = readb(&channel->control);
 149                ZSDELAY();
 150                if (regval & Rx_CH_AV)
 151                        break;
 152
 153                regval = read_zsreg(channel, R1);
 154                readb(&channel->data);
 155                ZSDELAY();
 156
 157                if (regval & (PAR_ERR | Rx_OVR | CRC_ERR)) {
 158                        writeb(ERR_RES, &channel->control);
 159                        ZSDELAY();
 160                        ZS_WSYNC(channel);
 161                }
 162        }
 163}
 164
 165/* This function must only be called when the TX is not busy.  The UART
 166 * port lock must be held and local interrupts disabled.
 167 */
 168static void __load_zsregs(struct zilog_channel *channel, unsigned char *regs)
 169{
 170        int i;
 171
 172        /* Let pending transmits finish.  */
 173        for (i = 0; i < 1000; i++) {
 174                unsigned char stat = read_zsreg(channel, R1);
 175                if (stat & ALL_SNT)
 176                        break;
 177                udelay(100);
 178        }
 179
 180        writeb(ERR_RES, &channel->control);
 181        ZSDELAY();
 182        ZS_WSYNC(channel);
 183
 184        ip22zilog_clear_fifo(channel);
 185
 186        /* Disable all interrupts.  */
 187        write_zsreg(channel, R1,
 188                    regs[R1] & ~(RxINT_MASK | TxINT_ENAB | EXT_INT_ENAB));
 189
 190        /* Set parity, sync config, stop bits, and clock divisor.  */
 191        write_zsreg(channel, R4, regs[R4]);
 192
 193        /* Set misc. TX/RX control bits.  */
 194        write_zsreg(channel, R10, regs[R10]);
 195
 196        /* Set TX/RX controls sans the enable bits.  */
 197        write_zsreg(channel, R3, regs[R3] & ~RxENAB);
 198        write_zsreg(channel, R5, regs[R5] & ~TxENAB);
 199
 200        /* Synchronous mode config.  */
 201        write_zsreg(channel, R6, regs[R6]);
 202        write_zsreg(channel, R7, regs[R7]);
 203
 204        /* Don't mess with the interrupt vector (R2, unused by us) and
 205         * master interrupt control (R9).  We make sure this is setup
 206         * properly at probe time then never touch it again.
 207         */
 208
 209        /* Disable baud generator.  */
 210        write_zsreg(channel, R14, regs[R14] & ~BRENAB);
 211
 212        /* Clock mode control.  */
 213        write_zsreg(channel, R11, regs[R11]);
 214
 215        /* Lower and upper byte of baud rate generator divisor.  */
 216        write_zsreg(channel, R12, regs[R12]);
 217        write_zsreg(channel, R13, regs[R13]);
 218        
 219        /* Now rewrite R14, with BRENAB (if set).  */
 220        write_zsreg(channel, R14, regs[R14]);
 221
 222        /* External status interrupt control.  */
 223        write_zsreg(channel, R15, regs[R15]);
 224
 225        /* Reset external status interrupts.  */
 226        write_zsreg(channel, R0, RES_EXT_INT);
 227        write_zsreg(channel, R0, RES_EXT_INT);
 228
 229        /* Rewrite R3/R5, this time without enables masked.  */
 230        write_zsreg(channel, R3, regs[R3]);
 231        write_zsreg(channel, R5, regs[R5]);
 232
 233        /* Rewrite R1, this time without IRQ enabled masked.  */
 234        write_zsreg(channel, R1, regs[R1]);
 235}
 236
 237/* Reprogram the Zilog channel HW registers with the copies found in the
 238 * software state struct.  If the transmitter is busy, we defer this update
 239 * until the next TX complete interrupt.  Else, we do it right now.
 240 *
 241 * The UART port lock must be held and local interrupts disabled.
 242 */
 243static void ip22zilog_maybe_update_regs(struct uart_ip22zilog_port *up,
 244                                       struct zilog_channel *channel)
 245{
 246        if (!ZS_REGS_HELD(up)) {
 247                if (ZS_TX_ACTIVE(up)) {
 248                        up->flags |= IP22ZILOG_FLAG_REGS_HELD;
 249                } else {
 250                        __load_zsregs(channel, up->curregs);
 251                }
 252        }
 253}
 254
 255static void ip22zilog_receive_chars(struct uart_ip22zilog_port *up,
 256                                   struct zilog_channel *channel,
 257                                   struct pt_regs *regs)
 258{
 259        struct tty_struct *tty = up->port.info->tty;    /* XXX info==NULL? */
 260
 261        while (1) {
 262                unsigned char ch, r1;
 263
 264                if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
 265                        tty->flip.work.func((void *)tty);
 266                        if (tty->flip.count >= TTY_FLIPBUF_SIZE)
 267                                return;         /* XXX Ignores SysRq when we need it most. Fix. */
 268                }
 269
 270                r1 = read_zsreg(channel, R1);
 271                if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
 272                        writeb(ERR_RES, &channel->control);
 273                        ZSDELAY();
 274                        ZS_WSYNC(channel);
 275                }
 276
 277                ch = readb(&channel->control);
 278                ZSDELAY();
 279
 280                /* This funny hack depends upon BRK_ABRT not interfering
 281                 * with the other bits we care about in R1.
 282                 */
 283                if (ch & BRK_ABRT)
 284                        r1 |= BRK_ABRT;
 285
 286                ch = readb(&channel->data);
 287                ZSDELAY();
 288
 289                ch &= up->parity_mask;
 290
 291                if (ZS_IS_CONS(up) && (r1 & BRK_ABRT)) {
 292                        /* Wait for BREAK to deassert to avoid potentially
 293                         * confusing the PROM.
 294                         */
 295                        while (1) {
 296                                ch = readb(&channel->control);
 297                                ZSDELAY();
 298                                if (!(ch & BRK_ABRT))
 299                                        break;
 300                        }
 301                        ip22_do_break();
 302                        return;
 303                }
 304
 305                /* A real serial line, record the character and status.  */
 306                *tty->flip.char_buf_ptr = ch;
 307                *tty->flip.flag_buf_ptr = TTY_NORMAL;
 308                up->port.icount.rx++;
 309                if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) {
 310                        if (r1 & BRK_ABRT) {
 311                                r1 &= ~(PAR_ERR | CRC_ERR);
 312                                up->port.icount.brk++;
 313                                if (uart_handle_break(&up->port))
 314                                        goto next_char;
 315                        }
 316                        else if (r1 & PAR_ERR)
 317                                up->port.icount.parity++;
 318                        else if (r1 & CRC_ERR)
 319                                up->port.icount.frame++;
 320                        if (r1 & Rx_OVR)
 321                                up->port.icount.overrun++;
 322                        r1 &= up->port.read_status_mask;
 323                        if (r1 & BRK_ABRT)
 324                                *tty->flip.flag_buf_ptr = TTY_BREAK;
 325                        else if (r1 & PAR_ERR)
 326                                *tty->flip.flag_buf_ptr = TTY_PARITY;
 327                        else if (r1 & CRC_ERR)
 328                                *tty->flip.flag_buf_ptr = TTY_FRAME;
 329                }
 330                if (uart_handle_sysrq_char(&up->port, ch, regs))
 331                        goto next_char;
 332
 333                if (up->port.ignore_status_mask == 0xff ||
 334                    (r1 & up->port.ignore_status_mask) == 0) {
 335                        tty->flip.flag_buf_ptr++;
 336                        tty->flip.char_buf_ptr++;
 337                        tty->flip.count++;
 338                }
 339                if ((r1 & Rx_OVR) &&
 340                    tty->flip.count < TTY_FLIPBUF_SIZE) {
 341                        *tty->flip.flag_buf_ptr = TTY_OVERRUN;
 342                        tty->flip.flag_buf_ptr++;
 343                        tty->flip.char_buf_ptr++;
 344                        tty->flip.count++;
 345                }
 346        next_char:
 347                ch = readb(&channel->control);
 348                ZSDELAY();
 349                if (!(ch & Rx_CH_AV))
 350                        break;
 351        }
 352
 353        tty_flip_buffer_push(tty);
 354}
 355
 356static void ip22zilog_status_handle(struct uart_ip22zilog_port *up,
 357                                   struct zilog_channel *channel,
 358                                   struct pt_regs *regs)
 359{
 360        unsigned char status;
 361
 362        status = readb(&channel->control);
 363        ZSDELAY();
 364
 365        writeb(RES_EXT_INT, &channel->control);
 366        ZSDELAY();
 367        ZS_WSYNC(channel);
 368
 369        if (ZS_WANTS_MODEM_STATUS(up)) {
 370                if (status & SYNC)
 371                        up->port.icount.dsr++;
 372
 373                /* The Zilog just gives us an interrupt when DCD/CTS/etc. change.
 374                 * But it does not tell us which bit has changed, we have to keep
 375                 * track of this ourselves.
 376                 */
 377                if ((status & DCD) ^ up->prev_status)
 378                        uart_handle_dcd_change(&up->port,
 379                                               (status & DCD));
 380                if ((status & CTS) ^ up->prev_status)
 381                        uart_handle_cts_change(&up->port,
 382                                               (status & CTS));
 383
 384                wake_up_interruptible(&up->port.info->delta_msr_wait);
 385        }
 386
 387        up->prev_status = status;
 388}
 389
 390static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up,
 391                                    struct zilog_channel *channel)
 392{
 393        struct circ_buf *xmit;
 394
 395        if (ZS_IS_CONS(up)) {
 396                unsigned char status = readb(&channel->control);
 397                ZSDELAY();
 398
 399                /* TX still busy?  Just wait for the next TX done interrupt.
 400                 *
 401                 * It can occur because of how we do serial console writes.  It would
 402                 * be nice to transmit console writes just like we normally would for
 403                 * a TTY line. (ie. buffered and TX interrupt driven).  That is not
 404                 * easy because console writes cannot sleep.  One solution might be
 405                 * to poll on enough port->xmit space becomming free.  -DaveM
 406                 */
 407                if (!(status & Tx_BUF_EMP))
 408                        return;
 409        }
 410
 411        up->flags &= ~IP22ZILOG_FLAG_TX_ACTIVE;
 412
 413        if (ZS_REGS_HELD(up)) {
 414                __load_zsregs(channel, up->curregs);
 415                up->flags &= ~IP22ZILOG_FLAG_REGS_HELD;
 416        }
 417
 418        if (ZS_TX_STOPPED(up)) {
 419                up->flags &= ~IP22ZILOG_FLAG_TX_STOPPED;
 420                goto ack_tx_int;
 421        }
 422
 423        if (up->port.x_char) {
 424                up->flags |= IP22ZILOG_FLAG_TX_ACTIVE;
 425                writeb(up->port.x_char, &channel->data);
 426                ZSDELAY();
 427                ZS_WSYNC(channel);
 428
 429                up->port.icount.tx++;
 430                up->port.x_char = 0;
 431                return;
 432        }
 433
 434        if (up->port.info == NULL)
 435                goto ack_tx_int;
 436        xmit = &up->port.info->xmit;
 437        if (uart_circ_empty(xmit)) {
 438                uart_write_wakeup(&up->port);
 439                goto ack_tx_int;
 440        }
 441        if (uart_tx_stopped(&up->port))
 442                goto ack_tx_int;
 443
 444        up->flags |= IP22ZILOG_FLAG_TX_ACTIVE;
 445        writeb(xmit->buf[xmit->tail], &channel->data);
 446        ZSDELAY();
 447        ZS_WSYNC(channel);
 448
 449        xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 450        up->port.icount.tx++;
 451
 452        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 453                uart_write_wakeup(&up->port);
 454
 455        return;
 456
 457ack_tx_int:
 458        writeb(RES_Tx_P, &channel->control);
 459        ZSDELAY();
 460        ZS_WSYNC(channel);
 461}
 462
 463static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 464{
 465        struct uart_ip22zilog_port *up = dev_id;
 466
 467        while (up) {
 468                struct zilog_channel *channel
 469                        = ZILOG_CHANNEL_FROM_PORT(&up->port);
 470                unsigned char r3;
 471
 472                spin_lock(&up->port.lock);
 473                r3 = read_zsreg(channel, R3);
 474
 475                /* Channel A */
 476                if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
 477                        writeb(RES_H_IUS, &channel->control);
 478                        ZSDELAY();
 479                        ZS_WSYNC(channel);
 480
 481                        if (r3 & CHARxIP)
 482                                ip22zilog_receive_chars(up, channel, regs);
 483                        if (r3 & CHAEXT)
 484                                ip22zilog_status_handle(up, channel, regs);
 485                        if (r3 & CHATxIP)
 486                                ip22zilog_transmit_chars(up, channel);
 487                }
 488                spin_unlock(&up->port.lock);
 489
 490                /* Channel B */
 491                up = up->next;
 492                channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
 493
 494                spin_lock(&up->port.lock);
 495                if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
 496                        writeb(RES_H_IUS, &channel->control);
 497                        ZSDELAY();
 498                        ZS_WSYNC(channel);
 499
 500                        if (r3 & CHBRxIP)
 501                                ip22zilog_receive_chars(up, channel, regs);
 502                        if (r3 & CHBEXT)
 503                                ip22zilog_status_handle(up, channel, regs);
 504                        if (r3 & CHBTxIP)
 505                                ip22zilog_transmit_chars(up, channel);
 506                }
 507                spin_unlock(&up->port.lock);
 508
 509                up = up->next;
 510        }
 511
 512        return IRQ_HANDLED;
 513}
 514
 515/* A convenient way to quickly get R0 status.  The caller must _not_ hold the
 516 * port lock, it is acquired here.
 517 */
 518static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port)
 519{
 520        struct zilog_channel *channel;
 521        unsigned long flags;
 522        unsigned char status;
 523
 524        spin_lock_irqsave(&port->lock, flags);
 525
 526        channel = ZILOG_CHANNEL_FROM_PORT(port);
 527        status = readb(&channel->control);
 528        ZSDELAY();
 529
 530        spin_unlock_irqrestore(&port->lock, flags);
 531
 532        return status;
 533}
 534
 535/* The port lock is not held.  */
 536static unsigned int ip22zilog_tx_empty(struct uart_port *port)
 537{
 538        unsigned char status;
 539        unsigned int ret;
 540
 541        status = ip22zilog_read_channel_status(port);
 542        if (status & Tx_BUF_EMP)
 543                ret = TIOCSER_TEMT;
 544        else
 545                ret = 0;
 546
 547        return ret;
 548}
 549
 550/* The port lock is not held.  */
 551static unsigned int ip22zilog_get_mctrl(struct uart_port *port)
 552{
 553        unsigned char status;
 554        unsigned int ret;
 555
 556        status = ip22zilog_read_channel_status(port);
 557
 558        ret = 0;
 559        if (status & DCD)
 560                ret |= TIOCM_CAR;
 561        if (status & SYNC)
 562                ret |= TIOCM_DSR;
 563        if (status & CTS)
 564                ret |= TIOCM_CTS;
 565
 566        return ret;
 567}
 568
 569/* The port lock is held and interrupts are disabled.  */
 570static void ip22zilog_set_mctrl(struct uart_port *port, unsigned int mctrl)
 571{
 572        struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port;
 573        struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
 574        unsigned char set_bits, clear_bits;
 575
 576        set_bits = clear_bits = 0;
 577
 578        if (mctrl & TIOCM_RTS)
 579                set_bits |= RTS;
 580        else
 581                clear_bits |= RTS;
 582        if (mctrl & TIOCM_DTR)
 583                set_bits |= DTR;
 584        else
 585                clear_bits |= DTR;
 586
 587        /* NOTE: Not subject to 'transmitter active' rule.  */ 
 588        up->curregs[R5] |= set_bits;
 589        up->curregs[R5] &= ~clear_bits;
 590        write_zsreg(channel, R5, up->curregs[R5]);
 591}
 592
 593/* The port lock is held and interrupts are disabled.  */
 594static void ip22zilog_stop_tx(struct uart_port *port, unsigned int tty_stop)
 595{
 596        struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port;
 597
 598        up->flags |= IP22ZILOG_FLAG_TX_STOPPED;
 599}
 600
 601/* The port lock is held and interrupts are disabled.  */
 602static void ip22zilog_start_tx(struct uart_port *port, unsigned int tty_start)
 603{
 604        struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port;
 605        struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
 606        unsigned char status;
 607
 608        up->flags |= IP22ZILOG_FLAG_TX_ACTIVE;
 609        up->flags &= ~IP22ZILOG_FLAG_TX_STOPPED;
 610
 611        status = readb(&channel->control);
 612        ZSDELAY();
 613
 614        /* TX busy?  Just wait for the TX done interrupt.  */
 615        if (!(status & Tx_BUF_EMP))
 616                return;
 617
 618        /* Send the first character to jump-start the TX done
 619         * IRQ sending engine.
 620         */
 621        if (port->x_char) {
 622                writeb(port->x_char, &channel->data);
 623                ZSDELAY();
 624                ZS_WSYNC(channel);
 625
 626                port->icount.tx++;
 627                port->x_char = 0;
 628        } else {
 629                struct circ_buf *xmit = &port->info->xmit;
 630
 631                writeb(xmit->buf[xmit->tail], &channel->data);
 632                ZSDELAY();
 633                ZS_WSYNC(channel);
 634
 635                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
 636                port->icount.tx++;
 637
 638                if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 639                        uart_write_wakeup(&up->port);
 640        }
 641}
 642
 643/* The port lock is held and interrupts are disabled.  */
 644static void ip22zilog_stop_rx(struct uart_port *port)
 645{
 646        struct uart_ip22zilog_port *up = UART_ZILOG(port);
 647        struct zilog_channel *channel;
 648
 649        if (ZS_IS_CONS(up))
 650                return;
 651
 652        channel = ZILOG_CHANNEL_FROM_PORT(port);
 653
 654        /* Disable all RX interrupts.  */
 655        up->curregs[R1] &= ~RxINT_MASK;
 656        ip22zilog_maybe_update_regs(up, channel);
 657}
 658
 659/* The port lock is held.  */
 660static void ip22zilog_enable_ms(struct uart_port *port)
 661{
 662        struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port;
 663        struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
 664        unsigned char new_reg;
 665
 666        new_reg = up->curregs[R15] | (DCDIE | SYNCIE | CTSIE);
 667        if (new_reg != up->curregs[R15]) {
 668                up->curregs[R15] = new_reg;
 669
 670                /* NOTE: Not subject to 'transmitter active' rule.  */ 
 671                write_zsreg(channel, R15, up->curregs[R15]);
 672        }
 673}
 674
 675/* The port lock is not held.  */
 676static void ip22zilog_break_ctl(struct uart_port *port, int break_state)
 677{
 678        struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port;
 679        struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
 680        unsigned char set_bits, clear_bits, new_reg;
 681        unsigned long flags;
 682
 683        set_bits = clear_bits = 0;
 684
 685        if (break_state)
 686                set_bits |= SND_BRK;
 687        else
 688                clear_bits |= SND_BRK;
 689
 690        spin_lock_irqsave(&port->lock, flags);
 691
 692        new_reg = (up->curregs[R5] | set_bits) & ~clear_bits;
 693        if (new_reg != up->curregs[R5]) {
 694                up->curregs[R5] = new_reg;
 695
 696                /* NOTE: Not subject to 'transmitter active' rule.  */ 
 697                write_zsreg(channel, R5, up->curregs[R5]);
 698        }
 699
 700        spin_unlock_irqrestore(&port->lock, flags);
 701}
 702
 703static void __ip22zilog_startup(struct uart_ip22zilog_port *up)
 704{
 705        struct zilog_channel *channel;
 706
 707        channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
 708        up->prev_status = readb(&channel->control);
 709
 710        /* Enable receiver and transmitter.  */
 711        up->curregs[R3] |= RxENAB;
 712        up->curregs[R5] |= TxENAB;
 713
 714        up->curregs[R1] |= EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
 715        ip22zilog_maybe_update_regs(up, channel);
 716}
 717
 718static int ip22zilog_startup(struct uart_port *port)
 719{
 720        struct uart_ip22zilog_port *up = UART_ZILOG(port);
 721        unsigned long flags;
 722
 723        if (ZS_IS_CONS(up))
 724                return 0;
 725
 726        spin_lock_irqsave(&port->lock, flags);
 727        __ip22zilog_startup(up);
 728        spin_unlock_irqrestore(&port->lock, flags);
 729        return 0;
 730}
 731
 732/*
 733 * The test for ZS_IS_CONS is explained by the following e-mail:
 734 *****
 735 * From: Russell King <rmk@arm.linux.org.uk>
 736 * Date: Sun, 8 Dec 2002 10:18:38 +0000
 737 *
 738 * On Sun, Dec 08, 2002 at 02:43:36AM -0500, Pete Zaitcev wrote:
 739 * > I boot my 2.5 boxes using "console=ttyS0,9600" argument,
 740 * > and I noticed that something is not right with reference
 741 * > counting in this case. It seems that when the console
 742 * > is open by kernel initially, this is not accounted
 743 * > as an open, and uart_startup is not called.
 744 *
 745 * That is correct.  We are unable to call uart_startup when the serial
 746 * console is initialised because it may need to allocate memory (as
 747 * request_irq does) and the memory allocators may not have been
 748 * initialised.
 749 *
 750 * 1. initialise the port into a state where it can send characters in the
 751 *    console write method.
 752 *
 753 * 2. don't do the actual hardware shutdown in your shutdown() method (but
 754 *    do the normal software shutdown - ie, free irqs etc)
 755 *****
 756 */
 757static void ip22zilog_shutdown(struct uart_port *port)
 758{
 759        struct uart_ip22zilog_port *up = UART_ZILOG(port);
 760        struct zilog_channel *channel;
 761        unsigned long flags;
 762
 763        if (ZS_IS_CONS(up))
 764                return;
 765
 766        spin_lock_irqsave(&port->lock, flags);
 767
 768        channel = ZILOG_CHANNEL_FROM_PORT(port);
 769
 770        /* Disable receiver and transmitter.  */
 771        up->curregs[R3] &= ~RxENAB;
 772        up->curregs[R5] &= ~TxENAB;
 773
 774        /* Disable all interrupts and BRK assertion.  */
 775        up->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
 776        up->curregs[R5] &= ~SND_BRK;
 777        ip22zilog_maybe_update_regs(up, channel);
 778
 779        spin_unlock_irqrestore(&port->lock, flags);
 780}
 781
 782/* Shared by TTY driver and serial console setup.  The port lock is held
 783 * and local interrupts are disabled.
 784 */
 785static void
 786ip22zilog_convert_to_zs(struct uart_ip22zilog_port *up, unsigned int cflag,
 787                       unsigned int iflag, int brg)
 788{
 789
 790        up->curregs[R10] = NRZ;
 791        up->curregs[R11] = TCBR | RCBR;
 792
 793        /* Program BAUD and clock source. */
 794        up->curregs[R4] &= ~XCLK_MASK;
 795        up->curregs[R4] |= X16CLK;
 796        up->curregs[R12] = brg & 0xff;
 797        up->curregs[R13] = (brg >> 8) & 0xff;
 798        up->curregs[R14] = BRENAB;
 799
 800        /* Character size, stop bits, and parity. */
 801        up->curregs[3] &= ~RxN_MASK;
 802        up->curregs[5] &= ~TxN_MASK;
 803        switch (cflag & CSIZE) {
 804        case CS5:
 805                up->curregs[3] |= Rx5;
 806                up->curregs[5] |= Tx5;
 807                up->parity_mask = 0x1f;
 808                break;
 809        case CS6:
 810                up->curregs[3] |= Rx6;
 811                up->curregs[5] |= Tx6;
 812                up->parity_mask = 0x3f;
 813                break;
 814        case CS7:
 815                up->curregs[3] |= Rx7;
 816                up->curregs[5] |= Tx7;
 817                up->parity_mask = 0x7f;
 818                break;
 819        case CS8:
 820        default:
 821                up->curregs[3] |= Rx8;
 822                up->curregs[5] |= Tx8;
 823                up->parity_mask = 0xff;
 824                break;
 825        };
 826        up->curregs[4] &= ~0x0c;
 827        if (cflag & CSTOPB)
 828                up->curregs[4] |= SB2;
 829        else
 830                up->curregs[4] |= SB1;
 831        if (cflag & PARENB)
 832                up->curregs[4] |= PAR_ENAB;
 833        else
 834                up->curregs[4] &= ~PAR_ENAB;
 835        if (!(cflag & PARODD))
 836                up->curregs[4] |= PAR_EVEN;
 837        else
 838                up->curregs[4] &= ~PAR_EVEN;
 839
 840        up->port.read_status_mask = Rx_OVR;
 841        if (iflag & INPCK)
 842                up->port.read_status_mask |= CRC_ERR | PAR_ERR;
 843        if (iflag & (BRKINT | PARMRK))
 844                up->port.read_status_mask |= BRK_ABRT;
 845
 846        up->port.ignore_status_mask = 0;
 847        if (iflag & IGNPAR)
 848                up->port.ignore_status_mask |= CRC_ERR | PAR_ERR;
 849        if (iflag & IGNBRK) {
 850                up->port.ignore_status_mask |= BRK_ABRT;
 851                if (iflag & IGNPAR)
 852                        up->port.ignore_status_mask |= Rx_OVR;
 853        }
 854
 855        if ((cflag & CREAD) == 0)
 856                up->port.ignore_status_mask = 0xff;
 857}
 858
 859/* The port lock is not held.  */
 860static void
 861ip22zilog_set_termios(struct uart_port *port, struct termios *termios,
 862                      struct termios *old)
 863{
 864        struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port;
 865        unsigned long flags;
 866        int baud, brg;
 867
 868        baud = uart_get_baud_rate(port, termios, old, 1200, 76800);
 869
 870        spin_lock_irqsave(&up->port.lock, flags);
 871
 872        brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
 873
 874        ip22zilog_convert_to_zs(up, termios->c_cflag, termios->c_iflag, brg);
 875
 876        if (UART_ENABLE_MS(&up->port, termios->c_cflag))
 877                up->flags |= IP22ZILOG_FLAG_MODEM_STATUS;
 878        else
 879                up->flags &= ~IP22ZILOG_FLAG_MODEM_STATUS;
 880
 881        up->cflag = termios->c_cflag;
 882
 883        ip22zilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port));
 884
 885        spin_unlock_irqrestore(&up->port.lock, flags);
 886}
 887
 888static const char *ip22zilog_type(struct uart_port *port)
 889{
 890        return "IP22-Zilog";
 891}
 892
 893/* We do not request/release mappings of the registers here, this
 894 * happens at early serial probe time.
 895 */
 896static void ip22zilog_release_port(struct uart_port *port)
 897{
 898}
 899
 900static int ip22zilog_request_port(struct uart_port *port)
 901{
 902        return 0;
 903}
 904
 905/* These do not need to do anything interesting either.  */
 906static void ip22zilog_config_port(struct uart_port *port, int flags)
 907{
 908}
 909
 910/* We do not support letting the user mess with the divisor, IRQ, etc. */
 911static int ip22zilog_verify_port(struct uart_port *port, struct serial_struct *ser)
 912{
 913        return -EINVAL;
 914}
 915
 916static struct uart_ops ip22zilog_pops = {
 917        .tx_empty       =       ip22zilog_tx_empty,
 918        .set_mctrl      =       ip22zilog_set_mctrl,
 919        .get_mctrl      =       ip22zilog_get_mctrl,
 920        .stop_tx        =       ip22zilog_stop_tx,
 921        .start_tx       =       ip22zilog_start_tx,
 922        .stop_rx        =       ip22zilog_stop_rx,
 923        .enable_ms      =       ip22zilog_enable_ms,
 924        .break_ctl      =       ip22zilog_break_ctl,
 925        .startup        =       ip22zilog_startup,
 926        .shutdown       =       ip22zilog_shutdown,
 927        .set_termios    =       ip22zilog_set_termios,
 928        .type           =       ip22zilog_type,
 929        .release_port   =       ip22zilog_release_port,
 930        .request_port   =       ip22zilog_request_port,
 931        .config_port    =       ip22zilog_config_port,
 932        .verify_port    =       ip22zilog_verify_port,
 933};
 934
 935static struct uart_ip22zilog_port *ip22zilog_port_table;
 936static struct zilog_layout **ip22zilog_chip_regs;
 937
 938static struct uart_ip22zilog_port *ip22zilog_irq_chain;
 939static int zilog_irq = -1;
 940
 941static void * __init alloc_one_table(unsigned long size)
 942{
 943        void *ret;
 944
 945        ret = kmalloc(size, GFP_KERNEL);
 946        if (ret != NULL)
 947                memset(ret, 0, size);
 948
 949        return ret;
 950}
 951
 952static void __init ip22zilog_alloc_tables(void)
 953{
 954        ip22zilog_port_table = (struct uart_ip22zilog_port *)
 955                alloc_one_table(NUM_CHANNELS * sizeof(struct uart_ip22zilog_port));
 956        ip22zilog_chip_regs = (struct zilog_layout **)
 957                alloc_one_table(NUM_IP22ZILOG * sizeof(struct zilog_layout *));
 958
 959        if (ip22zilog_port_table == NULL || ip22zilog_chip_regs == NULL) {
 960                panic("IP22-Zilog: Cannot allocate IP22-Zilog tables.");
 961        }
 962}
 963
 964/* Get the address of the registers for IP22-Zilog instance CHIP.  */
 965static struct zilog_layout * __init get_zs(int chip)
 966{
 967        unsigned long base;
 968
 969        if (chip < 0 || chip >= NUM_IP22ZILOG) {
 970                panic("IP22-Zilog: Illegal chip number %d in get_zs.", chip);
 971        }
 972
 973        /* Not probe-able, hard code it. */
 974        base = (unsigned long) &sgioc->uart;
 975
 976        zilog_irq = SGI_SERIAL_IRQ;
 977        request_mem_region(base, 8, "IP22-Zilog");
 978
 979        return (struct zilog_layout *) base;
 980}
 981
 982#define ZS_PUT_CHAR_MAX_DELAY   2000    /* 10 ms */
 983
 984#ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLE
 985static void ip22zilog_put_char(struct zilog_channel *channel, unsigned char ch)
 986{
 987        int loops = ZS_PUT_CHAR_MAX_DELAY;
 988
 989        /* This is a timed polling loop so do not switch the explicit
 990         * udelay with ZSDELAY as that is a NOP on some platforms.  -DaveM
 991         */
 992        do {
 993                unsigned char val = readb(&channel->control);
 994                if (val & Tx_BUF_EMP) {
 995                        ZSDELAY();
 996                        break;
 997                }
 998                udelay(5);
 999        } while (--loops);
1000
1001        writeb(ch, &channel->data);
1002        ZSDELAY();
1003        ZS_WSYNC(channel);
1004}
1005
1006static void
1007ip22zilog_console_write(struct console *con, const char *s, unsigned int count)
1008{
1009        struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index];
1010        struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
1011        unsigned long flags;
1012        int i;
1013
1014        spin_lock_irqsave(&up->port.lock, flags);
1015        for (i = 0; i < count; i++, s++) {
1016                ip22zilog_put_char(channel, *s);
1017                if (*s == 10)
1018                        ip22zilog_put_char(channel, 13);
1019        }
1020        udelay(2);
1021        spin_unlock_irqrestore(&up->port.lock, flags);
1022}
1023
1024void
1025ip22serial_console_termios(struct console *con, char *options)
1026{
1027        int baud = 9600, bits = 8, cflag;
1028        int parity = 'n';
1029        int flow = 'n';
1030
1031        if (options)
1032                uart_parse_options(options, &baud, &parity, &bits, &flow);
1033
1034        cflag = CREAD | HUPCL | CLOCAL;
1035
1036        switch (baud) {
1037                case 150: cflag |= B150; break;
1038                case 300: cflag |= B300; break;
1039                case 600: cflag |= B600; break;
1040                case 1200: cflag |= B1200; break;
1041                case 2400: cflag |= B2400; break;
1042                case 4800: cflag |= B4800; break;
1043                case 9600: cflag |= B9600; break;
1044                case 19200: cflag |= B19200; break;
1045                case 38400: cflag |= B38400; break;
1046                default: baud = 9600; cflag |= B9600; break;
1047        }
1048
1049        con->cflag = cflag | CS8;                       /* 8N1 */
1050}
1051
1052static int __init ip22zilog_console_setup(struct console *con, char *options)
1053{
1054        struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index];
1055        unsigned long flags;
1056        int baud, brg;
1057
1058        printk("Console: ttyS%d (IP22-Zilog)\n", con->index);
1059
1060        /* Get firmware console settings.  */
1061        ip22serial_console_termios(con, options);
1062
1063        /* Firmware console speed is limited to 150-->38400 baud so
1064         * this hackish cflag thing is OK.
1065         */
1066        switch (con->cflag & CBAUD) {
1067        case B150: baud = 150; break;
1068        case B300: baud = 300; break;
1069        case B600: baud = 600; break;
1070        case B1200: baud = 1200; break;
1071        case B2400: baud = 2400; break;
1072        case B4800: baud = 4800; break;
1073        default: case B9600: baud = 9600; break;
1074        case B19200: baud = 19200; break;
1075        case B38400: baud = 38400; break;
1076        };
1077
1078        brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
1079
1080        spin_lock_irqsave(&up->port.lock, flags);
1081
1082        up->curregs[R15] = BRKIE;
1083        ip22zilog_convert_to_zs(up, con->cflag, 0, brg);
1084
1085        __ip22zilog_startup(up);
1086
1087        spin_unlock_irqrestore(&up->port.lock, flags);
1088
1089        return 0;
1090}
1091
1092static struct uart_driver ip22zilog_reg;
1093
1094static struct console ip22zilog_console = {
1095        .name   =       "ttyS",
1096        .write  =       ip22zilog_console_write,
1097        .device =       uart_console_device,
1098        .setup  =       ip22zilog_console_setup,
1099        .flags  =       CON_PRINTBUFFER,
1100        .index  =       -1,
1101        .data   =       &ip22zilog_reg,
1102};
1103#endif /* CONFIG_SERIAL_IP22_ZILOG_CONSOLE */
1104
1105static struct uart_driver ip22zilog_reg = {
1106        .owner          = THIS_MODULE,
1107        .driver_name    = "serial",
1108        .devfs_name     = "tts/",
1109        .dev_name       = "ttyS",
1110        .major          = TTY_MAJOR,
1111        .minor          = 64,
1112        .nr             = NUM_CHANNELS,
1113#ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLE
1114        .cons           = &ip22zilog_console,
1115#endif
1116};
1117
1118static void __init ip22zilog_prepare(void)
1119{
1120        struct uart_ip22zilog_port *up;
1121        struct zilog_layout *rp;
1122        int channel, chip;
1123
1124        /*
1125         * Temporary fix.
1126         */
1127        for (channel = 0; channel < NUM_CHANNELS; channel++)
1128                spin_lock_init(&ip22zilog_port_table[channel].port.lock);
1129
1130        ip22zilog_irq_chain = &ip22zilog_port_table[NUM_CHANNELS - 1];
1131        up = &ip22zilog_port_table[0];
1132        for (channel = NUM_CHANNELS - 1 ; channel > 0; channel--)
1133                up[channel].next = &up[channel - 1];
1134        up[channel].next = NULL;
1135
1136        for (chip = 0; chip < NUM_IP22ZILOG; chip++) {
1137                if (!ip22zilog_chip_regs[chip]) {
1138                        ip22zilog_chip_regs[chip] = rp = get_zs(chip);
1139
1140                        up[(chip * 2) + 0].port.membase = (char *) &rp->channelB;
1141                        up[(chip * 2) + 1].port.membase = (char *) &rp->channelA;
1142
1143                        /* In theory mapbase is the physical address ...  */
1144                        up[(chip * 2) + 0].port.mapbase =
1145                                (unsigned long) ioremap((unsigned long) &rp->channelB, 8);
1146                        up[(chip * 2) + 1].port.mapbase =
1147                                (unsigned long) ioremap((unsigned long) &rp->channelA, 8);
1148                }
1149
1150                /* Channel A */
1151                up[(chip * 2) + 0].port.iotype = UPIO_MEM;
1152                up[(chip * 2) + 0].port.irq = zilog_irq;
1153                up[(chip * 2) + 0].port.uartclk = ZS_CLOCK;
1154                up[(chip * 2) + 0].port.fifosize = 1;
1155                up[(chip * 2) + 0].port.ops = &ip22zilog_pops;
1156                up[(chip * 2) + 0].port.type = PORT_IP22ZILOG;
1157                up[(chip * 2) + 0].port.flags = 0;
1158                up[(chip * 2) + 0].port.line = (chip * 2) + 0;
1159                up[(chip * 2) + 0].flags = 0;
1160
1161                /* Channel B */
1162                up[(chip * 2) + 1].port.iotype = UPIO_MEM;
1163                up[(chip * 2) + 1].port.irq = zilog_irq;
1164                up[(chip * 2) + 1].port.uartclk = ZS_CLOCK;
1165                up[(chip * 2) + 1].port.fifosize = 1;
1166                up[(chip * 2) + 1].port.ops = &ip22zilog_pops;
1167                up[(chip * 2) + 1].port.type = PORT_IP22ZILOG;
1168                up[(chip * 2) + 1].port.flags |= IP22ZILOG_FLAG_IS_CHANNEL_A;
1169                up[(chip * 2) + 1].port.line = (chip * 2) + 1;
1170                up[(chip * 2) + 1].flags = 0;
1171        }
1172}
1173
1174static void __init ip22zilog_init_hw(void)
1175{
1176        int i;
1177
1178        for (i = 0; i < NUM_CHANNELS; i++) {
1179                struct uart_ip22zilog_port *up = &ip22zilog_port_table[i];
1180                struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
1181                unsigned long flags;
1182                int baud, brg;
1183
1184                spin_lock_irqsave(&up->port.lock, flags);
1185
1186                if (ZS_IS_CHANNEL_A(up)) {
1187                        write_zsreg(channel, R9, FHWRES);
1188                        ZSDELAY_LONG();
1189                        (void) read_zsreg(channel, R0);
1190                }
1191
1192                /* Normal serial TTY. */
1193                up->parity_mask = 0xff;
1194                up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
1195                up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
1196                up->curregs[R3] = RxENAB | Rx8;
1197                up->curregs[R5] = TxENAB | Tx8;
1198                up->curregs[R9] = NV | MIE;
1199                up->curregs[R10] = NRZ;
1200                up->curregs[R11] = TCBR | RCBR;
1201                baud = 9600;
1202                brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
1203                up->curregs[R12] = (brg & 0xff);
1204                up->curregs[R13] = (brg >> 8) & 0xff;
1205                up->curregs[R14] = BRENAB;
1206                __load_zsregs(channel, up->curregs);
1207                /* set master interrupt enable */
1208                write_zsreg(channel, R9, up->curregs[R9]);
1209
1210                spin_unlock_irqrestore(&up->port.lock, flags);
1211        }
1212}
1213
1214static int __init ip22zilog_ports_init(void)
1215{
1216        int ret;
1217
1218        printk(KERN_INFO "Serial: IP22 Zilog driver (%d chips).\n", NUM_IP22ZILOG);
1219
1220        ip22zilog_prepare();
1221
1222        if (request_irq(zilog_irq, ip22zilog_interrupt, 0,
1223                        "IP22-Zilog", ip22zilog_irq_chain)) {
1224                panic("IP22-Zilog: Unable to register zs interrupt handler.\n");
1225        }
1226
1227        ip22zilog_init_hw();
1228
1229        ret = uart_register_driver(&ip22zilog_reg);
1230        if (ret == 0) {
1231                int i;
1232
1233                for (i = 0; i < NUM_CHANNELS; i++) {
1234                        struct uart_ip22zilog_port *up = &ip22zilog_port_table[i];
1235
1236                        uart_add_one_port(&ip22zilog_reg, &up->port);
1237                }
1238        }
1239
1240        return ret;
1241}
1242
1243static int __init ip22zilog_init(void)
1244{
1245        /* IP22 Zilog setup is hard coded, no probing to do.  */
1246        ip22zilog_alloc_tables();
1247        ip22zilog_ports_init();
1248
1249        return 0;
1250}
1251
1252static void __exit ip22zilog_exit(void)
1253{
1254        int i;
1255
1256        for (i = 0; i < NUM_CHANNELS; i++) {
1257                struct uart_ip22zilog_port *up = &ip22zilog_port_table[i];
1258
1259                uart_remove_one_port(&ip22zilog_reg, &up->port);
1260        }
1261
1262        uart_unregister_driver(&ip22zilog_reg);
1263}
1264
1265module_init(ip22zilog_init);
1266module_exit(ip22zilog_exit);
1267
1268/* David wrote it but I'm to blame for the bugs ...  */
1269MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
1270MODULE_DESCRIPTION("SGI Zilog serial port driver");
1271MODULE_LICENSE("GPL");
1272
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.