• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
107 struct 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  */
133 struct 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 
idio_24_gpio_get_direction(struct gpio_chip * chip,unsigned int offset)141 static 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 
idio_24_gpio_direction_input(struct gpio_chip * chip,unsigned int offset)163 static 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 
idio_24_gpio_direction_output(struct gpio_chip * chip,unsigned int offset,int value)185 static 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 
idio_24_gpio_get(struct gpio_chip * chip,unsigned int offset)208 static 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 
idio_24_gpio_get_multiple(struct gpio_chip * chip,unsigned long * mask,unsigned long * bits)242 static 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 
idio_24_gpio_set(struct gpio_chip * chip,unsigned int offset,int value)279 static 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 
idio_24_gpio_set_multiple(struct gpio_chip * chip,unsigned long * mask,unsigned long * bits)320 static 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 
idio_24_irq_ack(struct irq_data * data)368 static void idio_24_irq_ack(struct irq_data *data)
369 {
370 }
371 
idio_24_irq_mask(struct irq_data * data)372 static 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 
idio_24_irq_unmask(struct irq_data * data)401 static 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 
idio_24_irq_set_type(struct irq_data * data,unsigned int flow_type)430 static 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 
440 static 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 
idio_24_irq_handler(int irq,void * dev_id)448 static 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
484 static 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 
idio_24_probe(struct pci_dev * pdev,const struct pci_device_id * id)494 static 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 
573 static 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 };
578 MODULE_DEVICE_TABLE(pci, idio_24_pci_dev_id);
579 
580 static 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 
586 module_pci_driver(idio_24_driver);
587 
588 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
589 MODULE_DESCRIPTION("ACCES PCIe-IDIO-24 GPIO driver");
590 MODULE_LICENSE("GPL v2");
591