1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#undef DEBUG_DZ
30
31#if defined(CONFIG_SERIAL_DZ_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
32#define SUPPORT_SYSRQ
33#endif
34
35#include <linux/bitops.h>
36#include <linux/compiler.h>
37#include <linux/console.h>
38#include <linux/delay.h>
39#include <linux/errno.h>
40#include <linux/init.h>
41#include <linux/interrupt.h>
42#include <linux/ioport.h>
43#include <linux/kernel.h>
44#include <linux/major.h>
45#include <linux/module.h>
46#include <linux/serial.h>
47#include <linux/serial_core.h>
48#include <linux/sysrq.h>
49#include <linux/tty.h>
50#include <linux/tty_flip.h>
51
52#include <linux/atomic.h>
53#include <asm/bootinfo.h>
54#include <asm/io.h>
55
56#include <asm/dec/interrupts.h>
57#include <asm/dec/kn01.h>
58#include <asm/dec/kn02.h>
59#include <asm/dec/machtype.h>
60#include <asm/dec/prom.h>
61#include <asm/dec/system.h>
62
63#include "dz.h"
64
65
66MODULE_DESCRIPTION("DECstation DZ serial driver");
67MODULE_LICENSE("GPL");
68
69
70static char dz_name[] __initdata = "DECstation DZ serial driver version ";
71static char dz_version[] __initdata = "1.04";
72
73struct dz_port {
74 struct dz_mux *mux;
75 struct uart_port port;
76 unsigned int cflag;
77};
78
79struct dz_mux {
80 struct dz_port dport[DZ_NB_PORT];
81 atomic_t map_guard;
82 atomic_t irq_guard;
83 int initialised;
84};
85
86static struct dz_mux dz_mux;
87
88static inline struct dz_port *to_dport(struct uart_port *uport)
89{
90 return container_of(uport, struct dz_port, port);
91}
92
93
94
95
96
97
98
99
100
101
102static u16 dz_in(struct dz_port *dport, unsigned offset)
103{
104 void __iomem *addr = dport->port.membase + offset;
105
106 return readw(addr);
107}
108
109static void dz_out(struct dz_port *dport, unsigned offset, u16 value)
110{
111 void __iomem *addr = dport->port.membase + offset;
112
113 writew(value, addr);
114}
115
116
117
118
119
120
121
122
123
124
125
126static void dz_stop_tx(struct uart_port *uport)
127{
128 struct dz_port *dport = to_dport(uport);
129 u16 tmp, mask = 1 << dport->port.line;
130
131 tmp = dz_in(dport, DZ_TCR);
132 tmp &= ~mask;
133 dz_out(dport, DZ_TCR, tmp);
134}
135
136static void dz_start_tx(struct uart_port *uport)
137{
138 struct dz_port *dport = to_dport(uport);
139 u16 tmp, mask = 1 << dport->port.line;
140
141 tmp = dz_in(dport, DZ_TCR);
142 tmp |= mask;
143 dz_out(dport, DZ_TCR, tmp);
144}
145
146static void dz_stop_rx(struct uart_port *uport)
147{
148 struct dz_port *dport = to_dport(uport);
149
150 dport->cflag &= ~DZ_RXENAB;
151 dz_out(dport, DZ_LPR, dport->cflag);
152}
153
154static void dz_enable_ms(struct uart_port *uport)
155{
156
157}
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186static inline void dz_receive_chars(struct dz_mux *mux)
187{
188 struct uart_port *uport;
189 struct dz_port *dport = &mux->dport[0];
190 struct uart_icount *icount;
191 int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 };
192 unsigned char ch, flag;
193 u16 status;
194 int i;
195
196 while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) {
197 dport = &mux->dport[LINE(status)];
198 uport = &dport->port;
199
200 ch = UCHAR(status);
201 flag = TTY_NORMAL;
202
203 icount = &uport->icount;
204 icount->rx++;
205
206 if (unlikely(status & (DZ_OERR | DZ_FERR | DZ_PERR))) {
207
208
209
210
211
212
213
214 if (!ch) {
215 status |= (status & DZ_FERR) >>
216 (ffs(DZ_FERR) - ffs(DZ_BREAK));
217 status &= ~DZ_FERR;
218 }
219
220
221 if (status & DZ_BREAK) {
222 icount->brk++;
223 if (uart_handle_break(uport))
224 continue;
225 } else if (status & DZ_FERR)
226 icount->frame++;
227 else if (status & DZ_PERR)
228 icount->parity++;
229 if (status & DZ_OERR)
230 icount->overrun++;
231
232 status &= uport->read_status_mask;
233 if (status & DZ_BREAK)
234 flag = TTY_BREAK;
235 else if (status & DZ_FERR)
236 flag = TTY_FRAME;
237 else if (status & DZ_PERR)
238 flag = TTY_PARITY;
239
240 }
241
242 if (uart_handle_sysrq_char(uport, ch))
243 continue;
244
245 uart_insert_char(uport, status, DZ_OERR, ch, flag);
246 lines_rx[LINE(status)] = 1;
247 }
248 for (i = 0; i < DZ_NB_PORT; i++)
249 if (lines_rx[i])
250 tty_flip_buffer_push(&mux->dport[i].port.state->port);
251}
252
253
254
255
256
257
258
259
260static inline void dz_transmit_chars(struct dz_mux *mux)
261{
262 struct dz_port *dport = &mux->dport[0];
263 struct circ_buf *xmit;
264 unsigned char tmp;
265 u16 status;
266
267 status = dz_in(dport, DZ_CSR);
268 dport = &mux->dport[LINE(status)];
269 xmit = &dport->port.state->xmit;
270
271 if (dport->port.x_char) {
272 dz_out(dport, DZ_TDR, dport->port.x_char);
273 dport->port.icount.tx++;
274 dport->port.x_char = 0;
275 return;
276 }
277
278 if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) {
279 spin_lock(&dport->port.lock);
280 dz_stop_tx(&dport->port);
281 spin_unlock(&dport->port.lock);
282 return;
283 }
284
285
286
287
288
289 tmp = xmit->buf[xmit->tail];
290 xmit->tail = (xmit->tail + 1) & (DZ_XMIT_SIZE - 1);
291 dz_out(dport, DZ_TDR, tmp);
292 dport->port.icount.tx++;
293
294 if (uart_circ_chars_pending(xmit) < DZ_WAKEUP_CHARS)
295 uart_write_wakeup(&dport->port);
296
297
298 if (uart_circ_empty(xmit)) {
299 spin_lock(&dport->port.lock);
300 dz_stop_tx(&dport->port);
301 spin_unlock(&dport->port.lock);
302 }
303}
304
305
306
307
308
309
310
311
312
313static inline void check_modem_status(struct dz_port *dport)
314{
315
316
317
318
319
320 u16 status;
321
322
323 if (dport->port.line != DZ_MODEM)
324 return;
325
326 status = dz_in(dport, DZ_MSR);
327
328
329 if (status)
330 dport->port.icount.dsr++;
331}
332
333
334
335
336
337
338
339
340
341static irqreturn_t dz_interrupt(int irq, void *dev_id)
342{
343 struct dz_mux *mux = dev_id;
344 struct dz_port *dport = &mux->dport[0];
345 u16 status;
346
347
348 status = dz_in(dport, DZ_CSR);
349
350 if ((status & (DZ_RDONE | DZ_RIE)) == (DZ_RDONE | DZ_RIE))
351 dz_receive_chars(mux);
352
353 if ((status & (DZ_TRDY | DZ_TIE)) == (DZ_TRDY | DZ_TIE))
354 dz_transmit_chars(mux);
355
356 return IRQ_HANDLED;
357}
358
359
360
361
362
363
364
365static unsigned int dz_get_mctrl(struct uart_port *uport)
366{
367
368
369
370 struct dz_port *dport = to_dport(uport);
371 unsigned int mctrl = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
372
373 if (dport->port.line == DZ_MODEM) {
374 if (dz_in(dport, DZ_MSR) & DZ_MODEM_DSR)
375 mctrl &= ~TIOCM_DSR;
376 }
377
378 return mctrl;
379}
380
381static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl)
382{
383
384
385
386 struct dz_port *dport = to_dport(uport);
387 u16 tmp;
388
389 if (dport->port.line == DZ_MODEM) {
390 tmp = dz_in(dport, DZ_TCR);
391 if (mctrl & TIOCM_DTR)
392 tmp &= ~DZ_MODEM_DTR;
393 else
394 tmp |= DZ_MODEM_DTR;
395 dz_out(dport, DZ_TCR, tmp);
396 }
397}
398
399
400
401
402
403
404
405
406static int dz_startup(struct uart_port *uport)
407{
408 struct dz_port *dport = to_dport(uport);
409 struct dz_mux *mux = dport->mux;
410 unsigned long flags;
411 int irq_guard;
412 int ret;
413 u16 tmp;
414
415 irq_guard = atomic_add_return(1, &mux->irq_guard);
416 if (irq_guard != 1)
417 return 0;
418
419 ret = request_irq(dport->port.irq, dz_interrupt,
420 IRQF_SHARED, "dz", mux);
421 if (ret) {
422 atomic_add(-1, &mux->irq_guard);
423 printk(KERN_ERR "dz: Cannot get IRQ %d!\n", dport->port.irq);
424 return ret;
425 }
426
427 spin_lock_irqsave(&dport->port.lock, flags);
428
429
430 tmp = dz_in(dport, DZ_CSR);
431 tmp |= DZ_RIE | DZ_TIE;
432 dz_out(dport, DZ_CSR, tmp);
433
434 spin_unlock_irqrestore(&dport->port.lock, flags);
435
436 return 0;
437}
438
439
440
441
442
443
444
445
446
447static void dz_shutdown(struct uart_port *uport)
448{
449 struct dz_port *dport = to_dport(uport);
450 struct dz_mux *mux = dport->mux;
451 unsigned long flags;
452 int irq_guard;
453 u16 tmp;
454
455 spin_lock_irqsave(&dport->port.lock, flags);
456 dz_stop_tx(&dport->port);
457 spin_unlock_irqrestore(&dport->port.lock, flags);
458
459 irq_guard = atomic_add_return(-1, &mux->irq_guard);
460 if (!irq_guard) {
461
462 tmp = dz_in(dport, DZ_CSR);
463 tmp &= ~(DZ_RIE | DZ_TIE);
464 dz_out(dport, DZ_CSR, tmp);
465
466 free_irq(dport->port.irq, mux);
467 }
468}
469
470
471
472
473
474
475
476
477
478
479
480
481
482static unsigned int dz_tx_empty(struct uart_port *uport)
483{
484 struct dz_port *dport = to_dport(uport);
485 unsigned short tmp, mask = 1 << dport->port.line;
486
487 tmp = dz_in(dport, DZ_TCR);
488 tmp &= mask;
489
490 return tmp ? 0 : TIOCSER_TEMT;
491}
492
493static void dz_break_ctl(struct uart_port *uport, int break_state)
494{
495
496
497
498
499 struct dz_port *dport = to_dport(uport);
500 unsigned long flags;
501 unsigned short tmp, mask = 1 << dport->port.line;
502
503 spin_lock_irqsave(&uport->lock, flags);
504 tmp = dz_in(dport, DZ_TCR);
505 if (break_state)
506 tmp |= mask;
507 else
508 tmp &= ~mask;
509 dz_out(dport, DZ_TCR, tmp);
510 spin_unlock_irqrestore(&uport->lock, flags);
511}
512
513static int dz_encode_baud_rate(unsigned int baud)
514{
515 switch (baud) {
516 case 50:
517 return DZ_B50;
518 case 75:
519 return DZ_B75;
520 case 110:
521 return DZ_B110;
522 case 134:
523 return DZ_B134;
524 case 150:
525 return DZ_B150;
526 case 300:
527 return DZ_B300;
528 case 600:
529 return DZ_B600;
530 case 1200:
531 return DZ_B1200;
532 case 1800:
533 return DZ_B1800;
534 case 2000:
535 return DZ_B2000;
536 case 2400:
537 return DZ_B2400;
538 case 3600:
539 return DZ_B3600;
540 case 4800:
541 return DZ_B4800;
542 case 7200:
543 return DZ_B7200;
544 case 9600:
545 return DZ_B9600;
546 default:
547 return -1;
548 }
549}
550
551
552static void dz_reset(struct dz_port *dport)
553{
554 struct dz_mux *mux = dport->mux;
555
556 if (mux->initialised)
557 return;
558
559 dz_out(dport, DZ_CSR, DZ_CLR);
560 while (dz_in(dport, DZ_CSR) & DZ_CLR);
561 iob();
562
563
564 dz_out(dport, DZ_CSR, DZ_MSE);
565
566 mux->initialised = 1;
567}
568
569static void dz_set_termios(struct uart_port *uport, struct ktermios *termios,
570 struct ktermios *old_termios)
571{
572 struct dz_port *dport = to_dport(uport);
573 unsigned long flags;
574 unsigned int cflag, baud;
575 int bflag;
576
577 cflag = dport->port.line;
578
579 switch (termios->c_cflag & CSIZE) {
580 case CS5:
581 cflag |= DZ_CS5;
582 break;
583 case CS6:
584 cflag |= DZ_CS6;
585 break;
586 case CS7:
587 cflag |= DZ_CS7;
588 break;
589 case CS8:
590 default:
591 cflag |= DZ_CS8;
592 }
593
594 if (termios->c_cflag & CSTOPB)
595 cflag |= DZ_CSTOPB;
596 if (termios->c_cflag & PARENB)
597 cflag |= DZ_PARENB;
598 if (termios->c_cflag & PARODD)
599 cflag |= DZ_PARODD;
600
601 baud = uart_get_baud_rate(uport, termios, old_termios, 50, 9600);
602 bflag = dz_encode_baud_rate(baud);
603 if (bflag < 0) {
604 baud = uart_get_baud_rate(uport, old_termios, NULL, 50, 9600);
605 bflag = dz_encode_baud_rate(baud);
606 if (bflag < 0) {
607 baud = 9600;
608 bflag = DZ_B9600;
609 }
610 tty_termios_encode_baud_rate(termios, baud, baud);
611 }
612 cflag |= bflag;
613
614 if (termios->c_cflag & CREAD)
615 cflag |= DZ_RXENAB;
616
617 spin_lock_irqsave(&dport->port.lock, flags);
618
619 uart_update_timeout(uport, termios->c_cflag, baud);
620
621 dz_out(dport, DZ_LPR, cflag);
622 dport->cflag = cflag;
623
624
625 dport->port.read_status_mask = DZ_OERR;
626 if (termios->c_iflag & INPCK)
627 dport->port.read_status_mask |= DZ_FERR | DZ_PERR;
628 if (termios->c_iflag & (BRKINT | PARMRK))
629 dport->port.read_status_mask |= DZ_BREAK;
630
631
632 uport->ignore_status_mask = 0;
633 if ((termios->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK))
634 dport->port.ignore_status_mask |= DZ_OERR;
635 if (termios->c_iflag & IGNPAR)
636 dport->port.ignore_status_mask |= DZ_FERR | DZ_PERR;
637 if (termios->c_iflag & IGNBRK)
638 dport->port.ignore_status_mask |= DZ_BREAK;
639
640 spin_unlock_irqrestore(&dport->port.lock, flags);
641}
642
643
644
645
646
647
648static void dz_pm(struct uart_port *uport, unsigned int state,
649 unsigned int oldstate)
650{
651 struct dz_port *dport = to_dport(uport);
652 unsigned long flags;
653
654 spin_lock_irqsave(&dport->port.lock, flags);
655 if (state < 3)
656 dz_start_tx(&dport->port);
657 else
658 dz_stop_tx(&dport->port);
659 spin_unlock_irqrestore(&dport->port.lock, flags);
660}
661
662
663static const char *dz_type(struct uart_port *uport)
664{
665 return "DZ";
666}
667
668static void dz_release_port(struct uart_port *uport)
669{
670 struct dz_mux *mux = to_dport(uport)->mux;
671 int map_guard;
672
673 iounmap(uport->membase);
674 uport->membase = NULL;
675
676 map_guard = atomic_add_return(-1, &mux->map_guard);
677 if (!map_guard)
678 release_mem_region(uport->mapbase, dec_kn_slot_size);
679}
680
681static int dz_map_port(struct uart_port *uport)
682{
683 if (!uport->membase)
684 uport->membase = ioremap_nocache(uport->mapbase,
685 dec_kn_slot_size);
686 if (!uport->membase) {
687 printk(KERN_ERR "dz: Cannot map MMIO\n");
688 return -ENOMEM;
689 }
690 return 0;
691}
692
693static int dz_request_port(struct uart_port *uport)
694{
695 struct dz_mux *mux = to_dport(uport)->mux;
696 int map_guard;
697 int ret;
698
699 map_guard = atomic_add_return(1, &mux->map_guard);
700 if (map_guard == 1) {
701 if (!request_mem_region(uport->mapbase, dec_kn_slot_size,
702 "dz")) {
703 atomic_add(-1, &mux->map_guard);
704 printk(KERN_ERR
705 "dz: Unable to reserve MMIO resource\n");
706 return -EBUSY;
707 }
708 }
709 ret = dz_map_port(uport);
710 if (ret) {
711 map_guard = atomic_add_return(-1, &mux->map_guard);
712 if (!map_guard)
713 release_mem_region(uport->mapbase, dec_kn_slot_size);
714 return ret;
715 }
716 return 0;
717}
718
719static void dz_config_port(struct uart_port *uport, int flags)
720{
721 struct dz_port *dport = to_dport(uport);
722
723 if (flags & UART_CONFIG_TYPE) {
724 if (dz_request_port(uport))
725 return;
726
727 uport->type = PORT_DZ;
728
729 dz_reset(dport);
730 }
731}
732
733
734
735
736static int dz_verify_port(struct uart_port *uport, struct serial_struct *ser)
737{
738 int ret = 0;
739
740 if (ser->type != PORT_UNKNOWN && ser->type != PORT_DZ)
741 ret = -EINVAL;
742 if (ser->irq != uport->irq)
743 ret = -EINVAL;
744 return ret;
745}
746
747static struct uart_ops dz_ops = {
748 .tx_empty = dz_tx_empty,
749 .get_mctrl = dz_get_mctrl,
750 .set_mctrl = dz_set_mctrl,
751 .stop_tx = dz_stop_tx,
752 .start_tx = dz_start_tx,
753 .stop_rx = dz_stop_rx,
754 .enable_ms = dz_enable_ms,
755 .break_ctl = dz_break_ctl,
756 .startup = dz_startup,
757 .shutdown = dz_shutdown,
758 .set_termios = dz_set_termios,
759 .pm = dz_pm,
760 .type = dz_type,
761 .release_port = dz_release_port,
762 .request_port = dz_request_port,
763 .config_port = dz_config_port,
764 .verify_port = dz_verify_port,
765};
766
767static void __init dz_init_ports(void)
768{
769 static int first = 1;
770 unsigned long base;
771 int line;
772
773 if (!first)
774 return;
775 first = 0;
776
777 if (mips_machtype == MACH_DS23100 || mips_machtype == MACH_DS5100)
778 base = dec_kn_slot_base + KN01_DZ11;
779 else
780 base = dec_kn_slot_base + KN02_DZ11;
781
782 for (line = 0; line < DZ_NB_PORT; line++) {
783 struct dz_port *dport = &dz_mux.dport[line];
784 struct uart_port *uport = &dport->port;
785
786 dport->mux = &dz_mux;
787
788 uport->irq = dec_interrupt[DEC_IRQ_DZ11];
789 uport->fifosize = 1;
790 uport->iotype = UPIO_MEM;
791 uport->flags = UPF_BOOT_AUTOCONF;
792 uport->ops = &dz_ops;
793 uport->line = line;
794 uport->mapbase = base;
795 }
796}
797
798#ifdef CONFIG_SERIAL_DZ_CONSOLE
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813static void dz_console_putchar(struct uart_port *uport, int ch)
814{
815 struct dz_port *dport = to_dport(uport);
816 unsigned long flags;
817 unsigned short csr, tcr, trdy, mask;
818 int loops = 10000;
819
820 spin_lock_irqsave(&dport->port.lock, flags);
821 csr = dz_in(dport, DZ_CSR);
822 dz_out(dport, DZ_CSR, csr & ~DZ_TIE);
823 tcr = dz_in(dport, DZ_TCR);
824 tcr |= 1 << dport->port.line;
825 mask = tcr;
826 dz_out(dport, DZ_TCR, mask);
827 iob();
828 spin_unlock_irqrestore(&dport->port.lock, flags);
829
830 do {
831 trdy = dz_in(dport, DZ_CSR);
832 if (!(trdy & DZ_TRDY))
833 continue;
834 trdy = (trdy & DZ_TLINE) >> 8;
835 if (trdy == dport->port.line)
836 break;
837 mask &= ~(1 << trdy);
838 dz_out(dport, DZ_TCR, mask);
839 iob();
840 udelay(2);
841 } while (--loops);
842
843 if (loops)
844 dz_out(dport, DZ_TDR, ch);
845
846 dz_out(dport, DZ_TCR, tcr);
847 dz_out(dport, DZ_CSR, csr);
848}
849
850
851
852
853
854
855
856
857
858static void dz_console_print(struct console *co,
859 const char *str,
860 unsigned int count)
861{
862 struct dz_port *dport = &dz_mux.dport[co->index];
863#ifdef DEBUG_DZ
864 prom_printf((char *) str);
865#endif
866 uart_console_write(&dport->port, str, count, dz_console_putchar);
867}
868
869static int __init dz_console_setup(struct console *co, char *options)
870{
871 struct dz_port *dport = &dz_mux.dport[co->index];
872 struct uart_port *uport = &dport->port;
873 int baud = 9600;
874 int bits = 8;
875 int parity = 'n';
876 int flow = 'n';
877 int ret;
878
879 ret = dz_map_port(uport);
880 if (ret)
881 return ret;
882
883 spin_lock_init(&dport->port.lock);
884
885 dz_reset(dport);
886 dz_pm(uport, 0, -1);
887
888 if (options)
889 uart_parse_options(options, &baud, &parity, &bits, &flow);
890
891 return uart_set_options(&dport->port, co, baud, parity, bits, flow);
892}
893
894static struct uart_driver dz_reg;
895static struct console dz_console = {
896 .name = "ttyS",
897 .write = dz_console_print,
898 .device = uart_console_device,
899 .setup = dz_console_setup,
900 .flags = CON_PRINTBUFFER,
901 .index = -1,
902 .data = &dz_reg,
903};
904
905static int __init dz_serial_console_init(void)
906{
907 if (!IOASIC) {
908 dz_init_ports();
909 register_console(&dz_console);
910 return 0;
911 } else
912 return -ENXIO;
913}
914
915console_initcall(dz_serial_console_init);
916
917#define SERIAL_DZ_CONSOLE &dz_console
918#else
919#define SERIAL_DZ_CONSOLE NULL
920#endif
921
922static struct uart_driver dz_reg = {
923 .owner = THIS_MODULE,
924 .driver_name = "serial",
925 .dev_name = "ttyS",
926 .major = TTY_MAJOR,
927 .minor = 64,
928 .nr = DZ_NB_PORT,
929 .cons = SERIAL_DZ_CONSOLE,
930};
931
932static int __init dz_init(void)
933{
934 int ret, i;
935
936 if (IOASIC)
937 return -ENXIO;
938
939 printk("%s%s\n", dz_name, dz_version);
940
941 dz_init_ports();
942
943 ret = uart_register_driver(&dz_reg);
944 if (ret)
945 return ret;
946
947 for (i = 0; i < DZ_NB_PORT; i++)
948 uart_add_one_port(&dz_reg, &dz_mux.dport[i].port);
949
950 return 0;
951}
952
953module_init(dz_init);
954