serial: exar: Leave MPIOs as output for Commtech adapters
authorJan Kiszka <jan.kiszka@siemens.com>
Fri, 2 Jun 2017 07:28:44 +0000 (09:28 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 9 Jun 2017 09:23:36 +0000 (11:23 +0200)
Commtech adapters apparently need the original setting as outputs, see
https://marc.info/?l=linux-gpio&m=149557425201323&w=2. Account for that.

Fixes: 7dea8165f1d6 ("serial: exar: Preconfigure xr17v35x MPIOs as output")
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/8250/8250_exar.c

index 0a20f7185094bb4aa1d104fe18d2d6f6510271ec..a309bcffffcd37509c88dc4b305e8b6d82701d99 100644 (file)
@@ -170,19 +170,26 @@ pci_xr17c154_setup(struct exar8250 *priv, struct pci_dev *pcidev,
        return default_setup(priv, pcidev, idx, offset, port);
 }
 
-static void setup_gpio(u8 __iomem *p)
+static void setup_gpio(struct pci_dev *pcidev, u8 __iomem *p)
 {
+       /*
+        * The Commtech adapters required the MPIOs to be driven low. The Exar
+        * devices will export them as GPIOs, so we pre-configure them safely
+        * as inputs.
+        */
+       u8 dir = pcidev->vendor == PCI_VENDOR_ID_EXAR ? 0xff : 0x00;
+
        writeb(0x00, p + UART_EXAR_MPIOINT_7_0);
        writeb(0x00, p + UART_EXAR_MPIOLVL_7_0);
        writeb(0x00, p + UART_EXAR_MPIO3T_7_0);
        writeb(0x00, p + UART_EXAR_MPIOINV_7_0);
-       writeb(0xff, p + UART_EXAR_MPIOSEL_7_0);
+       writeb(dir,  p + UART_EXAR_MPIOSEL_7_0);
        writeb(0x00, p + UART_EXAR_MPIOOD_7_0);
        writeb(0x00, p + UART_EXAR_MPIOINT_15_8);
        writeb(0x00, p + UART_EXAR_MPIOLVL_15_8);
        writeb(0x00, p + UART_EXAR_MPIO3T_15_8);
        writeb(0x00, p + UART_EXAR_MPIOINV_15_8);
-       writeb(0xff, p + UART_EXAR_MPIOSEL_15_8);
+       writeb(dir,  p + UART_EXAR_MPIOSEL_15_8);
        writeb(0x00, p + UART_EXAR_MPIOOD_15_8);
 }
 
@@ -235,7 +242,7 @@ pci_xr17v35x_setup(struct exar8250 *priv, struct pci_dev *pcidev,
 
        if (idx == 0) {
                /* Setup Multipurpose Input/Output pins. */
-               setup_gpio(p);
+               setup_gpio(pcidev, p);
 
                port->port.private_data = xr17v35x_register_gpio(pcidev);
        }