linux/drivers/tty/serial/8250/8250_exar.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 *  Probe module for 8250/16550-type Exar chips PCI serial ports.
   4 *
   5 *  Based on drivers/tty/serial/8250/8250_pci.c,
   6 *
   7 *  Copyright (C) 2017 Sudip Mukherjee, All Rights Reserved.
   8 */
   9#include <linux/acpi.h>
  10#include <linux/dmi.h>
  11#include <linux/io.h>
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/pci.h>
  15#include <linux/property.h>
  16#include <linux/serial_core.h>
  17#include <linux/serial_reg.h>
  18#include <linux/slab.h>
  19#include <linux/string.h>
  20#include <linux/tty.h>
  21#include <linux/8250_pci.h>
  22
  23#include <asm/byteorder.h>
  24
  25#include "8250.h"
  26
  27#define PCI_DEVICE_ID_COMMTECH_4224PCI335       0x0002
  28#define PCI_DEVICE_ID_COMMTECH_4222PCI335       0x0004
  29#define PCI_DEVICE_ID_COMMTECH_2324PCI335       0x000a
  30#define PCI_DEVICE_ID_COMMTECH_2328PCI335       0x000b
  31#define PCI_DEVICE_ID_COMMTECH_4224PCIE         0x0020
  32#define PCI_DEVICE_ID_COMMTECH_4228PCIE         0x0021
  33#define PCI_DEVICE_ID_COMMTECH_4222PCIE         0x0022
  34#define PCI_DEVICE_ID_EXAR_XR17V4358            0x4358
  35#define PCI_DEVICE_ID_EXAR_XR17V8358            0x8358
  36
  37#define UART_EXAR_INT0          0x80
  38#define UART_EXAR_8XMODE        0x88    /* 8X sampling rate select */
  39
  40#define UART_EXAR_FCTR          0x08    /* Feature Control Register */
  41#define UART_FCTR_EXAR_IRDA     0x10    /* IrDa data encode select */
  42#define UART_FCTR_EXAR_485      0x20    /* Auto 485 half duplex dir ctl */
  43#define UART_FCTR_EXAR_TRGA     0x00    /* FIFO trigger table A */
  44#define UART_FCTR_EXAR_TRGB     0x60    /* FIFO trigger table B */
  45#define UART_FCTR_EXAR_TRGC     0x80    /* FIFO trigger table C */
  46#define UART_FCTR_EXAR_TRGD     0xc0    /* FIFO trigger table D programmable */
  47
  48#define UART_EXAR_TXTRG         0x0a    /* Tx FIFO trigger level write-only */
  49#define UART_EXAR_RXTRG         0x0b    /* Rx FIFO trigger level write-only */
  50
  51#define UART_EXAR_MPIOINT_7_0   0x8f    /* MPIOINT[7:0] */
  52#define UART_EXAR_MPIOLVL_7_0   0x90    /* MPIOLVL[7:0] */
  53#define UART_EXAR_MPIO3T_7_0    0x91    /* MPIO3T[7:0] */
  54#define UART_EXAR_MPIOINV_7_0   0x92    /* MPIOINV[7:0] */
  55#define UART_EXAR_MPIOSEL_7_0   0x93    /* MPIOSEL[7:0] */
  56#define UART_EXAR_MPIOOD_7_0    0x94    /* MPIOOD[7:0] */
  57#define UART_EXAR_MPIOINT_15_8  0x95    /* MPIOINT[15:8] */
  58#define UART_EXAR_MPIOLVL_15_8  0x96    /* MPIOLVL[15:8] */
  59#define UART_EXAR_MPIO3T_15_8   0x97    /* MPIO3T[15:8] */
  60#define UART_EXAR_MPIOINV_15_8  0x98    /* MPIOINV[15:8] */
  61#define UART_EXAR_MPIOSEL_15_8  0x99    /* MPIOSEL[15:8] */
  62#define UART_EXAR_MPIOOD_15_8   0x9a    /* MPIOOD[15:8] */
  63
  64#define UART_EXAR_RS485_DLY(x)  ((x) << 4)
  65
  66/*
  67 * IOT2040 MPIO wiring semantics:
  68 *
  69 * MPIO         Port    Function
  70 * ----         ----    --------
  71 * 0            2       Mode bit 0
  72 * 1            2       Mode bit 1
  73 * 2            2       Terminate bus
  74 * 3            -       <reserved>
  75 * 4            3       Mode bit 0
  76 * 5            3       Mode bit 1
  77 * 6            3       Terminate bus
  78 * 7            -       <reserved>
  79 * 8            2       Enable
  80 * 9            3       Enable
  81 * 10           -       Red LED
  82 * 11..15       -       <unused>
  83 */
  84
  85/* IOT2040 MPIOs 0..7 */
  86#define IOT2040_UART_MODE_RS232         0x01
  87#define IOT2040_UART_MODE_RS485         0x02
  88#define IOT2040_UART_MODE_RS422         0x03
  89#define IOT2040_UART_TERMINATE_BUS      0x04
  90
  91#define IOT2040_UART1_MASK              0x0f
  92#define IOT2040_UART2_SHIFT             4
  93
  94#define IOT2040_UARTS_DEFAULT_MODE      0x11    /* both RS232 */
  95#define IOT2040_UARTS_GPIO_LO_MODE      0x88    /* reserved pins as input */
  96
  97/* IOT2040 MPIOs 8..15 */
  98#define IOT2040_UARTS_ENABLE            0x03
  99#define IOT2040_UARTS_GPIO_HI_MODE      0xF8    /* enable & LED as outputs */
 100
 101struct exar8250;
 102
 103struct exar8250_platform {
 104        int (*rs485_config)(struct uart_port *, struct serial_rs485 *);
 105        int (*register_gpio)(struct pci_dev *, struct uart_8250_port *);
 106};
 107
 108/**
 109 * struct exar8250_board - board information
 110 * @num_ports: number of serial ports
 111 * @reg_shift: describes UART register mapping in PCI memory
 112 * @setup: quirk run at ->probe() stage
 113 * @exit: quirk run at ->remove() stage
 114 */
 115struct exar8250_board {
 116        unsigned int num_ports;
 117        unsigned int reg_shift;
 118        int     (*setup)(struct exar8250 *, struct pci_dev *,
 119                         struct uart_8250_port *, int);
 120        void    (*exit)(struct pci_dev *pcidev);
 121};
 122
 123struct exar8250 {
 124        unsigned int            nr;
 125        struct exar8250_board   *board;
 126        void __iomem            *virt;
 127        int                     line[0];
 128};
 129
 130static int default_setup(struct exar8250 *priv, struct pci_dev *pcidev,
 131                         int idx, unsigned int offset,
 132                         struct uart_8250_port *port)
 133{
 134        const struct exar8250_board *board = priv->board;
 135        unsigned int bar = 0;
 136
 137        port->port.iotype = UPIO_MEM;
 138        port->port.mapbase = pci_resource_start(pcidev, bar) + offset;
 139        port->port.membase = priv->virt + offset;
 140        port->port.regshift = board->reg_shift;
 141
 142        return 0;
 143}
 144
 145static int
 146pci_fastcom335_setup(struct exar8250 *priv, struct pci_dev *pcidev,
 147                     struct uart_8250_port *port, int idx)
 148{
 149        unsigned int offset = idx * 0x200;
 150        unsigned int baud = 1843200;
 151        u8 __iomem *p;
 152        int err;
 153
 154        port->port.uartclk = baud * 16;
 155
 156        err = default_setup(priv, pcidev, idx, offset, port);
 157        if (err)
 158                return err;
 159
 160        p = port->port.membase;
 161
 162        writeb(0x00, p + UART_EXAR_8XMODE);
 163        writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR);
 164        writeb(32, p + UART_EXAR_TXTRG);
 165        writeb(32, p + UART_EXAR_RXTRG);
 166
 167        /*
 168         * Setup Multipurpose Input/Output pins.
 169         */
 170        if (idx == 0) {
 171                switch (pcidev->device) {
 172                case PCI_DEVICE_ID_COMMTECH_4222PCI335:
 173                case PCI_DEVICE_ID_COMMTECH_4224PCI335:
 174                        writeb(0x78, p + UART_EXAR_MPIOLVL_7_0);
 175                        writeb(0x00, p + UART_EXAR_MPIOINV_7_0);
 176                        writeb(0x00, p + UART_EXAR_MPIOSEL_7_0);
 177                        break;
 178                case PCI_DEVICE_ID_COMMTECH_2324PCI335:
 179                case PCI_DEVICE_ID_COMMTECH_2328PCI335:
 180                        writeb(0x00, p + UART_EXAR_MPIOLVL_7_0);
 181                        writeb(0xc0, p + UART_EXAR_MPIOINV_7_0);
 182                        writeb(0xc0, p + UART_EXAR_MPIOSEL_7_0);
 183                        break;
 184                }
 185                writeb(0x00, p + UART_EXAR_MPIOINT_7_0);
 186                writeb(0x00, p + UART_EXAR_MPIO3T_7_0);
 187                writeb(0x00, p + UART_EXAR_MPIOOD_7_0);
 188        }
 189
 190        return 0;
 191}
 192
 193static int
 194pci_connect_tech_setup(struct exar8250 *priv, struct pci_dev *pcidev,
 195                       struct uart_8250_port *port, int idx)
 196{
 197        unsigned int offset = idx * 0x200;
 198        unsigned int baud = 1843200;
 199
 200        port->port.uartclk = baud * 16;
 201        return default_setup(priv, pcidev, idx, offset, port);
 202}
 203
 204static int
 205pci_xr17c154_setup(struct exar8250 *priv, struct pci_dev *pcidev,
 206                   struct uart_8250_port *port, int idx)
 207{
 208        unsigned int offset = idx * 0x200;
 209        unsigned int baud = 921600;
 210
 211        port->port.uartclk = baud * 16;
 212        return default_setup(priv, pcidev, idx, offset, port);
 213}
 214
 215static void setup_gpio(struct pci_dev *pcidev, u8 __iomem *p)
 216{
 217        /*
 218         * The Commtech adapters required the MPIOs to be driven low. The Exar
 219         * devices will export them as GPIOs, so we pre-configure them safely
 220         * as inputs.
 221         */
 222        u8 dir = pcidev->vendor == PCI_VENDOR_ID_EXAR ? 0xff : 0x00;
 223
 224        writeb(0x00, p + UART_EXAR_MPIOINT_7_0);
 225        writeb(0x00, p + UART_EXAR_MPIOLVL_7_0);
 226        writeb(0x00, p + UART_EXAR_MPIO3T_7_0);
 227        writeb(0x00, p + UART_EXAR_MPIOINV_7_0);
 228        writeb(dir,  p + UART_EXAR_MPIOSEL_7_0);
 229        writeb(0x00, p + UART_EXAR_MPIOOD_7_0);
 230        writeb(0x00, p + UART_EXAR_MPIOINT_15_8);
 231        writeb(0x00, p + UART_EXAR_MPIOLVL_15_8);
 232        writeb(0x00, p + UART_EXAR_MPIO3T_15_8);
 233        writeb(0x00, p + UART_EXAR_MPIOINV_15_8);
 234        writeb(dir,  p + UART_EXAR_MPIOSEL_15_8);
 235        writeb(0x00, p + UART_EXAR_MPIOOD_15_8);
 236}
 237
 238static void *
 239__xr17v35x_register_gpio(struct pci_dev *pcidev,
 240                         const struct property_entry *properties)
 241{
 242        struct platform_device *pdev;
 243
 244        pdev = platform_device_alloc("gpio_exar", PLATFORM_DEVID_AUTO);
 245        if (!pdev)
 246                return NULL;
 247
 248        pdev->dev.parent = &pcidev->dev;
 249        ACPI_COMPANION_SET(&pdev->dev, ACPI_COMPANION(&pcidev->dev));
 250
 251        if (platform_device_add_properties(pdev, properties) < 0 ||
 252            platform_device_add(pdev) < 0) {
 253                platform_device_put(pdev);
 254                return NULL;
 255        }
 256
 257        return pdev;
 258}
 259
 260static const struct property_entry exar_gpio_properties[] = {
 261        PROPERTY_ENTRY_U32("exar,first-pin", 0),
 262        PROPERTY_ENTRY_U32("ngpios", 16),
 263        { }
 264};
 265
 266static int xr17v35x_register_gpio(struct pci_dev *pcidev,
 267                                  struct uart_8250_port *port)
 268{
 269        if (pcidev->vendor == PCI_VENDOR_ID_EXAR)
 270                port->port.private_data =
 271                        __xr17v35x_register_gpio(pcidev, exar_gpio_properties);
 272
 273        return 0;
 274}
 275
 276static int generic_rs485_config(struct uart_port *port,
 277                                struct serial_rs485 *rs485)
 278{
 279        bool is_rs485 = !!(rs485->flags & SER_RS485_ENABLED);
 280        u8 __iomem *p = port->membase;
 281        u8 value;
 282
 283        value = readb(p + UART_EXAR_FCTR);
 284        if (is_rs485)
 285                value |= UART_FCTR_EXAR_485;
 286        else
 287                value &= ~UART_FCTR_EXAR_485;
 288
 289        writeb(value, p + UART_EXAR_FCTR);
 290
 291        if (is_rs485)
 292                writeb(UART_EXAR_RS485_DLY(4), p + UART_MSR);
 293
 294        port->rs485 = *rs485;
 295
 296        return 0;
 297}
 298
 299static const struct exar8250_platform exar8250_default_platform = {
 300        .register_gpio = xr17v35x_register_gpio,
 301        .rs485_config = generic_rs485_config,
 302};
 303
 304static int iot2040_rs485_config(struct uart_port *port,
 305                                struct serial_rs485 *rs485)
 306{
 307        bool is_rs485 = !!(rs485->flags & SER_RS485_ENABLED);
 308        u8 __iomem *p = port->membase;
 309        u8 mask = IOT2040_UART1_MASK;
 310        u8 mode, value;
 311
 312        if (is_rs485) {
 313                if (rs485->flags & SER_RS485_RX_DURING_TX)
 314                        mode = IOT2040_UART_MODE_RS422;
 315                else
 316                        mode = IOT2040_UART_MODE_RS485;
 317
 318                if (rs485->flags & SER_RS485_TERMINATE_BUS)
 319                        mode |= IOT2040_UART_TERMINATE_BUS;
 320        } else {
 321                mode = IOT2040_UART_MODE_RS232;
 322        }
 323
 324        if (port->line == 3) {
 325                mask <<= IOT2040_UART2_SHIFT;
 326                mode <<= IOT2040_UART2_SHIFT;
 327        }
 328
 329        value = readb(p + UART_EXAR_MPIOLVL_7_0);
 330        value &= ~mask;
 331        value |= mode;
 332        writeb(value, p + UART_EXAR_MPIOLVL_7_0);
 333
 334        return generic_rs485_config(port, rs485);
 335}
 336
 337static const struct property_entry iot2040_gpio_properties[] = {
 338        PROPERTY_ENTRY_U32("exar,first-pin", 10),
 339        PROPERTY_ENTRY_U32("ngpios", 1),
 340        { }
 341};
 342
 343static int iot2040_register_gpio(struct pci_dev *pcidev,
 344                              struct uart_8250_port *port)
 345{
 346        u8 __iomem *p = port->port.membase;
 347
 348        writeb(IOT2040_UARTS_DEFAULT_MODE, p + UART_EXAR_MPIOLVL_7_0);
 349        writeb(IOT2040_UARTS_GPIO_LO_MODE, p + UART_EXAR_MPIOSEL_7_0);
 350        writeb(IOT2040_UARTS_ENABLE, p + UART_EXAR_MPIOLVL_15_8);
 351        writeb(IOT2040_UARTS_GPIO_HI_MODE, p + UART_EXAR_MPIOSEL_15_8);
 352
 353        port->port.private_data =
 354                __xr17v35x_register_gpio(pcidev, iot2040_gpio_properties);
 355
 356        return 0;
 357}
 358
 359static const struct exar8250_platform iot2040_platform = {
 360        .rs485_config = iot2040_rs485_config,
 361        .register_gpio = iot2040_register_gpio,
 362};
 363
 364/*
 365 * For SIMATIC IOT2000, only IOT2040 and its variants have the Exar device,
 366 * IOT2020 doesn't have. Therefore it is sufficient to match on the common
 367 * board name after the device was found.
 368 */
 369static const struct dmi_system_id exar_platforms[] = {
 370        {
 371                .matches = {
 372                        DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
 373                },
 374                .driver_data = (void *)&iot2040_platform,
 375        },
 376        {}
 377};
 378
 379static int
 380pci_xr17v35x_setup(struct exar8250 *priv, struct pci_dev *pcidev,
 381                   struct uart_8250_port *port, int idx)
 382{
 383        const struct exar8250_platform *platform;
 384        const struct dmi_system_id *dmi_match;
 385        unsigned int offset = idx * 0x400;
 386        unsigned int baud = 7812500;
 387        u8 __iomem *p;
 388        int ret;
 389
 390        dmi_match = dmi_first_match(exar_platforms);
 391        if (dmi_match)
 392                platform = dmi_match->driver_data;
 393        else
 394                platform = &exar8250_default_platform;
 395
 396        port->port.uartclk = baud * 16;
 397        port->port.rs485_config = platform->rs485_config;
 398
 399        /*
 400         * Setup the UART clock for the devices on expansion slot to
 401         * half the clock speed of the main chip (which is 125MHz)
 402         */
 403        if (idx >= 8)
 404                port->port.uartclk /= 2;
 405
 406        ret = default_setup(priv, pcidev, idx, offset, port);
 407        if (ret)
 408                return ret;
 409
 410        p = port->port.membase;
 411
 412        writeb(0x00, p + UART_EXAR_8XMODE);
 413        writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR);
 414        writeb(128, p + UART_EXAR_TXTRG);
 415        writeb(128, p + UART_EXAR_RXTRG);
 416
 417        if (idx == 0) {
 418                /* Setup Multipurpose Input/Output pins. */
 419                setup_gpio(pcidev, p);
 420
 421                ret = platform->register_gpio(pcidev, port);
 422        }
 423
 424        return ret;
 425}
 426
 427static void pci_xr17v35x_exit(struct pci_dev *pcidev)
 428{
 429        struct exar8250 *priv = pci_get_drvdata(pcidev);
 430        struct uart_8250_port *port = serial8250_get_port(priv->line[0]);
 431        struct platform_device *pdev = port->port.private_data;
 432
 433        platform_device_unregister(pdev);
 434        port->port.private_data = NULL;
 435}
 436
 437/*
 438 * These Exar UARTs have an extra interrupt indicator that could fire for a
 439 * few interrupts that are not presented/cleared through IIR.  One of which is
 440 * a wakeup interrupt when coming out of sleep.  These interrupts are only
 441 * cleared by reading global INT0 or INT1 registers as interrupts are
 442 * associated with channel 0. The INT[3:0] registers _are_ accessible from each
 443 * channel's address space, but for the sake of bus efficiency we register a
 444 * dedicated handler at the PCI device level to handle them.
 445 */
 446static irqreturn_t exar_misc_handler(int irq, void *data)
 447{
 448        struct exar8250 *priv = data;
 449
 450        /* Clear all PCI interrupts by reading INT0. No effect on IIR */
 451        readb(priv->virt + UART_EXAR_INT0);
 452
 453        /* Clear INT0 for Expansion Interface slave ports, too */
 454        if (priv->board->num_ports > 8)
 455                readb(priv->virt + 0x2000 + UART_EXAR_INT0);
 456
 457        return IRQ_HANDLED;
 458}
 459
 460static int
 461exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
 462{
 463        unsigned int nr_ports, i, bar = 0, maxnr;
 464        struct exar8250_board *board;
 465        struct uart_8250_port uart;
 466        struct exar8250 *priv;
 467        int rc;
 468
 469        board = (struct exar8250_board *)ent->driver_data;
 470        if (!board)
 471                return -EINVAL;
 472
 473        rc = pcim_enable_device(pcidev);
 474        if (rc)
 475                return rc;
 476
 477        maxnr = pci_resource_len(pcidev, bar) >> (board->reg_shift + 3);
 478
 479        nr_ports = board->num_ports ? board->num_ports : pcidev->device & 0x0f;
 480
 481        priv = devm_kzalloc(&pcidev->dev, sizeof(*priv) +
 482                            sizeof(unsigned int) * nr_ports,
 483                            GFP_KERNEL);
 484        if (!priv)
 485                return -ENOMEM;
 486
 487        priv->board = board;
 488        priv->virt = pcim_iomap(pcidev, bar, 0);
 489        if (!priv->virt)
 490                return -ENOMEM;
 491
 492        pci_set_master(pcidev);
 493
 494        rc = pci_alloc_irq_vectors(pcidev, 1, 1, PCI_IRQ_ALL_TYPES);
 495        if (rc < 0)
 496                return rc;
 497
 498        memset(&uart, 0, sizeof(uart));
 499        uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ
 500                          | UPF_EXAR_EFR;
 501        uart.port.irq = pci_irq_vector(pcidev, 0);
 502        uart.port.dev = &pcidev->dev;
 503
 504        rc = devm_request_irq(&pcidev->dev, uart.port.irq, exar_misc_handler,
 505                         IRQF_SHARED, "exar_uart", priv);
 506        if (rc)
 507                return rc;
 508
 509        for (i = 0; i < nr_ports && i < maxnr; i++) {
 510                rc = board->setup(priv, pcidev, &uart, i);
 511                if (rc) {
 512                        dev_err(&pcidev->dev, "Failed to setup port %u\n", i);
 513                        break;
 514                }
 515
 516                dev_dbg(&pcidev->dev, "Setup PCI port: port %lx, irq %d, type %d\n",
 517                        uart.port.iobase, uart.port.irq, uart.port.iotype);
 518
 519                priv->line[i] = serial8250_register_8250_port(&uart);
 520                if (priv->line[i] < 0) {
 521                        dev_err(&pcidev->dev,
 522                                "Couldn't register serial port %lx, irq %d, type %d, error %d\n",
 523                                uart.port.iobase, uart.port.irq,
 524                                uart.port.iotype, priv->line[i]);
 525                        break;
 526                }
 527        }
 528        priv->nr = i;
 529        pci_set_drvdata(pcidev, priv);
 530        return 0;
 531}
 532
 533static void exar_pci_remove(struct pci_dev *pcidev)
 534{
 535        struct exar8250 *priv = pci_get_drvdata(pcidev);
 536        unsigned int i;
 537
 538        for (i = 0; i < priv->nr; i++)
 539                serial8250_unregister_port(priv->line[i]);
 540
 541        if (priv->board->exit)
 542                priv->board->exit(pcidev);
 543}
 544
 545static int __maybe_unused exar_suspend(struct device *dev)
 546{
 547        struct pci_dev *pcidev = to_pci_dev(dev);
 548        struct exar8250 *priv = pci_get_drvdata(pcidev);
 549        unsigned int i;
 550
 551        for (i = 0; i < priv->nr; i++)
 552                if (priv->line[i] >= 0)
 553                        serial8250_suspend_port(priv->line[i]);
 554
 555        /* Ensure that every init quirk is properly torn down */
 556        if (priv->board->exit)
 557                priv->board->exit(pcidev);
 558
 559        return 0;
 560}
 561
 562static int __maybe_unused exar_resume(struct device *dev)
 563{
 564        struct pci_dev *pcidev = to_pci_dev(dev);
 565        struct exar8250 *priv = pci_get_drvdata(pcidev);
 566        unsigned int i;
 567
 568        for (i = 0; i < priv->nr; i++)
 569                if (priv->line[i] >= 0)
 570                        serial8250_resume_port(priv->line[i]);
 571
 572        return 0;
 573}
 574
 575static SIMPLE_DEV_PM_OPS(exar_pci_pm, exar_suspend, exar_resume);
 576
 577static const struct exar8250_board pbn_fastcom335_2 = {
 578        .num_ports      = 2,
 579        .setup          = pci_fastcom335_setup,
 580};
 581
 582static const struct exar8250_board pbn_fastcom335_4 = {
 583        .num_ports      = 4,
 584        .setup          = pci_fastcom335_setup,
 585};
 586
 587static const struct exar8250_board pbn_fastcom335_8 = {
 588        .num_ports      = 8,
 589        .setup          = pci_fastcom335_setup,
 590};
 591
 592static const struct exar8250_board pbn_connect = {
 593        .setup          = pci_connect_tech_setup,
 594};
 595
 596static const struct exar8250_board pbn_exar_ibm_saturn = {
 597        .num_ports      = 1,
 598        .setup          = pci_xr17c154_setup,
 599};
 600
 601static const struct exar8250_board pbn_exar_XR17C15x = {
 602        .setup          = pci_xr17c154_setup,
 603};
 604
 605static const struct exar8250_board pbn_exar_XR17V35x = {
 606        .setup          = pci_xr17v35x_setup,
 607        .exit           = pci_xr17v35x_exit,
 608};
 609
 610static const struct exar8250_board pbn_exar_XR17V4358 = {
 611        .num_ports      = 12,
 612        .setup          = pci_xr17v35x_setup,
 613        .exit           = pci_xr17v35x_exit,
 614};
 615
 616static const struct exar8250_board pbn_exar_XR17V8358 = {
 617        .num_ports      = 16,
 618        .setup          = pci_xr17v35x_setup,
 619        .exit           = pci_xr17v35x_exit,
 620};
 621
 622#define CONNECT_DEVICE(devid, sdevid, bd) {                             \
 623        PCI_DEVICE_SUB(                                                 \
 624                PCI_VENDOR_ID_EXAR,                                     \
 625                PCI_DEVICE_ID_EXAR_##devid,                             \
 626                PCI_SUBVENDOR_ID_CONNECT_TECH,                          \
 627                PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_##sdevid), 0, 0,      \
 628                (kernel_ulong_t)&bd                                     \
 629        }
 630
 631#define EXAR_DEVICE(vend, devid, bd) {                                  \
 632        PCI_VDEVICE(vend, PCI_DEVICE_ID_##devid), (kernel_ulong_t)&bd   \
 633        }
 634
 635#define IBM_DEVICE(devid, sdevid, bd) {                 \
 636        PCI_DEVICE_SUB(                                 \
 637                PCI_VENDOR_ID_EXAR,                     \
 638                PCI_DEVICE_ID_EXAR_##devid,             \
 639                PCI_VENDOR_ID_IBM,                      \
 640                PCI_SUBDEVICE_ID_IBM_##sdevid), 0, 0,   \
 641                (kernel_ulong_t)&bd                     \
 642        }
 643
 644static const struct pci_device_id exar_pci_tbl[] = {
 645        CONNECT_DEVICE(XR17C152, UART_2_232, pbn_connect),
 646        CONNECT_DEVICE(XR17C154, UART_4_232, pbn_connect),
 647        CONNECT_DEVICE(XR17C158, UART_8_232, pbn_connect),
 648        CONNECT_DEVICE(XR17C152, UART_1_1, pbn_connect),
 649        CONNECT_DEVICE(XR17C154, UART_2_2, pbn_connect),
 650        CONNECT_DEVICE(XR17C158, UART_4_4, pbn_connect),
 651        CONNECT_DEVICE(XR17C152, UART_2, pbn_connect),
 652        CONNECT_DEVICE(XR17C154, UART_4, pbn_connect),
 653        CONNECT_DEVICE(XR17C158, UART_8, pbn_connect),
 654        CONNECT_DEVICE(XR17C152, UART_2_485, pbn_connect),
 655        CONNECT_DEVICE(XR17C154, UART_4_485, pbn_connect),
 656        CONNECT_DEVICE(XR17C158, UART_8_485, pbn_connect),
 657
 658        IBM_DEVICE(XR17C152, SATURN_SERIAL_ONE_PORT, pbn_exar_ibm_saturn),
 659
 660        /* Exar Corp. XR17C15[248] Dual/Quad/Octal UART */
 661        EXAR_DEVICE(EXAR, EXAR_XR17C152, pbn_exar_XR17C15x),
 662        EXAR_DEVICE(EXAR, EXAR_XR17C154, pbn_exar_XR17C15x),
 663        EXAR_DEVICE(EXAR, EXAR_XR17C158, pbn_exar_XR17C15x),
 664
 665        /* Exar Corp. XR17V[48]35[248] Dual/Quad/Octal/Hexa PCIe UARTs */
 666        EXAR_DEVICE(EXAR, EXAR_XR17V352, pbn_exar_XR17V35x),
 667        EXAR_DEVICE(EXAR, EXAR_XR17V354, pbn_exar_XR17V35x),
 668        EXAR_DEVICE(EXAR, EXAR_XR17V358, pbn_exar_XR17V35x),
 669        EXAR_DEVICE(EXAR, EXAR_XR17V4358, pbn_exar_XR17V4358),
 670        EXAR_DEVICE(EXAR, EXAR_XR17V8358, pbn_exar_XR17V8358),
 671        EXAR_DEVICE(COMMTECH, COMMTECH_4222PCIE, pbn_exar_XR17V35x),
 672        EXAR_DEVICE(COMMTECH, COMMTECH_4224PCIE, pbn_exar_XR17V35x),
 673        EXAR_DEVICE(COMMTECH, COMMTECH_4228PCIE, pbn_exar_XR17V35x),
 674
 675        EXAR_DEVICE(COMMTECH, COMMTECH_4222PCI335, pbn_fastcom335_2),
 676        EXAR_DEVICE(COMMTECH, COMMTECH_4224PCI335, pbn_fastcom335_4),
 677        EXAR_DEVICE(COMMTECH, COMMTECH_2324PCI335, pbn_fastcom335_4),
 678        EXAR_DEVICE(COMMTECH, COMMTECH_2328PCI335, pbn_fastcom335_8),
 679        { 0, }
 680};
 681MODULE_DEVICE_TABLE(pci, exar_pci_tbl);
 682
 683static struct pci_driver exar_pci_driver = {
 684        .name           = "exar_serial",
 685        .probe          = exar_pci_probe,
 686        .remove         = exar_pci_remove,
 687        .driver         = {
 688                .pm     = &exar_pci_pm,
 689        },
 690        .id_table       = exar_pci_tbl,
 691};
 692module_pci_driver(exar_pci_driver);
 693
 694MODULE_LICENSE("GPL");
 695MODULE_DESCRIPTION("Exar Serial Driver");
 696MODULE_AUTHOR("Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>");
 697