[PATCH] TTY layer buffering revamp
[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)
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)
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
220                 icount->rx++;
221
222                 /* keep track of the statistics */
223                 if (status & (DZ_OERR | DZ_FERR | DZ_PERR)) {
224                         if (status & DZ_PERR)   /* parity error */
225                                 icount->parity++;
226                         else if (status & DZ_FERR)      /* frame error */
227                                 icount->frame++;
228                         if (status & DZ_OERR)   /* overrun error */
229                                 icount->overrun++;
230
231                         /*  check to see if we should ignore the character
232                            and mask off conditions that should be ignored
233                          */
234
235                         if (status & dport->port.ignore_status_mask) {
236                                 if (++ignore > 100)
237                                         break;
238                                 goto ignore_char;
239                         }
240                         /* mask off the error conditions we want to ignore */
241                         tmp = status & dport->port.read_status_mask;
242
243                         if (tmp & DZ_PERR) {
244                                 flag = TTY_PARITY;
245 #ifdef DEBUG_DZ
246                                 debug_console("PERR\n", 5);
247 #endif
248                         } else if (tmp & DZ_FERR) {
249                                 flag = TTY_FRAME;
250 #ifdef DEBUG_DZ
251                                 debug_console("FERR\n", 5);
252 #endif
253                         }
254                         if (tmp & DZ_OERR) {
255 #ifdef DEBUG_DZ
256                                 debug_console("OERR\n", 5);
257 #endif
258                                 tty_insert_flip_char(tty, ch, flag);
259                                 ch = 0;
260                                 flag = TTY_OVERRUN;
261                         }
262                 }
263                 tty_insert_flip_char(tty, ch, flag);
264               ignore_char:
265         } while (status & DZ_DVAL);
266
267         if (tty)
268                 tty_flip_buffer_push(tty);
269 }
270
271 /*
272  * ------------------------------------------------------------
273  * transmit_char ()
274  *
275  * This routine deals with outputs to any lines.
276  * ------------------------------------------------------------
277  */
278 static inline void dz_transmit_chars(struct dz_port *dport)
279 {
280         struct circ_buf *xmit = &dport->port.info->xmit;
281         unsigned char tmp;
282
283         if (dport->port.x_char) {       /* XON/XOFF chars */
284                 dz_out(dport, DZ_TDR, dport->port.x_char);
285                 dport->port.icount.tx++;
286                 dport->port.x_char = 0;
287                 return;
288         }
289         /* if nothing to do or stopped or hardware stopped */
290         if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) {
291                 dz_stop_tx(&dport->port);
292                 return;
293         }
294
295         /*
296          * if something to do ... (rember the dz has no output fifo so we go
297          * one char at a time :-<
298          */
299         tmp = xmit->buf[xmit->tail];
300         xmit->tail = (xmit->tail + 1) & (DZ_XMIT_SIZE - 1);
301         dz_out(dport, DZ_TDR, tmp);
302         dport->port.icount.tx++;
303
304         if (uart_circ_chars_pending(xmit) < DZ_WAKEUP_CHARS)
305                 uart_write_wakeup(&dport->port);
306
307         /* Are we done */
308         if (uart_circ_empty(xmit))
309                 dz_stop_tx(&dport->port);
310 }
311
312 /*
313  * ------------------------------------------------------------
314  * check_modem_status ()
315  *
316  * Only valid for the MODEM line duh !
317  * ------------------------------------------------------------
318  */
319 static inline void check_modem_status(struct dz_port *dport)
320 {
321         unsigned short status;
322
323         /* if not ne modem line just return */
324         if (dport->port.line != DZ_MODEM)
325                 return;
326
327         status = dz_in(dport, DZ_MSR);
328
329         /* it's easy, since DSR2 is the only bit in the register */
330         if (status)
331                 dport->port.icount.dsr++;
332 }
333
334 /*
335  * ------------------------------------------------------------
336  * dz_interrupt ()
337  *
338  * this is the main interrupt routine for the DZ chip.
339  * It deals with the multiple ports.
340  * ------------------------------------------------------------
341  */
342 static irqreturn_t dz_interrupt(int irq, void *dev, struct pt_regs *regs)
343 {
344         struct dz_port *dport;
345         unsigned short status;
346
347         /* get the reason why we just got an irq */
348         status = dz_in((struct dz_port *)dev, DZ_CSR);
349         dport = &dz_ports[LINE(status)];
350
351         if (status & DZ_RDONE)
352                 dz_receive_chars(dport);
353
354         if (status & DZ_TRDY)
355                 dz_transmit_chars(dport);
356
357         /* FIXME: what about check modem status??? --rmk */
358
359         return IRQ_HANDLED;
360 }
361
362 /*
363  * -------------------------------------------------------------------
364  * Here ends the DZ interrupt routines.
365  * -------------------------------------------------------------------
366  */
367
368 static unsigned int dz_get_mctrl(struct uart_port *uport)
369 {
370         struct dz_port *dport = (struct dz_port *)uport;
371         unsigned int mctrl = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
372
373         if (dport->port.line == DZ_MODEM) {
374                 /*
375                  * CHECKME: This is a guess from the other code... --rmk
376                  */
377                 if (dz_in(dport, DZ_MSR) & DZ_MODEM_DSR)
378                         mctrl &= ~TIOCM_DSR;
379         }
380
381         return mctrl;
382 }
383
384 static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl)
385 {
386         struct dz_port *dport = (struct dz_port *)uport;
387         unsigned short tmp;
388
389         if (dport->port.line == DZ_MODEM) {
390                 tmp = dz_in(dport, DZ_TCR);
391                 if (mctrl & TIOCM_DTR)
392                         tmp &= ~DZ_MODEM_DTR;
393                 else
394                         tmp |= DZ_MODEM_DTR;
395                 dz_out(dport, DZ_TCR, tmp);
396         }
397 }
398
399 /*
400  * -------------------------------------------------------------------
401  * startup ()
402  *
403  * various initialization tasks
404  * -------------------------------------------------------------------
405  */
406 static int dz_startup(struct uart_port *uport)
407 {
408         struct dz_port *dport = (struct dz_port *)uport;
409         unsigned long flags;
410         unsigned short tmp;
411
412         /* The dz lines for the mouse/keyboard must be
413          * opened using their respective drivers.
414          */
415         if ((dport->port.line == DZ_KEYBOARD) ||
416             (dport->port.line == DZ_MOUSE))
417                 return -ENODEV;
418
419         spin_lock_irqsave(&dport->port.lock, flags);
420
421         /* enable the interrupt and the scanning */
422         tmp = dz_in(dport, DZ_CSR);
423         tmp |= DZ_RIE | DZ_TIE | DZ_MSE;
424         dz_out(dport, DZ_CSR, tmp);
425
426         spin_unlock_irqrestore(&dport->port.lock, flags);
427
428         return 0;
429 }
430
431 /*
432  * -------------------------------------------------------------------
433  * shutdown ()
434  *
435  * This routine will shutdown a serial port; interrupts are disabled, and
436  * DTR is dropped if the hangup on close termio flag is on.
437  * -------------------------------------------------------------------
438  */
439 static void dz_shutdown(struct uart_port *uport)
440 {
441         dz_stop_tx(uport);
442 }
443
444 /*
445  * get_lsr_info - get line status register info
446  *
447  * Purpose: Let user call ioctl() to get info when the UART physically
448  *          is emptied.  On bus types like RS485, the transmitter must
449  *          release the bus after transmitting. This must be done when
450  *          the transmit shift register is empty, not be done when the
451  *          transmit holding register is empty.  This functionality
452  *          allows an RS485 driver to be written in user space.
453  */
454 static unsigned int dz_tx_empty(struct uart_port *uport)
455 {
456         struct dz_port *dport = (struct dz_port *)uport;
457         unsigned short status = dz_in(dport, DZ_LPR);
458
459         /* FIXME: this appears to be obviously broken --rmk. */
460         return status ? TIOCSER_TEMT : 0;
461 }
462
463 static void dz_break_ctl(struct uart_port *uport, int break_state)
464 {
465         struct dz_port *dport = (struct dz_port *)uport;
466         unsigned long flags;
467         unsigned short tmp, mask = 1 << uport->line;
468
469         spin_lock_irqsave(&uport->lock, flags);
470         tmp = dz_in(dport, DZ_TCR);
471         if (break_state)
472                 tmp |= mask;
473         else
474                 tmp &= ~mask;
475         dz_out(dport, DZ_TCR, tmp);
476         spin_unlock_irqrestore(&uport->lock, flags);
477 }
478
479 static void dz_set_termios(struct uart_port *uport, struct termios *termios,
480                            struct termios *old_termios)
481 {
482         struct dz_port *dport = (struct dz_port *)uport;
483         unsigned long flags;
484         unsigned int cflag, baud;
485
486         cflag = dport->port.line;
487
488         switch (termios->c_cflag & CSIZE) {
489         case CS5:
490                 cflag |= DZ_CS5;
491                 break;
492         case CS6:
493                 cflag |= DZ_CS6;
494                 break;
495         case CS7:
496                 cflag |= DZ_CS7;
497                 break;
498         case CS8:
499         default:
500                 cflag |= DZ_CS8;
501         }
502
503         if (termios->c_cflag & CSTOPB)
504                 cflag |= DZ_CSTOPB;
505         if (termios->c_cflag & PARENB)
506                 cflag |= DZ_PARENB;
507         if (termios->c_cflag & PARODD)
508                 cflag |= DZ_PARODD;
509
510         baud = uart_get_baud_rate(uport, termios, old_termios, 50, 9600);
511         switch (baud) {
512         case 50:
513                 cflag |= DZ_B50;
514                 break;
515         case 75:
516                 cflag |= DZ_B75;
517                 break;
518         case 110:
519                 cflag |= DZ_B110;
520                 break;
521         case 134:
522                 cflag |= DZ_B134;
523                 break;
524         case 150:
525                 cflag |= DZ_B150;
526                 break;
527         case 300:
528                 cflag |= DZ_B300;
529                 break;
530         case 600:
531                 cflag |= DZ_B600;
532                 break;
533         case 1200:
534                 cflag |= DZ_B1200;
535                 break;
536         case 1800:
537                 cflag |= DZ_B1800;
538                 break;
539         case 2000:
540                 cflag |= DZ_B2000;
541                 break;
542         case 2400:
543                 cflag |= DZ_B2400;
544                 break;
545         case 3600:
546                 cflag |= DZ_B3600;
547                 break;
548         case 4800:
549                 cflag |= DZ_B4800;
550                 break;
551         case 7200:
552                 cflag |= DZ_B7200;
553                 break;
554         case 9600:
555         default:
556                 cflag |= DZ_B9600;
557         }
558
559         if (termios->c_cflag & CREAD)
560                 cflag |= DZ_RXENAB;
561
562         spin_lock_irqsave(&dport->port.lock, flags);
563
564         dz_out(dport, DZ_LPR, cflag);
565         dport->cflag = cflag;
566
567         /* setup accept flag */
568         dport->port.read_status_mask = DZ_OERR;
569         if (termios->c_iflag & INPCK)
570                 dport->port.read_status_mask |= DZ_FERR | DZ_PERR;
571
572         /* characters to ignore */
573         uport->ignore_status_mask = 0;
574         if (termios->c_iflag & IGNPAR)
575                 dport->port.ignore_status_mask |= DZ_FERR | DZ_PERR;
576
577         spin_unlock_irqrestore(&dport->port.lock, flags);
578 }
579
580 static const char *dz_type(struct uart_port *port)
581 {
582         return "DZ";
583 }
584
585 static void dz_release_port(struct uart_port *port)
586 {
587         /* nothing to do */
588 }
589
590 static int dz_request_port(struct uart_port *port)
591 {
592         return 0;
593 }
594
595 static void dz_config_port(struct uart_port *port, int flags)
596 {
597         if (flags & UART_CONFIG_TYPE)
598                 port->type = PORT_DZ;
599 }
600
601 /*
602  * verify the new serial_struct (for TIOCSSERIAL).
603  */
604 static int dz_verify_port(struct uart_port *port, struct serial_struct *ser)
605 {
606         int ret = 0;
607         if (ser->type != PORT_UNKNOWN && ser->type != PORT_DZ)
608                 ret = -EINVAL;
609         if (ser->irq != port->irq)
610                 ret = -EINVAL;
611         return ret;
612 }
613
614 static struct uart_ops dz_ops = {
615         .tx_empty       = dz_tx_empty,
616         .get_mctrl      = dz_get_mctrl,
617         .set_mctrl      = dz_set_mctrl,
618         .stop_tx        = dz_stop_tx,
619         .start_tx       = dz_start_tx,
620         .stop_rx        = dz_stop_rx,
621         .enable_ms      = dz_enable_ms,
622         .break_ctl      = dz_break_ctl,
623         .startup        = dz_startup,
624         .shutdown       = dz_shutdown,
625         .set_termios    = dz_set_termios,
626         .type           = dz_type,
627         .release_port   = dz_release_port,
628         .request_port   = dz_request_port,
629         .config_port    = dz_config_port,
630         .verify_port    = dz_verify_port,
631 };
632
633 static void __init dz_init_ports(void)
634 {
635         static int first = 1;
636         struct dz_port *dport;
637         unsigned long base;
638         int i;
639
640         if (!first)
641                 return;
642         first = 0;
643
644         if (mips_machtype == MACH_DS23100 ||
645             mips_machtype == MACH_DS5100)
646                 base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_DZ11);
647         else
648                 base = CKSEG1ADDR(KN02_SLOT_BASE + KN02_DZ11);
649
650         for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) {
651                 spin_lock_init(&dport->port.lock);
652                 dport->port.membase     = (char *) base;
653                 dport->port.iotype      = SERIAL_IO_PORT;
654                 dport->port.irq         = dec_interrupt[DEC_IRQ_DZ11];
655                 dport->port.line        = i;
656                 dport->port.fifosize    = 1;
657                 dport->port.ops         = &dz_ops;
658                 dport->port.flags       = UPF_BOOT_AUTOCONF;
659         }
660 }
661
662 static void dz_reset(struct dz_port *dport)
663 {
664         dz_out(dport, DZ_CSR, DZ_CLR);
665
666         while (dz_in(dport, DZ_CSR) & DZ_CLR);
667                 /* FIXME: cpu_relax? */
668
669         iob();
670
671         /* enable scanning */
672         dz_out(dport, DZ_CSR, DZ_MSE);
673 }
674
675 #ifdef CONFIG_SERIAL_DZ_CONSOLE
676 static void dz_console_put_char(struct dz_port *dport, unsigned char ch)
677 {
678         unsigned long flags;
679         int loops = 2500;
680         unsigned short tmp = ch;
681         /* this code sends stuff out to serial device - spinning its
682            wheels and waiting. */
683
684         spin_lock_irqsave(&dport->port.lock, flags);
685
686         /* spin our wheels */
687         while (((dz_in(dport, DZ_CSR) & DZ_TRDY) != DZ_TRDY) && loops--)
688                 /* FIXME: cpu_relax, udelay? --rmk */
689                 ;
690
691         /* Actually transmit the character. */
692         dz_out(dport, DZ_TDR, tmp);
693
694         spin_unlock_irqrestore(&dport->port.lock, flags);
695 }
696 /*
697  * -------------------------------------------------------------------
698  * dz_console_print ()
699  *
700  * dz_console_print is registered for printk.
701  * The console must be locked when we get here.
702  * -------------------------------------------------------------------
703  */
704 static void dz_console_print(struct console *cons,
705                              const char *str,
706                              unsigned int count)
707 {
708         struct dz_port *dport = &dz_ports[CONSOLE_LINE];
709 #ifdef DEBUG_DZ
710         prom_printf((char *) str);
711 #endif
712         while (count--) {
713                 if (*str == '\n')
714                         dz_console_put_char(dport, '\r');
715                 dz_console_put_char(dport, *str++);
716         }
717 }
718
719 static int __init dz_console_setup(struct console *co, char *options)
720 {
721         struct dz_port *dport = &dz_ports[CONSOLE_LINE];
722         int baud = 9600;
723         int bits = 8;
724         int parity = 'n';
725         int flow = 'n';
726         int ret;
727         unsigned short mask, tmp;
728
729         if (options)
730                 uart_parse_options(options, &baud, &parity, &bits, &flow);
731
732         dz_reset(dport);
733
734         ret = uart_set_options(&dport->port, co, baud, parity, bits, flow);
735         if (ret == 0) {
736                 mask = 1 << dport->port.line;
737                 tmp = dz_in(dport, DZ_TCR);     /* read the TX flag */
738                 if (!(tmp & mask)) {
739                         tmp |= mask;            /* set the TX flag */
740                         dz_out(dport, DZ_TCR, tmp);
741                 }
742         }
743
744         return ret;
745 }
746
747 static struct console dz_sercons =
748 {
749         .name   = "ttyS",
750         .write  = dz_console_print,
751         .device = uart_console_device,
752         .setup  = dz_console_setup,
753         .flags  = CON_CONSDEV | CON_PRINTBUFFER,
754         .index  = CONSOLE_LINE,
755 };
756
757 void __init dz_serial_console_init(void)
758 {
759         dz_init_ports();
760
761         register_console(&dz_sercons);
762 }
763
764 #define SERIAL_DZ_CONSOLE       &dz_sercons
765 #else
766 #define SERIAL_DZ_CONSOLE       NULL
767 #endif /* CONFIG_SERIAL_DZ_CONSOLE */
768
769 static struct uart_driver dz_reg = {
770         .owner                  = THIS_MODULE,
771         .driver_name            = "serial",
772 #ifdef CONFIG_DEVFS
773         .dev_name               = "tts/%d",
774 #else
775         .dev_name               = "ttyS%d",
776 #endif
777         .major                  = TTY_MAJOR,
778         .minor                  = 64,
779         .nr                     = DZ_NB_PORT,
780         .cons                   = SERIAL_DZ_CONSOLE,
781 };
782
783 int __init dz_init(void)
784 {
785         unsigned long flags;
786         int ret, i;
787
788         printk("%s%s\n", dz_name, dz_version);
789
790         dz_init_ports();
791
792         save_flags(flags);
793         cli();
794
795 #ifndef CONFIG_SERIAL_DZ_CONSOLE
796         /* reset the chip */
797         dz_reset(&dz_ports[0]);
798 #endif
799
800         /* order matters here... the trick is that flags
801            is updated... in request_irq - to immediatedly obliterate
802            it is unwise. */
803         restore_flags(flags);
804
805         if (request_irq(dz_ports[0].port.irq, dz_interrupt,
806                         SA_INTERRUPT, "DZ", &dz_ports[0]))
807                 panic("Unable to register DZ interrupt");
808
809         ret = uart_register_driver(&dz_reg);
810         if (ret != 0)
811                 return ret;
812
813         for (i = 0; i < DZ_NB_PORT; i++)
814                 uart_add_one_port(&dz_reg, &dz_ports[i].port);
815
816         return ret;
817 }
818
819 MODULE_DESCRIPTION("DECstation DZ serial driver");
820 MODULE_LICENSE("GPL");