aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorPhilippe Langlais <philippe.langlais@stericsson.com>2010-07-29 11:13:57 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 16:47:46 -0400
commit235dae5d094c415fcf0fc79fa637f1901bc8afe2 (patch)
tree947ea700996f68c0a601cb2a0204d475ca131f32 /drivers/serial
parentbf9c1fca9ae9a79ed209e7ab2c10b3862f3f6f72 (diff)
U6715 16550A serial driver support
UART Features extract from STEricsson U6715 data-sheet (arm926 SoC for mobile phone): * Fully compatible with industry standard 16C550 and 16C450 from various manufacturers * RX and TX 64 byte FIFO reduces CPU interrupts * Full double buffering * Modem control signals include CTS, RTS, (and DSR, DTR on UART1 only) * Automatic baud rate selection * Manual or automatic RTS/CTS smart hardware flow control * Programmable serial characteristics: – Baud rate generation (50 to 3.25M baud) – 5, 6, 7 or 8-bit characters – Even, odd or no-parity bit generation and detection – 1, 1.5 or 2 stop bit generation * Independent control of transmit, receive, line status, data set interrupts and FIFOs * Full status-reporting capabilities * Separate DMA signaling for RX and TX * Timed interrupt to spread receive interrupt on known duration * DMA time-out interrupt to allow detection of end of reception * Carkit pulse coding and decoding compliant with USB carkit control interface [40] In 16550A auto-configuration, if the fifo size is 64 then it's an U6 16550A port Add set_termios hook & export serial8250_do_set_termios to change uart clock following baudrate Signed-off-by: Philippe Langlais <philippe.langlais@stericsson.com> Acked-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/8250.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 355148dc085e..24110f6f61e0 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -300,6 +300,13 @@ static const struct serial8250_config uart_config[] = {
300 .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, 300 .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
301 .flags = UART_CAP_FIFO | UART_CAP_AFE, 301 .flags = UART_CAP_FIFO | UART_CAP_AFE,
302 }, 302 },
303 [PORT_U6_16550A] = {
304 .name = "U6_16550A",
305 .fifo_size = 64,
306 .tx_loadsz = 64,
307 .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
308 .flags = UART_CAP_FIFO | UART_CAP_AFE,
309 },
303}; 310};
304 311
305#if defined(CONFIG_MIPS_ALCHEMY) 312#if defined(CONFIG_MIPS_ALCHEMY)
@@ -1070,6 +1077,15 @@ static void autoconfig_16550a(struct uart_8250_port *up)
1070 DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); 1077 DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 ");
1071 } 1078 }
1072 serial_outp(up, UART_IER, iersave); 1079 serial_outp(up, UART_IER, iersave);
1080
1081 /*
1082 * We distinguish between 16550A and U6 16550A by counting
1083 * how many bytes are in the FIFO.
1084 */
1085 if (up->port.type == PORT_16550A && size_fifo(up) == 64) {
1086 up->port.type = PORT_U6_16550A;
1087 up->capabilities |= UART_CAP_AFE;
1088 }
1073} 1089}
1074 1090
1075/* 1091/*
@@ -2224,9 +2240,9 @@ static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int
2224 return quot; 2240 return quot;
2225} 2241}
2226 2242
2227static void 2243void
2228serial8250_set_termios(struct uart_port *port, struct ktermios *termios, 2244serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
2229 struct ktermios *old) 2245 struct ktermios *old)
2230{ 2246{
2231 struct uart_8250_port *up = (struct uart_8250_port *)port; 2247 struct uart_8250_port *up = (struct uart_8250_port *)port;
2232 unsigned char cval, fcr = 0; 2248 unsigned char cval, fcr = 0;
@@ -2402,6 +2418,17 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
2402 if (tty_termios_baud_rate(termios)) 2418 if (tty_termios_baud_rate(termios))
2403 tty_termios_encode_baud_rate(termios, baud, baud); 2419 tty_termios_encode_baud_rate(termios, baud, baud);
2404} 2420}
2421EXPORT_SYMBOL(serial8250_do_set_termios);
2422
2423static void
2424serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
2425 struct ktermios *old)
2426{
2427 if (port->set_termios)
2428 port->set_termios(port, termios, old);
2429 else
2430 serial8250_do_set_termios(port, termios, old);
2431}
2405 2432
2406static void 2433static void
2407serial8250_set_ldisc(struct uart_port *port, int new) 2434serial8250_set_ldisc(struct uart_port *port, int new)
@@ -2982,6 +3009,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
2982 port.type = p->type; 3009 port.type = p->type;
2983 port.serial_in = p->serial_in; 3010 port.serial_in = p->serial_in;
2984 port.serial_out = p->serial_out; 3011 port.serial_out = p->serial_out;
3012 port.set_termios = p->set_termios;
2985 port.dev = &dev->dev; 3013 port.dev = &dev->dev;
2986 port.irqflags |= irqflag; 3014 port.irqflags |= irqflag;
2987 ret = serial8250_register_port(&port); 3015 ret = serial8250_register_port(&port);
@@ -3145,6 +3173,9 @@ int serial8250_register_port(struct uart_port *port)
3145 uart->port.serial_in = port->serial_in; 3173 uart->port.serial_in = port->serial_in;
3146 if (port->serial_out) 3174 if (port->serial_out)
3147 uart->port.serial_out = port->serial_out; 3175 uart->port.serial_out = port->serial_out;
3176 /* Possibly override set_termios call */
3177 if (port->set_termios)
3178 uart->port.set_termios = port->set_termios;
3148 3179
3149 ret = uart_add_one_port(&serial8250_reg, &uart->port); 3180 ret = uart_add_one_port(&serial8250_reg, &uart->port);
3150 if (ret == 0) 3181 if (ret == 0)