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