From 93e3d58284626ff6466f9c3dac8800cd6f8079c6 Mon Sep 17 00:00:00 2001 From: John Villalovos Date: Tue, 20 Jul 2010 15:26:46 -0700 Subject: serial: fix missing bit coverage of ASYNC_FLAGS It seems that currently ASYNC_FLAGS is one bit short of covering all the bits of the ASYNC user flags. In particular it does not cover the ASYNC_AUTOPROBE bit. ASYNCB_LAST_USER and ASYNCB_AUTOPROBE are both equal to 15. Therefore: ASYNC_AUTOPROBE = 1000 0000 0000 0000 ASYNC_FLAGS = 0111 1111 1111 1111 So ASYNC_FLAGS is not covering the ASYNC_AUTOPROBE bit. This patch fixes the issue and with the patch the values will be: ASYNC_AUTOPROBE = 1000 0000 0000 0000 ASYNC_FLAGS = 1111 1111 1111 1111 As a side note, doing a "git grep" I didn't find any use of ASYNC_AUTOPROBE or ASYNCB_AUTOPROBE in the kernel, besides this include file. Signed-off-by: John Villalovos Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/serial.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/serial.h') diff --git a/include/linux/serial.h b/include/linux/serial.h index c8613c3ff9d3..c3b45add494d 100644 --- a/include/linux/serial.h +++ b/include/linux/serial.h @@ -151,7 +151,7 @@ struct serial_uart_config { #define ASYNC_BUGGY_UART (1U << ASYNCB_BUGGY_UART) #define ASYNC_AUTOPROBE (1U << ASYNCB_AUTOPROBE) -#define ASYNC_FLAGS ((1U << ASYNCB_LAST_USER) - 1) +#define ASYNC_FLAGS ((1U << (ASYNCB_LAST_USER + 1)) - 1) #define ASYNC_USR_MASK (ASYNC_SPD_HI|ASYNC_SPD_VHI| \ ASYNC_CALLOUT_NOHUP|ASYNC_SPD_SHI|ASYNC_LOW_LATENCY) #define ASYNC_SPD_CUST (ASYNC_SPD_HI|ASYNC_SPD_VHI) -- cgit v1.2.3 From 1b6331848b69d1ed165a6bdc75c4046d68767563 Mon Sep 17 00:00:00 2001 From: Claudio Scordino Date: Tue, 20 Jul 2010 15:26:47 -0700 Subject: serial: general fixes in the serial_rs485 structure Fix several issues related to the RS485 interface: - It adds the flag SER_RS485_RTS_BEFORE_SEND that was missing from the serial_rs485 structure (even if "delay_rts_before_send" was existing) - It adds a further "delay_rts_after_send" field for those drivers that can have a delay after send (e.g., atmel_serial) - It fixes the usage of the structure in the atmel_serial driver (where "delay_rts_before_send" should be used instead of "delay_rts_after_send"). Signed-off-by: Claudio Scordino Signed-off-by: Bernhard Roth Cc: Philippe De Muyter Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/serial/atmel_serial.c | 11 ++++++++--- include/linux/serial.h | 4 +++- 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'include/linux/serial.h') diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index a182def7007d..3892666b5fbd 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c @@ -217,7 +217,8 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) if (rs485conf->flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; - UART_PUT_TTGR(port, rs485conf->delay_rts_before_send); + if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND) + UART_PUT_TTGR(port, rs485conf->delay_rts_after_send); mode |= ATMEL_US_USMODE_RS485; } else { dev_dbg(port->dev, "Setting UART to RS232\n"); @@ -292,7 +293,9 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) if (atmel_port->rs485.flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); - UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send); + if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND) + UART_PUT_TTGR(port, + atmel_port->rs485.delay_rts_after_send); mode |= ATMEL_US_USMODE_RS485; } else { dev_dbg(port->dev, "Setting UART to RS232\n"); @@ -1211,7 +1214,9 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, if (atmel_port->rs485.flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); - UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send); + if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND) + UART_PUT_TTGR(port, + atmel_port->rs485.delay_rts_after_send); mode |= ATMEL_US_USMODE_RS485; } else { dev_dbg(port->dev, "Setting UART to RS232\n"); diff --git a/include/linux/serial.h b/include/linux/serial.h index c3b45add494d..ef914061511e 100644 --- a/include/linux/serial.h +++ b/include/linux/serial.h @@ -210,8 +210,10 @@ struct serial_rs485 { #define SER_RS485_ENABLED (1 << 0) #define SER_RS485_RTS_ON_SEND (1 << 1) #define SER_RS485_RTS_AFTER_SEND (1 << 2) +#define SER_RS485_RTS_BEFORE_SEND (1 << 3) __u32 delay_rts_before_send; /* Milliseconds */ - __u32 padding[6]; /* Memory is cheap, new structs + __u32 delay_rts_after_send; /* Milliseconds */ + __u32 padding[5]; /* Memory is cheap, new structs are a royal PITA .. */ }; -- cgit v1.2.3 From 235dae5d094c415fcf0fc79fa637f1901bc8afe2 Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Thu, 29 Jul 2010 17:13:57 +0200 Subject: U6715 16550A serial driver support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/serial/8250.c | 37 ++++++++++++++++++++++++++++++++++--- include/linux/serial.h | 3 ++- include/linux/serial_8250.h | 5 +++++ include/linux/serial_core.h | 3 +++ 4 files changed, 44 insertions(+), 4 deletions(-) (limited to 'include/linux/serial.h') 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[] = { .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, .flags = UART_CAP_FIFO | UART_CAP_AFE, }, + [PORT_U6_16550A] = { + .name = "U6_16550A", + .fifo_size = 64, + .tx_loadsz = 64, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .flags = UART_CAP_FIFO | UART_CAP_AFE, + }, }; #if defined(CONFIG_MIPS_ALCHEMY) @@ -1070,6 +1077,15 @@ static void autoconfig_16550a(struct uart_8250_port *up) DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); } serial_outp(up, UART_IER, iersave); + + /* + * We distinguish between 16550A and U6 16550A by counting + * how many bytes are in the FIFO. + */ + if (up->port.type == PORT_16550A && size_fifo(up) == 64) { + up->port.type = PORT_U6_16550A; + up->capabilities |= UART_CAP_AFE; + } } /* @@ -2224,9 +2240,9 @@ static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int return quot; } -static void -serial8250_set_termios(struct uart_port *port, struct ktermios *termios, - struct ktermios *old) +void +serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, + struct ktermios *old) { struct uart_8250_port *up = (struct uart_8250_port *)port; unsigned char cval, fcr = 0; @@ -2402,6 +2418,17 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios, if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); } +EXPORT_SYMBOL(serial8250_do_set_termios); + +static void +serial8250_set_termios(struct uart_port *port, struct ktermios *termios, + struct ktermios *old) +{ + if (port->set_termios) + port->set_termios(port, termios, old); + else + serial8250_do_set_termios(port, termios, old); +} static void serial8250_set_ldisc(struct uart_port *port, int new) @@ -2982,6 +3009,7 @@ static int __devinit serial8250_probe(struct platform_device *dev) port.type = p->type; port.serial_in = p->serial_in; port.serial_out = p->serial_out; + port.set_termios = p->set_termios; port.dev = &dev->dev; port.irqflags |= irqflag; ret = serial8250_register_port(&port); @@ -3145,6 +3173,9 @@ int serial8250_register_port(struct uart_port *port) uart->port.serial_in = port->serial_in; if (port->serial_out) uart->port.serial_out = port->serial_out; + /* Possibly override set_termios call */ + if (port->set_termios) + uart->port.set_termios = port->set_termios; ret = uart_add_one_port(&serial8250_reg, &uart->port); if (ret == 0) diff --git a/include/linux/serial.h b/include/linux/serial.h index ef914061511e..1ebc694a6d52 100644 --- a/include/linux/serial.h +++ b/include/linux/serial.h @@ -77,7 +77,8 @@ struct serial_struct { #define PORT_16654 11 #define PORT_16850 12 #define PORT_RSA 13 /* RSA-DV II/S card */ -#define PORT_MAX 13 +#define PORT_U6_16550A 14 +#define PORT_MAX 14 #define SERIAL_IO_PORT 0 #define SERIAL_IO_HUB6 1 diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index fb46aba11fb5..7638deaaba65 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -32,6 +32,9 @@ struct plat_serial8250_port { unsigned int type; /* If UPF_FIXED_TYPE */ unsigned int (*serial_in)(struct uart_port *, int); void (*serial_out)(struct uart_port *, int, int); + void (*set_termios)(struct uart_port *, + struct ktermios *new, + struct ktermios *old); }; /* @@ -71,5 +74,7 @@ extern int early_serial_setup(struct uart_port *port); extern int serial8250_find_port(struct uart_port *p); extern int serial8250_find_port_for_earlycon(void); extern int setup_early_serial8250_console(char *cmdline); +extern void serial8250_do_set_termios(struct uart_port *port, + struct ktermios *termios, struct ktermios *old); #endif diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index f8fce351463d..8129ca2d57e3 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -282,6 +282,9 @@ struct uart_port { unsigned char __iomem *membase; /* read/write[bwl] */ unsigned int (*serial_in)(struct uart_port *, int); void (*serial_out)(struct uart_port *, int, int); + void (*set_termios)(struct uart_port *, + struct ktermios *new, + struct ktermios *old); unsigned int irq; /* irq number */ unsigned long irqflags; /* irq flags */ unsigned int uartclk; /* base uart clock */ -- cgit v1.2.3 From 71cad0554956de87c3fc413b1eac9313887eb14f Mon Sep 17 00:00:00 2001 From: Philippe Langlais Date: Tue, 31 Aug 2010 14:19:09 +0200 Subject: serial: fix port type conflict between NS16550A & U6_16550A Bug seen by Dr. David Alan Gilbert with sparse Signed-off-by: Philippe Langlais Cc: stable Signed-off-by: Greg Kroah-Hartman --- include/linux/serial.h | 3 +-- include/linux/serial_core.h | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux/serial.h') diff --git a/include/linux/serial.h b/include/linux/serial.h index 1ebc694a6d52..ef914061511e 100644 --- a/include/linux/serial.h +++ b/include/linux/serial.h @@ -77,8 +77,7 @@ struct serial_struct { #define PORT_16654 11 #define PORT_16850 12 #define PORT_RSA 13 /* RSA-DV II/S card */ -#define PORT_U6_16550A 14 -#define PORT_MAX 14 +#define PORT_MAX 13 #define SERIAL_IO_PORT 0 #define SERIAL_IO_HUB6 1 diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 64458a9a8938..563e23400913 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -44,7 +44,8 @@ #define PORT_RM9000 16 /* PMC-Sierra RM9xxx internal UART */ #define PORT_OCTEON 17 /* Cavium OCTEON internal UART */ #define PORT_AR7 18 /* Texas Instruments AR7 internal UART */ -#define PORT_MAX_8250 18 /* max port ID */ +#define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */ +#define PORT_MAX_8250 19 /* max port ID */ /* * ARM specific type numbers. These are not currently guaranteed -- cgit v1.2.3