1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/config.h>
19#include <linux/module.h>
20#include <linux/errno.h>
21#include <linux/signal.h>
22#include <linux/sched.h>
23#include <linux/timer.h>
24#include <linux/interrupt.h>
25#include <linux/tty.h>
26#include <linux/tty_flip.h>
27#include <linux/serial.h>
28#include <linux/major.h>
29#include <linux/string.h>
30#include <linux/fcntl.h>
31#include <linux/ptrace.h>
32#include <linux/ioport.h>
33#include <linux/mm.h>
34#include <linux/slab.h>
35#include <linux/init.h>
36#include <linux/delay.h>
37#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_SH_KGDB_CONSOLE)
38#include <linux/console.h>
39#endif
40
41#include <asm/system.h>
42#include <asm/io.h>
43#include <asm/irq.h>
44#include <asm/uaccess.h>
45#include <asm/bitops.h>
46
47#include <linux/generic_serial.h>
48
49#ifdef CONFIG_SH_STANDARD_BIOS
50#include <asm/sh_bios.h>
51#endif
52
53#include "sh-sci.h"
54
55#ifdef CONFIG_SH_KGDB
56#include <asm/kgdb.h>
57
58int kgdb_sci_setup(void);
59static int kgdb_get_char(struct sci_port *port);
60static void kgdb_put_char(struct sci_port *port, char c);
61static void kgdb_handle_error(struct sci_port *port);
62static struct sci_port *kgdb_sci_port;
63
64#ifdef CONFIG_SH_KGDB_CONSOLE
65static struct console kgdbcons;
66void __init kgdb_console_init(void);
67#endif
68
69#endif
70
71#ifdef CONFIG_SERIAL_CONSOLE
72static struct console sercons;
73static struct sci_port* sercons_port=0;
74static int sercons_baud;
75#ifdef CONFIG_MAGIC_SYSRQ
76#include <linux/sysrq.h>
77static int break_pressed;
78#endif
79#endif
80
81
82#if !defined(SCIF_ONLY)
83static void sci_init_pins_sci(struct sci_port* port, unsigned int cflag);
84#endif
85#ifndef SCI_ONLY
86static void sci_init_pins_scif(struct sci_port* port, unsigned int cflag);
87#if defined(__sh3__) && !defined(CONFIG_CPU_SUBTYPE_SH7300)
88static void sci_init_pins_irda(struct sci_port* port, unsigned int cflag);
89#endif
90#endif
91static void sci_disable_tx_interrupts(void *ptr);
92static void sci_enable_tx_interrupts(void *ptr);
93static void sci_disable_rx_interrupts(void *ptr);
94static void sci_enable_rx_interrupts(void *ptr);
95static int sci_get_CD(void *ptr);
96static void sci_shutdown_port(void *ptr);
97static int sci_set_real_termios(void *ptr);
98static void sci_hungup(void *ptr);
99static void sci_close(void *ptr);
100static int sci_chars_in_buffer(void *ptr);
101static int sci_request_irq(struct sci_port *port);
102static void sci_free_irq(struct sci_port *port);
103static int sci_init_drivers(void);
104
105static struct tty_driver sci_driver, sci_callout_driver;
106
107static struct sci_port sci_ports[SCI_NPORTS] = SCI_INIT;
108static struct tty_struct *sci_table[SCI_NPORTS] = { NULL, };
109static struct termios *sci_termios[SCI_NPORTS];
110static struct termios *sci_termios_locked[SCI_NPORTS];
111
112static int sci_refcount;
113static int sci_debug = 0;
114
115#ifdef MODULE
116MODULE_PARM(sci_debug, "i");
117#endif
118
119#define dprintk(x...) do { if (sci_debug) printk(x); } while(0)
120
121#ifdef CONFIG_SERIAL_CONSOLE
122static void put_char(struct sci_port *port, char c)
123{
124 unsigned long flags;
125 unsigned short status;
126
127 save_and_cli(flags);
128
129 do
130 status = sci_in(port, SCxSR);
131 while (!(status & SCxSR_TDxE(port)));
132
133 sci_out(port, SCxTDR, c);
134 sci_in(port, SCxSR);
135 sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
136
137 restore_flags(flags);
138}
139#endif
140
141#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
142
143static void handle_error(struct sci_port *port)
144{
145 sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
146}
147
148static int get_char(struct sci_port *port)
149{
150 unsigned long flags;
151 unsigned short status;
152 int c;
153
154 save_and_cli(flags);
155 do {
156 status = sci_in(port, SCxSR);
157 if (status & SCxSR_ERRORS(port)) {
158 handle_error(port);
159 continue;
160 }
161 } while (!(status & SCxSR_RDxF(port)));
162 c = sci_in(port, SCxRDR);
163 sci_in(port, SCxSR);
164 sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
165 restore_flags(flags);
166
167 return c;
168}
169
170
171static const char hexchars[] = "0123456789abcdef";
172
173static __inline__ char highhex(int x)
174{
175 return hexchars[(x >> 4) & 0xf];
176}
177
178static __inline__ char lowhex(int x)
179{
180 return hexchars[x & 0xf];
181}
182
183#endif
184
185
186
187
188
189
190#ifdef CONFIG_SERIAL_CONSOLE
191static void put_string(struct sci_port *port, const char *buffer, int count)
192{
193 int i;
194 const unsigned char *p = buffer;
195
196#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
197 int checksum;
198 int usegdb=0;
199
200#ifdef CONFIG_SH_STANDARD_BIOS
201
202
203
204 usegdb |= sh_bios_in_gdb_mode();
205#endif
206#ifdef CONFIG_SH_KGDB
207 usegdb |= (kgdb_in_gdb_mode && (port == kgdb_sci_port));
208#endif
209
210 if (usegdb) {
211
212 do {
213 unsigned char c;
214 put_char(port, '$');
215 put_char(port, 'O');
216 checksum = 'O';
217
218 for (i=0; i<count; i++) {
219 int h, l;
220
221 c = *p++;
222 h = highhex(c);
223 l = lowhex(c);
224 put_char(port, h);
225 put_char(port, l);
226 checksum += h + l;
227 }
228 put_char(port, '#');
229 put_char(port, highhex(checksum));
230 put_char(port, lowhex(checksum));
231 } while (get_char(port) != '+');
232 } else
233#endif
234 for (i=0; i<count; i++) {
235 if (*p == 10)
236 put_char(port, '\r');
237 put_char(port, *p++);
238 }
239}
240#endif
241
242
243#if defined(CONFIG_SH_SECUREEDGE5410)
244
245struct timer_list sci_timer_struct;
246static unsigned char sci_dcdstatus[2];
247
248
249
250
251
252
253static void sci_timer(unsigned long data)
254{
255 unsigned short s, i;
256 unsigned char dcdstatus[2];
257
258 s = SECUREEDGE_READ_IOPORT();
259 dcdstatus[0] = !(s & 0x10);
260 dcdstatus[1] = !(s & 0x1);
261
262 for (i = 0; i < 2; i++) {
263 if (dcdstatus[i] != sci_dcdstatus[i]) {
264 if (sci_ports[i].gs.count != 0) {
265 if (sci_ports[i].gs.flags & ASYNC_CHECK_CD) {
266 if (dcdstatus[i]) {
267 wake_up_interruptible(&sci_ports[i].gs.open_wait);
268 } else if (!((sci_ports[i].gs.flags&ASYNC_CALLOUT_ACTIVE) &&
269 (sci_ports[i].gs.flags & ASYNC_CALLOUT_NOHUP))) {
270 if (sci_ports[i].gs.tty)
271 tty_hangup(sci_ports[i].gs.tty);
272 }
273 }
274 }
275 }
276 sci_dcdstatus[i] = dcdstatus[i];
277 }
278
279 sci_timer_struct.expires = jiffies + HZ/25;
280 add_timer(&sci_timer_struct);
281}
282
283#endif
284
285
286
287
288#ifdef CONFIG_SH_KGDB
289
290
291static int kgdb_is_char_ready(struct sci_port *port)
292{
293 unsigned short status = sci_in(port, SCxSR);
294
295 if (status & (SCxSR_ERRORS(port) | SCxSR_BRK(port)))
296 kgdb_handle_error(port);
297
298 return (status & SCxSR_RDxF(port));
299}
300
301
302static void kgdb_put_char(struct sci_port *port, char c)
303{
304 unsigned short status;
305
306 do
307 status = sci_in(port, SCxSR);
308 while (!(status & SCxSR_TDxE(port)));
309
310 sci_out(port, SCxTDR, c);
311 sci_in(port, SCxSR);
312 sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
313}
314
315
316static int kgdb_get_char(struct sci_port *port)
317{
318 int c;
319
320 if (kgdb_is_char_ready(port) == 0)
321 c = -1;
322 else {
323 c = sci_in(port, SCxRDR);
324 sci_in(port, SCxSR);
325 sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
326 }
327
328 return c;
329}
330
331
332static int kgdb_sci_getchar(void)
333{
334 volatile int c;
335
336
337 while ((c = kgdb_get_char(kgdb_sci_port)) < 0);
338
339 return c;
340}
341
342
343static void kgdb_sci_putchar(int c)
344{
345
346 kgdb_put_char(kgdb_sci_port, c);
347}
348
349
350static void kgdb_handle_error(struct sci_port *port)
351{
352 sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
353}
354
355
356static void kgdb_break_interrupt(int irq, void *ptr, struct pt_regs *regs)
357{
358 struct sci_port *port = ptr;
359 unsigned short status = sci_in(port, SCxSR);
360
361 if (status & SCxSR_BRK(port)) {
362
363
364 BREAKPOINT();
365
366
367 sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
368 return;
369 }
370}
371
372#endif
373
374static struct real_driver sci_real_driver = {
375 sci_disable_tx_interrupts,
376 sci_enable_tx_interrupts,
377 sci_disable_rx_interrupts,
378 sci_enable_rx_interrupts,
379 sci_get_CD,
380 sci_shutdown_port,
381 sci_set_real_termios,
382 sci_chars_in_buffer,
383 sci_close,
384 sci_hungup,
385 NULL
386};
387
388#if defined(SCI_ONLY) || defined(SCI_AND_SCIF)
389static void sci_init_pins_sci(struct sci_port* port, unsigned int cflag)
390{
391}
392#endif
393
394#if defined(SCIF_ONLY) || defined(SCI_AND_SCIF)
395#if defined(__sh3__)
396
397static void sci_init_pins_scif(struct sci_port* port, unsigned int cflag)
398{
399 unsigned int fcr_val = 0;
400
401#if !defined(CONFIG_CPU_SUBTYPE_SH7300)
402 {
403 unsigned short data;
404
405
406 data = ctrl_inw(SCPCR);
407
408 ctrl_outw(data&0x0cff, SCPCR);
409 }
410 if (cflag & CRTSCTS)
411 fcr_val |= SCFCR_MCE;
412 else {
413 unsigned short data;
414
415
416 data = ctrl_inw(SCPCR);
417
418
419 ctrl_outw((data&0x0cff)|0x1000, SCPCR);
420
421 data = ctrl_inb(SCPDR);
422
423 ctrl_outb(data&0xbf, SCPDR);
424 }
425#endif
426 sci_out(port, SCFCR, fcr_val);
427}
428
429static void sci_init_pins_irda(struct sci_port* port, unsigned int cflag)
430{
431 unsigned int fcr_val = 0;
432
433 if (cflag & CRTSCTS)
434 fcr_val |= SCFCR_MCE;
435
436 sci_out(port, SCFCR, fcr_val);
437}
438
439#else
440
441
442static void sci_init_pins_scif(struct sci_port* port, unsigned int cflag)
443{
444 unsigned int fcr_val = 0;
445
446 if (cflag & CRTSCTS) {
447 fcr_val |= SCFCR_MCE;
448 } else {
449 sci_out(port, SCSPTR, 0x0080);
450 }
451 sci_out(port, SCFCR, fcr_val);
452}
453
454#endif
455#endif
456
457static void sci_setsignals(struct sci_port *port, int dtr, int rts)
458{
459
460
461
462
463#if defined(CONFIG_SH_SECUREEDGE5410)
464 int flags;
465
466 save_and_cli(flags);
467 if (port == &sci_ports[1]) {
468 if (dtr == 0)
469 SECUREEDGE_WRITE_IOPORT(0x0080, 0x0080);
470 else if (dtr == 1)
471 SECUREEDGE_WRITE_IOPORT(0x0000, 0x0080);
472 }
473 if (port == &sci_ports[0]) {
474 if (dtr == 0)
475 SECUREEDGE_WRITE_IOPORT(0x0200, 0x0200);
476 else if (dtr == 1)
477 SECUREEDGE_WRITE_IOPORT(0x0000, 0x0200);
478 if (rts == 0)
479 SECUREEDGE_WRITE_IOPORT(0x0100, 0x0100);
480 else if (rts == 1)
481 SECUREEDGE_WRITE_IOPORT(0x0000, 0x0100);
482 }
483 restore_flags(flags);
484#endif
485}
486
487static int sci_getsignals(struct sci_port *port)
488{
489
490
491
492#if defined(CONFIG_SH_SECUREEDGE5410)
493 if (port == &sci_ports[1]) {
494 unsigned short s = SECUREEDGE_READ_IOPORT();
495 int rc = TIOCM_RTS|TIOCM_DSR|TIOCM_CTS;
496
497 if ((s & 0x0001) == 0)
498 rc |= TIOCM_CAR;
499 if ((SECUREEDGE_READ_IOPORT() & 0x0080) == 0)
500 rc |= TIOCM_DTR;
501 return(rc);
502 }
503 if (port == &sci_ports[0]) {
504 unsigned short s = SECUREEDGE_READ_IOPORT();
505 int rc = TIOCM_DSR;
506
507 if ((s & 0x0010) == 0)
508 rc |= TIOCM_CAR;
509 if ((s & 0x0004) == 0)
510 rc |= TIOCM_CTS;
511 if ((SECUREEDGE_READ_IOPORT() & 0x0200) == 0)
512 rc |= TIOCM_DTR;
513 if ((SECUREEDGE_READ_IOPORT() & 0x0100) == 0)
514 rc |= TIOCM_RTS;
515 return(rc);
516 }
517#endif
518
519 return TIOCM_DTR|TIOCM_RTS|TIOCM_DSR;
520}
521
522static void sci_set_baud(struct sci_port *port, int baud)
523{
524 int t;
525
526 switch (baud) {
527 case 0:
528 t = -1;
529 break;
530 case 2400:
531 t = BPS_2400;
532 break;
533 case 4800:
534 t = BPS_4800;
535 break;
536 case 9600:
537 t = BPS_9600;
538 break;
539 case 19200:
540 t = BPS_19200;
541 break;
542 case 38400:
543 t = BPS_38400;
544 break;
545 case 57600:
546 t = BPS_57600;
547 break;
548 case 230400:
549 if (BPS_230400 != BPS_115200) {
550 t = BPS_230400;
551 break;
552 }
553 default:
554 printk(KERN_INFO "sci: unsupported baud rate: %d, using 115200 instead.\n", baud);
555 case 115200:
556 t = BPS_115200;
557 break;
558 }
559
560 if (t > 0) {
561 sci_setsignals (port, 1, -1);
562 if(t >= 256) {
563 sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1);
564 t >>= 2;
565 } else {
566 sci_out(port, SCSMR, sci_in(port, SCSMR) & ~3);
567 }
568 sci_out(port, SCBRR, t);
569 udelay((1000000+(baud-1)) / baud);
570 } else {
571 sci_setsignals (port, 0, -1);
572 }
573}
574
575static void sci_set_termios_cflag(struct sci_port *port, int cflag, int baud)
576{
577 unsigned int status;
578 unsigned int smr_val;
579
580 do
581 status = sci_in(port, SCxSR);
582 while (!(status & SCxSR_TEND(port)));
583
584 sci_out(port, SCSCR, 0x00);
585
586 if (port->type == PORT_SCIF) {
587#if defined(CONFIG_CPU_SUBTYPE_SH7300)
588 sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST | SCFCR_TCRST);
589#else
590 sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
591#endif
592 }
593
594 smr_val = sci_in(port, SCSMR) & 3;
595 if ((cflag & CSIZE) == CS7)
596 smr_val |= 0x40;
597 if (cflag & PARENB)
598 smr_val |= 0x20;
599 if (cflag & PARODD)
600 smr_val |= 0x30;
601 if (cflag & CSTOPB)
602 smr_val |= 0x08;
603 sci_out(port, SCSMR, smr_val);
604 sci_set_baud(port, baud);
605
606 port->init_pins(port, cflag);
607 sci_out(port, SCSCR, SCSCR_INIT(port));
608
609 if (cflag & CLOCAL)
610 port->gs.flags &= ~ASYNC_CHECK_CD;
611 else
612 port->gs.flags |= ASYNC_CHECK_CD;
613}
614
615static int sci_set_real_termios(void *ptr)
616{
617 struct sci_port *port = ptr;
618
619 if (port->old_cflag != port->gs.tty->termios->c_cflag) {
620 port->old_cflag = port->gs.tty->termios->c_cflag;
621 sci_set_termios_cflag(port, port->old_cflag, port->gs.baud);
622 sci_enable_rx_interrupts(port);
623 }
624
625 return 0;
626}
627
628
629
630
631
632
633
634
635
636static inline void sci_sched_event(struct sci_port *port, int event)
637{
638 port->event |= 1 << event;
639 queue_task(&port->tqueue, &tq_immediate);
640 mark_bh(IMMEDIATE_BH);
641}
642
643static void sci_transmit_chars(struct sci_port *port)
644{
645 unsigned int count, i;
646 unsigned int txroom;
647 unsigned long flags;
648 unsigned short status;
649 unsigned short ctrl;
650 unsigned char c;
651
652 status = sci_in(port, SCxSR);
653 if (!(status & SCxSR_TDxE(port))) {
654 save_and_cli(flags);
655 ctrl = sci_in(port, SCSCR);
656 if (port->gs.xmit_cnt == 0) {
657 ctrl &= ~SCI_CTRL_FLAGS_TIE;
658 port->gs.flags &= ~GS_TX_INTEN;
659 } else
660 ctrl |= SCI_CTRL_FLAGS_TIE;
661 sci_out(port, SCSCR, ctrl);
662 restore_flags(flags);
663 return;
664 }
665
666 while (1) {
667 count = port->gs.xmit_cnt;
668 if (port->type == PORT_SCIF) {
669#if defined(CONFIG_CPU_SUBTYPE_SH7300)
670 txroom = 64 - (sci_in(port, SCFDR)>>8);
671#else
672 txroom = 16 - (sci_in(port, SCFDR)>>8);
673#endif
674 } else {
675 txroom = (sci_in(port, SCxSR) & SCI_TDRE)?1:0;
676 }
677 if (count > txroom)
678 count = txroom;
679
680
681 if (count > SERIAL_XMIT_SIZE - port->gs.xmit_tail)
682 count = SERIAL_XMIT_SIZE - port->gs.xmit_tail;
683
684
685 if (count == 0)
686 break;
687
688 for (i=0; i<count; i++) {
689 c = port->gs.xmit_buf[port->gs.xmit_tail + i];
690 sci_out(port, SCxTDR, c);
691 }
692 sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
693
694 port->icount.tx += count;
695
696
697 port->gs.xmit_tail = (port->gs.xmit_tail + count) & (SERIAL_XMIT_SIZE-1);
698
699
700
701 port->gs.xmit_cnt -= count;
702 }
703
704 if (port->gs.xmit_cnt <= port->gs.wakeup_chars)
705 sci_sched_event(port, SCI_EVENT_WRITE_WAKEUP);
706
707 save_and_cli(flags);
708 ctrl = sci_in(port, SCSCR);
709 if (port->gs.xmit_cnt == 0) {
710 ctrl &= ~SCI_CTRL_FLAGS_TIE;
711 port->gs.flags &= ~GS_TX_INTEN;
712 } else {
713 if (port->type == PORT_SCIF) {
714 sci_in(port, SCxSR);
715 sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
716 }
717 ctrl |= SCI_CTRL_FLAGS_TIE;
718 }
719 sci_out(port, SCSCR, ctrl);
720 restore_flags(flags);
721}
722
723
724#define STEPFN(c) ({int __c=(c); (((__c-1)|(__c)) == -1); })
725
726static inline void sci_receive_chars(struct sci_port *port,
727 struct pt_regs *regs)
728{
729 int count;
730 struct tty_struct *tty;
731 int copied=0;
732 unsigned short status;
733
734 status = sci_in(port, SCxSR);
735 if (!(status & SCxSR_RDxF(port)))
736 return;
737
738 tty = port->gs.tty;
739
740 while (1) {
741 if (port->type == PORT_SCIF) {
742#if defined(CONFIG_CPU_SUBTYPE_SH7300)
743 count = sci_in(port, SCFDR)&0x007f;
744#else
745 count = sci_in(port, SCFDR)&0x001f;
746#endif
747 } else {
748 count = (sci_in(port, SCxSR)&SCxSR_RDxF(port))?1:0;
749 }
750
751
752 sci_in(port, SCxSR);
753 sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
754
755
756 if (count == 0)
757 break;
758
759 if (port->type == PORT_SCI) {
760 if (tty->flip.count < TTY_FLIPBUF_SIZE) {
761 *tty->flip.char_buf_ptr++ = sci_in(port, SCxRDR);
762 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
763 tty->flip.count++;
764 port->icount.rx++;
765 copied++;
766 count--;
767 }
768 } else {
769 while (count > 0 && tty->flip.count < TTY_FLIPBUF_SIZE){
770 char c = sci_in(port, SCxRDR);
771 status = sci_in(port, SCxSR);
772
773#if defined(__SH3__)
774
775 if (port->break_flag) {
776 if ((c == 0) &&
777 (status & SCxSR_FER(port))) {
778 count--;
779 continue;
780 }
781
782 dprintk("scif: debounce<%02x>\n", c);
783 port->break_flag = 0;
784 if (STEPFN(c)) {
785 count--;
786 continue;
787 }
788 }
789#endif
790#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
791 if (break_pressed && (port == sercons_port)) {
792 if (c != 0 &&
793 time_before(jiffies,
794 break_pressed + HZ*5)) {
795 handle_sysrq(c, regs,
796 NULL, NULL);
797 break_pressed = 0;
798 count--;
799 continue;
800 } else if (c != 0) {
801 break_pressed = 0;
802 }
803 }
804#endif
805
806
807 *tty->flip.char_buf_ptr++ = c;
808
809 if (status&SCxSR_FER(port)) {
810 *tty->flip.flag_buf_ptr++ = TTY_FRAME;
811 dprintk("sci: frame error\n");
812 } else if (status&SCxSR_PER(port)) {
813 *tty->flip.flag_buf_ptr++ = TTY_PARITY;
814 dprintk("sci: parity error\n");
815 } else {
816 *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
817 }
818 tty->flip.count++;
819 port->icount.rx++;
820 copied++;
821 count--;
822 }
823 }
824
825
826 if (count > 0) {
827
828 tty->flip.flag_buf_ptr[TTY_FLIPBUF_SIZE - 1] = TTY_OVERRUN;
829 while (count-- > 0)
830 (void) sci_in(port, SCxRDR);
831 }
832 }
833
834 if (copied)
835
836 tty_flip_buffer_push(tty);
837 else {
838 sci_in(port, SCxSR);
839 sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
840 }
841}
842
843static inline int sci_handle_errors(struct sci_port *port)
844{
845 int copied = 0;
846 unsigned short status = sci_in(port, SCxSR);
847 struct tty_struct *tty = port->gs.tty;
848
849 if (status&SCxSR_ORER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
850
851 copied++;
852 *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
853 dprintk("sci: overrun error\n");
854 }
855
856 if (status&SCxSR_FER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
857 if (sci_rxd_in(port) == 0) {
858
859 copied++;
860 *tty->flip.flag_buf_ptr++ = TTY_BREAK;
861 dprintk("sci: BREAK detected\n");
862 }
863 else {
864
865 copied++;
866 *tty->flip.flag_buf_ptr++ = TTY_FRAME;
867 dprintk("sci: frame error\n");
868 }
869 }
870
871 if (status&SCxSR_PER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
872
873 copied++;
874 *tty->flip.flag_buf_ptr++ = TTY_PARITY;
875 dprintk("sci: parity error\n");
876 }
877
878 if (copied) {
879 tty->flip.count += copied;
880 tty_flip_buffer_push(tty);
881 }
882
883 return copied;
884}
885
886static inline int sci_handle_breaks(struct sci_port *port)
887{
888 int copied = 0;
889 unsigned short status = sci_in(port, SCxSR);
890 struct tty_struct *tty = port->gs.tty;
891
892 if (status&SCxSR_BRK(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
893#if defined(__SH3__)
894
895 if (port->break_flag)
896 goto break_continue;
897 port->break_flag = 1;
898#endif
899#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
900 if (port == sercons_port) {
901 if (break_pressed == 0) {
902 break_pressed = jiffies;
903 dprintk("sci: implied sysrq\n");
904 goto break_continue;
905 }
906
907 break_pressed = 0;
908 }
909#endif
910
911 copied++;
912 *tty->flip.flag_buf_ptr++ = TTY_BREAK;
913 dprintk("sci: BREAK detected\n");
914 }
915#if defined(CONFIG_CPU_SH3) || defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
916 break_continue:
917#endif
918
919#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined (CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_ST40)
920
921 if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) {
922 sci_out(port, SCLSR, 0);
923 if(tty->flip.count<TTY_FLIPBUF_SIZE) {
924 copied++;
925 *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
926 dprintk("sci: overrun error\n");
927 }
928 }
929#endif
930
931 if (copied) {
932 tty->flip.count += copied;
933 tty_flip_buffer_push(tty);
934 }
935
936 return copied;
937}
938
939static void sci_rx_interrupt(int irq, void *ptr, struct pt_regs *regs)
940{
941 struct sci_port *port = ptr;
942
943 if (port->gs.flags & GS_ACTIVE)
944 if (!(port->gs.flags & SCI_RX_THROTTLE)) {
945 sci_receive_chars(port, regs);
946 return;
947 }
948 sci_disable_rx_interrupts(port);
949}
950
951static void sci_tx_interrupt(int irq, void *ptr, struct pt_regs *regs)
952{
953 struct sci_port *port = ptr;
954
955 if (port->gs.flags & GS_ACTIVE)
956 sci_transmit_chars(port);
957 else {
958 sci_disable_tx_interrupts(port);
959 }
960}
961
962static void sci_er_interrupt(int irq, void *ptr, struct pt_regs *regs)
963{
964 struct sci_port *port = ptr;
965
966
967 if (port->type == PORT_SCI) {
968 if(sci_handle_errors(port)) {
969
970 sci_in(port, SCxSR);
971 sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
972 }
973 }
974 else
975 sci_rx_interrupt(irq, ptr, regs);
976
977 sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
978
979
980 sci_tx_interrupt(irq, ptr, regs);
981}
982
983static void sci_br_interrupt(int irq, void *ptr, struct pt_regs *regs)
984{
985 struct sci_port *port = ptr;
986
987
988 sci_handle_breaks(port);
989 sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
990}
991
992static void sci_mpxed_interrupt(int irq, void *ptr, struct pt_regs *regs)
993{
994 unsigned short ssr_status, scr_status;
995 struct sci_port *port = ptr;
996
997 ssr_status=sci_in(port,SCxSR);
998 scr_status=sci_in(port,SCSCR);
999
1000 if((ssr_status&0x0020) && (scr_status&0x0080)){
1001 sci_tx_interrupt(irq, ptr, regs);
1002 }
1003 if((ssr_status&0x0002) && (scr_status&0x0040)){
1004 sci_rx_interrupt(irq, ptr, regs);
1005 }
1006 if((ssr_status&0x0080) && (scr_status&0x0400)){
1007 sci_er_interrupt(irq, ptr, regs);
1008 }
1009 if((ssr_status&0x0010) && (scr_status&0x0200)){
1010 sci_br_interrupt(irq, ptr, regs);
1011 }
1012}
1013
1014static void do_softint(void *private_)
1015{
1016 struct sci_port *port = (struct sci_port *) private_;
1017 struct tty_struct *tty;
1018
1019 tty = port->gs.tty;
1020 if (!tty)
1021 return;
1022
1023 if (test_and_clear_bit(SCI_EVENT_WRITE_WAKEUP, &port->event)) {
1024 tty_wakeup(tty);
1025 }
1026}
1027
1028
1029
1030
1031
1032
1033static void sci_disable_tx_interrupts(void *ptr)
1034{
1035 struct sci_port *port = ptr;
1036 unsigned long flags;
1037 unsigned short ctrl;
1038
1039
1040 save_and_cli(flags);
1041 ctrl = sci_in(port, SCSCR);
1042 ctrl &= ~SCI_CTRL_FLAGS_TIE;
1043 sci_out(port, SCSCR, ctrl);
1044 restore_flags(flags);
1045}
1046
1047static void sci_enable_tx_interrupts(void *ptr)
1048{
1049 struct sci_port *port = ptr;
1050
1051 disable_irq(port->irqs[SCIx_TXI_IRQ]);
1052 sci_transmit_chars(port);
1053 enable_irq(port->irqs[SCIx_TXI_IRQ]);
1054}
1055
1056static void sci_disable_rx_interrupts(void * ptr)
1057{
1058 struct sci_port *port = ptr;
1059 unsigned long flags;
1060 unsigned short ctrl;
1061
1062
1063 save_and_cli(flags);
1064 ctrl = sci_in(port, SCSCR);
1065 ctrl &= ~SCI_CTRL_FLAGS_RIE;
1066 sci_out(port, SCSCR, ctrl);
1067 restore_flags(flags);
1068}
1069
1070static void sci_enable_rx_interrupts(void * ptr)
1071{
1072 struct sci_port *port = ptr;
1073 unsigned long flags;
1074 unsigned short ctrl;
1075
1076
1077 save_and_cli(flags);
1078 ctrl = sci_in(port, SCSCR);
1079 ctrl |= SCI_CTRL_FLAGS_RIE;
1080 sci_out(port, SCSCR, ctrl);
1081 restore_flags(flags);
1082}
1083
1084static int sci_get_CD(void * ptr)
1085{
1086
1087
1088#if defined(CONFIG_SH_SECUREEDGE5410)
1089 struct sci_port *port = ptr;
1090
1091 if (port == &sci_ports[0] || port == &sci_ports[1])
1092 if ((sci_getsignals(port) & TIOCM_CAR) == 0)
1093 return 0;
1094#endif
1095
1096 return 1;
1097}
1098
1099static int sci_chars_in_buffer(void * ptr)
1100{
1101 struct sci_port *port = ptr;
1102
1103 if (port->type == PORT_SCIF) {
1104 return (sci_in(port, SCFDR) >> 8) + ((sci_in(port, SCxSR) & SCxSR_TEND(port))? 0: 1);
1105 } else {
1106 return (sci_in(port, SCxSR) & SCxSR_TEND(port))? 0: 1;
1107 }
1108}
1109
1110static void sci_shutdown_port(void * ptr)
1111{
1112 struct sci_port *port = ptr;
1113
1114 port->gs.flags &= ~ GS_ACTIVE;
1115 if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL)
1116 sci_setsignals(port, 0, 0);
1117 sci_free_irq(port);
1118}
1119
1120
1121
1122
1123
1124
1125static int sci_open(struct tty_struct * tty, struct file * filp)
1126{
1127 struct sci_port *port;
1128 int retval = 0, line;
1129
1130 line = MINOR(tty->device) - SCI_MINOR_START;
1131
1132 if ((line < 0) || (line >= SCI_NPORTS))
1133 return -ENODEV;
1134
1135 port = &sci_ports[line];
1136
1137#if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
1138 if (port->base == 0) {
1139 port->base = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF");
1140 if (!port->base)
1141 goto failed_1;
1142 }
1143#endif
1144
1145 tty->driver_data = port;
1146 port->gs.tty = tty;
1147 port->gs.count++;
1148
1149 port->event = 0;
1150 port->tqueue.routine = do_softint;
1151 port->tqueue.data = port;
1152 port->break_flag = 0;
1153
1154 if (port->gs.count == 1) {
1155 MOD_INC_USE_COUNT;
1156
1157 retval = sci_request_irq(port);
1158 if (retval) {
1159 goto failed_1;
1160 }
1161 }
1162
1163
1164
1165
1166 retval = gs_init_port(&port->gs);
1167 if (retval) {
1168 goto failed_2;
1169 }
1170
1171 port->gs.flags |= GS_ACTIVE;
1172 sci_setsignals(port, 1,1);
1173
1174 retval = gs_block_til_ready(port, filp);
1175
1176 if (retval) {
1177 goto failed_2;
1178 }
1179
1180 if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
1181 if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
1182 *tty->termios = port->gs.normal_termios;
1183 else
1184 *tty->termios = port->gs.callout_termios;
1185 sci_set_real_termios(port);
1186 }
1187
1188#ifdef CONFIG_SERIAL_CONSOLE
1189 if (sercons.cflag && sercons.index == line) {
1190 tty->termios->c_cflag = sercons.cflag;
1191 port->gs.baud = sercons_baud;
1192 sercons.cflag = 0;
1193 sci_set_real_termios(port);
1194 }
1195#endif
1196
1197#ifdef CONFIG_SH_KGDB_CONSOLE
1198 if (kgdbcons.cflag && kgdbcons.index == line) {
1199 tty->termios->c_cflag = kgdbcons.cflag;
1200 port->gs.baud = kgdb_baud;
1201 sercons.cflag = 0;
1202 sci_set_real_termios(port);
1203 }
1204#elif CONFIG_SH_KGDB
1205
1206 if (port == kgdb_sci_port && kgdb_in_gdb_mode) {
1207 tty->termios->c_cflag = kgdb_cflag;
1208 port->gs.baud = kgdb_baud;
1209 sercons.cflag = 0;
1210 sci_set_real_termios(port);
1211 }
1212#endif
1213
1214 sci_enable_rx_interrupts(port);
1215
1216 port->gs.session = current->session;
1217 port->gs.pgrp = current->pgrp;
1218
1219 return 0;
1220
1221failed_2:
1222 sci_free_irq(port);
1223failed_1:
1224 MOD_DEC_USE_COUNT;
1225 port->gs.count--;
1226 return retval;
1227}
1228
1229static void sci_hungup(void *ptr)
1230{
1231 MOD_DEC_USE_COUNT;
1232}
1233
1234static void sci_close(void *ptr)
1235{
1236 MOD_DEC_USE_COUNT;
1237}
1238
1239static int sci_ioctl(struct tty_struct * tty, struct file * filp,
1240 unsigned int cmd, unsigned long arg)
1241{
1242 int rc;
1243 struct sci_port *port = tty->driver_data;
1244 int ival;
1245
1246 rc = 0;
1247 switch (cmd) {
1248 case TIOCGSOFTCAR:
1249 rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
1250 (unsigned int *) arg);
1251 break;
1252 case TIOCSSOFTCAR:
1253 if ((rc = get_user(ival, (unsigned int *) arg)) == 0)
1254 tty->termios->c_cflag =
1255 (tty->termios->c_cflag & ~CLOCAL) |
1256 (ival ? CLOCAL : 0);
1257 break;
1258 case TIOCGSERIAL:
1259 if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
1260 sizeof(struct serial_struct))) == 0)
1261 rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
1262 break;
1263 case TIOCSSERIAL:
1264 if ((rc = verify_area(VERIFY_READ, (void *) arg,
1265 sizeof(struct serial_struct))) == 0)
1266 rc = gs_setserial(&port->gs,
1267 (struct serial_struct *) arg);
1268 break;
1269 case TIOCMGET:
1270 ival = sci_getsignals(port);
1271 rc = put_user(ival, (unsigned int *) arg);
1272 break;
1273 case TIOCMBIS:
1274 if ((rc = get_user(ival, (unsigned int *) arg)) == 0)
1275 sci_setsignals(port, ((ival & TIOCM_DTR) ? 1 : -1),
1276 ((ival & TIOCM_RTS) ? 1 : -1));
1277 break;
1278 case TIOCMBIC:
1279 if ((rc = get_user(ival, (unsigned int *) arg)) == 0)
1280 sci_setsignals(port, ((ival & TIOCM_DTR) ? 0 : -1),
1281 ((ival & TIOCM_RTS) ? 0 : -1));
1282 break;
1283 case TIOCMSET:
1284 if ((rc = get_user(ival, (unsigned int *)arg)) == 0)
1285 sci_setsignals(port, ((ival & TIOCM_DTR) ? 1 : 0),
1286 ((ival & TIOCM_RTS) ? 1 : 0));
1287 break;
1288
1289 default:
1290 rc = -ENOIOCTLCMD;
1291 break;
1292 }
1293
1294 return rc;
1295}
1296
1297static void sci_throttle(struct tty_struct * tty)
1298{
1299 struct sci_port *port = (struct sci_port *)tty->driver_data;
1300
1301
1302
1303
1304 if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty)) )
1305 port->gs.flags |= SCI_RX_THROTTLE;
1306}
1307
1308static void sci_unthrottle(struct tty_struct * tty)
1309{
1310 struct sci_port *port = (struct sci_port *)tty->driver_data;
1311
1312
1313
1314
1315
1316 port->gs.flags &= ~SCI_RX_THROTTLE;
1317 sci_enable_rx_interrupts(port);
1318 return;
1319}
1320
1321#ifdef CONFIG_PROC_FS
1322static int sci_read_proc(char *page, char **start, off_t off, int count,
1323 int *eof, void *data)
1324{
1325 int i;
1326 struct sci_port *port;
1327 int len = 0;
1328
1329 len += sprintf(page, "sciinfo:0.1\n");
1330 for (i = 0; i < SCI_NPORTS && len < 4000; i++) {
1331 port = &sci_ports[i];
1332 len += sprintf(page+len, "%d: uart:%s address: %08x", i,
1333 (port->type == PORT_SCI) ? "SCI" : "SCIF",
1334 port->base);
1335 len += sprintf(page+len, " baud:%d", port->gs.baud);
1336 len += sprintf(page+len, " tx:%d rx:%d",
1337 port->icount.tx, port->icount.rx);
1338
1339 if (port->icount.frame)
1340 len += sprintf(page+len, " fe:%d", port->icount.frame);
1341 if (port->icount.parity)
1342 len += sprintf(page+len, " pe:%d", port->icount.parity);
1343 if (port->icount.brk)
1344 len += sprintf(page+len, " brk:%d", port->icount.brk);
1345 if (port->icount.overrun)
1346 len += sprintf(page+len, " oe:%d", port->icount.overrun);
1347 len += sprintf(page+len, "\n");
1348 }
1349 return len;
1350}
1351#endif
1352
1353
1354
1355
1356
1357static int sci_init_drivers(void)
1358{
1359 int error;
1360 struct sci_port *port;
1361
1362 memset(&sci_driver, 0, sizeof(sci_driver));
1363 sci_driver.magic = TTY_DRIVER_MAGIC;
1364 sci_driver.driver_name = "sci";
1365#ifdef CONFIG_DEVFS_FS
1366 sci_driver.name = "ttsc/%d";
1367#else
1368 sci_driver.name = "ttySC";
1369#endif
1370 sci_driver.major = SCI_MAJOR;
1371 sci_driver.minor_start = SCI_MINOR_START;
1372 sci_driver.num = SCI_NPORTS;
1373 sci_driver.type = TTY_DRIVER_TYPE_SERIAL;
1374 sci_driver.subtype = SERIAL_TYPE_NORMAL;
1375 sci_driver.init_termios = tty_std_termios;
1376 sci_driver.init_termios.c_cflag =
1377 B9600 | CS8 | CREAD | HUPCL | CLOCAL | CRTSCTS;
1378 sci_driver.flags = TTY_DRIVER_REAL_RAW;
1379 sci_driver.refcount = &sci_refcount;
1380 sci_driver.table = sci_table;
1381 sci_driver.termios = sci_termios;
1382 sci_driver.termios_locked = sci_termios_locked;
1383
1384 sci_driver.open = sci_open;
1385 sci_driver.close = gs_close;
1386 sci_driver.write = gs_write;
1387 sci_driver.put_char = gs_put_char;
1388 sci_driver.flush_chars = gs_flush_chars;
1389 sci_driver.write_room = gs_write_room;
1390 sci_driver.chars_in_buffer = gs_chars_in_buffer;
1391 sci_driver.flush_buffer = gs_flush_buffer;
1392 sci_driver.ioctl = sci_ioctl;
1393 sci_driver.throttle = sci_throttle;
1394 sci_driver.unthrottle = sci_unthrottle;
1395 sci_driver.set_termios = gs_set_termios;
1396 sci_driver.stop = gs_stop;
1397 sci_driver.start = gs_start;
1398 sci_driver.hangup = gs_hangup;
1399#ifdef CONFIG_PROC_FS
1400 sci_driver.read_proc = sci_read_proc;
1401#endif
1402
1403 sci_callout_driver = sci_driver;
1404#ifdef CONFIG_DEVFS_FS
1405 sci_callout_driver.name = "cusc/%d";
1406#else
1407 sci_callout_driver.name = "cusc";
1408#endif
1409 sci_callout_driver.major = SCI_MAJOR+1;
1410 sci_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
1411 sci_callout_driver.read_proc = NULL;
1412
1413 if ((error = tty_register_driver(&sci_driver))) {
1414 printk(KERN_ERR "sci: Couldn't register SCI driver, error = %d\n",
1415 error);
1416 return 1;
1417 }
1418 if ((error = tty_register_driver(&sci_callout_driver))) {
1419 tty_unregister_driver(&sci_driver);
1420 printk(KERN_ERR "sci: Couldn't register SCI callout driver, error = %d\n",
1421 error);
1422 return 1;
1423 }
1424
1425 for (port = &sci_ports[0]; port < &sci_ports[SCI_NPORTS]; port++) {
1426 port->gs.callout_termios = sci_callout_driver.init_termios;
1427 port->gs.normal_termios = sci_driver.init_termios;
1428 port->gs.magic = SCI_MAGIC;
1429 port->gs.close_delay = HZ/2;
1430 port->gs.closing_wait = 30 * HZ;
1431 port->gs.rd = &sci_real_driver;
1432 init_waitqueue_head(&port->gs.open_wait);
1433 init_waitqueue_head(&port->gs.close_wait);
1434 port->old_cflag = 0;
1435 port->icount.cts = port->icount.dsr =
1436 port->icount.rng = port->icount.dcd = 0;
1437 port->icount.rx = port->icount.tx = 0;
1438 port->icount.frame = port->icount.parity = 0;
1439 port->icount.overrun = port->icount.brk = 0;
1440 }
1441
1442 return 0;
1443}
1444
1445static int sci_request_irq(struct sci_port *port)
1446{
1447 int i;
1448 void (*handlers[4])(int irq, void *ptr, struct pt_regs *regs) = {
1449 sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt,
1450 sci_br_interrupt,
1451 };
1452
1453 if(port->irqs[0] == port->irqs[1]){
1454 if (!port->irqs[0]){
1455 printk(KERN_ERR "sci: Cannot allocate irq.(IRQ=0)\n");
1456 return -ENODEV;
1457 }
1458 if (request_irq(port->irqs[0], sci_mpxed_interrupt, SA_INTERRUPT,
1459 "sci", port)) {
1460 printk(KERN_ERR "sci: Cannot allocate irq.\n");
1461 return -ENODEV;
1462 }
1463 }
1464 else{
1465 for (i=0; i<4; i++) {
1466 if (!port->irqs[i]) continue;
1467 if (request_irq(port->irqs[i], handlers[i], SA_INTERRUPT,
1468 "sci", port)) {
1469 printk(KERN_ERR "sci: Cannot allocate irq.\n");
1470 return -ENODEV;
1471 }
1472 }
1473 }
1474 return 0;
1475}
1476
1477static void sci_free_irq(struct sci_port *port)
1478{
1479 int i;
1480
1481 if(port->irqs[0] == port->irqs[1]){
1482 if(!port->irqs[0]){
1483 printk("sci: sci_free_irq error\n");
1484 }else{
1485 free_irq(port->irqs[0], port);
1486 }
1487 }else{
1488 for (i=0; i<4; i++) {
1489 if (!port->irqs[i]) continue;
1490 free_irq(port->irqs[i], port);
1491 }
1492 }
1493}
1494
1495static char banner[] __initdata =
1496 KERN_INFO "SuperH SCI(F) driver initialized\n";
1497
1498int __init sci_init(void)
1499{
1500 struct sci_port *port;
1501 int j;
1502
1503 printk("%s", banner);
1504
1505 for (j=0; j<SCI_NPORTS; j++) {
1506 port = &sci_ports[j];
1507 printk(KERN_INFO "ttySC%d at 0x%08x is a %s\n", j, port->base,
1508 (port->type == PORT_SCI) ? "SCI" : "SCIF");
1509 }
1510
1511#if defined(CONFIG_SH_SECUREEDGE5410)
1512 init_timer(&sci_timer_struct);
1513 sci_timer_struct.function = sci_timer;
1514 sci_timer_struct.data = 0;
1515 sci_timer_struct.expires = jiffies + HZ/25;
1516 add_timer(&sci_timer_struct);
1517
1518 j = SECUREEDGE_READ_IOPORT();
1519 sci_dcdstatus[0] = !(j & 0x10);
1520 sci_dcdstatus[1] = !(j & 0x1);
1521#endif
1522
1523 sci_init_drivers();
1524
1525#ifdef CONFIG_SH_STANDARD_BIOS
1526 sh_bios_gdb_detach();
1527#endif
1528 return 0;
1529}
1530
1531module_init(sci_init);
1532
1533#ifdef MODULE
1534#undef func_enter
1535#undef func_exit
1536
1537void cleanup_module(void)
1538{
1539#if defined(CONFIG_SH_SECUREEDGE5410)
1540 del_timer(&sci_timer_struct);
1541#endif
1542 tty_unregister_driver(&sci_driver);
1543 tty_unregister_driver(&sci_callout_driver);
1544}
1545
1546#include "generic_serial.c"
1547#endif
1548
1549#ifdef CONFIG_SERIAL_CONSOLE
1550
1551
1552
1553
1554static void serial_console_write(struct console *co, const char *s,
1555 unsigned count)
1556{
1557 put_string(sercons_port, s, count);
1558}
1559
1560static kdev_t serial_console_device(struct console *c)
1561{
1562 return MKDEV(SCI_MAJOR, SCI_MINOR_START + c->index);
1563}
1564
1565
1566
1567
1568
1569
1570
1571static int __init serial_console_setup(struct console *co, char *options)
1572{
1573 int baud = 9600;
1574 int bits = 8;
1575 int parity = 'n';
1576 int cflag = CREAD | HUPCL | CLOCAL;
1577 char *s;
1578
1579 sercons_port = &sci_ports[co->index];
1580
1581#if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
1582 sercons_port->base = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF");
1583 if (!sercons_port->base)
1584 return -EINVAL;
1585#endif
1586
1587 if (options) {
1588 baud = simple_strtoul(options, NULL, 10);
1589 s = options;
1590 while(*s >= '0' && *s <= '9')
1591 s++;
1592 if (*s) parity = *s++;
1593 if (*s) bits = *s - '0';
1594 }
1595
1596
1597
1598
1599 switch (baud) {
1600 case 19200:
1601 cflag |= B19200;
1602 break;
1603 case 38400:
1604 cflag |= B38400;
1605 break;
1606 case 57600:
1607 cflag |= B57600;
1608 break;
1609 case 115200:
1610 cflag |= B115200;
1611 break;
1612 case 230400:
1613 cflag |= B230400;
1614 break;
1615 case 9600:
1616 default:
1617 cflag |= B9600;
1618 baud = 9600;
1619 break;
1620 }
1621 switch (bits) {
1622 case 7:
1623 cflag |= CS7;
1624 break;
1625 default:
1626 case 8:
1627 cflag |= CS8;
1628 break;
1629 }
1630 switch (parity) {
1631 case 'o': case 'O':
1632 cflag |= PARODD;
1633 break;
1634 case 'e': case 'E':
1635 cflag |= PARENB;
1636 break;
1637 }
1638
1639#ifdef CONFIG_SH_KGDB
1640 if (kgdb_in_gdb_mode && sercons_port == kgdb_sci_port) {
1641 co->cflag = kgdb_cflag;
1642 sercons_baud = kgdb_baud;
1643 sercons_port->old_cflag = cflag;
1644 }
1645 else
1646#endif
1647 {
1648 co->cflag = cflag;
1649 sercons_baud = baud;
1650
1651 sci_set_termios_cflag(sercons_port, cflag, baud);
1652 sercons_port->old_cflag = cflag;
1653 }
1654
1655 return 0;
1656}
1657
1658static struct console sercons = {
1659 name: "ttySC",
1660 write: serial_console_write,
1661 device: serial_console_device,
1662 setup: serial_console_setup,
1663 flags: CON_PRINTBUFFER,
1664 index: -1,
1665};
1666
1667
1668
1669
1670
1671#ifdef CONFIG_SH_EARLY_PRINTK
1672extern void sh_console_unregister (void);
1673#endif
1674
1675void __init sci_console_init(void)
1676{
1677 register_console(&sercons);
1678#ifdef CONFIG_SH_EARLY_PRINTK
1679
1680
1681
1682 sh_console_unregister();
1683#endif
1684}
1685#endif
1686
1687
1688#ifdef CONFIG_SH_KGDB
1689
1690
1691int kgdb_sci_setup(void)
1692{
1693 int cflag = CREAD | HUPCL | CLOCAL;
1694
1695 if ((kgdb_portnum < 0) || (kgdb_portnum >= SCI_NPORTS))
1696 return -1;
1697
1698 kgdb_sci_port = &sci_ports[kgdb_portnum];
1699
1700 switch (kgdb_baud) {
1701 case 115200:
1702 cflag |= B115200;
1703 break;
1704 case 57600:
1705 cflag |= B57600;
1706 break;
1707 case 38400:
1708 cflag |= B38400;
1709 break;
1710 case 19200:
1711 cflag |= B19200;
1712 break;
1713 case 9600:
1714 default:
1715 cflag |= B9600;
1716 kgdb_baud = 9600;
1717 break;
1718 }
1719
1720 switch (kgdb_bits) {
1721 case '7':
1722 cflag |= CS7;
1723 break;
1724 default:
1725 case '8':
1726 cflag |= CS8;
1727 break;
1728 }
1729
1730 switch (kgdb_parity) {
1731 case 'O':
1732 cflag |= PARODD;
1733 break;
1734 case 'E':
1735 cflag |= PARENB;
1736 break;
1737 }
1738
1739 kgdb_cflag = cflag;
1740 sci_set_termios_cflag(kgdb_sci_port, kgdb_cflag, kgdb_baud);
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750 kgdb_getchar = kgdb_sci_getchar;
1751 kgdb_putchar = kgdb_sci_putchar;
1752
1753 return 0;
1754}
1755
1756#ifdef CONFIG_SH_KGDB_CONSOLE
1757
1758
1759static kdev_t kgdb_console_device(struct console *c)
1760{
1761 return MKDEV(SCI_MAJOR, SCI_MINOR_START + c->index);
1762}
1763
1764
1765static int __init kgdb_console_setup(struct console *co, char *options)
1766{
1767
1768 co->cflag = kgdb_cflag;
1769
1770 return 0;
1771}
1772
1773
1774void __init kgdb_console_init(void)
1775{
1776 register_console(&kgdbcons);
1777}
1778
1779
1780static struct console kgdbcons = {
1781 name:"ttySC",
1782 write:kgdb_console_write,
1783 device:kgdb_console_device,
1784 wait_key:serial_console_wait_key,
1785 setup:kgdb_console_setup,
1786 flags:CON_PRINTBUFFER | CON_ENABLED,
1787 index:-1,
1788};
1789
1790#endif
1791
1792#endif
1793