aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/serial/8250.c15
-rw-r--r--drivers/serial/8250_pci.c36
-rw-r--r--include/linux/pci_ids.h3
-rw-r--r--include/linux/serial_core.h1
4 files changed, 55 insertions, 0 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 0d934bfbdd9b..b4b39811b445 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2083,6 +2083,20 @@ static int serial8250_startup(struct uart_port *port)
2083 2083
2084 serial8250_set_mctrl(&up->port, up->port.mctrl); 2084 serial8250_set_mctrl(&up->port, up->port.mctrl);
2085 2085
2086 /* Serial over Lan (SoL) hack:
2087 Intel 8257x Gigabit ethernet chips have a
2088 16550 emulation, to be used for Serial Over Lan.
2089 Those chips take a longer time than a normal
2090 serial device to signalize that a transmission
2091 data was queued. Due to that, the above test generally
2092 fails. One solution would be to delay the reading of
2093 iir. However, this is not reliable, since the timeout
2094 is variable. So, let's just don't test if we receive
2095 TX irq. This way, we'll never enable UART_BUG_TXEN.
2096 */
2097 if (up->port.flags & UPF_NO_TXEN_TEST)
2098 goto dont_test_tx_en;
2099
2086 /* 2100 /*
2087 * Do a quick test to see if we receive an 2101 * Do a quick test to see if we receive an
2088 * interrupt when we enable the TX irq. 2102 * interrupt when we enable the TX irq.
@@ -2102,6 +2116,7 @@ static int serial8250_startup(struct uart_port *port)
2102 up->bugs &= ~UART_BUG_TXEN; 2116 up->bugs &= ~UART_BUG_TXEN;
2103 } 2117 }
2104 2118
2119dont_test_tx_en:
2105 spin_unlock_irqrestore(&up->port.lock, flags); 2120 spin_unlock_irqrestore(&up->port.lock, flags);
2106 2121
2107 /* 2122 /*
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 536d8e510f66..533f82025adf 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -798,6 +798,21 @@ pci_default_setup(struct serial_private *priv,
798 return setup_port(priv, port, bar, offset, board->reg_shift); 798 return setup_port(priv, port, bar, offset, board->reg_shift);
799} 799}
800 800
801static int skip_tx_en_setup(struct serial_private *priv,
802 const struct pciserial_board *board,
803 struct uart_port *port, int idx)
804{
805 port->flags |= UPF_NO_TXEN_TEST;
806 printk(KERN_DEBUG "serial8250: skipping TxEn test for device "
807 "[%04x:%04x] subsystem [%04x:%04x]\n",
808 priv->dev->vendor,
809 priv->dev->device,
810 priv->dev->subsystem_vendor,
811 priv->dev->subsystem_device);
812
813 return pci_default_setup(priv, board, port, idx);
814}
815
801/* This should be in linux/pci_ids.h */ 816/* This should be in linux/pci_ids.h */
802#define PCI_VENDOR_ID_SBSMODULARIO 0x124B 817#define PCI_VENDOR_ID_SBSMODULARIO 0x124B
803#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B 818#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B
@@ -864,6 +879,27 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
864 .init = pci_inteli960ni_init, 879 .init = pci_inteli960ni_init,
865 .setup = pci_default_setup, 880 .setup = pci_default_setup,
866 }, 881 },
882 {
883 .vendor = PCI_VENDOR_ID_INTEL,
884 .device = PCI_DEVICE_ID_INTEL_8257X_SOL,
885 .subvendor = PCI_ANY_ID,
886 .subdevice = PCI_ANY_ID,
887 .setup = skip_tx_en_setup,
888 },
889 {
890 .vendor = PCI_VENDOR_ID_INTEL,
891 .device = PCI_DEVICE_ID_INTEL_82573L_SOL,
892 .subvendor = PCI_ANY_ID,
893 .subdevice = PCI_ANY_ID,
894 .setup = skip_tx_en_setup,
895 },
896 {
897 .vendor = PCI_VENDOR_ID_INTEL,
898 .device = PCI_DEVICE_ID_INTEL_82573E_SOL,
899 .subvendor = PCI_ANY_ID,
900 .subdevice = PCI_ANY_ID,
901 .setup = skip_tx_en_setup,
902 },
867 /* 903 /*
868 * ITE 904 * ITE
869 */ 905 */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 114b8192eab9..aca8c458aa8a 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2323,6 +2323,9 @@
2323#define PCI_DEVICE_ID_INTEL_82378 0x0484 2323#define PCI_DEVICE_ID_INTEL_82378 0x0484
2324#define PCI_DEVICE_ID_INTEL_I960 0x0960 2324#define PCI_DEVICE_ID_INTEL_I960 0x0960
2325#define PCI_DEVICE_ID_INTEL_I960RM 0x0962 2325#define PCI_DEVICE_ID_INTEL_I960RM 0x0962
2326#define PCI_DEVICE_ID_INTEL_8257X_SOL 0x1062
2327#define PCI_DEVICE_ID_INTEL_82573E_SOL 0x1085
2328#define PCI_DEVICE_ID_INTEL_82573L_SOL 0x108F
2326#define PCI_DEVICE_ID_INTEL_82815_MC 0x1130 2329#define PCI_DEVICE_ID_INTEL_82815_MC 0x1130
2327#define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132 2330#define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132
2328#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 2331#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 90bbbf0b1161..df9245c7bd3b 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -296,6 +296,7 @@ struct uart_port {
296#define UPF_HARDPPS_CD ((__force upf_t) (1 << 11)) 296#define UPF_HARDPPS_CD ((__force upf_t) (1 << 11))
297#define UPF_LOW_LATENCY ((__force upf_t) (1 << 13)) 297#define UPF_LOW_LATENCY ((__force upf_t) (1 << 13))
298#define UPF_BUGGY_UART ((__force upf_t) (1 << 14)) 298#define UPF_BUGGY_UART ((__force upf_t) (1 << 14))
299#define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15))
299#define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16)) 300#define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16))
300#define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) 301#define UPF_CONS_FLOW ((__force upf_t) (1 << 23))
301#define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) 302#define UPF_SHARE_IRQ ((__force upf_t) (1 << 24))