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