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