X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fserial%2Fsh-sci.c;h=44f6bf79bbe12725fc0ba499501ba49625bcda60;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=ad5b776d779b3ca56a8db712ddd89defefe2dbce;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index ad5b776d7..44f6bf79b 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -42,6 +42,7 @@ #include #include #include +#include #ifdef CONFIG_CPU_FREQ #include @@ -53,7 +54,9 @@ #include #include -#include +#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) +#include +#endif #ifdef CONFIG_SH_STANDARD_BIOS #include @@ -79,16 +82,18 @@ static struct sci_port *serial_console_port = 0; #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ /* Function prototypes */ -static void sci_stop_tx(struct uart_port *port, unsigned int tty_stop); -static void sci_start_tx(struct uart_port *port, unsigned int tty_start); +static void sci_stop_tx(struct uart_port *port); +static void sci_start_tx(struct uart_port *port); static void sci_start_rx(struct uart_port *port, unsigned int tty_start); static void sci_stop_rx(struct uart_port *port); static int sci_request_irq(struct sci_port *port); static void sci_free_irq(struct sci_port *port); -static struct sci_port sci_ports[SCI_NPORTS]; +static struct sci_port sci_ports[]; static struct uart_driver sci_uart_driver; +#define SCI_NPORTS sci_uart_driver.nr + #if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) static void handle_error(struct uart_port *port) @@ -168,7 +173,7 @@ static void put_string(struct sci_port *sci_port, const char *buffer, int count) int usegdb=0; #ifdef CONFIG_SH_STANDARD_BIOS - /* This call only does a trap the first time it is + /* This call only does a trap the first time it is * called, and so is safe to do here unconditionally */ usegdb |= sh_bios_in_gdb_mode(); @@ -324,47 +329,46 @@ static void sci_init_pins_sci(struct uart_port* port, unsigned int cflag) /* tx mark output*/ H8300_SCI_DR(ch) |= h8300_sci_pins[ch].tx; } -#else -static void sci_init_pins_sci(struct uart_port *port, unsigned int cflag) -{ -} #endif #endif #if defined(SCIF_ONLY) || defined(SCI_AND_SCIF) -#if defined(CONFIG_CPU_SH3) -/* For SH7705, SH7707, SH7709, SH7709A, SH7729, SH7300*/ +#if defined(CONFIG_CPU_SUBTYPE_SH7300) +/* SH7300 doesn't use RTS/CTS */ +static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) +{ + sci_out(port, SCFCR, 0); +} +#elif defined(CONFIG_CPU_SH3) +/* For SH7705, SH7707, SH7709, SH7709A, SH7729 */ static void sci_init_pins_scif(struct uart_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; + unsigned short data; + + /* We need to set SCPCR to enable RTS/CTS */ + data = ctrl_inw(SCPCR); + /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/ + ctrl_outw(data & 0x0fcf, SCPCR); - /* We need to set SCPCR to enable RTS/CTS */ - data = ctrl_inw(SCPCR); - /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/ - ctrl_outw(data&0x0fcf, SCPCR); - } if (cflag & CRTSCTS) fcr_val |= SCFCR_MCE; else { - unsigned short data; - /* We need to set SCPCR to enable RTS/CTS */ data = ctrl_inw(SCPCR); /* Clear out SCP7MD1,0, SCP4MD1,0, Set SCP6MD1,0 = {01} (output) */ - ctrl_outw((data&0x0fcf)|0x1000, SCPCR); + ctrl_outw((data & 0x0fcf) | 0x1000, SCPCR); data = ctrl_inb(SCPDR); /* Set /RTS2 (bit6) = 0 */ - ctrl_outb(data&0xbf, SCPDR); + ctrl_outb(data & 0xbf, SCPDR); } -#endif + sci_out(port, SCFCR, fcr_val); } +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag) { unsigned int fcr_val = 0; @@ -374,7 +378,7 @@ static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag) sci_out(port, SCFCR, fcr_val); } - +#endif #else /* For SH7750 */ @@ -385,7 +389,11 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) if (cflag & CRTSCTS) { fcr_val |= SCFCR_MCE; } else { +#ifdef CONFIG_CPU_SUBTYPE_SH7780 + ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */ +#else ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */ +#endif } sci_out(port, SCFCR, fcr_val); } @@ -422,7 +430,11 @@ static void sci_transmit_chars(struct uart_port *port) #if !defined(SCI_ONLY) if (port->type == PORT_SCIF) { +#if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780) + txroom = SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0x7f); +#else txroom = SCIF_TXROOM_MAX - (sci_in(port, SCFDR)>>8); +#endif } else { txroom = (sci_in(port, SCxSR) & SCI_TDRE)?1:0; } @@ -455,7 +467,7 @@ static void sci_transmit_chars(struct uart_port *port) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); if (uart_circ_empty(xmit)) { - sci_stop_tx(port, 0); + sci_stop_tx(port); } else { local_irq_save(flags); ctrl = sci_in(port, SCSCR); @@ -482,6 +494,7 @@ static inline void sci_receive_chars(struct uart_port *port, struct tty_struct *tty = port->info->tty; int i, count, copied = 0; unsigned short status; + unsigned char flag; status = sci_in(port, SCxSR); if (!(status & SCxSR_RDxF(port))) @@ -490,7 +503,11 @@ static inline void sci_receive_chars(struct uart_port *port, while (1) { #if !defined(SCI_ONLY) if (port->type == PORT_SCIF) { +#if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780) + count = sci_in(port, SCRFDR) & 0x7f; +#else count = sci_in(port, SCFDR)&SCIF_RFDC_MASK ; +#endif } else { count = (sci_in(port, SCxSR)&SCxSR_RDxF(port))?1:0; } @@ -499,8 +516,7 @@ static inline void sci_receive_chars(struct uart_port *port, #endif /* Don't copy more bytes than there is room for in the buffer */ - if (tty->flip.count + count > TTY_FLIPBUF_SIZE) - count = TTY_FLIPBUF_SIZE - tty->flip.count; + count = tty_buffer_request_room(tty, count); /* If for any reason we can't copy more data, we're done! */ if (count == 0) @@ -512,8 +528,7 @@ static inline void sci_receive_chars(struct uart_port *port, || uart_handle_sysrq_char(port, c, regs)) { count = 0; } else { - tty->flip.char_buf_ptr[0] = c; - tty->flip.flag_buf_ptr[0] = TTY_NORMAL; + tty_insert_flip_char(tty, c, TTY_NORMAL); } } else { for (i=0; iflip.char_buf_ptr[i] = c; if (status&SCxSR_FER(port)) { - tty->flip.flag_buf_ptr[i] = TTY_FRAME; + flag = TTY_FRAME; pr_debug("sci: frame error\n"); } else if (status&SCxSR_PER(port)) { - tty->flip.flag_buf_ptr[i] = TTY_PARITY; + flag = TTY_PARITY; pr_debug("sci: parity error\n"); - } else { - tty->flip.flag_buf_ptr[i] = TTY_NORMAL; - } + } else + flag = TTY_NORMAL; + tty_insert_flip_char(tty, c, flag); } } sci_in(port, SCxSR); /* dummy read */ sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); - /* Update the kernel buffer end */ - tty->flip.count += count; - tty->flip.char_buf_ptr += count; - tty->flip.flag_buf_ptr += count; copied += count; port->icount.rx += count; } @@ -608,48 +618,45 @@ static inline int sci_handle_errors(struct uart_port *port) unsigned short status = sci_in(port, SCxSR); struct tty_struct *tty = port->info->tty; - if (status&SCxSR_ORER(port) && tty->flip.countflip.flag_buf_ptr++ = TTY_OVERRUN; + if(tty_insert_flip_char(tty, 0, TTY_OVERRUN)) + copied++; pr_debug("sci: overrun error\n"); } - if (status&SCxSR_FER(port) && tty->flip.countbreak_flag) { - sci_port->break_flag = 1; - sci_schedule_break_timer((struct sci_port *)port); + if(!sci_port->break_flag) { + sci_port->break_flag = 1; + sci_schedule_break_timer((struct sci_port *)port); /* Do sysrq handling. */ - if(uart_handle_break(port)) { + if(uart_handle_break(port)) return 0; - } pr_debug("sci: BREAK detected\n"); - copied++; - *tty->flip.flag_buf_ptr++ = TTY_BREAK; + if(tty_insert_flip_char(tty, 0, TTY_BREAK)) + copied++; } } else { /* frame error */ - copied++; - *tty->flip.flag_buf_ptr++ = TTY_FRAME; + if(tty_insert_flip_char(tty, 0, TTY_FRAME)) + copied++; pr_debug("sci: frame error\n"); } } - if (status&SCxSR_PER(port) && tty->flip.countflip.flag_buf_ptr++ = TTY_PARITY; pr_debug("sci: parity error\n"); } - if (copied) { - tty->flip.count += copied; + if (copied) tty_flip_buffer_push(tty); - } return copied; } @@ -661,15 +668,14 @@ static inline int sci_handle_breaks(struct uart_port *port) struct tty_struct *tty = port->info->tty; struct sci_port *s = &sci_ports[port->line]; - if (!s->break_flag && status & SCxSR_BRK(port) && - tty->flip.count < TTY_FLIPBUF_SIZE) { + if (!s->break_flag && status & SCxSR_BRK(port)) { #if defined(CONFIG_CPU_SH3) /* Debounce break */ s->break_flag = 1; #endif /* Notify of BREAK */ - copied++; - *tty->flip.flag_buf_ptr++ = TTY_BREAK; + if(tty_insert_flip_char(tty, 0, TTY_BREAK)) + copied++; pr_debug("sci: BREAK detected\n"); } @@ -677,19 +683,15 @@ static inline int sci_handle_breaks(struct uart_port *port) /* XXX: Handle SCIF overrun error */ if (port->type == PORT_SCIF && (sci_in(port, SCLSR) & SCIF_ORER) != 0) { sci_out(port, SCLSR, 0); - if(tty->flip.countflip.flag_buf_ptr++ = TTY_OVERRUN; pr_debug("sci: overrun error\n"); } } #endif - if (copied) { - tty->flip.count += copied; + if (copied) tty_flip_buffer_push(tty); - } - return copied; } @@ -732,12 +734,9 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr, struct pt_regs *regs) struct tty_struct *tty = port->info->tty; sci_out(port, SCLSR, 0); - if(tty->flip.countflip.flag_buf_ptr++ = TTY_OVERRUN; - tty->flip.count++; - tty_flip_buffer_push(tty); - pr_debug("scif: overrun error\n"); - } + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + tty_flip_buffer_push(tty); + pr_debug("scif: overrun error\n"); } #endif sci_rx_interrupt(irq, ptr, regs); @@ -800,6 +799,7 @@ static int sci_notifier(struct notifier_block *self, unsigned long phase, void * (phase == CPUFREQ_RESUMECHANGE)){ for (i = 0; i < SCI_NPORTS; i++) { struct uart_port *port = &sci_ports[i].port; + struct clk *clk; /* * Update the uartclk per-port if frequency has @@ -812,7 +812,9 @@ static int sci_notifier(struct notifier_block *self, unsigned long phase, void * * * Clean this up later.. */ - port->uartclk = current_cpu_data.module_clock * 16; + clk = clk_get("module_clk"); + port->uartclk = clk_get_rate(clk) * 16; + clk_put(clk); } printk("%s: got a postchange notification for cpu %d (old %d, new %d)\n", @@ -900,7 +902,7 @@ static unsigned int sci_get_mctrl(struct uart_port *port) return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR; } -static void sci_start_tx(struct uart_port *port, unsigned int tty_start) +static void sci_start_tx(struct uart_port *port) { struct sci_port *s = &sci_ports[port->line]; @@ -909,7 +911,7 @@ static void sci_start_tx(struct uart_port *port, unsigned int tty_start) enable_irq(s->irqs[SCIx_TXI_IRQ]); } -static void sci_stop_tx(struct uart_port *port, unsigned int tty_stop) +static void sci_stop_tx(struct uart_port *port) { unsigned long flags; unsigned short ctrl; @@ -967,7 +969,7 @@ static int sci_startup(struct uart_port *port) #endif sci_request_irq(s); - sci_start_tx(port, 1); + sci_start_tx(port); sci_start_rx(port, 1); return 0; @@ -978,7 +980,7 @@ static void sci_shutdown(struct uart_port *port) struct sci_port *s = &sci_ports[port->line]; sci_stop_rx(port); - sci_stop_tx(port, 1); + sci_stop_tx(port); sci_free_irq(s); #if defined(__H8300S__) @@ -1025,15 +1027,20 @@ static void sci_set_termios(struct uart_port *port, struct termios *termios, sci_out(port, SCSMR, smr_val); switch (baud) { - case 0: t = -1; break; - case 2400: t = BPS_2400; break; - case 4800: t = BPS_4800; break; - case 9600: t = BPS_9600; break; - case 19200: t = BPS_19200; break; - case 38400: t = BPS_38400; break; - case 57600: t = BPS_57600; break; - case 115200: t = BPS_115200; break; - default: t = SCBRR_VALUE(baud); break; + case 0: + t = -1; + break; + default: + { +#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) + struct clk *clk = clk_get("module_clk"); + t = SCBRR_VALUE(baud, clk_get_rate(clk)); + clk_put(clk); +#else + t = SCBRR_VALUE(baud); +#endif + } + break; } if (t > 0) { @@ -1047,7 +1054,9 @@ static void sci_set_termios(struct uart_port *port, struct termios *termios, udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ } - s->init_pins(port, termios->c_cflag); + if (likely(s->init_pins)) + s->init_pins(port, termios->c_cflag); + sci_out(port, SCSCR, SCSCR_INIT(port)); if ((termios->c_cflag & CREAD) != 0) @@ -1124,31 +1133,30 @@ static struct uart_ops sci_uart_ops = { .verify_port = sci_verify_port, }; -static struct sci_port sci_ports[SCI_NPORTS] = { +static struct sci_port sci_ports[] = { #if defined(CONFIG_CPU_SUBTYPE_SH7708) { .port = { .membase = (void *)0xfffffe80, .mapbase = 0xfffffe80, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 25, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 0, }, .type = PORT_SCI, .irqs = SCI_IRQS, - .init_pins = sci_init_pins_sci, }, #elif defined(CONFIG_CPU_SUBTYPE_SH7705) { .port = { .membase = (void *)SCIF0, .mapbase = SCIF0, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 55, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 0, }, .type = PORT_SCIF, @@ -1159,10 +1167,10 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)SCIF2, .mapbase = SCIF2, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 59, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 1, }, .type = PORT_SCIF, @@ -1174,24 +1182,23 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)0xfffffe80, .mapbase = 0xfffffe80, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 25, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 0, }, .type = PORT_SCI, .irqs = SCI_IRQS, - .init_pins = sci_init_pins_sci, }, { .port = { .membase = (void *)0xa4000150, .mapbase = 0xa4000150, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 59, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 1, }, .type = PORT_SCIF, @@ -1202,10 +1209,10 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)0xa4000140, .mapbase = 0xa4000140, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 55, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 2, }, .type = PORT_IRDA, @@ -1217,10 +1224,10 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)0xA4430000, .mapbase = 0xA4430000, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 25, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 0, }, .type = PORT_SCIF, @@ -1232,25 +1239,25 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)0xffe00000, .mapbase = 0xffe00000, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 25, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 0, }, .type = PORT_SCIF, .irqs = SH73180_SCIF_IRQS, .init_pins = sci_init_pins_scif, }, -#elif defined(CONFIG_SH_RTS7751R2D) +#elif defined(CONFIG_CPU_SUBTYPE_SH4_202) { .port = { .membase = (void *)0xffe80000, .mapbase = 0xffe80000, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 43, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 0, }, .type = PORT_SCIF, @@ -1262,24 +1269,23 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)0xffe00000, .mapbase = 0xffe00000, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 25, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 0, }, .type = PORT_SCI, .irqs = SCI_IRQS, - .init_pins = sci_init_pins_sci, }, { .port = { .membase = (void *)0xffe80000, .mapbase = 0xffe80000, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 43, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 1, }, .type = PORT_SCIF, @@ -1291,10 +1297,10 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)0xfe600000, .mapbase = 0xfe600000, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 55, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 0, }, .type = PORT_SCIF, @@ -1305,10 +1311,10 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)0xfe610000, .mapbase = 0xfe610000, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 75, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 1, }, .type = PORT_SCIF, @@ -1319,40 +1325,25 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)0xfe620000, .mapbase = 0xfe620000, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 79, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 2, }, .type = PORT_SCIF, .irqs = SH7760_SCIF2_IRQS, .init_pins = sci_init_pins_scif, }, -#elif defined(CONFIG_CPU_SUBTYPE_SH4_202) - { - .port = { - .membase = (void *)0xffe80000, - .mapbase = 0xffe80000, - .iotype = SERIAL_IO_MEM, - .irq = 43, - .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, - .line = 0, - }, - .type = PORT_SCIF, - .irqs = SH4_SCIF_IRQS, - .init_pins = sci_init_pins_scif, - }, #elif defined(CONFIG_CPU_SUBTYPE_ST40STB1) { .port = { .membase = (void *)0xffe00000, .mapbase = 0xffe00000, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 26, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 0, }, .type = PORT_SCIF, @@ -1363,10 +1354,10 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)0xffe80000, .mapbase = 0xffe80000, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 43, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 1, }, .type = PORT_SCIF, @@ -1376,10 +1367,10 @@ static struct sci_port sci_ports[SCI_NPORTS] = { #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) { .port = { - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 42, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 0, }, .type = PORT_SCIF, @@ -1391,10 +1382,10 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)0x00ffffb0, .mapbase = 0x00ffffb0, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 54, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 0, }, .type = PORT_SCI, @@ -1405,10 +1396,10 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)0x00ffffb8, .mapbase = 0x00ffffb8, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 58, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 1, }, .type = PORT_SCI, @@ -1419,10 +1410,10 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)0x00ffffc0, .mapbase = 0x00ffffc0, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 62, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 2, }, .type = PORT_SCI, @@ -1434,10 +1425,10 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)0x00ffff78, .mapbase = 0x00ffff78, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 90, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 0, }, .type = PORT_SCI, @@ -1448,10 +1439,10 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)0x00ffff80, .mapbase = 0x00ffff80, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 94, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 1, }, .type = PORT_SCI, @@ -1462,16 +1453,88 @@ static struct sci_port sci_ports[SCI_NPORTS] = { .port = { .membase = (void *)0x00ffff88, .mapbase = 0x00ffff88, - .iotype = SERIAL_IO_MEM, + .iotype = UPIO_MEM, .irq = 98, .ops = &sci_uart_ops, - .flags = ASYNC_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF, .line = 2, }, .type = PORT_SCI, .irqs = H8S_SCI_IRQS2, .init_pins = sci_init_pins_sci, }, +#elif defined(CONFIG_CPU_SUBTYPE_SH7770) + { + .port = { + .membase = (void *)0xff923000, + .mapbase = 0xff923000, + .iotype = UPIO_MEM, + .irq = 61, + .ops = &sci_uart_ops, + .flags = UPF_BOOT_AUTOCONF, + .line = 0, + }, + .type = PORT_SCIF, + .irqs = SH7770_SCIF0_IRQS, + .init_pins = sci_init_pins_scif, + }, + { + .port = { + .membase = (void *)0xff924000, + .mapbase = 0xff924000, + .iotype = UPIO_MEM, + .irq = 62, + .ops = &sci_uart_ops, + .flags = UPF_BOOT_AUTOCONF, + .line = 1, + }, + .type = PORT_SCIF, + .irqs = SH7770_SCIF1_IRQS, + .init_pins = sci_init_pins_scif, + }, + { + .port = { + .membase = (void *)0xff925000, + .mapbase = 0xff925000, + .iotype = UPIO_MEM, + .irq = 63, + .ops = &sci_uart_ops, + .flags = UPF_BOOT_AUTOCONF, + .line = 2, + }, + .type = PORT_SCIF, + .irqs = SH7770_SCIF2_IRQS, + .init_pins = sci_init_pins_scif, + }, +#elif defined(CONFIG_CPU_SUBTYPE_SH7780) + { + .port = { + .membase = (void *)0xffe00000, + .mapbase = 0xffe00000, + .iotype = UPIO_MEM, + .irq = 43, + .ops = &sci_uart_ops, + .flags = UPF_BOOT_AUTOCONF, + .line = 0, + }, + .type = PORT_SCIF, + .irqs = SH7780_SCIF0_IRQS, + .init_pins = sci_init_pins_scif, + }, + { + .port = { + .membase = (void *)0xffe10000, + .mapbase = 0xffe10000, + .iotype = UPIO_MEM, + .irq = 79, + .ops = &sci_uart_ops, + .flags = UPF_BOOT_AUTOCONF, + .line = 1, + }, + .type = PORT_SCIF, + .irqs = SH7780_SCIF1_IRQS, + .init_pins = sci_init_pins_scif, + }, #else #error "CPU subtype not defined" #endif @@ -1497,9 +1560,6 @@ static int __init serial_console_setup(struct console *co, char *options) int flow = 'n'; int ret; - if (co->index >= SCI_NPORTS) - co->index = 0; - serial_console_port = &sci_ports[co->index]; port = &serial_console_port->port; port->type = serial_console_port->type; @@ -1513,13 +1573,20 @@ static int __init serial_console_setup(struct console *co, char *options) * We need to set the initial uartclk here, since otherwise it will * only ever be setup at sci_init() time. */ -#if !defined(__H8300H__) && !defined(__H8300S__) - port->uartclk = current_cpu_data.module_clock * 16; -#else +#if defined(__H8300H__) || defined(__H8300S__) port->uartclk = CONFIG_CPU_CLOCK; -#endif + #if defined(__H8300S__) h8300_sci_enable(port, sci_enable); +#endif +#elif defined(CONFIG_SUPERH64) + port->uartclk = current_cpu_info.module_clock * 16; +#else + { + struct clk *clk = clk_get("module_clk"); + port->uartclk = clk_get_rate(clk) * 16; + clk_put(clk); + } #endif if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); @@ -1583,7 +1650,7 @@ int __init kgdb_console_setup(struct console *co, char *options) int parity = 'n'; int flow = 'n'; - if (co->index >= SCI_NPORTS || co->index != kgdb_portnum) + if (co->index != kgdb_portnum) co->index = kgdb_portnum; if (options) @@ -1623,7 +1690,7 @@ console_initcall(kgdb_console_init); #elif defined(CONFIG_SERIAL_SH_SCI_CONSOLE) #define SCI_CONSOLE &serial_console #else -#define SCI_CONSOLE 0 +#define SCI_CONSOLE 0 #endif static char banner[] __initdata = @@ -1638,7 +1705,6 @@ static struct uart_driver sci_uart_driver = { .dev_name = "ttySC", .major = SCI_MAJOR, .minor = SCI_MINOR_START, - .nr = SCI_NPORTS, .cons = SCI_CONSOLE, }; @@ -1648,15 +1714,21 @@ static int __init sci_init(void) printk("%s", banner); + sci_uart_driver.nr = ARRAY_SIZE(sci_ports); + ret = uart_register_driver(&sci_uart_driver); if (ret == 0) { for (chan = 0; chan < SCI_NPORTS; chan++) { struct sci_port *sciport = &sci_ports[chan]; -#if !defined(__H8300H__) && !defined(__H8300S__) - sciport->port.uartclk = (current_cpu_data.module_clock * 16); -#else +#if defined(__H8300H__) || defined(__H8300S__) sciport->port.uartclk = CONFIG_CPU_CLOCK; +#elif defined(CONFIG_SUPERH64) + sciport->port.uartclk = current_cpu_info.module_clock * 16; +#else + struct clk *clk = clk_get("module_clk"); + sciport->port.uartclk = clk_get_rate(clk) * 16; + clk_put(clk); #endif uart_add_one_port(&sci_uart_driver, &sciport->port); sciport->break_timer.data = (unsigned long)sciport;