aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2012-04-06 14:49:50 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-09 13:38:30 -0400
commitbc02d15a3452fdf9276e8fb89c5e504a88df888a (patch)
treeb7014c75d121418b0bc88d8c74f699f9a59adc24 /drivers/tty
parent49b532f96fda23663f8be35593d1c1372c0f91e0 (diff)
serial/8250_pci: add a "force background timer" flag and use it for the "kt" serial port
Workaround dropped notifications in the iir register. Register reads coincident with new interrupt notifications sometimes result in this device clearing the interrupt event without reporting it in the read data. The serial core already has a heuristic for determining when a device has an untrustworthy iir register. In this case when we apriori know that the iir is faulty use a flag (UPF_BUG_THRE) to bypass the test and force usage of the background timer. [stable: 3.3.x] Acked-by: Alan Cox <alan@linux.intel.com> Cc: stable <stable@vger.kernel.org> Reported-by: Nhan H Mai <nhan.h.mai@intel.com> Reported-by: Sudhakar Mamillapalli <sudhakar@fb.com> Tested-by: Nhan H Mai <nhan.h.mai@intel.com> Tested-by: Sudhakar Mamillapalli <sudhakar@fb.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/8250/8250.c8
-rw-r--r--drivers/tty/serial/8250/8250_pci.c17
2 files changed, 21 insertions, 4 deletions
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
index 56492d208a7..5c27f7e6c9f 100644
--- a/drivers/tty/serial/8250/8250.c
+++ b/drivers/tty/serial/8250/8250.c
@@ -2035,10 +2035,12 @@ static int serial8250_startup(struct uart_port *port)
2035 spin_unlock_irqrestore(&port->lock, flags); 2035 spin_unlock_irqrestore(&port->lock, flags);
2036 2036
2037 /* 2037 /*
2038 * If the interrupt is not reasserted, setup a timer to 2038 * If the interrupt is not reasserted, or we otherwise
2039 * kick the UART on a regular basis. 2039 * don't trust the iir, setup a timer to kick the UART
2040 * on a regular basis.
2040 */ 2041 */
2041 if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) { 2042 if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) ||
2043 up->port.flags & UPF_BUG_THRE) {
2042 up->bugs |= UART_BUG_THRE; 2044 up->bugs |= UART_BUG_THRE;
2043 pr_debug("ttyS%d - using backup timer\n", 2045 pr_debug("ttyS%d - using backup timer\n",
2044 serial_index(port)); 2046 serial_index(port));
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 105dcfbd3d3..858dca865d6 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -1092,6 +1092,14 @@ static int skip_tx_en_setup(struct serial_private *priv,
1092 return pci_default_setup(priv, board, port, idx); 1092 return pci_default_setup(priv, board, port, idx);
1093} 1093}
1094 1094
1095static int kt_serial_setup(struct serial_private *priv,
1096 const struct pciserial_board *board,
1097 struct uart_port *port, int idx)
1098{
1099 port->flags |= UPF_BUG_THRE;
1100 return skip_tx_en_setup(priv, board, port, idx);
1101}
1102
1095static int pci_eg20t_init(struct pci_dev *dev) 1103static int pci_eg20t_init(struct pci_dev *dev)
1096{ 1104{
1097#if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE) 1105#if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE)
@@ -1110,7 +1118,6 @@ pci_xr17c154_setup(struct serial_private *priv,
1110 return pci_default_setup(priv, board, port, idx); 1118 return pci_default_setup(priv, board, port, idx);
1111} 1119}
1112 1120
1113/* This should be in linux/pci_ids.h */
1114#define PCI_VENDOR_ID_SBSMODULARIO 0x124B 1121#define PCI_VENDOR_ID_SBSMODULARIO 0x124B
1115#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B 1122#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B
1116#define PCI_DEVICE_ID_OCTPRO 0x0001 1123#define PCI_DEVICE_ID_OCTPRO 0x0001
@@ -1140,6 +1147,7 @@ pci_xr17c154_setup(struct serial_private *priv,
1140#define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538 1147#define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538
1141#define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 1148#define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6
1142#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 1149#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001
1150#define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d
1143 1151
1144/* Unknown vendors/cards - this should not be in linux/pci_ids.h */ 1152/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
1145#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 1153#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
@@ -1224,6 +1232,13 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
1224 .subdevice = PCI_ANY_ID, 1232 .subdevice = PCI_ANY_ID,
1225 .setup = ce4100_serial_setup, 1233 .setup = ce4100_serial_setup,
1226 }, 1234 },
1235 {
1236 .vendor = PCI_VENDOR_ID_INTEL,
1237 .device = PCI_DEVICE_ID_INTEL_PATSBURG_KT,
1238 .subvendor = PCI_ANY_ID,
1239 .subdevice = PCI_ANY_ID,
1240 .setup = kt_serial_setup,
1241 },
1227 /* 1242 /*
1228 * ITE 1243 * ITE
1229 */ 1244 */