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 0;
150
151 /* Isolated Inputs */
152 if (offset < 48)
153 return 1;
154
155 /* TTL/CMOS I/O */
156 /* OUT MODE = 1 when TTL/CMOS Output Mode is set */
157 return !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask);
158 }
159
idio_24_gpio_direction_input(struct gpio_chip * chip,unsigned int offset)160 static int idio_24_gpio_direction_input(struct gpio_chip *chip,
161 unsigned int offset)
162 {
163 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
164 unsigned long flags;
165 unsigned int ctl_state;
166 const unsigned long out_mode_mask = BIT(1);
167
168 /* TTL/CMOS I/O */
169 if (offset > 47) {
170 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
171
172 /* Clear TTL/CMOS Output Mode */
173 ctl_state = ioread8(&idio24gpio->reg->ctl) & ~out_mode_mask;
174 iowrite8(ctl_state, &idio24gpio->reg->ctl);
175
176 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
177 }
178
179 return 0;
180 }
181
idio_24_gpio_direction_output(struct gpio_chip * chip,unsigned int offset,int value)182 static int idio_24_gpio_direction_output(struct gpio_chip *chip,
183 unsigned int offset, int value)
184 {
185 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
186 unsigned long flags;
187 unsigned int ctl_state;
188 const unsigned long out_mode_mask = BIT(1);
189
190 /* TTL/CMOS I/O */
191 if (offset > 47) {
192 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
193
194 /* Set TTL/CMOS Output Mode */
195 ctl_state = ioread8(&idio24gpio->reg->ctl) | out_mode_mask;
196 iowrite8(ctl_state, &idio24gpio->reg->ctl);
197
198 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
199 }
200
201 chip->set(chip, offset, value);
202 return 0;
203 }
204
idio_24_gpio_get(struct gpio_chip * chip,unsigned int offset)205 static int idio_24_gpio_get(struct gpio_chip *chip, unsigned int offset)
206 {
207 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
208 const unsigned long offset_mask = BIT(offset % 8);
209 const unsigned long out_mode_mask = BIT(1);
210
211 /* FET Outputs */
212 if (offset < 8)
213 return !!(ioread8(&idio24gpio->reg->out0_7) & offset_mask);
214
215 if (offset < 16)
216 return !!(ioread8(&idio24gpio->reg->out8_15) & offset_mask);
217
218 if (offset < 24)
219 return !!(ioread8(&idio24gpio->reg->out16_23) & offset_mask);
220
221 /* Isolated Inputs */
222 if (offset < 32)
223 return !!(ioread8(&idio24gpio->reg->in0_7) & offset_mask);
224
225 if (offset < 40)
226 return !!(ioread8(&idio24gpio->reg->in8_15) & offset_mask);
227
228 if (offset < 48)
229 return !!(ioread8(&idio24gpio->reg->in16_23) & offset_mask);
230
231 /* TTL/CMOS Outputs */
232 if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
233 return !!(ioread8(&idio24gpio->reg->ttl_out0_7) & offset_mask);
234
235 /* TTL/CMOS Inputs */
236 return !!(ioread8(&idio24gpio->reg->ttl_in0_7) & offset_mask);
237 }
238
idio_24_gpio_get_multiple(struct gpio_chip * chip,unsigned long * mask,unsigned long * bits)239 static int idio_24_gpio_get_multiple(struct gpio_chip *chip,
240 unsigned long *mask, unsigned long *bits)
241 {
242 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
243 size_t i;
244 const unsigned int gpio_reg_size = 8;
245 unsigned int bits_offset;
246 size_t word_index;
247 unsigned int word_offset;
248 unsigned long word_mask;
249 const unsigned long port_mask = GENMASK(gpio_reg_size - 1, 0);
250 unsigned long port_state;
251 void __iomem *ports[] = {
252 &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
253 &idio24gpio->reg->out16_23, &idio24gpio->reg->in0_7,
254 &idio24gpio->reg->in8_15, &idio24gpio->reg->in16_23,
255 };
256 const unsigned long out_mode_mask = BIT(1);
257
258 /* clear bits array to a clean slate */
259 bitmap_zero(bits, chip->ngpio);
260
261 /* get bits are evaluated a gpio port register at a time */
262 for (i = 0; i < ARRAY_SIZE(ports) + 1; i++) {
263 /* gpio offset in bits array */
264 bits_offset = i * gpio_reg_size;
265
266 /* word index for bits array */
267 word_index = BIT_WORD(bits_offset);
268
269 /* gpio offset within current word of bits array */
270 word_offset = bits_offset % BITS_PER_LONG;
271
272 /* mask of get bits for current gpio within current word */
273 word_mask = mask[word_index] & (port_mask << word_offset);
274 if (!word_mask) {
275 /* no get bits in this port so skip to next one */
276 continue;
277 }
278
279 /* read bits from current gpio port (port 6 is TTL GPIO) */
280 if (i < 6)
281 port_state = ioread8(ports[i]);
282 else if (ioread8(&idio24gpio->reg->ctl) & out_mode_mask)
283 port_state = ioread8(&idio24gpio->reg->ttl_out0_7);
284 else
285 port_state = ioread8(&idio24gpio->reg->ttl_in0_7);
286
287 /* store acquired bits at respective bits array offset */
288 bits[word_index] |= port_state << word_offset;
289 }
290
291 return 0;
292 }
293
idio_24_gpio_set(struct gpio_chip * chip,unsigned int offset,int value)294 static void idio_24_gpio_set(struct gpio_chip *chip, unsigned int offset,
295 int value)
296 {
297 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
298 const unsigned long out_mode_mask = BIT(1);
299 void __iomem *base;
300 const unsigned int mask = BIT(offset % 8);
301 unsigned long flags;
302 unsigned int out_state;
303
304 /* Isolated Inputs */
305 if (offset > 23 && offset < 48)
306 return;
307
308 /* TTL/CMOS Inputs */
309 if (offset > 47 && !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask))
310 return;
311
312 /* TTL/CMOS Outputs */
313 if (offset > 47)
314 base = &idio24gpio->reg->ttl_out0_7;
315 /* FET Outputs */
316 else if (offset > 15)
317 base = &idio24gpio->reg->out16_23;
318 else if (offset > 7)
319 base = &idio24gpio->reg->out8_15;
320 else
321 base = &idio24gpio->reg->out0_7;
322
323 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
324
325 if (value)
326 out_state = ioread8(base) | mask;
327 else
328 out_state = ioread8(base) & ~mask;
329
330 iowrite8(out_state, base);
331
332 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
333 }
334
idio_24_gpio_set_multiple(struct gpio_chip * chip,unsigned long * mask,unsigned long * bits)335 static void idio_24_gpio_set_multiple(struct gpio_chip *chip,
336 unsigned long *mask, unsigned long *bits)
337 {
338 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
339 size_t i;
340 unsigned long bits_offset;
341 unsigned long gpio_mask;
342 const unsigned int gpio_reg_size = 8;
343 const unsigned long port_mask = GENMASK(gpio_reg_size, 0);
344 unsigned long flags;
345 unsigned int out_state;
346 void __iomem *ports[] = {
347 &idio24gpio->reg->out0_7, &idio24gpio->reg->out8_15,
348 &idio24gpio->reg->out16_23
349 };
350 const unsigned long out_mode_mask = BIT(1);
351 const unsigned int ttl_offset = 48;
352 const size_t ttl_i = BIT_WORD(ttl_offset);
353 const unsigned int word_offset = ttl_offset % BITS_PER_LONG;
354 const unsigned long ttl_mask = (mask[ttl_i] >> word_offset) & port_mask;
355 const unsigned long ttl_bits = (bits[ttl_i] >> word_offset) & ttl_mask;
356
357 /* set bits are processed a gpio port register at a time */
358 for (i = 0; i < ARRAY_SIZE(ports); i++) {
359 /* gpio offset in bits array */
360 bits_offset = i * gpio_reg_size;
361
362 /* check if any set bits for current port */
363 gpio_mask = (*mask >> bits_offset) & port_mask;
364 if (!gpio_mask) {
365 /* no set bits for this port so move on to next port */
366 continue;
367 }
368
369 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
370
371 /* process output lines */
372 out_state = ioread8(ports[i]) & ~gpio_mask;
373 out_state |= (*bits >> bits_offset) & gpio_mask;
374 iowrite8(out_state, ports[i]);
375
376 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
377 }
378
379 /* check if setting TTL lines and if they are in output mode */
380 if (!ttl_mask || !(ioread8(&idio24gpio->reg->ctl) & out_mode_mask))
381 return;
382
383 /* handle TTL output */
384 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
385
386 /* process output lines */
387 out_state = ioread8(&idio24gpio->reg->ttl_out0_7) & ~ttl_mask;
388 out_state |= ttl_bits;
389 iowrite8(out_state, &idio24gpio->reg->ttl_out0_7);
390
391 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
392 }
393
idio_24_irq_ack(struct irq_data * data)394 static void idio_24_irq_ack(struct irq_data *data)
395 {
396 }
397
idio_24_irq_mask(struct irq_data * data)398 static void idio_24_irq_mask(struct irq_data *data)
399 {
400 struct gpio_chip *const chip = irq_data_get_irq_chip_data(data);
401 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
402 unsigned long flags;
403 const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
404 unsigned char new_irq_mask;
405 const unsigned long bank_offset = bit_offset / 8;
406 unsigned char cos_enable_state;
407
408 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
409
410 idio24gpio->irq_mask &= ~BIT(bit_offset);
411 new_irq_mask = idio24gpio->irq_mask >> bank_offset * 8;
412
413 if (!new_irq_mask) {
414 cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
415
416 /* Disable Rising Edge detection */
417 cos_enable_state &= ~BIT(bank_offset);
418 /* Disable Falling Edge detection */
419 cos_enable_state &= ~BIT(bank_offset + 4);
420
421 iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable);
422 }
423
424 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
425 }
426
idio_24_irq_unmask(struct irq_data * data)427 static void idio_24_irq_unmask(struct irq_data *data)
428 {
429 struct gpio_chip *const chip = irq_data_get_irq_chip_data(data);
430 struct idio_24_gpio *const idio24gpio = gpiochip_get_data(chip);
431 unsigned long flags;
432 unsigned char prev_irq_mask;
433 const unsigned long bit_offset = irqd_to_hwirq(data) - 24;
434 const unsigned long bank_offset = bit_offset / 8;
435 unsigned char cos_enable_state;
436
437 raw_spin_lock_irqsave(&idio24gpio->lock, flags);
438
439 prev_irq_mask = idio24gpio->irq_mask >> bank_offset * 8;
440 idio24gpio->irq_mask |= BIT(bit_offset);
441
442 if (!prev_irq_mask) {
443 cos_enable_state = ioread8(&idio24gpio->reg->cos_enable);
444
445 /* Enable Rising Edge detection */
446 cos_enable_state |= BIT(bank_offset);
447 /* Enable Falling Edge detection */
448 cos_enable_state |= BIT(bank_offset + 4);
449
450 iowrite8(cos_enable_state, &idio24gpio->reg->cos_enable);
451 }
452
453 raw_spin_unlock_irqrestore(&idio24gpio->lock, flags);
454 }
455
idio_24_irq_set_type(struct irq_data * data,unsigned int flow_type)456 static int idio_24_irq_set_type(struct irq_data *data, unsigned int flow_type)
457 {
458 /* The only valid irq types are none and both-edges */
459 if (flow_type != IRQ_TYPE_NONE &&
460 (flow_type & IRQ_TYPE_EDGE_BOTH) != IRQ_TYPE_EDGE_BOTH)
461 return -EINVAL;
462
463 return 0;
464 }
465
466 static struct irq_chip idio_24_irqchip = {
467 .name = "pcie-idio-24",
468 .irq_ack = idio_24_irq_ack,
469 .irq_mask = idio_24_irq_mask,
470 .irq_unmask = idio_24_irq_unmask,
471 .irq_set_type = idio_24_irq_set_type
472 };
473
idio_24_irq_handler(int irq,void * dev_id)474 static irqreturn_t idio_24_irq_handler(int irq, void *dev_id)
475 {
476 struct idio_24_gpio *const idio24gpio = dev_id;
477 unsigned long irq_status;
478 struct gpio_chip *const chip = &idio24gpio->chip;
479 unsigned long irq_mask;
480 int gpio;
481
482 raw_spin_lock(&idio24gpio->lock);
483
484 /* Read Change-Of-State status */
485 irq_status = ioread32(&idio24gpio->reg->cos0_7);
486
487 raw_spin_unlock(&idio24gpio->lock);
488
489 /* Make sure our device generated IRQ */
490 if (!irq_status)
491 return IRQ_NONE;
492
493 /* Handle only unmasked IRQ */
494 irq_mask = idio24gpio->irq_mask & irq_status;
495
496 for_each_set_bit(gpio, &irq_mask, chip->ngpio - 24)
497 generic_handle_irq(irq_find_mapping(chip->irq.domain,
498 gpio + 24));
499
500 raw_spin_lock(&idio24gpio->lock);
501
502 /* Clear Change-Of-State status */
503 iowrite32(irq_status, &idio24gpio->reg->cos0_7);
504
505 raw_spin_unlock(&idio24gpio->lock);
506
507 return IRQ_HANDLED;
508 }
509
510 #define IDIO_24_NGPIO 56
511 static const char *idio_24_names[IDIO_24_NGPIO] = {
512 "OUT0", "OUT1", "OUT2", "OUT3", "OUT4", "OUT5", "OUT6", "OUT7",
513 "OUT8", "OUT9", "OUT10", "OUT11", "OUT12", "OUT13", "OUT14", "OUT15",
514 "OUT16", "OUT17", "OUT18", "OUT19", "OUT20", "OUT21", "OUT22", "OUT23",
515 "IIN0", "IIN1", "IIN2", "IIN3", "IIN4", "IIN5", "IIN6", "IIN7",
516 "IIN8", "IIN9", "IIN10", "IIN11", "IIN12", "IIN13", "IIN14", "IIN15",
517 "IIN16", "IIN17", "IIN18", "IIN19", "IIN20", "IIN21", "IIN22", "IIN23",
518 "TTL0", "TTL1", "TTL2", "TTL3", "TTL4", "TTL5", "TTL6", "TTL7"
519 };
520
idio_24_probe(struct pci_dev * pdev,const struct pci_device_id * id)521 static int idio_24_probe(struct pci_dev *pdev, const struct pci_device_id *id)
522 {
523 struct device *const dev = &pdev->dev;
524 struct idio_24_gpio *idio24gpio;
525 int err;
526 const size_t pci_plx_bar_index = 1;
527 const size_t pci_bar_index = 2;
528 const char *const name = pci_name(pdev);
529
530 idio24gpio = devm_kzalloc(dev, sizeof(*idio24gpio), GFP_KERNEL);
531 if (!idio24gpio)
532 return -ENOMEM;
533
534 err = pcim_enable_device(pdev);
535 if (err) {
536 dev_err(dev, "Failed to enable PCI device (%d)\n", err);
537 return err;
538 }
539
540 err = pcim_iomap_regions(pdev, BIT(pci_plx_bar_index) | BIT(pci_bar_index), name);
541 if (err) {
542 dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err);
543 return err;
544 }
545
546 idio24gpio->plx = pcim_iomap_table(pdev)[pci_plx_bar_index];
547 idio24gpio->reg = pcim_iomap_table(pdev)[pci_bar_index];
548
549 idio24gpio->chip.label = name;
550 idio24gpio->chip.parent = dev;
551 idio24gpio->chip.owner = THIS_MODULE;
552 idio24gpio->chip.base = -1;
553 idio24gpio->chip.ngpio = IDIO_24_NGPIO;
554 idio24gpio->chip.names = idio_24_names;
555 idio24gpio->chip.get_direction = idio_24_gpio_get_direction;
556 idio24gpio->chip.direction_input = idio_24_gpio_direction_input;
557 idio24gpio->chip.direction_output = idio_24_gpio_direction_output;
558 idio24gpio->chip.get = idio_24_gpio_get;
559 idio24gpio->chip.get_multiple = idio_24_gpio_get_multiple;
560 idio24gpio->chip.set = idio_24_gpio_set;
561 idio24gpio->chip.set_multiple = idio_24_gpio_set_multiple;
562
563 raw_spin_lock_init(&idio24gpio->lock);
564
565 /* Software board reset */
566 iowrite8(0, &idio24gpio->reg->soft_reset);
567 /*
568 * enable PLX PEX8311 internal PCI wire interrupt and local interrupt
569 * input
570 */
571 iowrite8((INTCSR_INTERNAL_PCI_WIRE | INTCSR_LOCAL_INPUT) >> 8,
572 idio24gpio->plx + PLX_PEX8311_PCI_LCS_INTCSR + 1);
573
574 err = devm_gpiochip_add_data(dev, &idio24gpio->chip, idio24gpio);
575 if (err) {
576 dev_err(dev, "GPIO registering failed (%d)\n", err);
577 return err;
578 }
579
580 err = gpiochip_irqchip_add(&idio24gpio->chip, &idio_24_irqchip, 0,
581 handle_edge_irq, IRQ_TYPE_NONE);
582 if (err) {
583 dev_err(dev, "Could not add irqchip (%d)\n", err);
584 return err;
585 }
586
587 err = devm_request_irq(dev, pdev->irq, idio_24_irq_handler, IRQF_SHARED,
588 name, idio24gpio);
589 if (err) {
590 dev_err(dev, "IRQ handler registering failed (%d)\n", err);
591 return err;
592 }
593
594 return 0;
595 }
596
597 static const struct pci_device_id idio_24_pci_dev_id[] = {
598 { PCI_DEVICE(0x494F, 0x0FD0) }, { PCI_DEVICE(0x494F, 0x0BD0) },
599 { PCI_DEVICE(0x494F, 0x07D0) }, { PCI_DEVICE(0x494F, 0x0FC0) },
600 { 0 }
601 };
602 MODULE_DEVICE_TABLE(pci, idio_24_pci_dev_id);
603
604 static struct pci_driver idio_24_driver = {
605 .name = "pcie-idio-24",
606 .id_table = idio_24_pci_dev_id,
607 .probe = idio_24_probe
608 };
609
610 module_pci_driver(idio_24_driver);
611
612 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
613 MODULE_DESCRIPTION("ACCES PCIe-IDIO-24 GPIO driver");
614 MODULE_LICENSE("GPL v2");
615