[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1280410348-28940-2-git-send-email-philippe.langlais@stericsson.com>
Date: Thu, 29 Jul 2010 15:32:28 +0200
From: Philippe Langlais <philippe.langlais@...ricsson.com>
To: <linux-kernel@...r.kernel.org>
Cc: <alan@...rguk.ukuu.org.uk>, <gregkh@...e.de>,
<ludovic.barre@...ricsson.com>, <vincent.guittot@...ricsson.com>,
Philippe Langlais <philippe.langlais@...ricsson.com>
Subject: [PATCH] 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 pre_set_termios call at normal serial8250_set_termios beginning
Signed-off-by: Philippe Langlais <philippe.langlais@...ricsson.com>
---
drivers/serial/8250.c | 24 ++++++++++++++++++++++++
include/linux/serial.h | 3 ++-
include/linux/serial_8250.h | 3 +++
include/linux/serial_core.h | 3 +++
4 files changed, 32 insertions(+), 1 deletions(-)
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 607ed7f..1e9e2f2 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_SERIAL_8250_AU1X00)
@@ -1075,6 +1082,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;
+ }
}
/*
@@ -2238,6 +2254,10 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
unsigned long flags;
unsigned int baud, quot;
+ /* Possibly call pre_set_termios function. */
+ if (port->pre_set_termios)
+ port->pre_set_termios(port, termios, old);
+
switch (termios->c_cflag & CSIZE) {
case CS5:
cval = UART_LCR_WLEN5;
@@ -2989,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.pre_set_termios = p->pre_set_termios;
port.dev = &dev->dev;
port.irqflags |= irqflag;
ret = serial8250_register_port(&port);
@@ -3152,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 add pre_set_termios call */
+ if (port->pre_set_termios)
+ uart->port.pre_set_termios = port->pre_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 c8613c3..06c99b6 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 fb46aba..f5fbc7e 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 (*pre_set_termios)(struct uart_port *,
+ struct ktermios *new,
+ struct ktermios *old);
};
/*
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 18f2fe0..5ff5591 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -279,6 +279,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 (*pre_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 */
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists