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