aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2012-07-12 08:00:31 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-07-12 17:48:11 -0400
commiteb26dfe8aa7eeb5a5aa0b7574550125f8aa4c3b3 (patch)
tree8734be494ef3888bf39d0f0a472cc37c5843c4b6 /drivers
parenta2d33d87d8a4a5047597439fb917f57e4264a79a (diff)
8250: add support for ASIX devices with a FIFO bug
Information and a different patch provided by <donald@asix.com.tw>. We do it a little differently to keep the modularity and to avoid playing with RLSI. We add a new uart bug for the parity flaw and set it in the pci matches. If parity check is enabled then we drop the FIFO trigger to 1 as per the Asix reference code. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/tty/serial/8250/8250.c8
-rw-r--r--drivers/tty/serial/8250/8250.h1
-rw-r--r--drivers/tty/serial/8250/8250_pci.c24
3 files changed, 28 insertions, 5 deletions
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
index ca42d16e5a12..44f52c6f15b9 100644
--- a/drivers/tty/serial/8250/8250.c
+++ b/drivers/tty/serial/8250/8250.c
@@ -2202,6 +2202,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
2202 unsigned char cval, fcr = 0; 2202 unsigned char cval, fcr = 0;
2203 unsigned long flags; 2203 unsigned long flags;
2204 unsigned int baud, quot; 2204 unsigned int baud, quot;
2205 int fifo_bug = 0;
2205 2206
2206 switch (termios->c_cflag & CSIZE) { 2207 switch (termios->c_cflag & CSIZE) {
2207 case CS5: 2208 case CS5:
@@ -2221,8 +2222,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
2221 2222
2222 if (termios->c_cflag & CSTOPB) 2223 if (termios->c_cflag & CSTOPB)
2223 cval |= UART_LCR_STOP; 2224 cval |= UART_LCR_STOP;
2224 if (termios->c_cflag & PARENB) 2225 if (termios->c_cflag & PARENB) {
2225 cval |= UART_LCR_PARITY; 2226 cval |= UART_LCR_PARITY;
2227 if (up->bugs & UART_BUG_PARITY)
2228 fifo_bug = 1;
2229 }
2226 if (!(termios->c_cflag & PARODD)) 2230 if (!(termios->c_cflag & PARODD))
2227 cval |= UART_LCR_EPAR; 2231 cval |= UART_LCR_EPAR;
2228#ifdef CMSPAR 2232#ifdef CMSPAR
@@ -2246,7 +2250,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
2246 2250
2247 if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { 2251 if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) {
2248 fcr = uart_config[port->type].fcr; 2252 fcr = uart_config[port->type].fcr;
2249 if (baud < 2400) { 2253 if (baud < 2400 || fifo_bug) {
2250 fcr &= ~UART_FCR_TRIGGER_MASK; 2254 fcr &= ~UART_FCR_TRIGGER_MASK;
2251 fcr |= UART_FCR_TRIGGER_1; 2255 fcr |= UART_FCR_TRIGGER_1;
2252 } 2256 }
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index f9719d167c8d..c335b2b23a5f 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -78,6 +78,7 @@ struct serial8250_config {
78#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ 78#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
79#define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */ 79#define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */
80#define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */ 80#define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */
81#define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */
81 82
82#define PROBE_RSA (1 << 0) 83#define PROBE_RSA (1 << 0)
83#define PROBE_ANY (~0) 84#define PROBE_ANY (~0)
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 2ef9a075eec5..62e10fe747a8 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -1032,8 +1032,15 @@ static int pci_oxsemi_tornado_init(struct pci_dev *dev)
1032 return number_uarts; 1032 return number_uarts;
1033} 1033}
1034 1034
1035static int 1035static int pci_asix_setup(struct serial_private *priv,
1036pci_default_setup(struct serial_private *priv, 1036 const struct pciserial_board *board,
1037 struct uart_8250_port *port, int idx)
1038{
1039 port->bugs |= UART_BUG_PARITY;
1040 return pci_default_setup(priv, board, port, idx);
1041}
1042
1043static int pci_default_setup(struct serial_private *priv,
1037 const struct pciserial_board *board, 1044 const struct pciserial_board *board,
1038 struct uart_8250_port *port, int idx) 1045 struct uart_8250_port *port, int idx)
1039{ 1046{
@@ -1187,6 +1194,7 @@ pci_xr17c154_setup(struct serial_private *priv,
1187#define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 1194#define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6
1188#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 1195#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001
1189#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d 1196#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d
1197#define PCI_VENDOR_ID_ASIX 0x9710
1190 1198
1191/* Unknown vendors/cards - this should not be in linux/pci_ids.h */ 1199/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
1192#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 1200#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
@@ -1726,7 +1734,17 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
1726 .subvendor = PCI_ANY_ID, 1734 .subvendor = PCI_ANY_ID,
1727 .subdevice = PCI_ANY_ID, 1735 .subdevice = PCI_ANY_ID,
1728 .setup = pci_omegapci_setup, 1736 .setup = pci_omegapci_setup,
1729 }, 1737 },
1738 /*
1739 * ASIX devices with FIFO bug
1740 */
1741 {
1742 .vendor = PCI_VENDOR_ID_ASIX,
1743 .device = PCI_ANY_ID,
1744 .subvendor = PCI_ANY_ID,
1745 .subdevice = PCI_ANY_ID,
1746 .setup = pci_asix_setup,
1747 },
1730 /* 1748 /*
1731 * Default "match everything" terminator entry 1749 * Default "match everything" terminator entry
1732 */ 1750 */