X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=drivers%2Fserial%2Fsh-sci.c;h=557b54ab2f25d22b0f623b7f6dde18cb12cc47f2;hb=97b5fe8e28d78779e35ac283bacb9eceffd5b4a3;hp=0251077693d13df22e347373f6b71c069314b9aa;hpb=762c69e3cad67a5cc5a01ba74e0b552ae4615258;p=mv-sheeva.git diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 0251077693d..557b54ab2f2 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -64,10 +64,6 @@ struct sci_port { /* Port IRQs: ERI, RXI, TXI, BRI (optional) */ unsigned int irqs[SCIx_NR_IRQS]; - /* Port pin configuration */ - void (*init_pins)(struct uart_port *port, - unsigned int cflag); - /* Port enable callback */ void (*enable)(struct uart_port *port); @@ -103,6 +99,8 @@ to_sci_port(struct uart_port *uart) } #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE) + +#ifdef CONFIG_CONSOLE_POLL static inline void handle_error(struct uart_port *port) { /* Clear error flags */ @@ -130,6 +128,7 @@ static int sci_poll_get_char(struct uart_port *port) return c; } +#endif static void sci_poll_put_char(struct uart_port *port, unsigned char c) { @@ -172,7 +171,7 @@ static inline void h8300_sci_disable(struct uart_port *port) #endif #if defined(__H8300H__) || defined(__H8300S__) -static void sci_init_pins_sci(struct uart_port *port, unsigned int cflag) +static void sci_init_pins(struct uart_port *port, unsigned int cflag) { int ch = (port->mapbase - SMR0) >> 3; @@ -187,140 +186,99 @@ 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 -#define sci_init_pins_sci NULL -#endif - -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) -static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag) +#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) +static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) { - unsigned int fcr_val = 0; - - if (cflag & CRTSCTS) - fcr_val |= SCFCR_MCE; - - sci_out(port, SCFCR, fcr_val); -} -#else -#define sci_init_pins_irda NULL -#endif - -#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) -static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) -{ - unsigned int fcr_val = 0; - - set_sh771x_scif_pfc(port); - if (cflag & CRTSCTS) - fcr_val |= SCFCR_MCE; - sci_out(port, SCFCR, fcr_val); + if (port->mapbase == 0xA4400000) { + __raw_writew(__raw_readw(PACR) & 0xffc0, PACR); + __raw_writew(__raw_readw(PBCR) & 0x0fff, PBCR); + } else if (port->mapbase == 0xA4410000) + __raw_writew(__raw_readw(PBCR) & 0xf003, PBCR); } #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7721) -static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) +static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) { - unsigned int fcr_val = 0; unsigned short data; if (cflag & CRTSCTS) { /* enable RTS/CTS */ if (port->mapbase == 0xa4430000) { /* SCIF0 */ /* Clear PTCR bit 9-2; enable all scif pins but sck */ - data = ctrl_inw(PORT_PTCR); - ctrl_outw((data & 0xfc03), PORT_PTCR); + data = __raw_readw(PORT_PTCR); + __raw_writew((data & 0xfc03), PORT_PTCR); } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ /* Clear PVCR bit 9-2 */ - data = ctrl_inw(PORT_PVCR); - ctrl_outw((data & 0xfc03), PORT_PVCR); + data = __raw_readw(PORT_PVCR); + __raw_writew((data & 0xfc03), PORT_PVCR); } - fcr_val |= SCFCR_MCE; } else { if (port->mapbase == 0xa4430000) { /* SCIF0 */ /* Clear PTCR bit 5-2; enable only tx and rx */ - data = ctrl_inw(PORT_PTCR); - ctrl_outw((data & 0xffc3), PORT_PTCR); + data = __raw_readw(PORT_PTCR); + __raw_writew((data & 0xffc3), PORT_PTCR); } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ /* Clear PVCR bit 5-2 */ - data = ctrl_inw(PORT_PVCR); - ctrl_outw((data & 0xffc3), PORT_PVCR); + data = __raw_readw(PORT_PVCR); + __raw_writew((data & 0xffc3), PORT_PVCR); } } - sci_out(port, SCFCR, fcr_val); } #elif defined(CONFIG_CPU_SH3) /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ -static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) +static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) { - unsigned int fcr_val = 0; unsigned short data; /* We need to set SCPCR to enable RTS/CTS */ - data = ctrl_inw(SCPCR); + data = __raw_readw(SCPCR); /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/ - ctrl_outw(data & 0x0fcf, SCPCR); + __raw_writew(data & 0x0fcf, SCPCR); - if (cflag & CRTSCTS) - fcr_val |= SCFCR_MCE; - else { + if (!(cflag & CRTSCTS)) { /* We need to set SCPCR to enable RTS/CTS */ - data = ctrl_inw(SCPCR); + data = __raw_readw(SCPCR); /* Clear out SCP7MD1,0, SCP4MD1,0, Set SCP6MD1,0 = {01} (output) */ - ctrl_outw((data & 0x0fcf) | 0x1000, SCPCR); + __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); data = ctrl_inb(SCPDR); /* Set /RTS2 (bit6) = 0 */ ctrl_outb(data & 0xbf, SCPDR); } - - sci_out(port, SCFCR, fcr_val); } #elif defined(CONFIG_CPU_SUBTYPE_SH7722) -static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) +static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) { - unsigned int fcr_val = 0; unsigned short data; if (port->mapbase == 0xffe00000) { - data = ctrl_inw(PSCR); + data = __raw_readw(PSCR); data &= ~0x03cf; - if (cflag & CRTSCTS) - fcr_val |= SCFCR_MCE; - else + if (!(cflag & CRTSCTS)) data |= 0x0340; - ctrl_outw(data, PSCR); + __raw_writew(data, PSCR); } - /* SCIF1 and SCIF2 should be setup by board code */ - - sci_out(port, SCFCR, fcr_val); -} -#elif defined(CONFIG_CPU_SUBTYPE_SH7723) -static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) -{ - /* Nothing to do here.. */ - sci_out(port, SCFCR, 0); } -#else -/* For SH7750 */ -static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) -{ - unsigned int fcr_val = 0; - - if (cflag & CRTSCTS) { - fcr_val |= SCFCR_MCE; - } else { -#if defined(CONFIG_CPU_SUBTYPE_SH7343) || defined(CONFIG_CPU_SUBTYPE_SH7366) - /* Nothing */ #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ defined(CONFIG_CPU_SUBTYPE_SH7780) || \ defined(CONFIG_CPU_SUBTYPE_SH7785) || \ defined(CONFIG_CPU_SUBTYPE_SHX3) - ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */ +static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) +{ + if (!(cflag & CRTSCTS)) + __raw_writew(0x0080, SCSPTR0); /* Set RTS = 1 */ +} +#elif defined(CONFIG_CPU_SH4) && !defined(CONFIG_CPU_SH4A) +static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) +{ + if (!(cflag & CRTSCTS)) + __raw_writew(0x0080, SCSPTR2); /* Set RTS = 1 */ +} #else - ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */ -#endif - } - sci_out(port, SCFCR, fcr_val); +static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) +{ + /* Nothing to do */ } #endif @@ -625,6 +583,27 @@ static inline int sci_handle_errors(struct uart_port *port) return copied; } +static inline int sci_handle_fifo_overrun(struct uart_port *port) +{ + struct tty_struct *tty = port->info->port.tty; + int copied = 0; + + if (port->type != PORT_SCIF) + return 0; + + if ((sci_in(port, SCLSR) & SCIF_ORER) != 0) { + sci_out(port, SCLSR, 0); + + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + tty_flip_buffer_push(tty); + + dev_notice(port->dev, "overrun error\n"); + copied++; + } + + return copied; +} + static inline int sci_handle_breaks(struct uart_port *port) { int copied = 0; @@ -647,20 +626,11 @@ static inline int sci_handle_breaks(struct uart_port *port) dev_dbg(port->dev, "BREAK detected\n"); } -#if defined(SCIF_ORER) - /* XXX: Handle SCIF overrun error */ - if (port->type != PORT_SCI && (sci_in(port, SCLSR) & SCIF_ORER) != 0) { - sci_out(port, SCLSR, 0); - if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) { - copied++; - dev_notice(port->dev, "overrun error\n"); - } - } -#endif - if (copied) tty_flip_buffer_push(tty); + copied += sci_handle_fifo_overrun(port); + return copied; } @@ -698,16 +668,7 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr) sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); } } else { -#if defined(SCIF_ORER) - if ((sci_in(port, SCLSR) & SCIF_ORER) != 0) { - struct tty_struct *tty = port->info->port.tty; - - sci_out(port, SCLSR, 0); - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - tty_flip_buffer_push(tty); - dev_notice(port->dev, "overrun error\n"); - } -#endif + sci_handle_fifo_overrun(port); sci_rx_interrupt(irq, ptr); } @@ -938,7 +899,6 @@ static void sci_shutdown(struct uart_port *port) static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { - struct sci_port *s = &sci_ports[port->line]; unsigned int status, baud, smr_val; int t = -1; @@ -980,8 +940,8 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ } - if (likely(s->init_pins)) - s->init_pins(port, termios->c_cflag); + sci_init_pins(port, termios->c_cflag); + sci_out(port, SCFCR, (termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0); sci_out(port, SCSCR, SCSCR_INIT(port)); @@ -1022,19 +982,6 @@ static void sci_config_port(struct uart_port *port, int flags) port->type = s->type; - switch (port->type) { - case PORT_SCI: - s->init_pins = sci_init_pins_sci; - break; - case PORT_SCIF: - case PORT_SCIFA: - s->init_pins = sci_init_pins_scif; - break; - case PORT_IRDA: - s->init_pins = sci_init_pins_irda; - break; - } - if (port->flags & UPF_IOREMAP && !port->membase) { #if defined(CONFIG_SUPERH64) port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF");