patch-2.4.22 linux-2.4.22/drivers/char/sh-sci.c
Next file: linux-2.4.22/drivers/char/sh-sci.h
Previous file: linux-2.4.22/drivers/char/sgiserial.h
Back to the patch index
Back to the overall index
- Lines: 763
- Date:
2003-08-25 04:44:41.000000000 -0700
- Orig file:
linux-2.4.21/drivers/char/sh-sci.c
- Orig date:
2002-08-02 17:39:43.000000000 -0700
diff -urN linux-2.4.21/drivers/char/sh-sci.c linux-2.4.22/drivers/char/sh-sci.c
@@ -1,4 +1,4 @@
-/* $Id: sh-sci.c,v 1.40 2000/04/15 06:57:29 gniibe Exp $
+/* $Id: sh-sci.c,v 1.1.1.1.2.7 2003/07/16 18:45:31 yoshii Exp $
*
* linux/drivers/char/sh-sci.c
*
@@ -6,6 +6,7 @@
* Copyright (C) 1999, 2000 Niibe Yutaka
* Copyright (C) 2000 Sugioka Toshinobu
* Modified to support multiple serial ports. Stuart Menefy (May 2000).
+ * Modified to support SH7300 SCIF. Takashi Kusuda (Jun 2003).
*
* TTY code is based on sx.c (Specialix SX driver) by:
*
@@ -32,7 +33,7 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/delay.h>
-#ifdef CONFIG_SERIAL_CONSOLE
+#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_SH_KGDB_CONSOLE)
#include <linux/console.h>
#endif
@@ -50,17 +51,39 @@
#include "sh-sci.h"
+#ifdef CONFIG_SH_KGDB
+#include <asm/kgdb.h>
+
+int kgdb_sci_setup(void);
+static int kgdb_get_char(struct sci_port *port);
+static void kgdb_put_char(struct sci_port *port, char c);
+static void kgdb_handle_error(struct sci_port *port);
+static struct sci_port *kgdb_sci_port;
+
+#ifdef CONFIG_SH_KGDB_CONSOLE
+static struct console kgdbcons;
+void __init kgdb_console_init(void);
+#endif /* CONFIG_SH_KGDB_CONSOLE */
+
+#endif /* CONFIG_SH_KGDB */
+
#ifdef CONFIG_SERIAL_CONSOLE
static struct console sercons;
static struct sci_port* sercons_port=0;
static int sercons_baud;
-#endif
+#ifdef CONFIG_MAGIC_SYSRQ
+#include <linux/sysrq.h>
+static int break_pressed;
+#endif /* CONFIG_MAGIC_SYSRQ */
+#endif /* CONFIG_SERIAL_CONSOLE */
/* Function prototypes */
+#if !defined(SCIF_ONLY)
static void sci_init_pins_sci(struct sci_port* port, unsigned int cflag);
+#endif
#ifndef SCI_ONLY
static void sci_init_pins_scif(struct sci_port* port, unsigned int cflag);
-#if defined(__sh3__)
+#if defined(__sh3__) && !defined(CONFIG_CPU_SUBTYPE_SH7300)
static void sci_init_pins_irda(struct sci_port* port, unsigned int cflag);
#endif
#endif
@@ -114,7 +137,7 @@
}
#endif
-#ifdef CONFIG_SH_STANDARD_BIOS
+#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
static void handle_error(struct sci_port *port)
{ /* Clear error flags */
@@ -156,7 +179,7 @@
return hexchars[x & 0xf];
}
-#endif
+#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
/*
* Send the packet in buffer. The host gets one chance to read it.
@@ -168,13 +191,22 @@
{
int i;
const unsigned char *p = buffer;
-#ifdef CONFIG_SH_STANDARD_BIOS
+
+#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB)
int checksum;
+ int usegdb=0;
+#ifdef CONFIG_SH_STANDARD_BIOS
/* This call only does a trap the first time it is
* called, and so is safe to do here unconditionally
*/
- if (sh_bios_in_gdb_mode()) {
+ usegdb |= sh_bios_in_gdb_mode();
+#endif
+#ifdef CONFIG_SH_KGDB
+ usegdb |= (kgdb_in_gdb_mode && (port == kgdb_sci_port));
+#endif
+
+ if (usegdb) {
/* $<packet info>#<checksum>. */
do {
unsigned char c;
@@ -197,15 +229,101 @@
put_char(port, lowhex(checksum));
} while (get_char(port) != '+');
} else
-#endif
+#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
for (i=0; i<count; i++) {
if (*p == 10)
put_char(port, '\r');
put_char(port, *p++);
}
}
-#endif
+#endif /* CONFIG_SERIAL_CONSOLE */
+
+
+#ifdef CONFIG_SH_KGDB
+
+/* Is the SCI ready, ie is there a char waiting? */
+static int kgdb_is_char_ready(struct sci_port *port)
+{
+ unsigned short status = sci_in(port, SCxSR);
+
+ if (status & (SCxSR_ERRORS(port) | SCxSR_BRK(port)))
+ kgdb_handle_error(port);
+
+ return (status & SCxSR_RDxF(port));
+}
+
+/* Write a char */
+static void kgdb_put_char(struct sci_port *port, char c)
+{
+ unsigned short status;
+
+ do
+ status = sci_in(port, SCxSR);
+ while (!(status & SCxSR_TDxE(port)));
+
+ sci_out(port, SCxTDR, c);
+ sci_in(port, SCxSR); /* Dummy read */
+ sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
+}
+
+/* Get a char if there is one, else ret -1 */
+static int kgdb_get_char(struct sci_port *port)
+{
+ int c;
+ if (kgdb_is_char_ready(port) == 0)
+ c = -1;
+ else {
+ c = sci_in(port, SCxRDR);
+ sci_in(port, SCxSR); /* Dummy read */
+ sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+ }
+
+ return c;
+}
+
+/* Called from kgdbstub.c to get a character, i.e. is blocking */
+static int kgdb_sci_getchar(void)
+{
+ volatile int c;
+
+ /* Keep trying to read a character, this could be neater */
+ while ((c = kgdb_get_char(kgdb_sci_port)) < 0);
+
+ return c;
+}
+
+/* Called from kgdbstub.c to put a character, just a wrapper */
+static void kgdb_sci_putchar(int c)
+{
+
+ kgdb_put_char(kgdb_sci_port, c);
+}
+
+/* Clear any errors on the SCI */
+static void kgdb_handle_error(struct sci_port *port)
+{
+ sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); /* Clear error flags */
+}
+
+/* Breakpoint if there's a break sent on the serial port */
+static void kgdb_break_interrupt(int irq, void *ptr, struct pt_regs *regs)
+{
+ struct sci_port *port = ptr;
+ unsigned short status = sci_in(port, SCxSR);
+
+ if (status & SCxSR_BRK(port)) {
+
+ /* Break into the debugger if a break is detected */
+ BREAKPOINT();
+
+ /* Clear */
+ sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
+ return;
+ }
+}
+
+#endif /* CONFIG_SH_KGDB */
static struct real_driver sci_real_driver = {
sci_disable_tx_interrupts,
@@ -229,11 +347,12 @@
#if defined(SCIF_ONLY) || defined(SCI_AND_SCIF)
#if defined(__sh3__)
-/* For SH7707, SH7709, SH7709A, SH7729 */
+/* For SH7300, SH7707, SH7709, SH7709A, SH7729 */
static void sci_init_pins_scif(struct sci_port* port, unsigned int cflag)
{
unsigned int fcr_val = 0;
+#if !defined(CONFIG_CPU_SUBTYPE_SH7300) /* SH7300 doesn't use RTS/CTS */
{
unsigned short data;
@@ -257,6 +376,7 @@
/* Set /RTS2 (bit6) = 0 */
ctrl_outb(data&0xbf, SCPDR);
}
+#endif
sci_out(port, SCFCR, fcr_val);
}
@@ -280,7 +400,7 @@
if (cflag & CRTSCTS) {
fcr_val |= SCFCR_MCE;
} else {
- ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */
+ sci_out(port, SCSPTR, 0x0080); /* Set RTS = 1 */
}
sci_out(port, SCFCR, fcr_val);
}
@@ -372,7 +492,11 @@
sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */
if (port->type == PORT_SCIF) {
+#if defined(CONFIG_CPU_SUBTYPE_SH7300)
+ sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST | SCFCR_TCRST);
+#else
sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
+#endif
}
smr_val = sci_in(port, SCSMR) & 3;
@@ -381,7 +505,7 @@
if (cflag & PARENB)
smr_val |= 0x20;
if (cflag & PARODD)
- smr_val |= 0x10;
+ smr_val |= 0x30;
if (cflag & CSTOPB)
smr_val |= 0x08;
sci_out(port, SCSMR, smr_val);
@@ -461,14 +585,18 @@
while (1) {
count = port->gs.xmit_cnt;
if (port->type == PORT_SCIF) {
+#if defined(CONFIG_CPU_SUBTYPE_SH7300)
+ txroom = 64 - (sci_in(port, SCFDR)>>8);
+#else
txroom = 16 - (sci_in(port, SCFDR)>>8);
+#endif
} else {
txroom = (sci_in(port, SCxSR) & SCI_TDRE)?1:0;
}
if (count > txroom)
count = txroom;
- /* Don't copy pas the end of the source buffer */
+ /* Don't copy past the end of the source buffer */
if (count > SERIAL_XMIT_SIZE - port->gs.xmit_tail)
count = SERIAL_XMIT_SIZE - port->gs.xmit_tail;
@@ -511,7 +639,11 @@
restore_flags(flags);
}
-static inline void sci_receive_chars(struct sci_port *port)
+/* On SH3, SCIF may read end-of-break as a space->mark char */
+#define STEPFN(c) ({int __c=(c); (((__c-1)|(__c)) == -1); })
+
+static inline void sci_receive_chars(struct sci_port *port,
+ struct pt_regs *regs)
{
int i, count;
struct tty_struct *tty;
@@ -525,7 +657,11 @@
tty = port->gs.tty;
while (1) {
if (port->type == PORT_SCIF) {
+#if defined(CONFIG_CPU_SUBTYPE_SH7300)
+ count = sci_in(port, SCFDR)&0x007f;
+#else
count = sci_in(port, SCFDR)&0x001f;
+#endif
} else {
count = (sci_in(port, SCxSR)&SCxSR_RDxF(port))?1:0;
}
@@ -534,7 +670,7 @@
if (tty->flip.count + count > TTY_FLIPBUF_SIZE)
count = TTY_FLIPBUF_SIZE - tty->flip.count;
- /* If for one reason or another, we can't copy more data, we're done! */
+ /* If for any reason we can't copy more data, we're done! */
if (count == 0)
break;
@@ -543,8 +679,43 @@
tty->flip.flag_buf_ptr[0] = TTY_NORMAL;
} else {
for (i=0; i<count; i++) {
- tty->flip.char_buf_ptr[i] = sci_in(port, SCxRDR);
+ char c = sci_in(port, SCxRDR);
status = sci_in(port, SCxSR);
+#if defined(__SH3__)
+ /* Skip "chars" during break */
+ if (port->break_flag) {
+ if ((c == 0) &&
+ (status & SCxSR_FER(port))) {
+ count--; i--;
+ continue;
+ }
+ /* Nonzero => end-of-break */
+ dprintk("scif: debounce<%02x>\n", c);
+ port->break_flag = 0;
+ if (STEPFN(c)) {
+ count--; i--;
+ continue;
+ }
+ }
+#endif /* __SH3__ */
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+ if (break_pressed && (port == sercons_port)) {
+ if (c != 0 &&
+ time_before(jiffies,
+ break_pressed + HZ*5)) {
+ handle_sysrq(c, regs,
+ NULL, NULL);
+ break_pressed = 0;
+ count--; i--;
+ continue;
+ } else if (c != 0) {
+ break_pressed = 0;
+ }
+ }
+#endif /* CONFIG_SERIAL_CONSOLE && CONFIG_MAGIC_SYSRQ */
+
+ /* Store data and status */
+ tty->flip.char_buf_ptr[i] = c;
if (status&SCxSR_FER(port)) {
tty->flip.flag_buf_ptr[i] = TTY_FRAME;
dprintk("sci: frame error\n");
@@ -572,6 +743,10 @@
if (copied)
/* Tell the rest of the system the news. New characters! */
tty_flip_buffer_push(tty);
+ else {
+ sci_in(port, SCxSR); /* dummy read */
+ sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+ }
}
static inline int sci_handle_errors(struct sci_port *port)
@@ -624,13 +799,31 @@
struct tty_struct *tty = port->gs.tty;
if (status&SCxSR_BRK(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
+#if defined(__SH3__)
+ /* Debounce break */
+ if (port->break_flag)
+ goto break_continue;
+ port->break_flag = 1;
+#endif
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+ if (port == sercons_port) {
+ if (break_pressed == 0) {
+ break_pressed = jiffies;
+ dprintk("sci: implied sysrq\n");
+ goto break_continue;
+ }
+ /* Double break implies a real break */
+ break_pressed = 0;
+ }
+#endif
/* Notify of BREAK */
copied++;
*tty->flip.flag_buf_ptr++ = TTY_BREAK;
dprintk("sci: BREAK detected\n");
}
+ break_continue:
-#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_ST40STB1)
+#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_ST40)
/* XXX: Handle SCIF overrun error */
if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) {
sci_out(port, SCLSR, 0);
@@ -656,7 +849,7 @@
if (port->gs.flags & GS_ACTIVE)
if (!(port->gs.flags & SCI_RX_THROTTLE)) {
- sci_receive_chars(port);
+ sci_receive_chars(port, regs);
return;
}
sci_disable_rx_interrupts(port);
@@ -703,6 +896,28 @@
sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
}
+static void sci_mpxed_interrupt(int irq, void *ptr, struct pt_regs *regs)
+{
+ unsigned short ssr_status, scr_status;
+ struct sci_port *port = ptr;
+
+ ssr_status=sci_in(port,SCxSR);
+ scr_status=sci_in(port,SCSCR);
+
+ if((ssr_status&0x0020) && (scr_status&0x0080)){ /* Tx Interrupt */
+ sci_tx_interrupt(irq, ptr, regs);
+ }
+ if((ssr_status&0x0002) && (scr_status&0x0040)){ /* Rx Interrupt */
+ sci_rx_interrupt(irq, ptr, regs);
+ }
+ if((ssr_status&0x0080) && (scr_status&0x0400)){ /* Error Interrupt */
+ sci_er_interrupt(irq, ptr, regs);
+ }
+ if((ssr_status&0x0010) && (scr_status&0x0200)){ /* Break Interrupt */
+ sci_br_interrupt(irq, ptr, regs);
+ }
+}
+
static void do_softint(void *private_)
{
struct sci_port *port = (struct sci_port *) private_;
@@ -811,7 +1026,7 @@
static int sci_open(struct tty_struct * tty, struct file * filp)
{
struct sci_port *port;
- int retval, line;
+ int retval = 0, line;
line = MINOR(tty->device) - SCI_MINOR_START;
@@ -820,6 +1035,14 @@
port = &sci_ports[line];
+#if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
+ if (port->base == 0) {
+ port->base = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF");
+ if (!port->base)
+ goto failed_1;
+ }
+#endif
+
tty->driver_data = port;
port->gs.tty = tty;
port->gs.count++;
@@ -827,31 +1050,32 @@
port->event = 0;
port->tqueue.routine = do_softint;
port->tqueue.data = port;
+ port->break_flag = 0;
+
+ if (port->gs.count == 1) {
+ MOD_INC_USE_COUNT;
+
+ retval = sci_request_irq(port);
+ if (retval) {
+ goto failed_1;
+ }
+ }
/*
* Start up serial port
*/
retval = gs_init_port(&port->gs);
if (retval) {
- goto failed_1;
+ goto failed_2;
}
port->gs.flags |= GS_ACTIVE;
sci_setsignals(port, 1,1);
- if (port->gs.count == 1) {
- MOD_INC_USE_COUNT;
-
- retval = sci_request_irq(port);
- if (retval) {
- goto failed_2;
- }
- }
-
retval = gs_block_til_ready(port, filp);
if (retval) {
- goto failed_3;
+ goto failed_2;
}
if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
@@ -871,6 +1095,23 @@
}
#endif
+#ifdef CONFIG_SH_KGDB_CONSOLE
+ if (kgdbcons.cflag && kgdbcons.index == line) {
+ tty->termios->c_cflag = kgdbcons.cflag;
+ port->gs.baud = kgdb_baud;
+ sercons.cflag = 0;
+ sci_set_real_termios(port);
+ }
+#elif CONFIG_SH_KGDB
+ /* Even for non-console, may defer to kgdb */
+ if (port == kgdb_sci_port && kgdb_in_gdb_mode) {
+ tty->termios->c_cflag = kgdb_cflag;
+ port->gs.baud = kgdb_baud;
+ sercons.cflag = 0;
+ sci_set_real_termios(port);
+ }
+#endif /* CONFIG_SH_KGDB */
+
sci_enable_rx_interrupts(port);
port->gs.session = current->session;
@@ -878,11 +1119,10 @@
return 0;
-failed_3:
- sci_free_irq(port);
failed_2:
- MOD_DEC_USE_COUNT;
+ sci_free_irq(port);
failed_1:
+ MOD_DEC_USE_COUNT;
port->gs.count--;
return retval;
}
@@ -975,6 +1215,7 @@
* was throttled
*/
port->gs.flags &= ~SCI_RX_THROTTLE;
+ sci_enable_rx_interrupts(port);
return;
}
@@ -1110,14 +1351,27 @@
sci_br_interrupt,
};
- for (i=0; i<4; i++) {
- if (!port->irqs[i]) continue;
- if (request_irq(port->irqs[i], handlers[i], SA_INTERRUPT,
+ if(port->irqs[0] == port->irqs[1]){
+ if (!port->irqs[0]){
+ printk(KERN_ERR "sci: Cannot allocate irq.(IRQ=0)\n");
+ return -ENODEV;
+ }
+ if (request_irq(port->irqs[0], sci_mpxed_interrupt, SA_INTERRUPT,
"sci", port)) {
printk(KERN_ERR "sci: Cannot allocate irq.\n");
return -ENODEV;
}
}
+ else{
+ for (i=0; i<4; i++) {
+ if (!port->irqs[i]) continue;
+ if (request_irq(port->irqs[i], handlers[i], SA_INTERRUPT,
+ "sci", port)) {
+ printk(KERN_ERR "sci: Cannot allocate irq.\n");
+ return -ENODEV;
+ }
+ }
+ }
return 0;
}
@@ -1125,10 +1379,18 @@
{
int i;
- for (i=0; i<4; i++) {
- if (!port->irqs[i]) continue;
- free_irq(port->irqs[i], port);
- }
+ if(port->irqs[0] == port->irqs[1]){
+ if(!port->irqs[0]){
+ printk("sci: sci_free_irq error\n");
+ }else{
+ free_irq(port->irqs[0], port);
+ }
+ }else{
+ for (i=0; i<4; i++) {
+ if (!port->irqs[i]) continue;
+ free_irq(port->irqs[i], port);
+ }
+ }
}
static char banner[] __initdata =
@@ -1202,6 +1464,12 @@
sercons_port = &sci_ports[co->index];
+#if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
+ sercons_port->base = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF");
+ if (!sercons_port->base)
+ return -EINVAL;
+#endif
+
if (options) {
baud = simple_strtoul(options, NULL, 10);
s = options;
@@ -1251,11 +1519,21 @@
break;
}
- co->cflag = cflag;
- sercons_baud = baud;
+#ifdef CONFIG_SH_KGDB
+ if (kgdb_in_gdb_mode && sercons_port == kgdb_sci_port) {
+ co->cflag = kgdb_cflag;
+ sercons_baud = kgdb_baud;
+ sercons_port->old_cflag = cflag;
+ }
+ else
+#endif /* CONFIG_SH_KGDB */
+ {
+ co->cflag = cflag;
+ sercons_baud = baud;
- sci_set_termios_cflag(sercons_port, cflag, baud);
- sercons_port->old_cflag = cflag;
+ sci_set_termios_cflag(sercons_port, cflag, baud);
+ sercons_port->old_cflag = cflag;
+ }
return 0;
}
@@ -1288,3 +1566,110 @@
#endif
}
#endif /* CONFIG_SERIAL_CONSOLE */
+
+
+#ifdef CONFIG_SH_KGDB
+
+/* Initialise the KGDB serial port */
+int kgdb_sci_setup(void)
+{
+ int cflag = CREAD | HUPCL | CLOCAL;
+
+ if ((kgdb_portnum < 0) || (kgdb_portnum >= SCI_NPORTS))
+ return -1;
+
+ kgdb_sci_port = &sci_ports[kgdb_portnum];
+
+ switch (kgdb_baud) {
+ case 115200:
+ cflag |= B115200;
+ break;
+ case 57600:
+ cflag |= B57600;
+ break;
+ case 38400:
+ cflag |= B38400;
+ break;
+ case 19200:
+ cflag |= B19200;
+ break;
+ case 9600:
+ default:
+ cflag |= B9600;
+ kgdb_baud = 9600;
+ break;
+ }
+
+ switch (kgdb_bits) {
+ case '7':
+ cflag |= CS7;
+ break;
+ default:
+ case '8':
+ cflag |= CS8;
+ break;
+ }
+
+ switch (kgdb_parity) {
+ case 'O':
+ cflag |= PARODD;
+ break;
+ case 'E':
+ cflag |= PARENB;
+ break;
+ }
+
+ kgdb_cflag = cflag;
+ sci_set_termios_cflag(kgdb_sci_port, kgdb_cflag, kgdb_baud);
+
+ /* Set up the interrupt for BREAK from GDB */
+ /* Commented out for now since it may not be possible yet...
+ request_irq(kgdb_sci_port->irqs[0], kgdb_break_interrupt,
+ SA_INTERRUPT, "sci", kgdb_sci_port);
+ sci_enable_rx_interrupts(kgdb_sci_port);
+ */
+
+ /* Setup complete: initialize function pointers */
+ kgdb_getchar = kgdb_sci_getchar;
+ kgdb_putchar = kgdb_sci_putchar;
+
+ return 0;
+}
+
+#ifdef CONFIG_SH_KGDB_CONSOLE
+
+/* Create a console device */
+static kdev_t kgdb_console_device(struct console *c)
+{
+ return MKDEV(SCI_MAJOR, SCI_MINOR_START + c->index);
+}
+
+/* Set up the KGDB console */
+static int __init kgdb_console_setup(struct console *co, char *options)
+{
+ /* NB we ignore 'options' because we've already done the setup */
+ co->cflag = kgdb_cflag;
+
+ return 0;
+}
+
+/* Register the KGDB console so we get messages (d'oh!) */
+void __init kgdb_console_init(void)
+{
+ register_console(&kgdbcons);
+}
+
+/* The console structure for KGDB */
+static struct console kgdbcons = {
+ name:"ttySC",
+ write:kgdb_console_write,
+ device:kgdb_console_device,
+ wait_key:serial_console_wait_key,
+ setup:kgdb_console_setup,
+ flags:CON_PRINTBUFFER | CON_ENABLED,
+ index:-1,
+};
+
+#endif /* CONFIG_SH_KGDB_CONSOLE */
+
+#endif /* CONFIG_SH_KGDB */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)