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