cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

gpio-pcie-idio-24.c (17250B)


      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");