cleanup
[linux-2.4.21-pre4.git] / drivers / char / 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
24 #define DEBUG_DZ 1
25
26 #include <linux/config.h>
27 #include <linux/version.h>
28 #include <linux/kernel.h>
29 #include <linux/sched.h>
30 #include <linux/init.h>
31 #include <linux/slab.h>
32 #include <linux/mm.h>
33 #include <linux/major.h>
34 #include <linux/module.h>
35 #include <linux/param.h>
36 #include <linux/tqueue.h>
37 #include <linux/interrupt.h>
38 #include <asm-mips/wbflush.h>
39 #include <asm/dec/interrupts.h>
40
41 #include <linux/console.h>
42 #include <linux/tty.h>
43 #include <linux/tty_flip.h>
44 #include <linux/serial.h>
45
46 #include <asm/uaccess.h>
47 #include <asm/irq.h>
48 #include <asm/dec/machtype.h>
49 #include <asm/dec/kn01.h>
50 #include <asm/dec/kn02.h>
51
52 #include <linux/ptrace.h>
53 #include <linux/fs.h>
54 #include <asm/bootinfo.h>
55
56 #define CONSOLE_LINE (3)        /* for definition of struct console */
57
58 extern int (*prom_printf) (char *,...);
59
60 #include "dz.h"
61
62 #define DZ_INTR_DEBUG 1
63
64 DECLARE_TASK_QUEUE(tq_serial);
65
66 static struct dz_serial *lines[4];
67 static unsigned char tmp_buffer[256];
68
69 #ifdef DEBUG_DZ
70 /*
71  * debugging code to send out chars via prom 
72  */
73 static void debug_console(const char *s, int count)
74 {
75         unsigned i;
76
77         for (i = 0; i < count; i++) {
78                 if (*s == 10)
79                         prom_printf("%c", 13);
80                 prom_printf("%c", *s++);
81         }
82 }
83 #endif
84
85 /*
86  * ------------------------------------------------------------
87  * dz_in () and dz_out ()
88  *
89  * These routines are used to access the registers of the DZ 
90  * chip, hiding relocation differences between implementation.
91  * ------------------------------------------------------------
92  */
93
94 static inline unsigned short dz_in(struct dz_serial *info, unsigned offset)
95 {
96         volatile unsigned short *addr =
97                 (volatile unsigned short *) (info->port + offset);
98         return *addr;
99 }
100
101 static inline void dz_out(struct dz_serial *info, unsigned offset,
102                           unsigned short value)
103 {
104
105         volatile unsigned short *addr =
106                 (volatile unsigned short *) (info->port + offset);
107         *addr = value;
108 }
109
110 /*
111  * ------------------------------------------------------------
112  * rs_stop () and rs_start ()
113  *
114  * These routines are called before setting or resetting 
115  * tty->stopped. They enable or disable transmitter interrupts, 
116  * as necessary.
117  * ------------------------------------------------------------
118  */
119
120 static void dz_stop(struct tty_struct *tty)
121 {
122         struct dz_serial *info;
123         unsigned short mask, tmp;
124
125         if (tty == 0)
126                 return;
127
128         info = (struct dz_serial *) tty->driver_data;
129
130         mask = 1 << info->line;
131         tmp = dz_in(info, DZ_TCR);      /* read the TX flag */
132
133         tmp &= ~mask;           /* clear the TX flag */
134         dz_out(info, DZ_TCR, tmp);
135 }
136
137 static void dz_start(struct tty_struct *tty)
138 {
139         struct dz_serial *info = (struct dz_serial *) tty->driver_data;
140         unsigned short mask, tmp;
141
142         mask = 1 << info->line;
143         tmp = dz_in(info, DZ_TCR);      /* read the TX flag */
144
145         tmp |= mask;            /* set the TX flag */
146         dz_out(info, DZ_TCR, tmp);
147
148 }
149
150 /*
151  * ------------------------------------------------------------
152  * Here starts the interrupt handling routines.  All of the 
153  * following subroutines are declared as inline and are folded 
154  * into dz_interrupt.  They were separated out for readability's 
155  * sake. 
156  *
157  * Note: rs_interrupt() is a "fast" interrupt, which means that it
158  * runs with interrupts turned off.  People who may want to modify
159  * rs_interrupt() should try to keep the interrupt handler as fast as
160  * possible.  After you are done making modifications, it is not a bad
161  * idea to do:
162  * 
163  * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer dz.c
164  *
165  * and look at the resulting assemble code in serial.s.
166  *
167  * ------------------------------------------------------------
168  */
169
170 /*
171  * ------------------------------------------------------------
172  * dz_sched_event ()
173  *
174  * This routine is used by the interrupt handler to schedule
175  * processing in the software interrupt portion of the driver.
176  * ------------------------------------------------------------
177  */
178 static inline void dz_sched_event(struct dz_serial *info, int event)
179 {
180         info->event |= 1 << event;
181         queue_task(&info->tqueue, &tq_serial);
182         mark_bh(SERIAL_BH);
183 }
184
185 /*
186  * ------------------------------------------------------------
187  * receive_char ()
188  *
189  * This routine deals with inputs from any lines.
190  * ------------------------------------------------------------
191  */
192 static inline void receive_chars(struct dz_serial *info_in)
193 {
194
195         struct dz_serial *info;
196         struct tty_struct *tty = 0;
197         struct async_icount *icount;
198         int ignore = 0;
199         unsigned short status, tmp;
200         unsigned char ch;
201
202         /* this code is going to be a problem...
203            the call to tty_flip_buffer is going to need
204            to be rethought...
205          */
206         do {
207                 status = dz_in(info_in, DZ_RBUF);
208                 info = lines[LINE(status)];
209
210                 /* punt so we don't get duplicate characters */
211                 if (!(status & DZ_DVAL))
212                         goto ignore_char;
213
214
215                 ch = UCHAR(status);     /* grab the char */
216
217 #if 0
218                 if (info->is_console) {
219                         if (ch == 0)
220                                 return;         /* it's a break ... */
221                 }
222 #endif
223
224                 tty = info->tty;        /* now tty points to the proper dev */
225                 icount = &info->icount;
226
227                 if (!tty)
228                         break;
229                 if (tty->flip.count >= TTY_FLIPBUF_SIZE)
230                         break;
231
232                 *tty->flip.char_buf_ptr = ch;
233                 *tty->flip.flag_buf_ptr = 0;
234                 icount->rx++;
235
236                 /* keep track of the statistics */
237                 if (status & (DZ_OERR | DZ_FERR | DZ_PERR)) {
238                         if (status & DZ_PERR)   /* parity error */
239                                 icount->parity++;
240                         else if (status & DZ_FERR)      /* frame error */
241                                 icount->frame++;
242                         if (status & DZ_OERR)   /* overrun error */
243                                 icount->overrun++;
244
245                         /*  check to see if we should ignore the character
246                            and mask off conditions that should be ignored
247                          */
248
249                         if (status & info->ignore_status_mask) {
250                                 if (++ignore > 100)
251                                         break;
252                                 goto ignore_char;
253                         }
254                         /* mask off the error conditions we want to ignore */
255                         tmp = status & info->read_status_mask;
256
257                         if (tmp & DZ_PERR) {
258                                 *tty->flip.flag_buf_ptr = TTY_PARITY;
259                                 debug_console("PERR\n", 5);
260                         } else if (tmp & DZ_FERR) {
261                                 *tty->flip.flag_buf_ptr = TTY_FRAME;
262                                 debug_console("FERR\n", 5);
263                         }
264                         if (tmp & DZ_OERR) {
265                                 debug_console("OERR\n", 5);
266                                 if (tty->flip.count < TTY_FLIPBUF_SIZE) {
267                                         tty->flip.count++;
268                                         tty->flip.flag_buf_ptr++;
269                                         tty->flip.char_buf_ptr++;
270                                         *tty->flip.flag_buf_ptr = TTY_OVERRUN;
271                                 }
272                         }
273                 }
274                 tty->flip.flag_buf_ptr++;
275                 tty->flip.char_buf_ptr++;
276                 tty->flip.count++;
277               ignore_char:
278         } while (status & DZ_DVAL);
279
280         if (tty)
281                 tty_flip_buffer_push(tty);
282 }
283
284 /*
285  * ------------------------------------------------------------
286  * transmit_char ()
287  *
288  * This routine deals with outputs to any lines.
289  * ------------------------------------------------------------
290  */
291 static inline void transmit_chars(struct dz_serial *info)
292 {
293         unsigned char tmp;
294
295
296
297         if (info->x_char) {     /* XON/XOFF chars */
298                 dz_out(info, DZ_TDR, info->x_char);
299                 info->icount.tx++;
300                 info->x_char = 0;
301                 return;
302         }
303         /* if nothing to do or stopped or hardware stopped */
304         if ((info->xmit_cnt <= 0) || info->tty->stopped || info->tty->hw_stopped) {
305                 dz_stop(info->tty);
306                 return;
307         }
308         /*
309          * if something to do ... (rember the dz has no output fifo so we go
310          * one char at a time :-<
311          */
312         tmp = (unsigned short) info->xmit_buf[info->xmit_tail++];
313         dz_out(info, DZ_TDR, tmp);
314         info->xmit_tail = info->xmit_tail & (DZ_XMIT_SIZE - 1);
315         info->icount.tx++;
316
317         if (--info->xmit_cnt < WAKEUP_CHARS)
318                 dz_sched_event(info, DZ_EVENT_WRITE_WAKEUP);
319
320
321         /* Are we done */
322         if (info->xmit_cnt <= 0)
323                 dz_stop(info->tty);
324 }
325
326 /*
327  * ------------------------------------------------------------
328  * check_modem_status ()
329  *
330  * Only valid for the MODEM line duh !
331  * ------------------------------------------------------------
332  */
333 static inline void check_modem_status(struct dz_serial *info)
334 {
335         unsigned short status;
336
337         /* if not ne modem line just return */
338         if (info->line != DZ_MODEM)
339                 return;
340
341         status = dz_in(info, DZ_MSR);
342
343         /* it's easy, since DSR2 is the only bit in the register */
344         if (status)
345                 info->icount.dsr++;
346 }
347
348 /*
349  * ------------------------------------------------------------
350  * dz_interrupt ()
351  *
352  * this is the main interrupt routine for the DZ chip.
353  * It deals with the multiple ports.
354  * ------------------------------------------------------------
355  */
356 static void dz_interrupt(int irq, void *dev, struct pt_regs *regs)
357 {
358         struct dz_serial *info;
359         unsigned short status;
360
361         /* get the reason why we just got an irq */
362         status = dz_in((struct dz_serial *) dev, DZ_CSR);
363         info = lines[LINE(status)];     /* re-arrange info the proper port */
364
365         if (status & DZ_RDONE)
366                 receive_chars(info);    /* the receive function */
367
368         if (status & DZ_TRDY)
369                 transmit_chars(info);
370 }
371
372 /*
373  * -------------------------------------------------------------------
374  * Here ends the DZ interrupt routines.
375  * -------------------------------------------------------------------
376  */
377
378 /*
379  * This routine is used to handle the "bottom half" processing for the
380  * serial driver, known also the "software interrupt" processing.
381  * This processing is done at the kernel interrupt level, after the
382  * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
383  * is where time-consuming activities which can not be done in the
384  * interrupt driver proper are done; the interrupt driver schedules
385  * them using rs_sched_event(), and they get done here.
386  */
387 static void do_serial_bh(void)
388 {
389         run_task_queue(&tq_serial);
390 }
391
392 static void do_softint(void *private_data)
393 {
394         struct dz_serial *info = (struct dz_serial *) private_data;
395         struct tty_struct *tty = info->tty;
396
397         if (!tty)
398                 return;
399
400         if (test_and_clear_bit(DZ_EVENT_WRITE_WAKEUP, &info->event)) {
401                 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
402                         (tty->ldisc.write_wakeup) (tty);
403                 wake_up_interruptible(&tty->write_wait);
404         }
405 }
406
407 /*
408  * -------------------------------------------------------------------
409  * This routine is called from the scheduler tqueue when the interrupt
410  * routine has signalled that a hangup has occurred.  The path of
411  * hangup processing is:
412  *
413  *      serial interrupt routine -> (scheduler tqueue) ->
414  *      do_serial_hangup() -> tty->hangup() -> rs_hangup()
415  * ------------------------------------------------------------------- 
416  */
417 static void do_serial_hangup(void *private_data)
418 {
419         struct dz_serial *info = (struct dz_serial *) private_data;
420         struct tty_struct *tty = info->tty;;
421
422         if (!tty)
423                 return;
424
425         tty_hangup(tty);
426 }
427
428 /*
429  * -------------------------------------------------------------------
430  * startup ()
431  *
432  * various initialization tasks
433  * ------------------------------------------------------------------- 
434  */
435 static int startup(struct dz_serial *info)
436 {
437         unsigned long page, flags;
438         unsigned short tmp;
439
440         if (info->is_initialized)
441                 return 0;
442
443         save_flags(flags);
444         cli();
445
446         if (!info->port) {
447                 if (info->tty)
448                         set_bit(TTY_IO_ERROR, &info->tty->flags);
449                 restore_flags(flags);
450                 return -ENODEV;
451         }
452         if (!info->xmit_buf) {
453                 page = get_free_page(GFP_KERNEL);
454                 if (!page) {
455                         restore_flags(flags);
456                         return -ENOMEM;
457                 }
458                 info->xmit_buf = (unsigned char *) page;
459         }
460         if (info->tty)
461                 clear_bit(TTY_IO_ERROR, &info->tty->flags);
462
463         /* enable the interrupt and the scanning */
464         tmp = dz_in(info, DZ_CSR);
465         tmp |= (DZ_RIE | DZ_TIE | DZ_MSE);
466         dz_out(info, DZ_CSR, tmp);
467
468         info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
469
470         /* set up the speed */
471         change_speed(info);
472
473         /* clear the line transmitter buffer 
474            I can't figure out why I need to do this - but
475            its necessary - in order for the console portion
476            and the interrupt portion to live happily side by side.
477          */
478
479         /* clear the line transmitter buffer 
480            I can't figure out why I need to do this - but
481            its necessary - in order for the console portion
482            and the interrupt portion to live happily side by side.
483          */
484
485         info->is_initialized = 1;
486
487         restore_flags(flags);
488         return 0;
489 }
490
491 /* 
492  * -------------------------------------------------------------------
493  * shutdown ()
494  *
495  * This routine will shutdown a serial port; interrupts are disabled, and
496  * DTR is dropped if the hangup on close termio flag is on.
497  * ------------------------------------------------------------------- 
498  */
499 static void shutdown(struct dz_serial *info)
500 {
501         unsigned long flags;
502         unsigned short tmp;
503
504         if (!info->is_initialized)
505                 return;
506
507         save_flags(flags);
508         cli();
509
510         dz_stop(info->tty);
511
512
513
514         info->cflags &= ~DZ_CREAD;      /* turn off receive enable flag */
515         dz_out(info, DZ_LPR, info->cflags);
516
517         if (info->xmit_buf) {   /* free Tx buffer */
518                 free_page((unsigned long) info->xmit_buf);
519                 info->xmit_buf = 0;
520         }
521         if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
522                 tmp = dz_in(info, DZ_TCR);
523                 if (tmp & DZ_MODEM_DTR) {
524                         tmp &= ~DZ_MODEM_DTR;
525                         dz_out(info, DZ_TCR, tmp);
526                 }
527         }
528         if (info->tty)
529                 set_bit(TTY_IO_ERROR, &info->tty->flags);
530
531         info->is_initialized = 0;
532         restore_flags(flags);
533 }
534
535 /* 
536  * -------------------------------------------------------------------
537  * change_speed ()
538  *
539  * set the baud rate.
540  * ------------------------------------------------------------------- 
541  */
542 static void change_speed(struct dz_serial *info)
543 {
544         unsigned long flags;
545         unsigned cflag;
546         int baud;
547
548         if (!info->tty || !info->tty->termios)
549                 return;
550
551         save_flags(flags);
552         cli();
553
554         info->cflags = info->line;
555
556         cflag = info->tty->termios->c_cflag;
557
558         switch (cflag & CSIZE) {
559         case CS5:
560                 info->cflags |= DZ_CS5;
561                 break;
562         case CS6:
563                 info->cflags |= DZ_CS6;
564                 break;
565         case CS7:
566                 info->cflags |= DZ_CS7;
567                 break;
568         case CS8:
569         default:
570                 info->cflags |= DZ_CS8;
571         }
572
573         if (cflag & CSTOPB)
574                 info->cflags |= DZ_CSTOPB;
575         if (cflag & PARENB)
576                 info->cflags |= DZ_PARENB;
577         if (cflag & PARODD)
578                 info->cflags |= DZ_PARODD;
579
580         baud = tty_get_baud_rate(info->tty);
581         switch (baud) {
582         case 50:
583                 info->cflags |= DZ_B50;
584                 break;
585         case 75:
586                 info->cflags |= DZ_B75;
587                 break;
588         case 110:
589                 info->cflags |= DZ_B110;
590                 break;
591         case 134:
592                 info->cflags |= DZ_B134;
593                 break;
594         case 150:
595                 info->cflags |= DZ_B150;
596                 break;
597         case 300:
598                 info->cflags |= DZ_B300;
599                 break;
600         case 600:
601                 info->cflags |= DZ_B600;
602                 break;
603         case 1200:
604                 info->cflags |= DZ_B1200;
605                 break;
606         case 1800:
607                 info->cflags |= DZ_B1800;
608                 break;
609         case 2000:
610                 info->cflags |= DZ_B2000;
611                 break;
612         case 2400:
613                 info->cflags |= DZ_B2400;
614                 break;
615         case 3600:
616                 info->cflags |= DZ_B3600;
617                 break;
618         case 4800:
619                 info->cflags |= DZ_B4800;
620                 break;
621         case 7200:
622                 info->cflags |= DZ_B7200;
623                 break;
624         case 9600:
625         default:
626                 info->cflags |= DZ_B9600;
627         }
628
629         info->cflags |= DZ_RXENAB;
630         dz_out(info, DZ_LPR, info->cflags);
631
632         /* setup accept flag */
633         info->read_status_mask = DZ_OERR;
634         if (I_INPCK(info->tty))
635                 info->read_status_mask |= (DZ_FERR | DZ_PERR);
636
637         /* characters to ignore */
638         info->ignore_status_mask = 0;
639         if (I_IGNPAR(info->tty))
640                 info->ignore_status_mask |= (DZ_FERR | DZ_PERR);
641
642         restore_flags(flags);
643 }
644
645 /* 
646  * -------------------------------------------------------------------
647  * dz_flush_char ()
648  *
649  * Flush the buffer.
650  * ------------------------------------------------------------------- 
651  */
652 static void dz_flush_chars(struct tty_struct *tty)
653 {
654         struct dz_serial *info = (struct dz_serial *) tty->driver_data;
655         unsigned long flags;
656
657         if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf)
658                 return;
659
660         save_flags(flags);
661         cli();
662
663         dz_start(info->tty);
664
665         restore_flags(flags);
666 }
667
668
669 /* 
670  * -------------------------------------------------------------------
671  * dz_write ()
672  *
673  * main output routine.
674  * ------------------------------------------------------------------- 
675  */
676 static int dz_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
677 {
678         struct dz_serial *info = (struct dz_serial *) tty->driver_data;
679         unsigned long flags;
680         int c, ret = 0;
681
682         if (!tty)
683                 return ret;
684         if (!info->xmit_buf)
685                 return ret;
686         if (!tmp_buf)
687                 tmp_buf = tmp_buffer;
688
689
690
691         if (from_user) {
692
693                 down(&tmp_buf_sem);
694                 while (1) {
695                         c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head));
696                         if (c <= 0)
697                                 break;
698
699                         c -= copy_from_user(tmp_buf, buf, c);
700                         if (!c) {
701                                 if (!ret)
702                                         ret = -EFAULT;
703                                 break;
704                         }
705                         save_flags(flags);
706                         cli();
707
708                         c = MIN(c, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head));
709                         memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
710                         info->xmit_head = ((info->xmit_head + c) & (DZ_XMIT_SIZE - 1));
711                         info->xmit_cnt += c;
712
713                         restore_flags(flags);
714
715                         buf += c;
716                         count -= c;
717                         ret += c;
718                 }
719
720                 up(&tmp_buf_sem);
721         } else {
722
723
724                 while (1) {
725                         save_flags(flags);
726                         cli();
727
728                         c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE - info->xmit_head));
729                         if (c <= 0) {
730                                 restore_flags(flags);
731                                 break;
732                         }
733                         memcpy(info->xmit_buf + info->xmit_head, buf, c);
734                         info->xmit_head = ((info->xmit_head + c) & (DZ_XMIT_SIZE - 1));
735                         info->xmit_cnt += c;
736
737                         restore_flags(flags);
738
739                         buf += c;
740                         count -= c;
741                         ret += c;
742                 }
743         }
744
745
746         if (info->xmit_cnt) {
747                 if (!tty->stopped) {
748                         if (!tty->hw_stopped) {
749                                 dz_start(info->tty);
750                         }
751                 }
752         }
753         return ret;
754 }
755
756 /* 
757  * -------------------------------------------------------------------
758  * dz_write_room ()
759  *
760  * compute the amount of space available for writing.
761  * ------------------------------------------------------------------- 
762  */
763 static int dz_write_room(struct tty_struct *tty)
764 {
765         struct dz_serial *info = (struct dz_serial *) tty->driver_data;
766         int ret;
767
768         ret = DZ_XMIT_SIZE - info->xmit_cnt - 1;
769         if (ret < 0)
770                 ret = 0;
771         return ret;
772 }
773
774 /* 
775  * -------------------------------------------------------------------
776  * dz_chars_in_buffer ()
777  *
778  * compute the amount of char left to be transmitted
779  * ------------------------------------------------------------------- 
780  */
781 static int dz_chars_in_buffer(struct tty_struct *tty)
782 {
783         struct dz_serial *info = (struct dz_serial *) tty->driver_data;
784
785         return info->xmit_cnt;
786 }
787
788 /* 
789  * -------------------------------------------------------------------
790  * dz_flush_buffer ()
791  *
792  * Empty the output buffer
793  * ------------------------------------------------------------------- 
794  */
795 static void dz_flush_buffer(struct tty_struct *tty)
796 {
797         struct dz_serial *info = (struct dz_serial *) tty->driver_data;
798
799         cli();
800         info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
801         sti();
802
803         wake_up_interruptible(&tty->write_wait);
804
805         if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
806                 (tty->ldisc.write_wakeup) (tty);
807 }
808
809 /*
810  * ------------------------------------------------------------
811  * dz_throttle () and dz_unthrottle ()
812  * 
813  * This routine is called by the upper-layer tty layer to signal that
814  * incoming characters should be throttled (or not).
815  * ------------------------------------------------------------
816  */
817 static void dz_throttle(struct tty_struct *tty)
818 {
819         struct dz_serial *info = (struct dz_serial *) tty->driver_data;
820
821         if (I_IXOFF(tty))
822                 info->x_char = STOP_CHAR(tty);
823 }
824
825 static void dz_unthrottle(struct tty_struct *tty)
826 {
827         struct dz_serial *info = (struct dz_serial *) tty->driver_data;
828
829         if (I_IXOFF(tty)) {
830                 if (info->x_char)
831                         info->x_char = 0;
832                 else
833                         info->x_char = START_CHAR(tty);
834         }
835 }
836
837 static void dz_send_xchar(struct tty_struct *tty, char ch)
838 {
839         struct dz_serial *info = (struct dz_serial *) tty->driver_data;
840
841         info->x_char = ch;
842
843         if (ch)
844                 dz_start(info->tty);
845 }
846
847 /*
848  * ------------------------------------------------------------
849  * rs_ioctl () and friends
850  * ------------------------------------------------------------
851  */
852 static int get_serial_info(struct dz_serial *info,
853                            struct serial_struct *retinfo)
854 {
855         struct serial_struct tmp;
856
857         if (!retinfo)
858                 return -EFAULT;
859
860         memset(&tmp, 0, sizeof(tmp));
861
862         tmp.type = info->type;
863         tmp.line = info->line;
864         tmp.port = info->port;
865         tmp.irq = SERIAL;
866         tmp.flags = info->flags;
867         tmp.baud_base = info->baud_base;
868         tmp.close_delay = info->close_delay;
869         tmp.closing_wait = info->closing_wait;
870
871         return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
872 }
873
874 static int set_serial_info(struct dz_serial *info,
875                            struct serial_struct *new_info)
876 {
877         struct serial_struct new_serial;
878         struct dz_serial old_info;
879         int retval = 0;
880
881         if (!new_info)
882                 return -EFAULT;
883
884         if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
885                 return -EFAULT;
886
887         old_info = *info;
888
889         if (!capable(CAP_SYS_ADMIN))
890                 return -EPERM;
891
892         if (info->count > 1)
893                 return -EBUSY;
894
895         /*
896          * OK, past this point, all the error checking has been done.
897          * At this point, we start making changes.....
898          */
899
900         info->baud_base = new_serial.baud_base;
901         info->type = new_serial.type;
902         info->close_delay = new_serial.close_delay;
903         info->closing_wait = new_serial.closing_wait;
904
905         retval = startup(info);
906         return retval;
907 }
908
909 /*
910  * get_lsr_info - get line status register info
911  *
912  * Purpose: Let user call ioctl() to get info when the UART physically
913  *          is emptied.  On bus types like RS485, the transmitter must
914  *          release the bus after transmitting. This must be done when
915  *          the transmit shift register is empty, not be done when the
916  *          transmit holding register is empty.  This functionality
917  *          allows an RS485 driver to be written in user space. 
918  */
919 static int get_lsr_info(struct dz_serial *info, unsigned int *value)
920 {
921         unsigned short status = dz_in(info, DZ_LPR);
922
923         return put_user(status, value);
924 }
925
926 /*
927  * This routine sends a break character out the serial port.
928  */
929 static void send_break(struct dz_serial *info, int duration)
930 {
931         unsigned long flags;
932         unsigned short tmp, mask;
933
934         if (!info->port)
935                 return;
936
937         mask = 1 << info->line;
938         tmp = dz_in(info, DZ_TCR);
939         tmp |= mask;
940
941         current->state = TASK_INTERRUPTIBLE;
942
943         save_flags(flags);
944         cli();
945
946         dz_out(info, DZ_TCR, tmp);
947
948         schedule_timeout(duration);
949
950         tmp &= ~mask;
951         dz_out(info, DZ_TCR, tmp);
952
953         restore_flags(flags);
954 }
955
956 static int dz_ioctl(struct tty_struct *tty, struct file *file,
957                     unsigned int cmd, unsigned long arg)
958 {
959         struct dz_serial *info = (struct dz_serial *) tty->driver_data;
960         int retval;
961
962         if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
963             (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
964             (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
965                 if (tty->flags & (1 << TTY_IO_ERROR))
966                         return -EIO;
967         }
968         switch (cmd) {
969         case TCSBRK:            /* SVID version: non-zero arg --> no break */
970                 retval = tty_check_change(tty);
971                 if (retval)
972                         return retval;
973                 tty_wait_until_sent(tty, 0);
974                 if (!arg)
975                         send_break(info, HZ / 4);       /* 1/4 second */
976                 return 0;
977
978         case TCSBRKP:           /* support for POSIX tcsendbreak() */
979                 retval = tty_check_change(tty);
980                 if (retval)
981                         return retval;
982                 tty_wait_until_sent(tty, 0);
983                 send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
984                 return 0;
985
986         case TIOCGSOFTCAR:
987                 return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
988
989         case TIOCSSOFTCAR:
990                 if (get_user(arg, (unsigned long *) arg))
991                         return -EFAULT;
992                 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) |
993                                          (arg ? CLOCAL : 0));
994                 return 0;
995
996         case TIOCGSERIAL:
997                 return get_serial_info(info, (struct serial_struct *) arg);
998
999         case TIOCSSERIAL:
1000                 return set_serial_info(info, (struct serial_struct *) arg);
1001
1002         case TIOCSERGETLSR:     /* Get line status register */
1003                 return get_lsr_info(info, (unsigned int *) arg);
1004
1005         case TIOCSERGSTRUCT:
1006                 return copy_to_user((struct dz_serial *) arg, info,
1007                                  sizeof(struct dz_serial)) ? -EFAULT : 0;
1008
1009         default:
1010                 return -ENOIOCTLCMD;
1011         }
1012
1013         return 0;
1014 }
1015
1016 static void dz_set_termios(struct tty_struct *tty,
1017                            struct termios *old_termios)
1018 {
1019         struct dz_serial *info = (struct dz_serial *) tty->driver_data;
1020
1021         if (tty->termios->c_cflag == old_termios->c_cflag)
1022                 return;
1023
1024         change_speed(info);
1025
1026         if ((old_termios->c_cflag & CRTSCTS) &&
1027             !(tty->termios->c_cflag & CRTSCTS)) {
1028                 tty->hw_stopped = 0;
1029                 dz_start(tty);
1030         }
1031 }
1032
1033 /*
1034  * ------------------------------------------------------------
1035  * dz_close()
1036  * 
1037  * This routine is called when the serial port gets closed.  First, we
1038  * wait for the last remaining data to be sent.  Then, we turn off
1039  * the transmit enable and receive enable flags.
1040  * ------------------------------------------------------------
1041  */
1042 static void dz_close(struct tty_struct *tty, struct file *filp)
1043 {
1044         struct dz_serial *info = (struct dz_serial *) tty->driver_data;
1045         unsigned long flags;
1046
1047         if (!info)
1048                 return;
1049
1050         save_flags(flags);
1051         cli();
1052
1053         if (tty_hung_up_p(filp)) {
1054                 restore_flags(flags);
1055                 return;
1056         }
1057         if ((tty->count == 1) && (info->count != 1)) {
1058                 /*
1059                  * Uh, oh.  tty->count is 1, which means that the tty
1060                  * structure will be freed.  Info->count should always
1061                  * be one in these conditions.  If it's greater than
1062                  * one, we've got real problems, since it means the
1063                  * serial port won't be shutdown.
1064                  */
1065                 printk("dz_close: bad serial port count; tty->count is 1, "
1066                        "info->count is %d\n", info->count);
1067                 info->count = 1;
1068         }
1069         if (--info->count < 0) {
1070                 printk("ds_close: bad serial port count for ttyS%02d: %d\n",
1071                        info->line, info->count);
1072                 info->count = 0;
1073         }
1074         if (info->count) {
1075                 restore_flags(flags);
1076                 return;
1077         }
1078         info->flags |= DZ_CLOSING;
1079         /*
1080          * Save the termios structure, since this port may have
1081          * separate termios for callout and dialin.
1082          */
1083         if (info->flags & DZ_NORMAL_ACTIVE)
1084                 info->normal_termios = *tty->termios;
1085         if (info->flags & DZ_CALLOUT_ACTIVE)
1086                 info->callout_termios = *tty->termios;
1087         /*
1088          * Now we wait for the transmit buffer to clear; and we notify 
1089          * the line discipline to only process XON/XOFF characters.
1090          */
1091         tty->closing = 1;
1092
1093         if (info->closing_wait != DZ_CLOSING_WAIT_NONE)
1094                 tty_wait_until_sent(tty, info->closing_wait);
1095
1096         /*
1097          * At this point we stop accepting input.  To do this, we
1098          * disable the receive line status interrupts.
1099          */
1100
1101         shutdown(info);
1102
1103         if (tty->driver.flush_buffer)
1104                 tty->driver.flush_buffer(tty);
1105         if (tty->ldisc.flush_buffer)
1106                 tty->ldisc.flush_buffer(tty);
1107         tty->closing = 0;
1108         info->event = 0;
1109         info->tty = 0;
1110
1111         if (tty->ldisc.num != ldiscs[N_TTY].num) {
1112                 if (tty->ldisc.close)
1113                         (tty->ldisc.close) (tty);
1114                 tty->ldisc = ldiscs[N_TTY];
1115                 tty->termios->c_line = N_TTY;
1116                 if (tty->ldisc.open)
1117                         (tty->ldisc.open) (tty);
1118         }
1119         if (info->blocked_open) {
1120                 if (info->close_delay) {
1121                         current->state = TASK_INTERRUPTIBLE;
1122                         schedule_timeout(info->close_delay);
1123                 }
1124                 wake_up_interruptible(&info->open_wait);
1125         }
1126         info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE | DZ_CLOSING);
1127         wake_up_interruptible(&info->close_wait);
1128
1129         restore_flags(flags);
1130 }
1131
1132 /*
1133  * dz_hangup () --- called by tty_hangup() when a hangup is signaled.
1134  */
1135 static void dz_hangup(struct tty_struct *tty)
1136 {
1137         struct dz_serial *info = (struct dz_serial *) tty->driver_data;
1138
1139         dz_flush_buffer(tty);
1140         shutdown(info);
1141         info->event = 0;
1142         info->count = 0;
1143         info->flags &= ~(DZ_NORMAL_ACTIVE | DZ_CALLOUT_ACTIVE);
1144         info->tty = 0;
1145         wake_up_interruptible(&info->open_wait);
1146 }
1147
1148 /*
1149  * ------------------------------------------------------------
1150  * rs_open() and friends
1151  * ------------------------------------------------------------
1152  */
1153 static int block_til_ready(struct tty_struct *tty, struct file *filp, struct dz_serial *info)
1154 {
1155         DECLARE_WAITQUEUE(wait, current);
1156         int retval;
1157         int do_clocal = 0;
1158
1159         /*
1160          * If the device is in the middle of being closed, then block
1161          * until it's done, and then try again.
1162          */
1163         if (info->flags & DZ_CLOSING) {
1164                 interruptible_sleep_on(&info->close_wait);
1165                 return -EAGAIN;
1166         }
1167         /*
1168          * If this is a callout device, then just make sure the normal
1169          * device isn't being used.
1170          */
1171         if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
1172                 if (info->flags & DZ_NORMAL_ACTIVE)
1173                         return -EBUSY;
1174
1175                 if ((info->flags & DZ_CALLOUT_ACTIVE) &&
1176                     (info->flags & DZ_SESSION_LOCKOUT) &&
1177                     (info->session != current->session))
1178                         return -EBUSY;
1179
1180                 if ((info->flags & DZ_CALLOUT_ACTIVE) &&
1181                     (info->flags & DZ_PGRP_LOCKOUT) &&
1182                     (info->pgrp != current->pgrp))
1183                         return -EBUSY;
1184                 info->flags |= DZ_CALLOUT_ACTIVE;
1185                 return 0;
1186         }
1187         /*
1188          * If non-blocking mode is set, or the port is not enabled,
1189          * then make the check up front and then exit.
1190          */
1191         if ((filp->f_flags & O_NONBLOCK) ||
1192             (tty->flags & (1 << TTY_IO_ERROR))) {
1193                 if (info->flags & DZ_CALLOUT_ACTIVE)
1194                         return -EBUSY;
1195                 info->flags |= DZ_NORMAL_ACTIVE;
1196                 return 0;
1197         }
1198         if (info->flags & DZ_CALLOUT_ACTIVE) {
1199                 if (info->normal_termios.c_cflag & CLOCAL)
1200                         do_clocal = 1;
1201         } else {
1202                 if (tty->termios->c_cflag & CLOCAL)
1203                         do_clocal = 1;
1204         }
1205
1206         /*
1207          * Block waiting for the carrier detect and the line to become
1208          * free (i.e., not in use by the callout).  While we are in
1209          * this loop, info->count is dropped by one, so that
1210          * dz_close() knows when to free things.  We restore it upon
1211          * exit, either normal or abnormal.
1212          */
1213         retval = 0;
1214         add_wait_queue(&info->open_wait, &wait);
1215
1216         info->count--;
1217         info->blocked_open++;
1218         while (1) {
1219                 set_current_state(TASK_INTERRUPTIBLE);
1220                 if (tty_hung_up_p(filp) || !(info->is_initialized)) {
1221                         retval = -EAGAIN;
1222                         break;
1223                 }
1224                 if (!(info->flags & DZ_CALLOUT_ACTIVE) &&
1225                     !(info->flags & DZ_CLOSING) && do_clocal)
1226                         break;
1227                 if (signal_pending(current)) {
1228                         retval = -ERESTARTSYS;
1229                         break;
1230                 }
1231                 schedule();
1232         }
1233
1234         current->state = TASK_RUNNING;
1235         remove_wait_queue(&info->open_wait, &wait);
1236         if (!tty_hung_up_p(filp))
1237                 info->count++;
1238         info->blocked_open--;
1239
1240         if (retval)
1241                 return retval;
1242         info->flags |= DZ_NORMAL_ACTIVE;
1243         return 0;
1244 }
1245
1246 /*
1247  * This routine is called whenever a serial port is opened.  It
1248  * enables interrupts for a serial port. It also performs the 
1249  * serial-specific initialization for the tty structure.
1250  */
1251 static int dz_open(struct tty_struct *tty, struct file *filp)
1252 {
1253         struct dz_serial *info;
1254         int retval, line;
1255
1256         line = MINOR(tty->device) - tty->driver.minor_start;
1257
1258         /* The dz lines for the mouse/keyboard must be
1259          * opened using their respective drivers.
1260          */
1261         if ((line < 0) || (line >= DZ_NB_PORT))
1262                 return -ENODEV;
1263
1264         if ((line == DZ_KEYBOARD) || (line == DZ_MOUSE))
1265                 return -ENODEV;
1266
1267         info = lines[line];
1268         info->count++;
1269
1270         tty->driver_data = info;
1271         info->tty = tty;
1272
1273         /*
1274          * Start up serial port
1275          */
1276         retval = startup(info);
1277         if (retval)
1278                 return retval;
1279
1280         retval = block_til_ready(tty, filp, info);
1281         if (retval)
1282                 return retval;
1283
1284         if ((info->count == 1) && (info->flags & DZ_SPLIT_TERMIOS)) {
1285                 if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
1286                         *tty->termios = info->normal_termios;
1287                 else
1288                         *tty->termios = info->callout_termios;
1289                 change_speed(info);
1290
1291         }
1292         info->session = current->session;
1293         info->pgrp = current->pgrp;
1294         return 0;
1295 }
1296
1297 static void show_serial_version(void)
1298 {
1299         printk("%s%s\n", dz_name, dz_version);
1300 }
1301
1302 int __init dz_init(void)
1303 {
1304         int i, tmp;
1305         long flags;
1306         struct dz_serial *info;
1307
1308         /* Setup base handler, and timer table. */
1309         init_bh(SERIAL_BH, do_serial_bh);
1310
1311         show_serial_version();
1312
1313         memset(&serial_driver, 0, sizeof(struct tty_driver));
1314         serial_driver.magic = TTY_DRIVER_MAGIC;
1315 #if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
1316         serial_driver.name = "ttyS";
1317 #else
1318         serial_driver.name = "tts/%d";
1319 #endif
1320         serial_driver.major = TTY_MAJOR;
1321         serial_driver.minor_start = 64;
1322         serial_driver.num = DZ_NB_PORT;
1323         serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
1324         serial_driver.subtype = SERIAL_TYPE_NORMAL;
1325         serial_driver.init_termios = tty_std_termios;
1326
1327         serial_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
1328                                              CLOCAL;
1329         serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
1330         serial_driver.refcount = &serial_refcount;
1331         serial_driver.table = serial_table;
1332         serial_driver.termios = serial_termios;
1333         serial_driver.termios_locked = serial_termios_locked;
1334
1335         serial_driver.open = dz_open;
1336         serial_driver.close = dz_close;
1337         serial_driver.write = dz_write;
1338         serial_driver.flush_chars = dz_flush_chars;
1339         serial_driver.write_room = dz_write_room;
1340         serial_driver.chars_in_buffer = dz_chars_in_buffer;
1341         serial_driver.flush_buffer = dz_flush_buffer;
1342         serial_driver.ioctl = dz_ioctl;
1343         serial_driver.throttle = dz_throttle;
1344         serial_driver.unthrottle = dz_unthrottle;
1345         serial_driver.send_xchar = dz_send_xchar;
1346         serial_driver.set_termios = dz_set_termios;
1347         serial_driver.stop = dz_stop;
1348         serial_driver.start = dz_start;
1349         serial_driver.hangup = dz_hangup;
1350
1351         /*
1352          * The callout device is just like normal device except for
1353          * major number and the subtype code.
1354          */
1355         callout_driver = serial_driver;
1356 #if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
1357         callout_driver.name = "cua";
1358 #else
1359         callout_driver.name = "cua/%d";
1360 #endif
1361         callout_driver.major = TTYAUX_MAJOR;
1362         callout_driver.subtype = SERIAL_TYPE_CALLOUT;
1363
1364         if (tty_register_driver(&serial_driver))
1365                 panic("Couldn't register serial driver");
1366         if (tty_register_driver(&callout_driver))
1367                 panic("Couldn't register callout driver");
1368         save_flags(flags);
1369         cli();
1370
1371         for (i = 0; i < DZ_NB_PORT; i++) {
1372                 info = &multi[i];
1373                 lines[i] = info;
1374                 info->magic = SERIAL_MAGIC;
1375
1376                 if (mips_machtype == MACH_DS23100 ||
1377                     mips_machtype == MACH_DS5100)
1378                         info->port = (unsigned long) KN01_DZ11_BASE;
1379                 else
1380                         info->port = (unsigned long) KN02_DZ11_BASE;
1381
1382                 info->line = i;
1383                 info->tty = 0;
1384                 info->close_delay = 50;
1385                 info->closing_wait = 3000;
1386                 info->x_char = 0;
1387                 info->event = 0;
1388                 info->count = 0;
1389                 info->blocked_open = 0;
1390                 info->tqueue.routine = do_softint;
1391                 info->tqueue.data = info;
1392                 info->tqueue_hangup.routine = do_serial_hangup;
1393                 info->tqueue_hangup.data = info;
1394                 info->callout_termios = callout_driver.init_termios;
1395                 info->normal_termios = serial_driver.init_termios;
1396                 init_waitqueue_head(&info->open_wait);
1397                 init_waitqueue_head(&info->close_wait);
1398
1399                 /*
1400                  * If we are pointing to address zero then punt - not correctly
1401                  * set up in setup.c to handle this.
1402                  */
1403                 if (!info->port)
1404                         return 0;
1405
1406                 printk("ttyS%02d at 0x%08x (irq = %d)\n", info->line,
1407                        info->port, SERIAL);
1408
1409                 tty_register_devfs(&serial_driver, 0,
1410                                  serial_driver.minor_start + info->line);
1411                 tty_register_devfs(&callout_driver, 0,
1412                                 callout_driver.minor_start + info->line);
1413         }
1414
1415         /* reset the chip */
1416 #ifndef CONFIG_SERIAL_CONSOLE
1417         dz_out(info, DZ_CSR, DZ_CLR);
1418         while ((tmp = dz_in(info, DZ_CSR)) & DZ_CLR);
1419         wbflush();
1420
1421         /* enable scanning */
1422         dz_out(info, DZ_CSR, DZ_MSE);
1423 #endif
1424
1425         /* order matters here... the trick is that flags
1426            is updated... in request_irq - to immediatedly obliterate
1427            it is unwise. */
1428         restore_flags(flags);
1429
1430
1431         if (request_irq(SERIAL, dz_interrupt, SA_INTERRUPT, "DZ", lines[0]))
1432                 panic("Unable to register DZ interrupt");
1433
1434         return 0;
1435 }
1436
1437 #ifdef CONFIG_SERIAL_CONSOLE
1438 static void dz_console_put_char(unsigned char ch)
1439 {
1440         unsigned long flags;
1441         int loops = 2500;
1442         unsigned short tmp = ch;
1443         /* this code sends stuff out to serial device - spinning its
1444            wheels and waiting. */
1445
1446         /* force the issue - point it at lines[3] */
1447         dz_console = &multi[CONSOLE_LINE];
1448
1449         save_flags(flags);
1450         cli();
1451
1452
1453         /* spin our wheels */
1454         while (((dz_in(dz_console, DZ_CSR) & DZ_TRDY) != DZ_TRDY) && loops--);
1455
1456         /* Actually transmit the character. */
1457         dz_out(dz_console, DZ_TDR, tmp);
1458
1459         restore_flags(flags);
1460 }
1461 /* 
1462  * -------------------------------------------------------------------
1463  * dz_console_print ()
1464  *
1465  * dz_console_print is registered for printk.
1466  * The console must be locked when we get here.
1467  * ------------------------------------------------------------------- 
1468  */
1469 static void dz_console_print(struct console *cons,
1470                              const char *str,
1471                              unsigned int count)
1472 {
1473 #ifdef DEBUG_DZ
1474         prom_printf((char *) str);
1475 #endif
1476         while (count--) {
1477                 if (*str == '\n')
1478                         dz_console_put_char('\r');
1479                 dz_console_put_char(*str++);
1480         }
1481 }
1482
1483 static kdev_t dz_console_device(struct console *c)
1484 {
1485         return MKDEV(TTY_MAJOR, 64 + c->index);
1486 }
1487
1488 static int __init dz_console_setup(struct console *co, char *options)
1489 {
1490         int baud = 9600;
1491         int bits = 8;
1492         int parity = 'n';
1493         int cflag = CREAD | HUPCL | CLOCAL;
1494         char *s;
1495         unsigned short mask, tmp;
1496
1497         if (options) {
1498                 baud = simple_strtoul(options, NULL, 10);
1499                 s = options;
1500                 while (*s >= '0' && *s <= '9')
1501                         s++;
1502                 if (*s)
1503                         parity = *s++;
1504                 if (*s)
1505                         bits = *s - '0';
1506         }
1507         /*
1508          *    Now construct a cflag setting.
1509          */
1510         switch (baud) {
1511         case 1200:
1512                 cflag |= DZ_B1200;
1513                 break;
1514         case 2400:
1515                 cflag |= DZ_B2400;
1516                 break;
1517         case 4800:
1518                 cflag |= DZ_B4800;
1519                 break;
1520         case 9600:
1521         default:
1522                 cflag |= DZ_B9600;
1523                 break;
1524         }
1525         switch (bits) {
1526         case 7:
1527                 cflag |= DZ_CS7;
1528                 break;
1529         default:
1530         case 8:
1531                 cflag |= DZ_CS8;
1532                 break;
1533         }
1534         switch (parity) {
1535         case 'o':
1536         case 'O':
1537                 cflag |= DZ_PARODD;
1538                 break;
1539         case 'e':
1540         case 'E':
1541                 cflag |= DZ_PARENB;
1542                 break;
1543         }
1544         co->cflag = cflag;
1545
1546         /* TOFIX: force to console line */
1547         dz_console = &multi[CONSOLE_LINE];
1548         if ((mips_machtype == MACH_DS23100) || (mips_machtype == MACH_DS5100))
1549                 dz_console->port = KN01_DZ11_BASE;
1550         else
1551                 dz_console->port = KN02_DZ11_BASE;
1552         dz_console->line = CONSOLE_LINE;
1553
1554         dz_out(dz_console, DZ_CSR, DZ_CLR);
1555         while ((tmp = dz_in(dz_console, DZ_CSR)) & DZ_CLR);
1556
1557         /* enable scanning */
1558         dz_out(dz_console, DZ_CSR, DZ_MSE);
1559
1560         /*  Set up flags... */
1561         dz_console->cflags = 0;
1562         dz_console->cflags |= DZ_B9600;
1563         dz_console->cflags |= DZ_CS8;
1564         dz_console->cflags |= DZ_PARENB;
1565         dz_out(dz_console, DZ_LPR, dz_console->cflags);
1566
1567         mask = 1 << dz_console->line;
1568         tmp = dz_in(dz_console, DZ_TCR);        /* read the TX flag */
1569         if (!(tmp & mask)) {
1570                 tmp |= mask;    /* set the TX flag */
1571                 dz_out(dz_console, DZ_TCR, tmp);
1572         }
1573         return 0;
1574 }
1575
1576 static struct console dz_sercons =
1577 {
1578     name:       "ttyS",
1579     write:      dz_console_print,
1580     device:     dz_console_device,
1581     setup:      dz_console_setup,
1582     flags:      CON_CONSDEV | CON_PRINTBUFFER,
1583     index:      CONSOLE_LINE,
1584 };
1585
1586 void __init dz_serial_console_init(void)
1587 {
1588         register_console(&dz_sercons);
1589 }
1590
1591 #endif /* CONFIG_SERIAL_CONSOLE */
1592
1593 MODULE_LICENSE("GPL");