aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial
diff options
context:
space:
mode:
authorThor Thayer <tthayer@opensource.altera.com>2016-09-22 15:56:16 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-09-27 06:55:50 -0400
commit8e5470c9839caff94fe334e67ff7e7ace587282a (patch)
treed96d839061310f9c2e94f7fc24fc906d338f4d01 /drivers/tty/serial
parentffea043965e4634617485b4d313d6c0099d817f0 (diff)
serial: 8250: Set Altera 16550 TX FIFO Threshold
The Altera 16550 soft IP UART requires 2 additional registers for TX FIFO threshold support. These 2 registers enable the TX FIFO Low Watermark and set the TX FIFO Low Watermark. Set the TX FIFO threshold to the FIFO size - tx_loadsz. Signed-off-by: Thor Thayer <tthayer@opensource.altera.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r--drivers/tty/serial/8250/8250_port.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 28d29fac1973..1bfb6fdbaa20 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -1870,6 +1870,30 @@ static int exar_handle_irq(struct uart_port *port)
1870 return ret; 1870 return ret;
1871} 1871}
1872 1872
1873/*
1874 * Newer 16550 compatible parts such as the SC16C650 & Altera 16550 Soft IP
1875 * have a programmable TX threshold that triggers the THRE interrupt in
1876 * the IIR register. In this case, the THRE interrupt indicates the FIFO
1877 * has space available. Load it up with tx_loadsz bytes.
1878 */
1879static int serial8250_tx_threshold_handle_irq(struct uart_port *port)
1880{
1881 unsigned long flags;
1882 unsigned int iir = serial_port_in(port, UART_IIR);
1883
1884 /* TX Threshold IRQ triggered so load up FIFO */
1885 if ((iir & UART_IIR_ID) == UART_IIR_THRI) {
1886 struct uart_8250_port *up = up_to_u8250p(port);
1887
1888 spin_lock_irqsave(&port->lock, flags);
1889 serial8250_tx_chars(up);
1890 spin_unlock_irqrestore(&port->lock, flags);
1891 }
1892
1893 iir = serial_port_in(port, UART_IIR);
1894 return serial8250_handle_irq(port, iir);
1895}
1896
1873static unsigned int serial8250_tx_empty(struct uart_port *port) 1897static unsigned int serial8250_tx_empty(struct uart_port *port)
1874{ 1898{
1875 struct uart_8250_port *up = up_to_u8250p(port); 1899 struct uart_8250_port *up = up_to_u8250p(port);
@@ -2159,6 +2183,25 @@ int serial8250_do_startup(struct uart_port *port)
2159 serial_port_out(port, UART_LCR, 0); 2183 serial_port_out(port, UART_LCR, 0);
2160 } 2184 }
2161 2185
2186 /*
2187 * For the Altera 16550 variants, set TX threshold trigger level.
2188 */
2189 if (((port->type == PORT_ALTR_16550_F32) ||
2190 (port->type == PORT_ALTR_16550_F64) ||
2191 (port->type == PORT_ALTR_16550_F128)) && (port->fifosize > 1)) {
2192 /* Bounds checking of TX threshold (valid 0 to fifosize-2) */
2193 if ((up->tx_loadsz < 2) || (up->tx_loadsz > port->fifosize)) {
2194 pr_err("ttyS%d TX FIFO Threshold errors, skipping\n",
2195 serial_index(port));
2196 } else {
2197 serial_port_out(port, UART_ALTR_AFR,
2198 UART_ALTR_EN_TXFIFO_LW);
2199 serial_port_out(port, UART_ALTR_TX_LOW,
2200 port->fifosize - up->tx_loadsz);
2201 port->handle_irq = serial8250_tx_threshold_handle_irq;
2202 }
2203 }
2204
2162 if (port->irq) { 2205 if (port->irq) {
2163 unsigned char iir1; 2206 unsigned char iir1;
2164 /* 2207 /*