Commit | Line | Data |
---|---|---|
33782dd5 HS |
1 | /* |
2 | * comedi_pci.c | |
3 | * Comedi PCI driver specific functions. | |
4 | * | |
5 | * COMEDI - Linux Control and Measurement Device Interface | |
6 | * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License as published by | |
10 | * the Free Software Foundation; either version 2 of the License, or | |
11 | * (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
33782dd5 HS |
17 | */ |
18 | ||
bc3fe156 | 19 | #include <linux/module.h> |
33782dd5 | 20 | #include <linux/pci.h> |
aac307f9 | 21 | #include <linux/interrupt.h> |
33782dd5 HS |
22 | |
23 | #include "comedidev.h" | |
24 | ||
25 | /** | |
26 | * comedi_to_pci_dev() - comedi_device pointer to pci_dev pointer. | |
27 | * @dev: comedi_device struct | |
28 | */ | |
29 | struct pci_dev *comedi_to_pci_dev(struct comedi_device *dev) | |
30 | { | |
31 | return dev->hw_dev ? to_pci_dev(dev->hw_dev) : NULL; | |
32 | } | |
33 | EXPORT_SYMBOL_GPL(comedi_to_pci_dev); | |
34 | ||
35 | /** | |
36 | * comedi_pci_enable() - Enable the PCI device and request the regions. | |
818f569f | 37 | * @dev: comedi_device struct |
33782dd5 | 38 | */ |
818f569f | 39 | int comedi_pci_enable(struct comedi_device *dev) |
33782dd5 | 40 | { |
818f569f | 41 | struct pci_dev *pcidev = comedi_to_pci_dev(dev); |
33782dd5 HS |
42 | int rc; |
43 | ||
818f569f HS |
44 | if (!pcidev) |
45 | return -ENODEV; | |
46 | ||
33782dd5 HS |
47 | rc = pci_enable_device(pcidev); |
48 | if (rc < 0) | |
49 | return rc; | |
50 | ||
46c58127 | 51 | rc = pci_request_regions(pcidev, dev->board_name); |
33782dd5 HS |
52 | if (rc < 0) |
53 | pci_disable_device(pcidev); | |
00ca6884 IA |
54 | else |
55 | dev->ioenabled = true; | |
33782dd5 HS |
56 | |
57 | return rc; | |
58 | } | |
59 | EXPORT_SYMBOL_GPL(comedi_pci_enable); | |
60 | ||
61 | /** | |
62 | * comedi_pci_disable() - Release the regions and disable the PCI device. | |
7f072f54 | 63 | * @dev: comedi_device struct |
33782dd5 | 64 | */ |
7f072f54 | 65 | void comedi_pci_disable(struct comedi_device *dev) |
33782dd5 | 66 | { |
7f072f54 HS |
67 | struct pci_dev *pcidev = comedi_to_pci_dev(dev); |
68 | ||
00ca6884 | 69 | if (pcidev && dev->ioenabled) { |
7f072f54 HS |
70 | pci_release_regions(pcidev); |
71 | pci_disable_device(pcidev); | |
72 | } | |
00ca6884 | 73 | dev->ioenabled = false; |
33782dd5 HS |
74 | } |
75 | EXPORT_SYMBOL_GPL(comedi_pci_disable); | |
76 | ||
aac307f9 HS |
77 | /** |
78 | * comedi_pci_detach() - A generic (*detach) function for PCI drivers. | |
79 | * @dev: comedi_device struct | |
80 | */ | |
81 | void comedi_pci_detach(struct comedi_device *dev) | |
82 | { | |
83 | struct pci_dev *pcidev = comedi_to_pci_dev(dev); | |
84 | ||
85 | if (!pcidev || !dev->ioenabled) | |
86 | return; | |
87 | ||
88 | if (dev->irq) { | |
89 | free_irq(dev->irq, dev); | |
90 | dev->irq = 0; | |
91 | } | |
92 | if (dev->mmio) { | |
93 | iounmap(dev->mmio); | |
94 | dev->mmio = NULL; | |
95 | } | |
96 | comedi_pci_disable(dev); | |
97 | } | |
98 | EXPORT_SYMBOL_GPL(comedi_pci_detach); | |
99 | ||
33782dd5 HS |
100 | /** |
101 | * comedi_pci_auto_config() - Configure/probe a comedi PCI driver. | |
102 | * @pcidev: pci_dev struct | |
103 | * @driver: comedi_driver struct | |
b8f4ac23 | 104 | * @context: driver specific data, passed to comedi_auto_config() |
33782dd5 HS |
105 | * |
106 | * Typically called from the pci_driver (*probe) function. | |
107 | */ | |
108 | int comedi_pci_auto_config(struct pci_dev *pcidev, | |
b8f4ac23 HS |
109 | struct comedi_driver *driver, |
110 | unsigned long context) | |
33782dd5 | 111 | { |
b8f4ac23 | 112 | return comedi_auto_config(&pcidev->dev, driver, context); |
33782dd5 HS |
113 | } |
114 | EXPORT_SYMBOL_GPL(comedi_pci_auto_config); | |
115 | ||
116 | /** | |
117 | * comedi_pci_auto_unconfig() - Unconfigure/remove a comedi PCI driver. | |
118 | * @pcidev: pci_dev struct | |
119 | * | |
120 | * Typically called from the pci_driver (*remove) function. | |
121 | */ | |
122 | void comedi_pci_auto_unconfig(struct pci_dev *pcidev) | |
123 | { | |
124 | comedi_auto_unconfig(&pcidev->dev); | |
125 | } | |
126 | EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); | |
127 | ||
128 | /** | |
129 | * comedi_pci_driver_register() - Register a comedi PCI driver. | |
130 | * @comedi_driver: comedi_driver struct | |
131 | * @pci_driver: pci_driver struct | |
132 | * | |
133 | * This function is used for the module_init() of comedi PCI drivers. | |
134 | * Do not call it directly, use the module_comedi_pci_driver() helper | |
135 | * macro instead. | |
136 | */ | |
137 | int comedi_pci_driver_register(struct comedi_driver *comedi_driver, | |
138 | struct pci_driver *pci_driver) | |
139 | { | |
140 | int ret; | |
141 | ||
142 | ret = comedi_driver_register(comedi_driver); | |
143 | if (ret < 0) | |
144 | return ret; | |
145 | ||
146 | ret = pci_register_driver(pci_driver); | |
147 | if (ret < 0) { | |
148 | comedi_driver_unregister(comedi_driver); | |
149 | return ret; | |
150 | } | |
151 | ||
152 | return 0; | |
153 | } | |
154 | EXPORT_SYMBOL_GPL(comedi_pci_driver_register); | |
155 | ||
156 | /** | |
157 | * comedi_pci_driver_unregister() - Unregister a comedi PCI driver. | |
158 | * @comedi_driver: comedi_driver struct | |
159 | * @pci_driver: pci_driver struct | |
160 | * | |
161 | * This function is used for the module_exit() of comedi PCI drivers. | |
162 | * Do not call it directly, use the module_comedi_pci_driver() helper | |
163 | * macro instead. | |
164 | */ | |
165 | void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver, | |
166 | struct pci_driver *pci_driver) | |
167 | { | |
168 | pci_unregister_driver(pci_driver); | |
169 | comedi_driver_unregister(comedi_driver); | |
170 | } | |
171 | EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); | |
bc3fe156 IA |
172 | |
173 | static int __init comedi_pci_init(void) | |
174 | { | |
175 | return 0; | |
176 | } | |
177 | module_init(comedi_pci_init); | |
178 | ||
179 | static void __exit comedi_pci_exit(void) | |
180 | { | |
181 | } | |
182 | module_exit(comedi_pci_exit); | |
183 | ||
184 | MODULE_AUTHOR("http://www.comedi.org"); | |
185 | MODULE_DESCRIPTION("Comedi PCI interface module"); | |
186 | MODULE_LICENSE("GPL"); |