linux/drivers/gpio/gpio-pcie-idio-24.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * GPIO driver for the ACCES PCIe-IDIO-24 family
   4 * Copyright (C) 2018 William Breathitt Gray
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License, version 2, as
   8 * published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful, but
  11 * WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * General Public License for more details.
  14 *
  15 * This driver supports the following ACCES devices: PCIe-IDIO-24,
  16 * PCIe-IDI-24, PCIe-IDO-24, and PCIe-IDIO-12.
  17 */
  18#include <linux/bitmap.h>
  19#include <linux/bitops.h>
  20#include <linux/device.h>
  21#include <linux/errno.h>
  22#include <linux/gpio/driver.h>
  23#include <linux/interrupt.h>
  24#include <linux/irqdesc.h>
  25#include <linux/kernel.h>
  26#include <linux/module.h>
  27#include <linux/pci.h>
  28#include <linux/spinlock.h>
  29#include <linux/types.h>
  30
  31/*
  32 * PLX PEX8311 PCI LCS_INTCSR Interrupt Control/Status
  33 *
  34 * Bit: Description
  35 *   0: Enable Interrupt Sources (Bit 0)
  36 *   1: Enable Interrupt Sources (Bit 1)
  37 *   2: Generate Internal PCI Bus Internal SERR# Interrupt
  38 *   3: Mailbox Interrupt Enable
  39 *   4: Power Management Interrupt Enable
  40 *   5: Power Management Interrupt
  41 *   6: Slave Read Local Data Parity Check Error Enable
  42 *   7: Slave Read Local Data Parity Check Error Status
  43 *   8: Internal PCI Wire Interrupt Enable
  44 *   9: PCI Express Doorbell Interrupt Enable
  45 *  10: PCI Abort Interrupt Enable
  46 *  11: Local Interrupt Input Enable
  47 *  12: Retry Abort Enable
  48 *  13: PCI Express Doorbell Interrupt Active
  49 *  14: PCI Abort Interrupt Active
  50 *  15: Local Interrupt Input Active
  51 *  16: Local Interrupt Output Enable
  52 *  17: Local Doorbell Interrupt Enable
  53 *  18: DMA Channel 0 Interrupt Enable
  54 *  19: DMA Channel 1 Interrupt Enable
  55 *  20: Local Doorbell Interrupt Active
  56 *  21: DMA Channel 0 Interrupt Active
  57 *  22: DMA Channel 1 Interrupt Active
  58 *  23: Built-In Self-Test (BIST) Interrupt Active
  59 *  24: Direct Master was the Bus Master during a Master or Target Abort
  60 *  25: DMA Channel 0 was the Bus Master during a Master or Target Abort
  61 *  26: DMA Channel 1 was the Bus Master during a Master or Target Abort
  62 *  27: Target Abort after internal 256 consecutive Master Retrys
  63 *  28: PCI Bus wrote data to LCS_MBOX0
  64 *  29: PCI Bus wrote data to LCS_MBOX1
  65 *  30: PCI Bus wrote data to LCS_MBOX2
  66 *  31: PCI Bus wrote data to LCS_MBOX3
  67 */
  68#define PLX_PEX8311_PCI_LCS_INTCSR  0x68
  69#define INTCSR_INTERNAL_PCI_WIRE    BIT(8)
  70#define INTCSR_LOCAL_INPUT          BIT(11)
  71
  72/**
  73 * struct idio_24_gpio_reg - GPIO device registers structure
  74 * @out0_7:     Read: FET Outputs 0-7
  75 *              Write: FET Outputs 0-7
  76 * @out8_15:    Read: FET Outputs 8-15
  77 *              Write: FET Outputs 8-15
  78 * @out16_23:   Read: FET Outputs 16-23
  79 *              Write: FET Outputs 16-23
  80 * @ttl_out0_7: Read: TTL/CMOS Outputs 0-7
  81 *              Write: TTL/CMOS Outputs 0-7
  82 * @in0_7:      Read: Isolated Inputs 0-7
  83 *              Write: Reserved
  84 * @in8_15:     Read: Isolated Inputs 8-15
  85 *              Write: Reserved
  86 * @in16_23:    Read: Isolated Inputs 16-23
  87 *              Write: Reserved
  88 * @ttl_in0_7:  Read: TTL/CMOS Inputs 0-7
  89 *              Write: Reserved
  90 * @cos0_7:     Read: COS Status Inputs 0-7
  91 *              Write: COS Clear Inputs 0-7
  92 * @cos8_15:    Read: COS Status Inputs 8-15
  93 *              Write: COS Clear Inputs 8-15
  94 * @cos16_23:   Read: COS Status Inputs 16-23
  95 *              Write: COS Clear Inputs 16-23
  96 * @cos_ttl0_7: Read: COS Status TTL/CMOS 0-7
  97 *              Write: COS Clear TTL/CMOS 0-7
  98 * @ctl:        Read: Control Register
  99 *              Write: Control Register
 100 * @reserved:   Read: Reserved
 101 *              Write: Reserved
 102 * @cos_enable: Read: COS Enable
 103 *              Write: COS Enable
 104 * @soft_reset: Read: IRQ Output Pin Status
 105 *              Write: Software Board Reset
 106 */
 107struct idio_24_gpio_reg {
 108        u8 out0_7;
 109        u8 out8_15;
 110        u8 out16_23;
 111        u8 ttl_out0_7;
 112        u8 in0_7;
 113        u8 in8_15;
 114        u8 in16_23;
 115        u8 ttl_in0_7;
 116        u8 cos0_7;
 117        u8 cos8_15;
 118        u8 cos16_23;
 119        u8 cos_ttl0_7;
 120        u8 ctl;
 121        u8 reserved;
 122        u8 cos_enable;
 123        u8 soft_reset;
 124};
 125
 126/**
 127 * struct idio_24_gpio - GPIO device private data structure
 128 * @chip:       instance of the gpio_chip
 129 * @lock:       synchronization lock to prevent I/O race conditions
 130 * @reg:        I/O address offset for the GPIO device registers
 131 * @irq_mask:   I/O bits affected by interrupts
 132 */
 133struct idio_24_gpio {
 134        struct gpio_chip chip;
 135        raw_spinlock_t lock;
 136        __u8 __iomem *plx;
 137        struct idio_24_gpio_reg __iomem *reg;
 138        unsigned long irq_mask;
 139};
 140
 141static int idio_24_gpio_get_direction(struct gpio_chip *chip,
 142        unsigned int offset)
 143{
 144        struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
 145        const unsigned long out_mode_mask = BIT(1);
 146
 147        /* FET Outputs */
 148        if (offset < 24)
 149                return GPIO_LINE_DIRECTION_OUT;
 150
 151        /* Isolated Inputs */
 152        if (offset < 48)
 153                return GPIO_LINE_DIRECTION_IN;
 154
 155        /* TTL/CMOS I/O */
 156        /* OUT MODE = 1 when TTL/CMOS Output Mode is set */
 157        if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
 158                return GPIO_LINE_DIRECTION_OUT;
 159
 160        return GPIO_LINE_DIRECTION_IN;
 161}
 162
 163static int idio_24_gpio_direction_input(struct gpio_chip *chip,
 164        unsigned int offset)
 165{
 166        struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
 167        unsigned long flags;
 168        unsigned int ctl_state;
 169        const unsigned long out_mode_mask = BIT(1);
 170
 171        /* TTL/CMOS I/O */
 172        if (offset > 47) {
 173                raw_spin_lock_irqsave(&idio24gpio->lock, flags);
 174
 175                /* Clear TTL/CMOS Output Mode */
 176                ctl_state = ioread8(&idio24gpio->reg->ctl) & ~out_mode_mask;
 177                iowrite8(ctl_state, &idio24gpio->reg->ctl);
 178
 179                raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
 180        }
 181
 182        return 0;
 183}
 184
 185static int idio_24_gpio_direction_output(struct gpio_chip *chip,
 186        unsigned int offset, int value)
 187{
 188        struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
 189        unsigned long flags;
 190        unsigned int ctl_state;
 191        const unsigned long out_mode_mask = BIT(1);
 192
 193        /* TTL/CMOS I/O */
 194        if (offset > 47) {
 195                raw_spin_lock_irqsave(&idio24gpio->lock, flags);
 196
 197                /* Set TTL/CMOS Output Mode */
 198                ctl_state = ioread8(&idio24gpio->reg->ctl) | out_mode_mask;
 199                iowrite8(ctl_state, &idio24gpio->reg->ctl);
 200
 201                raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
 202        }
 203
 204        chip->set(chip, offset, value);
 205        return 0;
 206}
 207
 208static int idio_24_gpio_get(struct gpio_chip *chip, unsigned int offset)
 209{
 210        struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
 211        const unsigned long offset_mask = BIT(offset % 8);
 212        const unsigned long out_mode_mask = BIT(1);
 213
 214        /* FET Outputs */
 215        if (offset < 8)
 216                return !!(ioread8(&idio24gpio->reg->out0_7) & offset_mask);
 217
 218        if (offset < 16)
 219                return !!(ioread8(&idio24gpio->reg->out8_15) & offset_mask);
 220
 221        if (offset < 24)
 222                return !!(ioread8(&idio24gpio->reg->out16_23) & offset_mask);
 223
 224        /* Isolated Inputs */
 225        if (offset < 32)
 226                return !!(ioread8(&idio24gpio->reg->in0_7) & offset_mask);
 227
 228        if (offset < 40)
 229                return !!(ioread8(&idio24gpio->reg->in8_15) & offset_mask);
 230
 231        if (offset < 48)
 232                return !!(ioread8(&idio24gpio->reg->in16_23) & offset_mask);
 233
 234        /* TTL/CMOS Outputs */
 235        if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
 236                return !!(ioread8(&idio24gpio->reg->ttl_out0_7) & offset_mask);
 237
 238        /* TTL/CMOS Inputs */
 239        return !!(ioread8(&idio24gpio->reg->ttl_in0_7) & offset_mask);
 240}
 241
 242static int idio_24_gpio_get_multiple(struct gpio_chip *chip,
 243        unsigned long *mask, unsigned long *bits)
 244{
 245        struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
 246        unsigned long offset;
 247        unsigned long gpio_mask;
 248        void __iomem *ports[] = {
 249                &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
 250                &idio24gpio->reg->out16_23, &idio24gpio->reg->in0_7,
 251                &idio24gpio->reg->in8_15, &idio24gpio->reg->in16_23,
 252        };
 253        size_t index;
 254        unsigned long port_state;
 255        const unsigned long out_mode_mask = BIT(1);
 256
 257        /* clear bits array to a clean slate */
 258        bitmap_zero(bits, chip->ngpio);
 259
 260        for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
 261                index = offset / 8;
 262
 263                /* read bits from current gpio port (port 6 is TTL GPIO) */
 264                if (index < 6)
 265                        port_state = ioread8(ports[index]);
 266                else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
 267                        port_state = ioread8(&idio24gpio->reg->ttl_out0_7);
 268                else
 269                        port_state = ioread8(&idio24gpio->reg->ttl_in0_7);
 270
 271                port_state &= gpio_mask;
 272
 273                bitmap_set_value8(bits, port_state, offset);
 274        }
 275
 276        return 0;
 277}
 278
 279static void idio_24_gpio_set(struct gpio_chip *chip, unsigned int offset,
 280        int value)
 281{
 282        struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
 283        const unsigned long out_mode_mask = BIT(1);
 284        void __iomem *base;
 285        const unsigned int mask = BIT(offset % 8);
 286        unsigned long flags;
 287        unsigned int out_state;
 288
 289        /* Isolated Inputs */
 290        if (offset > 23 && offset < 48)
 291                return;
 292
 293        /* TTL/CMOS Inputs */
 294        if (offset > 47 && !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask))
 295                return;
 296
 297        /* TTL/CMOS Outputs */
 298        if (offset > 47)
 299                base = &idio24gpio->reg->ttl_out0_7;
 300        /* FET Outputs */
 301        else if (offset > 15)
 302                base = &idio24gpio->reg->out16_23;
 303        else if (offset > 7)
 304                base = &idio24gpio->reg->out8_15;
 305        else
 306                base = &idio24gpio->reg->out0_7;
 307
 308        raw_spin_lock_irqsave(&idio24gpio->lock, flags);
 309
 310        if (value)
 311                out_state = ioread8(base) | mask;
 312        else
 313                out_state = ioread8(base) & ~mask;
 314
 315        iowrite8(out_state, base);
 316
 317        raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
 318}
 319
 320static void idio_24_gpio_set_multiple(struct gpio_chip *chip,
 321        unsigned long *mask, unsigned long *bits)
 322{
 323        struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
 324        unsigned long offset;
 325        unsigned long gpio_mask;
 326        void __iomem *ports[] = {
 327                &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
 328                &idio24gpio->reg->out16_23
 329        };
 330        size_t index;
 331        unsigned long bitmask;
 332        unsigned long flags;
 333        unsigned long out_state;
 334        const unsigned long out_mode_mask = BIT(1);
 335
 336        for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
 337                index = offset / 8;
 338
 339                bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
 340
 341                raw_spin_lock_irqsave(&idio24gpio->lock, flags);
 342
 343                /* read bits from current gpio port (port 6 is TTL GPIO) */
 344                if (index < 6) {
 345                        out_state = ioread8(ports[index]);
 346                } else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) {
 347                        out_state = ioread8(&idio24gpio->reg->ttl_out0_7);
 348                } else {
 349                        /* skip TTL GPIO if set for input */
 350                        raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
 351                        continue;
 352                }
 353
 354                /* set requested bit states */
 355                out_state &= ~gpio_mask;
 356                out_state |= bitmask;
 357
 358                /* write bits for current gpio port (port 6 is TTL GPIO) */
 359                if (index < 6)
 360                        iowrite8(out_state, ports[index]);
 361                else
 362                        iowrite8(out_state, &idio24gpio->reg->ttl_out0_7);
 363
 364                raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
 365        }
 366}
 367
 368static void idio_24_irq_ack(struct irq_data *data)
 369{
 370}
 371
 372static void idio_24_irq_mask(struct irq_data *data)
 373{
 374        struct gpio_chip *const chip = irq_data_get_irq_chip_data(data);
 375        struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
 376        unsigned long flags;
 377        const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
 378        unsigned char new_irq_mask;
 379        const unsigned long bank_offset = bit_offset / 8;
 380        unsigned char cos_enable_state;
 381
 382        raw_spin_lock_irqsave(&idio24gpio->lock, flags);
 383
 384        idio24gpio->irq_mask &= ~BIT(bit_offset);
 385        new_irq_mask = idio24gpio->irq_mask >> bank_offset * 8;
 386
 387        if (!new_irq_mask) {
 388                cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
 389
 390                /* Disable Rising Edge detection */
 391                cos_enable_state &= ~BIT(bank_offset);
 392                /* Disable Falling Edge detection */
 393                cos_enable_state &= ~BIT(bank_offset + 4);
 394
 395                iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable);
 396        }
 397
 398        raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
 399}
 400
 401static void idio_24_irq_unmask(struct irq_data *data)
 402{
 403        struct gpio_chip *const chip = irq_data_get_irq_chip_data(data);
 404        struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
 405        unsigned long flags;
 406        unsigned char prev_irq_mask;
 407        const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
 408        const unsigned long bank_offset = bit_offset / 8;
 409        unsigned char cos_enable_state;
 410
 411        raw_spin_lock_irqsave(&idio24gpio->lock, flags);
 412
 413        prev_irq_mask = idio24gpio->irq_mask >> bank_offset * 8;
 414        idio24gpio->irq_mask |= BIT(bit_offset);
 415
 416        if (!prev_irq_mask) {
 417                cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
 418
 419                /* Enable Rising Edge detection */
 420                cos_enable_state |= BIT(bank_offset);
 421                /* Enable Falling Edge detection */
 422                cos_enable_state |= BIT(bank_offset + 4);
 423
 424                iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable);
 425        }
 426
 427        raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
 428}
 429
 430static int idio_24_irq_set_type(struct irq_data *data, unsigned int flow_type)
 431{
 432        /* The only valid irq types are none and both-edges */
 433        if (flow_type != IRQ_TYPE_NONE &&
 434                (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
 435                return -EINVAL;
 436
 437        return 0;
 438}
 439
 440static struct irq_chip idio_24_irqchip = {
 441        .name = "pcie-idio-24",
 442        .irq_ack = idio_24_irq_ack,
 443        .irq_mask = idio_24_irq_mask,
 444        .irq_unmask = idio_24_irq_unmask,
 445        .irq_set_type = idio_24_irq_set_type
 446};
 447
 448static irqreturn_t idio_24_irq_handler(int irq, void *dev_id)
 449{
 450        struct idio_24_gpio *const idio24gpio = dev_id;
 451        unsigned long irq_status;
 452        struct gpio_chip *const chip = &idio24gpio->chip;
 453        unsigned long irq_mask;
 454        int gpio;
 455
 456        raw_spin_lock(&idio24gpio->lock);
 457
 458        /* Read Change-Of-State status */
 459        irq_status = ioread32(&idio24gpio->reg->cos0_7);
 460
 461        raw_spin_unlock(&idio24gpio->lock);
 462
 463        /* Make sure our device generated IRQ */
 464        if (!irq_status)
 465                return IRQ_NONE;
 466
 467        /* Handle only unmasked IRQ */
 468        irq_mask = idio24gpio->irq_mask & irq_status;
 469
 470        for_each_set_bit(gpio, &irq_mask, chip->ngpio - 24)
 471                generic_handle_domain_irq(chip->irq.domain, gpio + 24);
 472
 473        raw_spin_lock(&idio24gpio->lock);
 474
 475        /* Clear Change-Of-State status */
 476        iowrite32(irq_status, &idio24gpio->reg->cos0_7);
 477
 478        raw_spin_unlock(&idio24gpio->lock);
 479
 480        return IRQ_HANDLED;
 481}
 482
 483#define IDIO_24_NGPIO 56
 484static const char *idio_24_names[IDIO_24_NGPIO] = {
 485        "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
 486        "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
 487        "OUT16", "OUT17", "OUT18", "OUT19", "OUT20", "OUT21", "OUT22", "OUT23",
 488        "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
 489        "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15",
 490        "IIN16", "IIN17", "IIN18", "IIN19", "IIN20", "IIN21", "IIN22", "IIN23",
 491        "TTL0", "TTL1", "TTL2", "TTL3", "TTL4", "TTL5", "TTL6", "TTL7"
 492};
 493
 494static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 495{
 496        struct device *const dev = &pdev->dev;
 497        struct idio_24_gpio *idio24gpio;
 498        int err;
 499        const size_t pci_plx_bar_index = 1;
 500        const size_t pci_bar_index = 2;
 501        const char *const name = pci_name(pdev);
 502        struct gpio_irq_chip *girq;
 503
 504        idio24gpio = devm_kzalloc(dev, sizeof(*idio24gpio), GFP_KERNEL);
 505        if (!idio24gpio)
 506                return -ENOMEM;
 507
 508        err = pcim_enable_device(pdev);
 509        if (err) {
 510                dev_err(dev, "Failed to enable PCI device (%d)\n", err);
 511                return err;
 512        }
 513
 514        err = pcim_iomap_regions(pdev, BIT(pci_plx_bar_index) | BIT(pci_bar_index), name);
 515        if (err) {
 516                dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
 517                return err;
 518        }
 519
 520        idio24gpio->plx = pcim_iomap_table(pdev)[pci_plx_bar_index];
 521        idio24gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];
 522
 523        idio24gpio->chip.label = name;
 524        idio24gpio->chip.parent = dev;
 525        idio24gpio->chip.owner = THIS_MODULE;
 526        idio24gpio->chip.base = -1;
 527        idio24gpio->chip.ngpio = IDIO_24_NGPIO;
 528        idio24gpio->chip.names = idio_24_names;
 529        idio24gpio->chip.get_direction = idio_24_gpio_get_direction;
 530        idio24gpio->chip.direction_input = idio_24_gpio_direction_input;
 531        idio24gpio->chip.direction_output = idio_24_gpio_direction_output;
 532        idio24gpio->chip.get = idio_24_gpio_get;
 533        idio24gpio->chip.get_multiple = idio_24_gpio_get_multiple;
 534        idio24gpio->chip.set = idio_24_gpio_set;
 535        idio24gpio->chip.set_multiple = idio_24_gpio_set_multiple;
 536
 537        girq = &idio24gpio->chip.irq;
 538        girq->chip = &idio_24_irqchip;
 539        /* This will let us handle the parent IRQ in the driver */
 540        girq->parent_handler = NULL;
 541        girq->num_parents = 0;
 542        girq->parents = NULL;
 543        girq->default_type = IRQ_TYPE_NONE;
 544        girq->handler = handle_edge_irq;
 545
 546        raw_spin_lock_init(&idio24gpio->lock);
 547
 548        /* Software board reset */
 549        iowrite8(0, &idio24gpio->reg->soft_reset);
 550        /*
 551         * enable PLX PEX8311 internal PCI wire interrupt and local interrupt
 552         * input
 553         */
 554        iowrite8((INTCSR_INTERNAL_PCI_WIRE | INTCSR_LOCAL_INPUT) >> 8,
 555                 idio24gpio->plx + PLX_PEX8311_PCI_LCS_INTCSR + 1);
 556
 557        err = devm_gpiochip_add_data(dev, &idio24gpio->chip, idio24gpio);
 558        if (err) {
 559                dev_err(dev, "GPIO registering failed (%d)\n", err);
 560                return err;
 561        }
 562
 563        err = devm_request_irq(dev, pdev->irq, idio_24_irq_handler, IRQF_SHARED,
 564                name, idio24gpio);
 565        if (err) {
 566                dev_err(dev, "IRQ handler registering failed (%d)\n", err);
 567                return err;
 568        }
 569
 570        return 0;
 571}
 572
 573static const struct pci_device_id idio_24_pci_dev_id[] = {
 574        { PCI_DEVICE(0x494F, 0x0FD0) }, { PCI_DEVICE(0x494F, 0x0BD0) },
 575        { PCI_DEVICE(0x494F, 0x07D0) }, { PCI_DEVICE(0x494F, 0x0FC0) },
 576        { 0 }
 577};
 578MODULE_DEVICE_TABLE(pci, idio_24_pci_dev_id);
 579
 580static struct pci_driver idio_24_driver = {
 581        .name = "pcie-idio-24",
 582        .id_table = idio_24_pci_dev_id,
 583        .probe = idio_24_probe
 584};
 585
 586module_pci_driver(idio_24_driver);
 587
 588MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
 589MODULE_DESCRIPTION("ACCES PCIe-IDIO-24 GPIO driver");
 590MODULE_LICENSE("GPL v2");
 591