ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / serial / dz.c
1 /*
2  * dz.c: Serial port driver for DECStations equiped 
3  *       with the DZ chipset.
4  *
5  * Copyright (C) 1998 Olivier A. D. Lebaillif 
6  *             
7  * Email: olivier.lebaillif@ifrsys.com
8  *
9  * [31-AUG-98] triemer
10  * Changed IRQ to use Harald's dec internals interrupts.h
11  * removed base_addr code - moving address assignment to setup.c
12  * Changed name of dz_init to rs_init to be consistent with tc code
13  * [13-NOV-98] triemer fixed code to receive characters
14  *    after patches by harald to irq code.  
15  * [09-JAN-99] triemer minor fix for schedule - due to removal of timeout
16  *            field from "current" - somewhere between 2.1.121 and 2.1.131
17  Qua Jun 27 15:02:26 BRT 2001
18  * [27-JUN-2001] Arnaldo Carvalho de Melo <acme@conectiva.com.br> - cleanups
19  *  
20  * Parts (C) 1999 David Airlie, airlied@linux.ie 
21  * [07-SEP-99] Bugfixes 
22  *
23  * [06-Jan-2002] Russell King <rmk@arm.linux.org.uk>
24  * Converted to new serial core
25  */
26
27 #undef DEBUG_DZ
28
29 #include <linux/config.h>
30 #include <linux/module.h>
31 #include <linux/tty.h>
32 #include <linux/interrupt.h>
33 #include <linux/init.h>
34 #include <linux/console.h>
35 #include <linux/serial.h>
36 #include <linux/serial_core.h>
37
38 #include <asm/bootinfo.h>
39 #include <asm/dec/interrupts.h>
40 #include <asm/dec/kn01.h>
41 #include <asm/dec/kn02.h>
42 #include <asm/dec/machtype.h>
43 #include <asm/dec/prom.h>
44 #include <asm/irq.h>
45 #include <asm/system.h>
46 #include <asm/uaccess.h>
47
48 #define CONSOLE_LINE (3)        /* for definition of struct console */
49
50 #include "dz.h"
51
52 #define DZ_INTR_DEBUG 1
53
54 static char *dz_name = "DECstation DZ serial driver version ";
55 static char *dz_version = "1.02";
56
57 struct dz_port {
58         struct uart_port        port;
59         unsigned int            cflag;
60 };
61
62 static struct dz_port dz_ports[DZ_NB_PORT];
63
64 #ifdef DEBUG_DZ
65 /*
66  * debugging code to send out chars via prom 
67  */
68 static void debug_console(const char *s, int count)
69 {
70         unsigned i;
71
72         for (i = 0; i < count; i++) {
73                 if (*s == 10)
74                         prom_printf("%c", 13);
75                 prom_printf("%c", *s++);
76         }
77 }
78 #endif
79
80 /*
81  * ------------------------------------------------------------
82  * dz_in () and dz_out ()
83  *
84  * These routines are used to access the registers of the DZ 
85  * chip, hiding relocation differences between implementation.
86  * ------------------------------------------------------------
87  */
88
89 static inline unsigned short dz_in(struct dz_port *dport, unsigned offset)
90 {
91         volatile unsigned short *addr =
92                 (volatile unsigned short *) (dport->port.membase + offset);
93         return *addr;
94 }
95
96 static inline void dz_out(struct dz_port *dport, unsigned offset,
97                           unsigned short value)
98 {
99         volatile unsigned short *addr =
100                 (volatile unsigned short *) (dport->port.membase + offset);
101         *addr = value;
102 }
103
104 /*
105  * ------------------------------------------------------------
106  * rs_stop () and rs_start ()
107  *
108  * These routines are called before setting or resetting 
109  * tty->stopped. They enable or disable transmitter interrupts, 
110  * as necessary.
111  * ------------------------------------------------------------
112  */
113
114 static void dz_stop_tx(struct uart_port *uport, unsigned int tty_stop)
115 {
116         struct dz_port *dport = (struct dz_port *)uport;
117         unsigned short tmp, mask = 1 << dport->port.line;
118         unsigned long flags;
119
120         spin_lock_irqsave(&dport->port.lock, flags);
121         tmp = dz_in(dport, DZ_TCR);     /* read the TX flag */
122         tmp &= ~mask;                   /* clear the TX flag */
123         dz_out(dport, DZ_TCR, tmp);
124         spin_unlock_irqrestore(&dport->port.lock, flags);
125 }
126
127 static void dz_start_tx(struct uart_port *uport, unsigned int tty_start)
128 {
129         struct dz_port *dport = (struct dz_port *)uport;
130         unsigned short tmp, mask = 1 << dport->port.line;
131         unsigned long flags;
132
133         spin_lock_irqsave(&dport->port.lock, flags);
134         tmp = dz_in(dport, DZ_TCR);     /* read the TX flag */
135         tmp |= mask;                    /* set the TX flag */
136         dz_out(dport, DZ_TCR, tmp);
137         spin_unlock_irqrestore(&dport->port.lock, flags);
138 }
139
140 static void dz_stop_rx(struct uart_port *uport)
141 {
142         struct dz_port *dport = (struct dz_port *)uport;
143         unsigned long flags;
144
145         spin_lock_irqsave(&dport->port.lock, flags);
146         dport->cflag &= ~DZ_CREAD;
147         dz_out(dport, DZ_LPR, dport->cflag);
148         spin_unlock_irqrestore(&dport->port.lock, flags);
149 }
150
151 static void dz_enable_ms(struct uart_port *port)
152 {
153         /* nothing to do */
154 }
155
156 /*
157  * ------------------------------------------------------------
158  * Here starts the interrupt handling routines.  All of the 
159  * following subroutines are declared as inline and are folded 
160  * into dz_interrupt.  They were separated out for readability's 
161  * sake. 
162  *
163  * Note: rs_interrupt() is a "fast" interrupt, which means that it
164  * runs with interrupts turned off.  People who may want to modify
165  * rs_interrupt() should try to keep the interrupt handler as fast as
166  * possible.  After you are done making modifications, it is not a bad
167  * idea to do:
168  * 
169  *      make drivers/serial/dz.s
170  *
171  * and look at the resulting assemble code in dz.s.
172  *
173  * ------------------------------------------------------------
174  */
175
176 /*
177  * ------------------------------------------------------------
178  * receive_char ()
179  *
180  * This routine deals with inputs from any lines.
181  * ------------------------------------------------------------
182  */
183 static inline void dz_receive_chars(struct dz_port *dport)
184 {
185         struct tty_struct *tty = NULL;
186         struct uart_icount *icount;
187         int ignore = 0;
188         unsigned short status, tmp;
189         unsigned char ch;
190
191         /* this code is going to be a problem...
192            the call to tty_flip_buffer is going to need
193            to be rethought...
194          */
195         do {
196                 status = dz_in(dport, DZ_RBUF);
197
198                 /* punt so we don't get duplicate characters */
199                 if (!(status & DZ_DVAL))
200                         goto ignore_char;
201
202
203                 ch = UCHAR(status);     /* grab the char */
204
205 #if 0
206                 if (info->is_console) {
207                         if (ch == 0)
208                                 return;         /* it's a break ... */
209                 }
210 #endif
211
212                 tty = dport->port.info->tty;/* now tty points to the proper dev */
213                 icount = &dport->port.icount;
214
215                 if (!tty)
216                         break;
217                 if (tty->flip.count >= TTY_FLIPBUF_SIZE)
218                         break;
219
220                 *tty->flip.char_buf_ptr = ch;
221                 *tty->flip.flag_buf_ptr = 0;
222                 icount->rx++;
223
224                 /* keep track of the statistics */
225                 if (status & (DZ_OERR | DZ_FERR | DZ_PERR)) {
226                         if (status & DZ_PERR)   /* parity error */
227                                 icount->parity++;
228                         else if (status & DZ_FERR)      /* frame error */
229                                 icount->frame++;
230                         if (status & DZ_OERR)   /* overrun error */
231                                 icount->overrun++;
232
233                         /*  check to see if we should ignore the character
234                            and mask off conditions that should be ignored
235                          */
236
237                         if (status & dport->port.ignore_status_mask) {
238                                 if (++ignore > 100)
239                                         break;
240                                 goto ignore_char;
241                         }
242                         /* mask off the error conditions we want to ignore */
243                         tmp = status & dport->port.read_status_mask;
244
245                         if (tmp & DZ_PERR) {
246                                 *tty->flip.flag_buf_ptr = TTY_PARITY;
247 #ifdef DEBUG_DZ
248                                 debug_console("PERR\n", 5);
249 #endif
250                         } else if (tmp & DZ_FERR) {
251                                 *tty->flip.flag_buf_ptr = TTY_FRAME;
252 #ifdef DEBUG_DZ
253                                 debug_console("FERR\n", 5);
254 #endif
255                         }
256                         if (tmp & DZ_OERR) {
257 #ifdef DEBUG_DZ
258                                 debug_console("OERR\n", 5);
259 #endif
260                                 if (tty->flip.count < TTY_FLIPBUF_SIZE) {
261                                         tty->flip.count++;
262                                         tty->flip.flag_buf_ptr++;
263                                         tty->flip.char_buf_ptr++;
264                                         *tty->flip.flag_buf_ptr = TTY_OVERRUN;
265                                 }
266                         }
267                 }
268                 tty->flip.flag_buf_ptr++;
269                 tty->flip.char_buf_ptr++;
270                 tty->flip.count++;
271               ignore_char:
272         } while (status & DZ_DVAL);
273
274         if (tty)
275                 tty_flip_buffer_push(tty);
276 }
277
278 /*
279  * ------------------------------------------------------------
280  * transmit_char ()
281  *
282  * This routine deals with outputs to any lines.
283  * ------------------------------------------------------------
284  */
285 static inline void dz_transmit_chars(struct dz_port *dport)
286 {
287         struct circ_buf *xmit = &dport->port.info->xmit;
288         unsigned char tmp;
289
290         if (dport->port.x_char) {       /* XON/XOFF chars */
291                 dz_out(dport, DZ_TDR, dport->port.x_char);
292                 dport->port.icount.tx++;
293                 dport->port.x_char = 0;
294                 return;
295         }
296         /* if nothing to do or stopped or hardware stopped */
297         if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) {
298                 dz_stop_tx(&dport->port, 0);
299                 return;
300         }
301
302         /*
303          * if something to do ... (rember the dz has no output fifo so we go
304          * one char at a time :-<
305          */
306         tmp = xmit->buf[xmit->tail];
307         xmit->tail = (xmit->tail + 1) & (DZ_XMIT_SIZE - 1);
308         dz_out(dport, DZ_TDR, tmp);
309         dport->port.icount.tx++;
310
311         if (uart_circ_chars_pending(xmit) < DZ_WAKEUP_CHARS)
312                 uart_write_wakeup(&dport->port);
313
314         /* Are we done */
315         if (uart_circ_empty(xmit))
316                 dz_stop_tx(&dport->port, 0);
317 }
318
319 /*
320  * ------------------------------------------------------------
321  * check_modem_status ()
322  *
323  * Only valid for the MODEM line duh !
324  * ------------------------------------------------------------
325  */
326 static inline void check_modem_status(struct dz_port *dport)
327 {
328         unsigned short status;
329
330         /* if not ne modem line just return */
331         if (dport->port.line != DZ_MODEM)
332                 return;
333
334         status = dz_in(dport, DZ_MSR);
335
336         /* it's easy, since DSR2 is the only bit in the register */
337         if (status)
338                 dport->port.icount.dsr++;
339 }
340
341 /*
342  * ------------------------------------------------------------
343  * dz_interrupt ()
344  *
345  * this is the main interrupt routine for the DZ chip.
346  * It deals with the multiple ports.
347  * ------------------------------------------------------------
348  */
349 static irqreturn_t dz_interrupt(int irq, void *dev, struct pt_regs *regs)
350 {
351         struct dz_port *dport;
352         unsigned short status;
353
354         /* get the reason why we just got an irq */
355         status = dz_in((struct dz_port *)dev, DZ_CSR);
356         dport = &dz_ports[LINE(status)];
357
358         if (status & DZ_RDONE)
359                 dz_receive_chars(dport);
360
361         if (status & DZ_TRDY)
362                 dz_transmit_chars(dport);
363
364         /* FIXME: what about check modem status??? --rmk */
365
366         return IRQ_HANDLED;
367 }
368
369 /*
370  * -------------------------------------------------------------------
371  * Here ends the DZ interrupt routines.
372  * -------------------------------------------------------------------
373  */
374
375 static unsigned int dz_get_mctrl(struct uart_port *uport)
376 {
377         struct dz_port *dport = (struct dz_port *)uport;
378         unsigned int mctrl = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
379
380         if (dport->port.line == DZ_MODEM) {
381                 /*
382                  * CHECKME: This is a guess from the other code... --rmk
383                  */
384                 if (dz_in(dport, DZ_MSR) & DZ_MODEM_DSR)
385                         mctrl &= ~TIOCM_DSR;
386         }
387
388         return mctrl;
389 }
390
391 static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl)
392 {
393         struct dz_port *dport = (struct dz_port *)uport;
394         unsigned short tmp;
395
396         if (dport->port.line == DZ_MODEM) {
397                 tmp = dz_in(dport, DZ_TCR);
398                 if (mctrl & TIOCM_DTR)
399                         tmp &= ~DZ_MODEM_DTR;
400                 else
401                         tmp |= DZ_MODEM_DTR;
402                 dz_out(dport, DZ_TCR, tmp);
403         }
404 }
405
406 /*
407  * -------------------------------------------------------------------
408  * startup ()
409  *
410  * various initialization tasks
411  * ------------------------------------------------------------------- 
412  */
413 static int dz_startup(struct uart_port *uport)
414 {
415         struct dz_port *dport = (struct dz_port *)uport;
416         unsigned long flags;
417         unsigned short tmp;
418
419         /* The dz lines for the mouse/keyboard must be
420          * opened using their respective drivers.
421          */
422         if ((dport->port.line == DZ_KEYBOARD) ||
423             (dport->port.line == DZ_MOUSE))
424                 return -ENODEV;
425
426         spin_lock_irqsave(&dport->port.lock, flags);
427
428         /* enable the interrupt and the scanning */
429         tmp = dz_in(dport, DZ_CSR);
430         tmp |= DZ_RIE | DZ_TIE | DZ_MSE;
431         dz_out(dport, DZ_CSR, tmp);
432
433         spin_unlock_irqrestore(&dport->port.lock, flags);
434
435         return 0;
436 }
437
438 /* 
439  * -------------------------------------------------------------------
440  * shutdown ()
441  *
442  * This routine will shutdown a serial port; interrupts are disabled, and
443  * DTR is dropped if the hangup on close termio flag is on.
444  * ------------------------------------------------------------------- 
445  */
446 static void dz_shutdown(struct uart_port *uport)
447 {
448         dz_stop_tx(uport, 0);
449 }
450
451 /*
452  * get_lsr_info - get line status register info
453  *
454  * Purpose: Let user call ioctl() to get info when the UART physically
455  *          is emptied.  On bus types like RS485, the transmitter must
456  *          release the bus after transmitting. This must be done when
457  *          the transmit shift register is empty, not be done when the
458  *          transmit holding register is empty.  This functionality
459  *          allows an RS485 driver to be written in user space. 
460  */
461 static unsigned int dz_tx_empty(struct uart_port *uport)
462 {
463         struct dz_port *dport = (struct dz_port *)uport;
464         unsigned short status = dz_in(dport, DZ_LPR);
465
466         /* FIXME: this appears to be obviously broken --rmk. */
467         return status ? TIOCSER_TEMT : 0;
468 }
469
470 static void dz_break_ctl(struct uart_port *uport, int break_state)
471 {
472         struct dz_port *dport = (struct dz_port *)uport;
473         unsigned long flags;
474         unsigned short tmp, mask = 1 << uport->line;
475
476         spin_lock_irqsave(&uport->lock, flags);
477         tmp = dz_in(dport, DZ_TCR);
478         if (break_state)
479                 tmp |= mask;
480         else
481                 tmp &= ~mask;
482         dz_out(dport, DZ_TCR, tmp);
483         spin_unlock_irqrestore(&uport->lock, flags);
484 }
485
486 static void dz_set_termios(struct uart_port *uport, struct termios *termios,
487                            struct termios *old_termios)
488 {
489         struct dz_port *dport = (struct dz_port *)uport;
490         unsigned long flags;
491         unsigned int cflag, baud;
492
493         cflag = dport->port.line;
494
495         switch (termios->c_cflag & CSIZE) {
496         case CS5:
497                 cflag |= DZ_CS5;
498                 break;
499         case CS6:
500                 cflag |= DZ_CS6;
501                 break;
502         case CS7:
503                 cflag |= DZ_CS7;
504                 break;
505         case CS8:
506         default:
507                 cflag |= DZ_CS8;
508         }
509
510         if (termios->c_cflag & CSTOPB)
511                 cflag |= DZ_CSTOPB;
512         if (termios->c_cflag & PARENB)
513                 cflag |= DZ_PARENB;
514         if (termios->c_cflag & PARODD)
515                 cflag |= DZ_PARODD;
516
517         baud = uart_get_baud_rate(uport, termios, old_termios, 50, 9600);
518         switch (baud) {
519         case 50:
520                 cflag |= DZ_B50;
521                 break;
522         case 75:
523                 cflag |= DZ_B75;
524                 break;
525         case 110:
526                 cflag |= DZ_B110;
527                 break;
528         case 134:
529                 cflag |= DZ_B134;
530                 break;
531         case 150:
532                 cflag |= DZ_B150;
533                 break;
534         case 300:
535                 cflag |= DZ_B300;
536                 break;
537         case 600:
538                 cflag |= DZ_B600;
539                 break;
540         case 1200:
541                 cflag |= DZ_B1200;
542                 break;
543         case 1800:
544                 cflag |= DZ_B1800;
545                 break;
546         case 2000:
547                 cflag |= DZ_B2000;
548                 break;
549         case 2400:
550                 cflag |= DZ_B2400;
551                 break;
552         case 3600:
553                 cflag |= DZ_B3600;
554                 break;
555         case 4800:
556                 cflag |= DZ_B4800;
557                 break;
558         case 7200:
559                 cflag |= DZ_B7200;
560                 break;
561         case 9600:
562         default:
563                 cflag |= DZ_B9600;
564         }
565
566         if (termios->c_cflag & CREAD)
567                 cflag |= DZ_RXENAB;
568
569         spin_lock_irqsave(&dport->port.lock, flags);
570
571         dz_out(dport, DZ_LPR, cflag);
572         dport->cflag = cflag;
573
574         /* setup accept flag */
575         dport->port.read_status_mask = DZ_OERR;
576         if (termios->c_iflag & INPCK)
577                 dport->port.read_status_mask |= DZ_FERR | DZ_PERR;
578
579         /* characters to ignore */
580         uport->ignore_status_mask = 0;
581         if (termios->c_iflag & IGNPAR)
582                 dport->port.ignore_status_mask |= DZ_FERR | DZ_PERR;
583
584         spin_unlock_irqrestore(&dport->port.lock, flags);
585 }
586
587 static const char *dz_type(struct uart_port *port)
588 {
589         return "DZ";
590 }
591
592 static void dz_release_port(struct uart_port *port)
593 {
594         /* nothing to do */
595 }
596
597 static int dz_request_port(struct uart_port *port)
598 {
599         return 0;
600 }
601
602 static void dz_config_port(struct uart_port *port, int flags)
603 {
604         if (flags & UART_CONFIG_TYPE)
605                 port->type = PORT_DZ;
606 }
607
608 /*
609  * verify the new serial_struct (for TIOCSSERIAL).
610  */
611 static int dz_verify_port(struct uart_port *port, struct serial_struct *ser)
612 {
613         int ret = 0;
614         if (ser->type != PORT_UNKNOWN && ser->type != PORT_DZ)
615                 ret = -EINVAL;
616         if (ser->irq != port->irq)
617                 ret = -EINVAL;
618         return ret;
619 }
620
621 static struct uart_ops dz_ops = {
622         .tx_empty       = dz_tx_empty,
623         .get_mctrl      = dz_get_mctrl,
624         .set_mctrl      = dz_set_mctrl,
625         .stop_tx        = dz_stop_tx,
626         .start_tx       = dz_start_tx,
627         .stop_rx        = dz_stop_rx,
628         .enable_ms      = dz_enable_ms,
629         .break_ctl      = dz_break_ctl,
630         .startup        = dz_startup,
631         .shutdown       = dz_shutdown,
632         .set_termios    = dz_set_termios,
633         .type           = dz_type,
634         .release_port   = dz_release_port,
635         .request_port   = dz_request_port,
636         .config_port    = dz_config_port,
637         .verify_port    = dz_verify_port,
638 };
639
640 static void __init dz_init_ports(void)
641 {
642         static int first = 1;
643         struct dz_port *dport;
644         unsigned long base;
645         int i;
646
647         if (!first)
648                 return;
649         first = 0;
650
651         if (mips_machtype == MACH_DS23100 ||
652             mips_machtype == MACH_DS5100)
653                 base = (unsigned long) KN01_DZ11_BASE;
654         else
655                 base = (unsigned long) KN02_DZ11_BASE;
656
657         for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) {
658                 spin_lock_init(&dport->port.lock);
659                 dport->port.membase     = (char *) base;
660                 dport->port.iotype      = SERIAL_IO_PORT;
661                 dport->port.irq         = dec_interrupt[DEC_IRQ_DZ11];
662                 dport->port.line        = i;
663                 dport->port.fifosize    = 1;
664                 dport->port.ops         = &dz_ops;
665                 dport->port.flags       = UPF_BOOT_AUTOCONF;
666         }
667 }
668
669 static void dz_reset(struct dz_port *dport)
670 {
671         dz_out(dport, DZ_CSR, DZ_CLR);
672
673         while (dz_in(dport, DZ_CSR) & DZ_CLR);
674                 /* FIXME: cpu_relax? */
675
676         iob();
677
678         /* enable scanning */
679         dz_out(dport, DZ_CSR, DZ_MSE);
680 }
681
682 #ifdef CONFIG_SERIAL_DZ_CONSOLE
683 static void dz_console_put_char(struct dz_port *dport, unsigned char ch)
684 {
685         unsigned long flags;
686         int loops = 2500;
687         unsigned short tmp = ch;
688         /* this code sends stuff out to serial device - spinning its
689            wheels and waiting. */
690
691         spin_lock_irqsave(&dport->port.lock, flags);
692
693         /* spin our wheels */
694         while (((dz_in(dport, DZ_CSR) & DZ_TRDY) != DZ_TRDY) && loops--)
695                 /* FIXME: cpu_relax, udelay? --rmk */
696                 ;
697
698         /* Actually transmit the character. */
699         dz_out(dport, DZ_TDR, tmp);
700
701         spin_unlock_irqrestore(&dport->port.lock, flags);
702 }
703 /* 
704  * -------------------------------------------------------------------
705  * dz_console_print ()
706  *
707  * dz_console_print is registered for printk.
708  * The console must be locked when we get here.
709  * ------------------------------------------------------------------- 
710  */
711 static void dz_console_print(struct console *cons,
712                              const char *str,
713                              unsigned int count)
714 {
715         struct dz_port *dport = &dz_ports[CONSOLE_LINE];
716 #ifdef DEBUG_DZ
717         prom_printf((char *) str);
718 #endif
719         while (count--) {
720                 if (*str == '\n')
721                         dz_console_put_char(dport, '\r');
722                 dz_console_put_char(dport, *str++);
723         }
724 }
725
726 static int __init dz_console_setup(struct console *co, char *options)
727 {
728         struct dz_port *dport = &dz_ports[CONSOLE_LINE];
729         int baud = 9600;
730         int bits = 8;
731         int parity = 'n';
732         int flow = 'n';
733         int ret;
734         unsigned short mask, tmp;
735
736         if (options)
737                 uart_parse_options(options, &baud, &parity, &bits, &flow);
738
739         dz_reset(dport);
740
741         ret = uart_set_options(&dport->port, co, baud, parity, bits, flow);
742         if (ret == 0) {
743                 mask = 1 << dport->port.line;
744                 tmp = dz_in(dport, DZ_TCR);     /* read the TX flag */
745                 if (!(tmp & mask)) {
746                         tmp |= mask;            /* set the TX flag */
747                         dz_out(dport, DZ_TCR, tmp);
748                 }
749         }
750
751         return ret;
752 }
753
754 static struct console dz_sercons =
755 {
756         .name   = "ttyS",
757         .write  = dz_console_print,
758         .device = uart_console_device,
759         .setup  = dz_console_setup,
760         .flags  = CON_CONSDEV | CON_PRINTBUFFER,
761         .index  = CONSOLE_LINE,
762 };
763
764 void __init dz_serial_console_init(void)
765 {
766         dz_init_ports();
767
768         register_console(&dz_sercons);
769 }
770
771 #define SERIAL_DZ_CONSOLE       &dz_sercons
772 #else
773 #define SERIAL_DZ_CONSOLE       NULL
774 #endif /* CONFIG_SERIAL_DZ_CONSOLE */
775
776 static struct uart_driver dz_reg = {
777         .owner                  = THIS_MODULE,
778         .driver_name            = "serial",
779 #ifdef CONFIG_DEVFS
780         .dev_name               = "tts/%d",
781 #else
782         .dev_name               = "ttyS%d",
783 #endif
784         .major                  = TTY_MAJOR,
785         .minor                  = 64,
786         .nr                     = DZ_NB_PORT,
787         .cons                   = SERIAL_DZ_CONSOLE,
788 };
789
790 int __init dz_init(void)
791 {
792         unsigned long flags;
793         int ret, i;
794
795         printk("%s%s\n", dz_name, dz_version);
796
797         dz_init_ports();
798
799         save_flags(flags);
800         cli();
801
802 #ifndef CONFIG_SERIAL_DZ_CONSOLE
803         /* reset the chip */
804         dz_reset(&dz_ports[0]);
805 #endif
806
807         /* order matters here... the trick is that flags
808            is updated... in request_irq - to immediatedly obliterate
809            it is unwise. */
810         restore_flags(flags);
811
812         if (request_irq(dz_ports[0].port.irq, dz_interrupt,
813                         SA_INTERRUPT, "DZ", &dz_ports[0]))
814                 panic("Unable to register DZ interrupt");
815
816         ret = uart_register_driver(&dz_reg);
817         if (ret != 0)
818                 return ret;
819
820         for (i = 0; i < DZ_NB_PORT; i++)
821                 uart_add_one_port(&dz_reg, &dz_ports[i].port);
822
823         return ret;
824 }
825
826 MODULE_DESCRIPTION("DECstation DZ serial driver");
827 MODULE_LICENSE("GPL");