Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * GPIO driver for the ACCES PCIe-IDIO-24 family
0004  * Copyright (C) 2018 William Breathitt Gray
0005  *
0006  * This program is free software; you can redistribute it and/or modify
0007  * it under the terms of the GNU General Public License, version 2, as
0008  * published by the Free Software Foundation.
0009  *
0010  * This program is distributed in the hope that it will be useful, but
0011  * WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013  * General Public License for more details.
0014  *
0015  * This driver supports the following ACCES devices: PCIe-IDIO-24,
0016  * PCIe-IDI-24, PCIe-IDO-24, and PCIe-IDIO-12.
0017  */
0018 #include <linux/bitmap.h>
0019 #include <linux/bitops.h>
0020 #include <linux/device.h>
0021 #include <linux/errno.h>
0022 #include <linux/gpio/driver.h>
0023 #include <linux/interrupt.h>
0024 #include <linux/irqdesc.h>
0025 #include <linux/kernel.h>
0026 #include <linux/module.h>
0027 #include <linux/pci.h>
0028 #include <linux/spinlock.h>
0029 #include <linux/types.h>
0030 
0031 /*
0032  * PLX PEX8311 PCI LCS_INTCSR Interrupt Control/Status
0033  *
0034  * Bit: Description
0035  *   0: Enable Interrupt Sources (Bit 0)
0036  *   1: Enable Interrupt Sources (Bit 1)
0037  *   2: Generate Internal PCI Bus Internal SERR# Interrupt
0038  *   3: Mailbox Interrupt Enable
0039  *   4: Power Management Interrupt Enable
0040  *   5: Power Management Interrupt
0041  *   6: Slave Read Local Data Parity Check Error Enable
0042  *   7: Slave Read Local Data Parity Check Error Status
0043  *   8: Internal PCI Wire Interrupt Enable
0044  *   9: PCI Express Doorbell Interrupt Enable
0045  *  10: PCI Abort Interrupt Enable
0046  *  11: Local Interrupt Input Enable
0047  *  12: Retry Abort Enable
0048  *  13: PCI Express Doorbell Interrupt Active
0049  *  14: PCI Abort Interrupt Active
0050  *  15: Local Interrupt Input Active
0051  *  16: Local Interrupt Output Enable
0052  *  17: Local Doorbell Interrupt Enable
0053  *  18: DMA Channel 0 Interrupt Enable
0054  *  19: DMA Channel 1 Interrupt Enable
0055  *  20: Local Doorbell Interrupt Active
0056  *  21: DMA Channel 0 Interrupt Active
0057  *  22: DMA Channel 1 Interrupt Active
0058  *  23: Built-In Self-Test (BIST) Interrupt Active
0059  *  24: Direct Master was the Bus Master during a Master or Target Abort
0060  *  25: DMA Channel 0 was the Bus Master during a Master or Target Abort
0061  *  26: DMA Channel 1 was the Bus Master during a Master or Target Abort
0062  *  27: Target Abort after internal 256 consecutive Master Retrys
0063  *  28: PCI Bus wrote data to LCS_MBOX0
0064  *  29: PCI Bus wrote data to LCS_MBOX1
0065  *  30: PCI Bus wrote data to LCS_MBOX2
0066  *  31: PCI Bus wrote data to LCS_MBOX3
0067  */
0068 #define PLX_PEX8311_PCI_LCS_INTCSR  0x68
0069 #define INTCSR_INTERNAL_PCI_WIRE    BIT(8)
0070 #define INTCSR_LOCAL_INPUT          BIT(11)
0071 
0072 /**
0073  * struct idio_24_gpio_reg - GPIO device registers structure
0074  * @out0_7: Read: FET Outputs 0-7
0075  *      Write: FET Outputs 0-7
0076  * @out8_15:    Read: FET Outputs 8-15
0077  *      Write: FET Outputs 8-15
0078  * @out16_23:   Read: FET Outputs 16-23
0079  *      Write: FET Outputs 16-23
0080  * @ttl_out0_7: Read: TTL/CMOS Outputs 0-7
0081  *      Write: TTL/CMOS Outputs 0-7
0082  * @in0_7:  Read: Isolated Inputs 0-7
0083  *      Write: Reserved
0084  * @in8_15: Read: Isolated Inputs 8-15
0085  *      Write: Reserved
0086  * @in16_23:    Read: Isolated Inputs 16-23
0087  *      Write: Reserved
0088  * @ttl_in0_7:  Read: TTL/CMOS Inputs 0-7
0089  *      Write: Reserved
0090  * @cos0_7: Read: COS Status Inputs 0-7
0091  *      Write: COS Clear Inputs 0-7
0092  * @cos8_15:    Read: COS Status Inputs 8-15
0093  *      Write: COS Clear Inputs 8-15
0094  * @cos16_23:   Read: COS Status Inputs 16-23
0095  *      Write: COS Clear Inputs 16-23
0096  * @cos_ttl0_7: Read: COS Status TTL/CMOS 0-7
0097  *      Write: COS Clear TTL/CMOS 0-7
0098  * @ctl:    Read: Control Register
0099  *      Write: Control Register
0100  * @reserved:   Read: Reserved
0101  *      Write: Reserved
0102  * @cos_enable: Read: COS Enable
0103  *      Write: COS Enable
0104  * @soft_reset: Read: IRQ Output Pin Status
0105  *      Write: Software Board Reset
0106  */
0107 struct idio_24_gpio_reg {
0108     u8 out0_7;
0109     u8 out8_15;
0110     u8 out16_23;
0111     u8 ttl_out0_7;
0112     u8 in0_7;
0113     u8 in8_15;
0114     u8 in16_23;
0115     u8 ttl_in0_7;
0116     u8 cos0_7;
0117     u8 cos8_15;
0118     u8 cos16_23;
0119     u8 cos_ttl0_7;
0120     u8 ctl;
0121     u8 reserved;
0122     u8 cos_enable;
0123     u8 soft_reset;
0124 };
0125 
0126 /**
0127  * struct idio_24_gpio - GPIO device private data structure
0128  * @chip:   instance of the gpio_chip
0129  * @lock:   synchronization lock to prevent I/O race conditions
0130  * @reg:    I/O address offset for the GPIO device registers
0131  * @irq_mask:   I/O bits affected by interrupts
0132  */
0133 struct idio_24_gpio {
0134     struct gpio_chip chip;
0135     raw_spinlock_t lock;
0136     __u8 __iomem *plx;
0137     struct idio_24_gpio_reg __iomem *reg;
0138     unsigned long irq_mask;
0139 };
0140 
0141 static int idio_24_gpio_get_direction(struct gpio_chip *chip,
0142     unsigned int offset)
0143 {
0144     struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0145     const unsigned long out_mode_mask = BIT(1);
0146 
0147     /* FET Outputs */
0148     if (offset < 24)
0149         return GPIO_LINE_DIRECTION_OUT;
0150 
0151     /* Isolated Inputs */
0152     if (offset < 48)
0153         return GPIO_LINE_DIRECTION_IN;
0154 
0155     /* TTL/CMOS I/O */
0156     /* OUT MODE = 1 when TTL/CMOS Output Mode is set */
0157     if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
0158         return GPIO_LINE_DIRECTION_OUT;
0159 
0160     return GPIO_LINE_DIRECTION_IN;
0161 }
0162 
0163 static int idio_24_gpio_direction_input(struct gpio_chip *chip,
0164     unsigned int offset)
0165 {
0166     struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0167     unsigned long flags;
0168     unsigned int ctl_state;
0169     const unsigned long out_mode_mask = BIT(1);
0170 
0171     /* TTL/CMOS I/O */
0172     if (offset > 47) {
0173         raw_spin_lock_irqsave(&idio24gpio->lock, flags);
0174 
0175         /* Clear TTL/CMOS Output Mode */
0176         ctl_state = ioread8(&idio24gpio->reg->ctl) & ~out_mode_mask;
0177         iowrite8(ctl_state, &idio24gpio->reg->ctl);
0178 
0179         raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
0180     }
0181 
0182     return 0;
0183 }
0184 
0185 static int idio_24_gpio_direction_output(struct gpio_chip *chip,
0186     unsigned int offset, int value)
0187 {
0188     struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0189     unsigned long flags;
0190     unsigned int ctl_state;
0191     const unsigned long out_mode_mask = BIT(1);
0192 
0193     /* TTL/CMOS I/O */
0194     if (offset > 47) {
0195         raw_spin_lock_irqsave(&idio24gpio->lock, flags);
0196 
0197         /* Set TTL/CMOS Output Mode */
0198         ctl_state = ioread8(&idio24gpio->reg->ctl) | out_mode_mask;
0199         iowrite8(ctl_state, &idio24gpio->reg->ctl);
0200 
0201         raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
0202     }
0203 
0204     chip->set(chip, offset, value);
0205     return 0;
0206 }
0207 
0208 static int idio_24_gpio_get(struct gpio_chip *chip, unsigned int offset)
0209 {
0210     struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0211     const unsigned long offset_mask = BIT(offset % 8);
0212     const unsigned long out_mode_mask = BIT(1);
0213 
0214     /* FET Outputs */
0215     if (offset < 8)
0216         return !!(ioread8(&idio24gpio->reg->out0_7) & offset_mask);
0217 
0218     if (offset < 16)
0219         return !!(ioread8(&idio24gpio->reg->out8_15) & offset_mask);
0220 
0221     if (offset < 24)
0222         return !!(ioread8(&idio24gpio->reg->out16_23) & offset_mask);
0223 
0224     /* Isolated Inputs */
0225     if (offset < 32)
0226         return !!(ioread8(&idio24gpio->reg->in0_7) & offset_mask);
0227 
0228     if (offset < 40)
0229         return !!(ioread8(&idio24gpio->reg->in8_15) & offset_mask);
0230 
0231     if (offset < 48)
0232         return !!(ioread8(&idio24gpio->reg->in16_23) & offset_mask);
0233 
0234     /* TTL/CMOS Outputs */
0235     if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
0236         return !!(ioread8(&idio24gpio->reg->ttl_out0_7) & offset_mask);
0237 
0238     /* TTL/CMOS Inputs */
0239     return !!(ioread8(&idio24gpio->reg->ttl_in0_7) & offset_mask);
0240 }
0241 
0242 static int idio_24_gpio_get_multiple(struct gpio_chip *chip,
0243     unsigned long *mask, unsigned long *bits)
0244 {
0245     struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0246     unsigned long offset;
0247     unsigned long gpio_mask;
0248     void __iomem *ports[] = {
0249         &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
0250         &idio24gpio->reg->out16_23, &idio24gpio->reg->in0_7,
0251         &idio24gpio->reg->in8_15, &idio24gpio->reg->in16_23,
0252     };
0253     size_t index;
0254     unsigned long port_state;
0255     const unsigned long out_mode_mask = BIT(1);
0256 
0257     /* clear bits array to a clean slate */
0258     bitmap_zero(bits, chip->ngpio);
0259 
0260     for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
0261         index = offset / 8;
0262 
0263         /* read bits from current gpio port (port 6 is TTL GPIO) */
0264         if (index < 6)
0265             port_state = ioread8(ports[index]);
0266         else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
0267             port_state = ioread8(&idio24gpio->reg->ttl_out0_7);
0268         else
0269             port_state = ioread8(&idio24gpio->reg->ttl_in0_7);
0270 
0271         port_state &= gpio_mask;
0272 
0273         bitmap_set_value8(bits, port_state, offset);
0274     }
0275 
0276     return 0;
0277 }
0278 
0279 static void idio_24_gpio_set(struct gpio_chip *chip, unsigned int offset,
0280     int value)
0281 {
0282     struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0283     const unsigned long out_mode_mask = BIT(1);
0284     void __iomem *base;
0285     const unsigned int mask = BIT(offset % 8);
0286     unsigned long flags;
0287     unsigned int out_state;
0288 
0289     /* Isolated Inputs */
0290     if (offset > 23 && offset < 48)
0291         return;
0292 
0293     /* TTL/CMOS Inputs */
0294     if (offset > 47 && !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask))
0295         return;
0296 
0297     /* TTL/CMOS Outputs */
0298     if (offset > 47)
0299         base = &idio24gpio->reg->ttl_out0_7;
0300     /* FET Outputs */
0301     else if (offset > 15)
0302         base = &idio24gpio->reg->out16_23;
0303     else if (offset > 7)
0304         base = &idio24gpio->reg->out8_15;
0305     else
0306         base = &idio24gpio->reg->out0_7;
0307 
0308     raw_spin_lock_irqsave(&idio24gpio->lock, flags);
0309 
0310     if (value)
0311         out_state = ioread8(base) | mask;
0312     else
0313         out_state = ioread8(base) & ~mask;
0314 
0315     iowrite8(out_state, base);
0316 
0317     raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
0318 }
0319 
0320 static void idio_24_gpio_set_multiple(struct gpio_chip *chip,
0321     unsigned long *mask, unsigned long *bits)
0322 {
0323     struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0324     unsigned long offset;
0325     unsigned long gpio_mask;
0326     void __iomem *ports[] = {
0327         &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
0328         &idio24gpio->reg->out16_23
0329     };
0330     size_t index;
0331     unsigned long bitmask;
0332     unsigned long flags;
0333     unsigned long out_state;
0334     const unsigned long out_mode_mask = BIT(1);
0335 
0336     for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
0337         index = offset / 8;
0338 
0339         bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
0340 
0341         raw_spin_lock_irqsave(&idio24gpio->lock, flags);
0342 
0343         /* read bits from current gpio port (port 6 is TTL GPIO) */
0344         if (index < 6) {
0345             out_state = ioread8(ports[index]);
0346         } else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask) {
0347             out_state = ioread8(&idio24gpio->reg->ttl_out0_7);
0348         } else {
0349             /* skip TTL GPIO if set for input */
0350             raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
0351             continue;
0352         }
0353 
0354         /* set requested bit states */
0355         out_state &= ~gpio_mask;
0356         out_state |= bitmask;
0357 
0358         /* write bits for current gpio port (port 6 is TTL GPIO) */
0359         if (index < 6)
0360             iowrite8(out_state, ports[index]);
0361         else
0362             iowrite8(out_state, &idio24gpio->reg->ttl_out0_7);
0363 
0364         raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
0365     }
0366 }
0367 
0368 static void idio_24_irq_ack(struct irq_data *data)
0369 {
0370 }
0371 
0372 static void idio_24_irq_mask(struct irq_data *data)
0373 {
0374     struct gpio_chip *const chip = irq_data_get_irq_chip_data(data);
0375     struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0376     unsigned long flags;
0377     const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
0378     unsigned char new_irq_mask;
0379     const unsigned long bank_offset = bit_offset / 8;
0380     unsigned char cos_enable_state;
0381 
0382     raw_spin_lock_irqsave(&idio24gpio->lock, flags);
0383 
0384     idio24gpio->irq_mask &= ~BIT(bit_offset);
0385     new_irq_mask = idio24gpio->irq_mask >> bank_offset * 8;
0386 
0387     if (!new_irq_mask) {
0388         cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
0389 
0390         /* Disable Rising Edge detection */
0391         cos_enable_state &= ~BIT(bank_offset);
0392         /* Disable Falling Edge detection */
0393         cos_enable_state &= ~BIT(bank_offset + 4);
0394 
0395         iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable);
0396     }
0397 
0398     raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
0399 }
0400 
0401 static void idio_24_irq_unmask(struct irq_data *data)
0402 {
0403     struct gpio_chip *const chip = irq_data_get_irq_chip_data(data);
0404     struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
0405     unsigned long flags;
0406     unsigned char prev_irq_mask;
0407     const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
0408     const unsigned long bank_offset = bit_offset / 8;
0409     unsigned char cos_enable_state;
0410 
0411     raw_spin_lock_irqsave(&idio24gpio->lock, flags);
0412 
0413     prev_irq_mask = idio24gpio->irq_mask >> bank_offset * 8;
0414     idio24gpio->irq_mask |= BIT(bit_offset);
0415 
0416     if (!prev_irq_mask) {
0417         cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
0418 
0419         /* Enable Rising Edge detection */
0420         cos_enable_state |= BIT(bank_offset);
0421         /* Enable Falling Edge detection */
0422         cos_enable_state |= BIT(bank_offset + 4);
0423 
0424         iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable);
0425     }
0426 
0427     raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
0428 }
0429 
0430 static int idio_24_irq_set_type(struct irq_data *data, unsigned int flow_type)
0431 {
0432     /* The only valid irq types are none and both-edges */
0433     if (flow_type != IRQ_TYPE_NONE &&
0434         (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
0435         return -EINVAL;
0436 
0437     return 0;
0438 }
0439 
0440 static struct irq_chip idio_24_irqchip = {
0441     .name = "pcie-idio-24",
0442     .irq_ack = idio_24_irq_ack,
0443     .irq_mask = idio_24_irq_mask,
0444     .irq_unmask = idio_24_irq_unmask,
0445     .irq_set_type = idio_24_irq_set_type
0446 };
0447 
0448 static irqreturn_t idio_24_irq_handler(int irq, void *dev_id)
0449 {
0450     struct idio_24_gpio *const idio24gpio = dev_id;
0451     unsigned long irq_status;
0452     struct gpio_chip *const chip = &idio24gpio->chip;
0453     unsigned long irq_mask;
0454     int gpio;
0455 
0456     raw_spin_lock(&idio24gpio->lock);
0457 
0458     /* Read Change-Of-State status */
0459     irq_status = ioread32(&idio24gpio->reg->cos0_7);
0460 
0461     raw_spin_unlock(&idio24gpio->lock);
0462 
0463     /* Make sure our device generated IRQ */
0464     if (!irq_status)
0465         return IRQ_NONE;
0466 
0467     /* Handle only unmasked IRQ */
0468     irq_mask = idio24gpio->irq_mask & irq_status;
0469 
0470     for_each_set_bit(gpio, &irq_mask, chip->ngpio - 24)
0471         generic_handle_domain_irq(chip->irq.domain, gpio + 24);
0472 
0473     raw_spin_lock(&idio24gpio->lock);
0474 
0475     /* Clear Change-Of-State status */
0476     iowrite32(irq_status, &idio24gpio->reg->cos0_7);
0477 
0478     raw_spin_unlock(&idio24gpio->lock);
0479 
0480     return IRQ_HANDLED;
0481 }
0482 
0483 #define IDIO_24_NGPIO 56
0484 static const char *idio_24_names[IDIO_24_NGPIO] = {
0485     "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
0486     "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
0487     "OUT16", "OUT17", "OUT18", "OUT19", "OUT20", "OUT21", "OUT22", "OUT23",
0488     "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
0489     "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15",
0490     "IIN16", "IIN17", "IIN18", "IIN19", "IIN20", "IIN21", "IIN22", "IIN23",
0491     "TTL0", "TTL1", "TTL2", "TTL3", "TTL4", "TTL5", "TTL6", "TTL7"
0492 };
0493 
0494 static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
0495 {
0496     struct device *const dev = &pdev->dev;
0497     struct idio_24_gpio *idio24gpio;
0498     int err;
0499     const size_t pci_plx_bar_index = 1;
0500     const size_t pci_bar_index = 2;
0501     const char *const name = pci_name(pdev);
0502     struct gpio_irq_chip *girq;
0503 
0504     idio24gpio = devm_kzalloc(dev, sizeof(*idio24gpio), GFP_KERNEL);
0505     if (!idio24gpio)
0506         return -ENOMEM;
0507 
0508     err = pcim_enable_device(pdev);
0509     if (err) {
0510         dev_err(dev, "Failed to enable PCI device (%d)\n", err);
0511         return err;
0512     }
0513 
0514     err = pcim_iomap_regions(pdev, BIT(pci_plx_bar_index) | BIT(pci_bar_index), name);
0515     if (err) {
0516         dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
0517         return err;
0518     }
0519 
0520     idio24gpio->plx = pcim_iomap_table(pdev)[pci_plx_bar_index];
0521     idio24gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];
0522 
0523     idio24gpio->chip.label = name;
0524     idio24gpio->chip.parent = dev;
0525     idio24gpio->chip.owner = THIS_MODULE;
0526     idio24gpio->chip.base = -1;
0527     idio24gpio->chip.ngpio = IDIO_24_NGPIO;
0528     idio24gpio->chip.names = idio_24_names;
0529     idio24gpio->chip.get_direction = idio_24_gpio_get_direction;
0530     idio24gpio->chip.direction_input = idio_24_gpio_direction_input;
0531     idio24gpio->chip.direction_output = idio_24_gpio_direction_output;
0532     idio24gpio->chip.get = idio_24_gpio_get;
0533     idio24gpio->chip.get_multiple = idio_24_gpio_get_multiple;
0534     idio24gpio->chip.set = idio_24_gpio_set;
0535     idio24gpio->chip.set_multiple = idio_24_gpio_set_multiple;
0536 
0537     girq = &idio24gpio->chip.irq;
0538     girq->chip = &idio_24_irqchip;
0539     /* This will let us handle the parent IRQ in the driver */
0540     girq->parent_handler = NULL;
0541     girq->num_parents = 0;
0542     girq->parents = NULL;
0543     girq->default_type = IRQ_TYPE_NONE;
0544     girq->handler = handle_edge_irq;
0545 
0546     raw_spin_lock_init(&idio24gpio->lock);
0547 
0548     /* Software board reset */
0549     iowrite8(0, &idio24gpio->reg->soft_reset);
0550     /*
0551      * enable PLX PEX8311 internal PCI wire interrupt and local interrupt
0552      * input
0553      */
0554     iowrite8((INTCSR_INTERNAL_PCI_WIRE | INTCSR_LOCAL_INPUT) >> 8,
0555          idio24gpio->plx + PLX_PEX8311_PCI_LCS_INTCSR + 1);
0556 
0557     err = devm_gpiochip_add_data(dev, &idio24gpio->chip, idio24gpio);
0558     if (err) {
0559         dev_err(dev, "GPIO registering failed (%d)\n", err);
0560         return err;
0561     }
0562 
0563     err = devm_request_irq(dev, pdev->irq, idio_24_irq_handler, IRQF_SHARED,
0564         name, idio24gpio);
0565     if (err) {
0566         dev_err(dev, "IRQ handler registering failed (%d)\n", err);
0567         return err;
0568     }
0569 
0570     return 0;
0571 }
0572 
0573 static const struct pci_device_id idio_24_pci_dev_id[] = {
0574     { PCI_DEVICE(0x494F, 0x0FD0) }, { PCI_DEVICE(0x494F, 0x0BD0) },
0575     { PCI_DEVICE(0x494F, 0x07D0) }, { PCI_DEVICE(0x494F, 0x0FC0) },
0576     { 0 }
0577 };
0578 MODULE_DEVICE_TABLE(pci, idio_24_pci_dev_id);
0579 
0580 static struct pci_driver idio_24_driver = {
0581     .name = "pcie-idio-24",
0582     .id_table = idio_24_pci_dev_id,
0583     .probe = idio_24_probe
0584 };
0585 
0586 module_pci_driver(idio_24_driver);
0587 
0588 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
0589 MODULE_DESCRIPTION("ACCES PCIe-IDIO-24 GPIO driver");
0590 MODULE_LICENSE("GPL v2");