]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
serial: 8250_exar: Absorb remaining 8250_port INT0 support
authorAaron Sierra <asierra@xes-inc.com>
Thu, 1 Aug 2019 18:59:56 +0000 (13:59 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Sep 2019 10:43:50 +0000 (12:43 +0200)
Move INT0 clearing out of common, per-port serial8250_do_startup()
into PCI device probe/resume.

As described in commit 2c0ac5b48a35 ("serial: exar: Fix stuck MSIs"),
the purpose of clearing INT0 is to prevent the PCI interrupt line from
becoming stuck asserted, "which is fatal with edge-triggered MSIs".

Like the clearing via interrupt handler that moved from common code in
commit c7e1b4059075 ("tty: serial: exar: Relocate sleep wake-up
handling"), this clearing at startup can be better handled at the PCI
device level.

Cc: Jan Kiszka <jan.kiszka@siemens.com>
Cc: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
Signed-off-by: Aaron Sierra <asierra@xes-inc.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20190801185956.3222-1-asierra@xes-inc.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/8250/8250_exar.c
drivers/tty/serial/8250/8250_port.c

index 357e20a6566fcabf81073a9820437688fd2749ca..3e93bd2326c93f1b985f29c6ad262816d2c63725 100644 (file)
@@ -493,6 +493,16 @@ static void pci_xr17v35x_exit(struct pci_dev *pcidev)
        port->port.private_data = NULL;
 }
 
+static inline void exar_misc_clear(struct exar8250 *priv)
+{
+       /* Clear all PCI interrupts by reading INT0. No effect on IIR */
+       readb(priv->virt + UART_EXAR_INT0);
+
+       /* Clear INT0 for Expansion Interface slave ports, too */
+       if (priv->board->num_ports > 8)
+               readb(priv->virt + 0x2000 + UART_EXAR_INT0);
+}
+
 /*
  * These Exar UARTs have an extra interrupt indicator that could fire for a
  * few interrupts that are not presented/cleared through IIR.  One of which is
@@ -504,14 +514,7 @@ static void pci_xr17v35x_exit(struct pci_dev *pcidev)
  */
 static irqreturn_t exar_misc_handler(int irq, void *data)
 {
-       struct exar8250 *priv = data;
-
-       /* Clear all PCI interrupts by reading INT0. No effect on IIR */
-       readb(priv->virt + UART_EXAR_INT0);
-
-       /* Clear INT0 for Expansion Interface slave ports, too */
-       if (priv->board->num_ports > 8)
-               readb(priv->virt + 0x2000 + UART_EXAR_INT0);
+       exar_misc_clear(data);
 
        return IRQ_HANDLED;
 }
@@ -584,6 +587,9 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
        if (rc)
                return rc;
 
+       /* Clear interrupts */
+       exar_misc_clear(priv);
+
        for (i = 0; i < nr_ports && i < maxnr; i++) {
                rc = board->setup(priv, pcidev, &uart, i);
                if (rc) {
@@ -642,6 +648,8 @@ static int __maybe_unused exar_resume(struct device *dev)
        struct exar8250 *priv = dev_get_drvdata(dev);
        unsigned int i;
 
+       exar_misc_clear(priv);
+
        for (i = 0; i < priv->nr; i++)
                if (priv->line[i] >= 0)
                        serial8250_resume_port(priv->line[i]);
index 995a7e8b78390b60c1702cf91958c942fc06e8e2..706645f89132c4a35900dc743ee596ebc7928dd7 100644 (file)
 
 #include "8250.h"
 
-/*
- * These are definitions for the Exar XR17V35X and XR17(C|D)15X
- */
-#define UART_EXAR_INT0         0x80
-
 /* Nuvoton NPCM timeout register */
 #define UART_NPCM_TOR          7
 #define UART_NPCM_TOIE         BIT(7)  /* Timeout Interrupt Enable */
@@ -2138,8 +2133,6 @@ int serial8250_do_startup(struct uart_port *port)
        serial_port_in(port, UART_RX);
        serial_port_in(port, UART_IIR);
        serial_port_in(port, UART_MSR);
-       if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X))
-               serial_port_in(port, UART_EXAR_INT0);
 
        /*
         * At this point, there's no way the LSR could still be 0xff;
@@ -2297,8 +2290,6 @@ int serial8250_do_startup(struct uart_port *port)
        serial_port_in(port, UART_RX);
        serial_port_in(port, UART_IIR);
        serial_port_in(port, UART_MSR);
-       if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X))
-               serial_port_in(port, UART_EXAR_INT0);
        up->lsr_saved_flags = 0;
        up->msr_saved_flags = 0;