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