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