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 */
 113struct exar8250_board {
 114        unsigned int num_ports;
 115        unsigned int reg_shift;
 116        bool has_slave;
 117        int     (*setup)(struct exar8250 *, struct pci_dev *,
 118                         struct uart_8250_port *, int);
 119        void    (*exit)(struct pci_dev *pcidev);
 120};
 121
 122struct exar8250 {
 123        unsigned int            nr;
 124        struct exar8250_board   *board;
 125        void __iomem            *virt;
 126        int                     line[0];
 127};
 128
 129static int default_setup(struct exar8250 *priv, struct pci_dev *pcidev,
 130                         int idx, unsigned int offset,
 131                         struct uart_8250_port *port)
 132{
 133        const struct exar8250_board *board = priv->board;
 134        unsigned int bar = 0;
 135
 136        port->port.iotype = UPIO_MEM;
 137        port->port.mapbase = pci_resource_start(pcidev, bar) + offset;
 138        port->port.membase = priv->virt + offset;
 139        port->port.regshift = board->reg_shift;
 140
 141        return 0;
 142}
 143
 144static int
 145pci_fastcom335_setup(struct exar8250 *priv, struct pci_dev *pcidev,
 146                     struct uart_8250_port *port, int idx)
 147{
 148        unsigned int offset = idx * 0x200;
 149        unsigned int baud = 1843200;
 150        u8 __iomem *p;
 151        int err;
 152
 153        port->port.uartclk = baud * 16;
 154
 155        err = default_setup(priv, pcidev, idx, offset, port);
 156        if (err)
 157                return err;
 158
 159        p = port->port.membase;
 160
 161        writeb(0x00, p + UART_EXAR_8XMODE);
 162        writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR);
 163        writeb(32, p + UART_EXAR_TXTRG);
 164        writeb(32, p + UART_EXAR_RXTRG);
 165
 166        /*
 167         * Setup Multipurpose Input/Output pins.
 168         */
 169        if (idx == 0) {
 170                switch (pcidev->device) {
 171                case PCI_DEVICE_ID_COMMTECH_4222PCI335:
 172                case PCI_DEVICE_ID_COMMTECH_4224PCI335:
 173                        writeb(0x78, p + UART_EXAR_MPIOLVL_7_0);
 174                        writeb(0x00, p + UART_EXAR_MPIOINV_7_0);
 175                        writeb(0x00, p + UART_EXAR_MPIOSEL_7_0);
 176                        break;
 177                case PCI_DEVICE_ID_COMMTECH_2324PCI335:
 178                case PCI_DEVICE_ID_COMMTECH_2328PCI335:
 179                        writeb(0x00, p + UART_EXAR_MPIOLVL_7_0);
 180                        writeb(0xc0, p + UART_EXAR_MPIOINV_7_0);
 181                        writeb(0xc0, p + UART_EXAR_MPIOSEL_7_0);
 182                        break;
 183                }
 184                writeb(0x00, p + UART_EXAR_MPIOINT_7_0);
 185                writeb(0x00, p + UART_EXAR_MPIO3T_7_0);
 186                writeb(0x00, p + UART_EXAR_MPIOOD_7_0);
 187        }
 188
 189        return 0;
 190}
 191
 192static int
 193pci_connect_tech_setup(struct exar8250 *priv, struct pci_dev *pcidev,
 194                       struct uart_8250_port *port, int idx)
 195{
 196        unsigned int offset = idx * 0x200;
 197        unsigned int baud = 1843200;
 198
 199        port->port.uartclk = baud * 16;
 200        return default_setup(priv, pcidev, idx, offset, port);
 201}
 202
 203static int
 204pci_xr17c154_setup(struct exar8250 *priv, struct pci_dev *pcidev,
 205                   struct uart_8250_port *port, int idx)
 206{
 207        unsigned int offset = idx * 0x200;
 208        unsigned int baud = 921600;
 209
 210        port->port.uartclk = baud * 16;
 211        return default_setup(priv, pcidev, idx, offset, port);
 212}
 213
 214static void setup_gpio(struct pci_dev *pcidev, u8 __iomem *p)
 215{
 216        /*
 217         * The Commtech adapters required the MPIOs to be driven low. The Exar
 218         * devices will export them as GPIOs, so we pre-configure them safely
 219         * as inputs.
 220         */
 221        u8 dir = pcidev->vendor == PCI_VENDOR_ID_EXAR ? 0xff : 0x00;
 222
 223        writeb(0x00, p + UART_EXAR_MPIOINT_7_0);
 224        writeb(0x00, p + UART_EXAR_MPIOLVL_7_0);
 225        writeb(0x00, p + UART_EXAR_MPIO3T_7_0);
 226        writeb(0x00, p + UART_EXAR_MPIOINV_7_0);
 227        writeb(dir,  p + UART_EXAR_MPIOSEL_7_0);
 228        writeb(0x00, p + UART_EXAR_MPIOOD_7_0);
 229        writeb(0x00, p + UART_EXAR_MPIOINT_15_8);
 230        writeb(0x00, p + UART_EXAR_MPIOLVL_15_8);
 231        writeb(0x00, p + UART_EXAR_MPIO3T_15_8);
 232        writeb(0x00, p + UART_EXAR_MPIOINV_15_8);
 233        writeb(dir,  p + UART_EXAR_MPIOSEL_15_8);
 234        writeb(0x00, p + UART_EXAR_MPIOOD_15_8);
 235}
 236
 237static void *
 238__xr17v35x_register_gpio(struct pci_dev *pcidev,
 239                         const struct property_entry *properties)
 240{
 241        struct platform_device *pdev;
 242
 243        pdev = platform_device_alloc("gpio_exar", PLATFORM_DEVID_AUTO);
 244        if (!pdev)
 245                return NULL;
 246
 247        pdev->dev.parent = &pcidev->dev;
 248        ACPI_COMPANION_SET(&pdev->dev, ACPI_COMPANION(&pcidev->dev));
 249
 250        if (platform_device_add_properties(pdev, properties) < 0 ||
 251            platform_device_add(pdev) < 0) {
 252                platform_device_put(pdev);
 253                return NULL;
 254        }
 255
 256        return pdev;
 257}
 258
 259static const struct property_entry exar_gpio_properties[] = {
 260        PROPERTY_ENTRY_U32("exar,first-pin", 0),
 261        PROPERTY_ENTRY_U32("ngpios", 16),
 262        { }
 263};
 264
 265static int xr17v35x_register_gpio(struct pci_dev *pcidev,
 266                                  struct uart_8250_port *port)
 267{
 268        if (pcidev->vendor == PCI_VENDOR_ID_EXAR)
 269                port->port.private_data =
 270                        __xr17v35x_register_gpio(pcidev, exar_gpio_properties);
 271
 272        return 0;
 273}
 274
 275static const struct exar8250_platform exar8250_default_platform = {
 276        .register_gpio = xr17v35x_register_gpio,
 277};
 278
 279static int iot2040_rs485_config(struct uart_port *port,
 280                                struct serial_rs485 *rs485)
 281{
 282        bool is_rs485 = !!(rs485->flags & SER_RS485_ENABLED);
 283        u8 __iomem *p = port->membase;
 284        u8 mask = IOT2040_UART1_MASK;
 285        u8 mode, value;
 286
 287        if (is_rs485) {
 288                if (rs485->flags & SER_RS485_RX_DURING_TX)
 289                        mode = IOT2040_UART_MODE_RS422;
 290                else
 291                        mode = IOT2040_UART_MODE_RS485;
 292
 293                if (rs485->flags & SER_RS485_TERMINATE_BUS)
 294                        mode |= IOT2040_UART_TERMINATE_BUS;
 295        } else {
 296                mode = IOT2040_UART_MODE_RS232;
 297        }
 298
 299        if (port->line == 3) {
 300                mask <<= IOT2040_UART2_SHIFT;
 301                mode <<= IOT2040_UART2_SHIFT;
 302        }
 303
 304        value = readb(p + UART_EXAR_MPIOLVL_7_0);
 305        value &= ~mask;
 306        value |= mode;
 307        writeb(value, p + UART_EXAR_MPIOLVL_7_0);
 308
 309        value = readb(p + UART_EXAR_FCTR);
 310        if (is_rs485)
 311                value |= UART_FCTR_EXAR_485;
 312        else
 313                value &= ~UART_FCTR_EXAR_485;
 314        writeb(value, p + UART_EXAR_FCTR);
 315
 316        if (is_rs485)
 317                writeb(UART_EXAR_RS485_DLY(4), p + UART_MSR);
 318
 319        port->rs485 = *rs485;
 320
 321        return 0;
 322}
 323
 324static const struct property_entry iot2040_gpio_properties[] = {
 325        PROPERTY_ENTRY_U32("exar,first-pin", 10),
 326        PROPERTY_ENTRY_U32("ngpios", 1),
 327        { }
 328};
 329
 330static int iot2040_register_gpio(struct pci_dev *pcidev,
 331                              struct uart_8250_port *port)
 332{
 333        u8 __iomem *p = port->port.membase;
 334
 335        writeb(IOT2040_UARTS_DEFAULT_MODE, p + UART_EXAR_MPIOLVL_7_0);
 336        writeb(IOT2040_UARTS_GPIO_LO_MODE, p + UART_EXAR_MPIOSEL_7_0);
 337        writeb(IOT2040_UARTS_ENABLE, p + UART_EXAR_MPIOLVL_15_8);
 338        writeb(IOT2040_UARTS_GPIO_HI_MODE, p + UART_EXAR_MPIOSEL_15_8);
 339
 340        port->port.private_data =
 341                __xr17v35x_register_gpio(pcidev, iot2040_gpio_properties);
 342
 343        return 0;
 344}
 345
 346static const struct exar8250_platform iot2040_platform = {
 347        .rs485_config = iot2040_rs485_config,
 348        .register_gpio = iot2040_register_gpio,
 349};
 350
 351static const struct dmi_system_id exar_platforms[] = {
 352        {
 353                .matches = {
 354                        DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
 355                        DMI_EXACT_MATCH(DMI_BOARD_ASSET_TAG,
 356                                        "6ES7647-0AA00-1YA2"),
 357                },
 358                .driver_data = (void *)&iot2040_platform,
 359        },
 360        {}
 361};
 362
 363static int
 364pci_xr17v35x_setup(struct exar8250 *priv, struct pci_dev *pcidev,
 365                   struct uart_8250_port *port, int idx)
 366{
 367        const struct exar8250_board *board = priv->board;
 368        const struct exar8250_platform *platform;
 369        const struct dmi_system_id *dmi_match;
 370        unsigned int offset = idx * 0x400;
 371        unsigned int baud = 7812500;
 372        u8 __iomem *p;
 373        int ret;
 374
 375        dmi_match = dmi_first_match(exar_platforms);
 376        if (dmi_match)
 377                platform = dmi_match->driver_data;
 378        else
 379                platform = &exar8250_default_platform;
 380
 381        port->port.uartclk = baud * 16;
 382        port->port.rs485_config = platform->rs485_config;
 383
 384        /*
 385         * Setup the uart clock for the devices on expansion slot to
 386         * half the clock speed of the main chip (which is 125MHz)
 387         */
 388        if (board->has_slave && idx >= 8)
 389                port->port.uartclk /= 2;
 390
 391        ret = default_setup(priv, pcidev, idx, offset, port);
 392        if (ret)
 393                return ret;
 394
 395        p = port->port.membase;
 396
 397        writeb(0x00, p + UART_EXAR_8XMODE);
 398        writeb(UART_FCTR_EXAR_TRGD, p + UART_EXAR_FCTR);
 399        writeb(128, p + UART_EXAR_TXTRG);
 400        writeb(128, p + UART_EXAR_RXTRG);
 401
 402        if (idx == 0) {
 403                /* Setup Multipurpose Input/Output pins. */
 404                setup_gpio(pcidev, p);
 405
 406                ret = platform->register_gpio(pcidev, port);
 407        }
 408
 409        return ret;
 410}
 411
 412static void pci_xr17v35x_exit(struct pci_dev *pcidev)
 413{
 414        struct exar8250 *priv = pci_get_drvdata(pcidev);
 415        struct uart_8250_port *port = serial8250_get_port(priv->line[0]);
 416        struct platform_device *pdev = port->port.private_data;
 417
 418        platform_device_unregister(pdev);
 419        port->port.private_data = NULL;
 420}
 421
 422/*
 423 * These Exar UARTs have an extra interrupt indicator that could fire for a
 424 * few interrupts that are not presented/cleared through IIR.  One of which is
 425 * a wakeup interrupt when coming out of sleep.  These interrupts are only
 426 * cleared by reading global INT0 or INT1 registers as interrupts are
 427 * associated with channel 0. The INT[3:0] registers _are_ accessible from each
 428 * channel's address space, but for the sake of bus efficiency we register a
 429 * dedicated handler at the PCI device level to handle them.
 430 */
 431static irqreturn_t exar_misc_handler(int irq, void *data)
 432{
 433        struct exar8250 *priv = data;
 434
 435        /* Clear all PCI interrupts by reading INT0. No effect on IIR */
 436        ioread8(priv->virt + UART_EXAR_INT0);
 437
 438        return IRQ_HANDLED;
 439}
 440
 441static int
 442exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
 443{
 444        unsigned int nr_ports, i, bar = 0, maxnr;
 445        struct exar8250_board *board;
 446        struct uart_8250_port uart;
 447        struct exar8250 *priv;
 448        int rc;
 449
 450        board = (struct exar8250_board *)ent->driver_data;
 451        if (!board)
 452                return -EINVAL;
 453
 454        rc = pcim_enable_device(pcidev);
 455        if (rc)
 456                return rc;
 457
 458        maxnr = pci_resource_len(pcidev, bar) >> (board->reg_shift + 3);
 459
 460        nr_ports = board->num_ports ? board->num_ports : pcidev->device & 0x0f;
 461
 462        priv = devm_kzalloc(&pcidev->dev, sizeof(*priv) +
 463                            sizeof(unsigned int) * nr_ports,
 464                            GFP_KERNEL);
 465        if (!priv)
 466                return -ENOMEM;
 467
 468        priv->board = board;
 469        priv->virt = pcim_iomap(pcidev, bar, 0);
 470        if (!priv->virt)
 471                return -ENOMEM;
 472
 473        pci_set_master(pcidev);
 474
 475        rc = pci_alloc_irq_vectors(pcidev, 1, 1, PCI_IRQ_ALL_TYPES);
 476        if (rc < 0)
 477                return rc;
 478
 479        memset(&uart, 0, sizeof(uart));
 480        uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ
 481                          | UPF_EXAR_EFR;
 482        uart.port.irq = pci_irq_vector(pcidev, 0);
 483        uart.port.dev = &pcidev->dev;
 484
 485        rc = devm_request_irq(&pcidev->dev, uart.port.irq, exar_misc_handler,
 486                         IRQF_SHARED, "exar_uart", priv);
 487        if (rc)
 488                return rc;
 489
 490        for (i = 0; i < nr_ports && i < maxnr; i++) {
 491                rc = board->setup(priv, pcidev, &uart, i);
 492                if (rc) {
 493                        dev_err(&pcidev->dev, "Failed to setup port %u\n", i);
 494                        break;
 495                }
 496
 497                dev_dbg(&pcidev->dev, "Setup PCI port: port %lx, irq %d, type %d\n",
 498                        uart.port.iobase, uart.port.irq, uart.port.iotype);
 499
 500                priv->line[i] = serial8250_register_8250_port(&uart);
 501                if (priv->line[i] < 0) {
 502                        dev_err(&pcidev->dev,
 503                                "Couldn't register serial port %lx, irq %d, type %d, error %d\n",
 504                                uart.port.iobase, uart.port.irq,
 505                                uart.port.iotype, priv->line[i]);
 506                        break;
 507                }
 508        }
 509        priv->nr = i;
 510        pci_set_drvdata(pcidev, priv);
 511        return 0;
 512}
 513
 514static void exar_pci_remove(struct pci_dev *pcidev)
 515{
 516        struct exar8250 *priv = pci_get_drvdata(pcidev);
 517        unsigned int i;
 518
 519        for (i = 0; i < priv->nr; i++)
 520                serial8250_unregister_port(priv->line[i]);
 521
 522        if (priv->board->exit)
 523                priv->board->exit(pcidev);
 524}
 525
 526static int __maybe_unused exar_suspend(struct device *dev)
 527{
 528        struct pci_dev *pcidev = to_pci_dev(dev);
 529        struct exar8250 *priv = pci_get_drvdata(pcidev);
 530        unsigned int i;
 531
 532        for (i = 0; i < priv->nr; i++)
 533                if (priv->line[i] >= 0)
 534                        serial8250_suspend_port(priv->line[i]);
 535
 536        /* Ensure that every init quirk is properly torn down */
 537        if (priv->board->exit)
 538                priv->board->exit(pcidev);
 539
 540        return 0;
 541}
 542
 543static int __maybe_unused exar_resume(struct device *dev)
 544{
 545        struct pci_dev *pcidev = to_pci_dev(dev);
 546        struct exar8250 *priv = pci_get_drvdata(pcidev);
 547        unsigned int i;
 548
 549        for (i = 0; i < priv->nr; i++)
 550                if (priv->line[i] >= 0)
 551                        serial8250_resume_port(priv->line[i]);
 552
 553        return 0;
 554}
 555
 556static SIMPLE_DEV_PM_OPS(exar_pci_pm, exar_suspend, exar_resume);
 557
 558static const struct exar8250_board pbn_fastcom335_2 = {
 559        .num_ports      = 2,
 560        .setup          = pci_fastcom335_setup,
 561};
 562
 563static const struct exar8250_board pbn_fastcom335_4 = {
 564        .num_ports      = 4,
 565        .setup          = pci_fastcom335_setup,
 566};
 567
 568static const struct exar8250_board pbn_fastcom335_8 = {
 569        .num_ports      = 8,
 570        .setup          = pci_fastcom335_setup,
 571};
 572
 573static const struct exar8250_board pbn_connect = {
 574        .setup          = pci_connect_tech_setup,
 575};
 576
 577static const struct exar8250_board pbn_exar_ibm_saturn = {
 578        .num_ports      = 1,
 579        .setup          = pci_xr17c154_setup,
 580};
 581
 582static const struct exar8250_board pbn_exar_XR17C15x = {
 583        .setup          = pci_xr17c154_setup,
 584};
 585
 586static const struct exar8250_board pbn_exar_XR17V35x = {
 587        .setup          = pci_xr17v35x_setup,
 588        .exit           = pci_xr17v35x_exit,
 589};
 590
 591static const struct exar8250_board pbn_exar_XR17V4358 = {
 592        .num_ports      = 12,
 593        .has_slave      = true,
 594        .setup          = pci_xr17v35x_setup,
 595        .exit           = pci_xr17v35x_exit,
 596};
 597
 598static const struct exar8250_board pbn_exar_XR17V8358 = {
 599        .num_ports      = 16,
 600        .has_slave      = true,
 601        .setup          = pci_xr17v35x_setup,
 602        .exit           = pci_xr17v35x_exit,
 603};
 604
 605#define CONNECT_DEVICE(devid, sdevid, bd) {                             \
 606        PCI_DEVICE_SUB(                                                 \
 607                PCI_VENDOR_ID_EXAR,                                     \
 608                PCI_DEVICE_ID_EXAR_##devid,                             \
 609                PCI_SUBVENDOR_ID_CONNECT_TECH,                          \
 610                PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_##sdevid), 0, 0,      \
 611                (kernel_ulong_t)&bd                                     \
 612        }
 613
 614#define EXAR_DEVICE(vend, devid, bd) {                                  \
 615        PCI_VDEVICE(vend, PCI_DEVICE_ID_##devid), (kernel_ulong_t)&bd   \
 616        }
 617
 618#define IBM_DEVICE(devid, sdevid, bd) {                 \
 619        PCI_DEVICE_SUB(                                 \
 620                PCI_VENDOR_ID_EXAR,                     \
 621                PCI_DEVICE_ID_EXAR_##devid,             \
 622                PCI_VENDOR_ID_IBM,                      \
 623                PCI_SUBDEVICE_ID_IBM_##sdevid), 0, 0,   \
 624                (kernel_ulong_t)&bd                     \
 625        }
 626
 627static const struct pci_device_id exar_pci_tbl[] = {
 628        CONNECT_DEVICE(XR17C152, UART_2_232, pbn_connect),
 629        CONNECT_DEVICE(XR17C154, UART_4_232, pbn_connect),
 630        CONNECT_DEVICE(XR17C158, UART_8_232, pbn_connect),
 631        CONNECT_DEVICE(XR17C152, UART_1_1, pbn_connect),
 632        CONNECT_DEVICE(XR17C154, UART_2_2, pbn_connect),
 633        CONNECT_DEVICE(XR17C158, UART_4_4, pbn_connect),
 634        CONNECT_DEVICE(XR17C152, UART_2, pbn_connect),
 635        CONNECT_DEVICE(XR17C154, UART_4, pbn_connect),
 636        CONNECT_DEVICE(XR17C158, UART_8, pbn_connect),
 637        CONNECT_DEVICE(XR17C152, UART_2_485, pbn_connect),
 638        CONNECT_DEVICE(XR17C154, UART_4_485, pbn_connect),
 639        CONNECT_DEVICE(XR17C158, UART_8_485, pbn_connect),
 640
 641        IBM_DEVICE(XR17C152, SATURN_SERIAL_ONE_PORT, pbn_exar_ibm_saturn),
 642
 643        /* Exar Corp. XR17C15[248] Dual/Quad/Octal UART */
 644        EXAR_DEVICE(EXAR, EXAR_XR17C152, pbn_exar_XR17C15x),
 645        EXAR_DEVICE(EXAR, EXAR_XR17C154, pbn_exar_XR17C15x),
 646        EXAR_DEVICE(EXAR, EXAR_XR17C158, pbn_exar_XR17C15x),
 647
 648        /* Exar Corp. XR17V[48]35[248] Dual/Quad/Octal/Hexa PCIe UARTs */
 649        EXAR_DEVICE(EXAR, EXAR_XR17V352, pbn_exar_XR17V35x),
 650        EXAR_DEVICE(EXAR, EXAR_XR17V354, pbn_exar_XR17V35x),
 651        EXAR_DEVICE(EXAR, EXAR_XR17V358, pbn_exar_XR17V35x),
 652        EXAR_DEVICE(EXAR, EXAR_XR17V4358, pbn_exar_XR17V4358),
 653        EXAR_DEVICE(EXAR, EXAR_XR17V8358, pbn_exar_XR17V8358),
 654        EXAR_DEVICE(COMMTECH, COMMTECH_4222PCIE, pbn_exar_XR17V35x),
 655        EXAR_DEVICE(COMMTECH, COMMTECH_4224PCIE, pbn_exar_XR17V35x),
 656        EXAR_DEVICE(COMMTECH, COMMTECH_4228PCIE, pbn_exar_XR17V35x),
 657
 658        EXAR_DEVICE(COMMTECH, COMMTECH_4222PCI335, pbn_fastcom335_2),
 659        EXAR_DEVICE(COMMTECH, COMMTECH_4224PCI335, pbn_fastcom335_4),
 660        EXAR_DEVICE(COMMTECH, COMMTECH_2324PCI335, pbn_fastcom335_4),
 661        EXAR_DEVICE(COMMTECH, COMMTECH_2328PCI335, pbn_fastcom335_8),
 662        { 0, }
 663};
 664MODULE_DEVICE_TABLE(pci, exar_pci_tbl);
 665
 666static struct pci_driver exar_pci_driver = {
 667        .name           = "exar_serial",
 668        .probe          = exar_pci_probe,
 669        .remove         = exar_pci_remove,
 670        .driver         = {
 671                .pm     = &exar_pci_pm,
 672        },
 673        .id_table       = exar_pci_tbl,
 674};
 675module_pci_driver(exar_pci_driver);
 676
 677MODULE_LICENSE("GPL");
 678MODULE_DESCRIPTION("Exar Serial Driver");
 679MODULE_AUTHOR("Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>");
 680