comedi_pci.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * comedi_pci.c
  4. * Comedi PCI driver specific functions.
  5. *
  6. * COMEDI - Linux Control and Measurement Device Interface
  7. * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
  8. */
  9. #include <linux/module.h>
  10. #include <linux/interrupt.h>
  11. #include "comedi_pci.h"
  12. /**
  13. * comedi_to_pci_dev() - Return PCI device attached to COMEDI device
  14. * @dev: COMEDI device.
  15. *
  16. * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a
  17. * a &struct device embedded in a &struct pci_dev.
  18. *
  19. * Return: Attached PCI device if @dev->hw_dev is non-%NULL.
  20. * Return %NULL if @dev->hw_dev is %NULL.
  21. */
  22. struct pci_dev *comedi_to_pci_dev(struct comedi_device *dev)
  23. {
  24. return dev->hw_dev ? to_pci_dev(dev->hw_dev) : NULL;
  25. }
  26. EXPORT_SYMBOL_GPL(comedi_to_pci_dev);
  27. /**
  28. * comedi_pci_enable() - Enable the PCI device and request the regions
  29. * @dev: COMEDI device.
  30. *
  31. * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a
  32. * a &struct device embedded in a &struct pci_dev. Enable the PCI device
  33. * and request its regions. Set @dev->ioenabled to %true if successful,
  34. * otherwise undo what was done.
  35. *
  36. * Calls to comedi_pci_enable() and comedi_pci_disable() cannot be nested.
  37. *
  38. * Return:
  39. * 0 on success,
  40. * -%ENODEV if @dev->hw_dev is %NULL,
  41. * -%EBUSY if regions busy,
  42. * or some negative error number if failed to enable PCI device.
  43. *
  44. */
  45. int comedi_pci_enable(struct comedi_device *dev)
  46. {
  47. struct pci_dev *pcidev = comedi_to_pci_dev(dev);
  48. int rc;
  49. if (!pcidev)
  50. return -ENODEV;
  51. rc = pci_enable_device(pcidev);
  52. if (rc < 0)
  53. return rc;
  54. rc = pci_request_regions(pcidev, dev->board_name);
  55. if (rc < 0)
  56. pci_disable_device(pcidev);
  57. else
  58. dev->ioenabled = true;
  59. return rc;
  60. }
  61. EXPORT_SYMBOL_GPL(comedi_pci_enable);
  62. /**
  63. * comedi_pci_disable() - Release the regions and disable the PCI device
  64. * @dev: COMEDI device.
  65. *
  66. * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a
  67. * a &struct device embedded in a &struct pci_dev. If the earlier call
  68. * to comedi_pci_enable() was successful, release the PCI device's regions
  69. * and disable it. Reset @dev->ioenabled back to %false.
  70. */
  71. void comedi_pci_disable(struct comedi_device *dev)
  72. {
  73. struct pci_dev *pcidev = comedi_to_pci_dev(dev);
  74. if (pcidev && dev->ioenabled) {
  75. pci_release_regions(pcidev);
  76. pci_disable_device(pcidev);
  77. }
  78. dev->ioenabled = false;
  79. }
  80. EXPORT_SYMBOL_GPL(comedi_pci_disable);
  81. /**
  82. * comedi_pci_detach() - A generic "detach" handler for PCI COMEDI drivers
  83. * @dev: COMEDI device.
  84. *
  85. * COMEDI drivers for PCI devices that need no special clean-up of private data
  86. * and have no ioremapped regions other than that pointed to by @dev->mmio may
  87. * use this function as its "detach" handler called by the COMEDI core when a
  88. * COMEDI device is being detached from the low-level driver. It may be also
  89. * called from a more specific "detach" handler that does additional clean-up.
  90. *
  91. * Free the IRQ if @dev->irq is non-zero, iounmap @dev->mmio if it is
  92. * non-%NULL, and call comedi_pci_disable() to release the PCI device's regions
  93. * and disable it.
  94. */
  95. void comedi_pci_detach(struct comedi_device *dev)
  96. {
  97. struct pci_dev *pcidev = comedi_to_pci_dev(dev);
  98. if (!pcidev || !dev->ioenabled)
  99. return;
  100. if (dev->irq) {
  101. free_irq(dev->irq, dev);
  102. dev->irq = 0;
  103. }
  104. if (dev->mmio) {
  105. iounmap(dev->mmio);
  106. dev->mmio = NULL;
  107. }
  108. comedi_pci_disable(dev);
  109. }
  110. EXPORT_SYMBOL_GPL(comedi_pci_detach);
  111. /**
  112. * comedi_pci_auto_config() - Configure/probe a PCI COMEDI device
  113. * @pcidev: PCI device.
  114. * @driver: Registered COMEDI driver.
  115. * @context: Driver specific data, passed to comedi_auto_config().
  116. *
  117. * Typically called from the pci_driver (*probe) function. Auto-configure
  118. * a COMEDI device, using the &struct device embedded in *@pcidev as the
  119. * hardware device. The @context value gets passed through to @driver's
  120. * "auto_attach" handler. The "auto_attach" handler may call
  121. * comedi_to_pci_dev() on the passed in COMEDI device to recover @pcidev.
  122. *
  123. * Return: The result of calling comedi_auto_config() (0 on success, or
  124. * a negative error number on failure).
  125. */
  126. int comedi_pci_auto_config(struct pci_dev *pcidev,
  127. struct comedi_driver *driver,
  128. unsigned long context)
  129. {
  130. return comedi_auto_config(&pcidev->dev, driver, context);
  131. }
  132. EXPORT_SYMBOL_GPL(comedi_pci_auto_config);
  133. /**
  134. * comedi_pci_auto_unconfig() - Unconfigure/remove a PCI COMEDI device
  135. * @pcidev: PCI device.
  136. *
  137. * Typically called from the pci_driver (*remove) function. Auto-unconfigure
  138. * a COMEDI device attached to this PCI device, using a pointer to the
  139. * &struct device embedded in *@pcidev as the hardware device. The COMEDI
  140. * driver's "detach" handler will be called during unconfiguration of the
  141. * COMEDI device.
  142. *
  143. * Note that the COMEDI device may have already been unconfigured using the
  144. * %COMEDI_DEVCONFIG ioctl, in which case this attempt to unconfigure it
  145. * again should be ignored.
  146. */
  147. void comedi_pci_auto_unconfig(struct pci_dev *pcidev)
  148. {
  149. comedi_auto_unconfig(&pcidev->dev);
  150. }
  151. EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig);
  152. /**
  153. * comedi_pci_driver_register() - Register a PCI COMEDI driver
  154. * @comedi_driver: COMEDI driver to be registered.
  155. * @pci_driver: PCI driver to be registered.
  156. *
  157. * This function is called from the module_init() of PCI COMEDI driver modules
  158. * to register the COMEDI driver and the PCI driver. Do not call it directly,
  159. * use the module_comedi_pci_driver() helper macro instead.
  160. *
  161. * Return: 0 on success, or a negative error number on failure.
  162. */
  163. int comedi_pci_driver_register(struct comedi_driver *comedi_driver,
  164. struct pci_driver *pci_driver)
  165. {
  166. int ret;
  167. ret = comedi_driver_register(comedi_driver);
  168. if (ret < 0)
  169. return ret;
  170. ret = pci_register_driver(pci_driver);
  171. if (ret < 0) {
  172. comedi_driver_unregister(comedi_driver);
  173. return ret;
  174. }
  175. return 0;
  176. }
  177. EXPORT_SYMBOL_GPL(comedi_pci_driver_register);
  178. /**
  179. * comedi_pci_driver_unregister() - Unregister a PCI COMEDI driver
  180. * @comedi_driver: COMEDI driver to be unregistered.
  181. * @pci_driver: PCI driver to be unregistered.
  182. *
  183. * This function is called from the module_exit() of PCI COMEDI driver modules
  184. * to unregister the PCI driver and the COMEDI driver. Do not call it
  185. * directly, use the module_comedi_pci_driver() helper macro instead.
  186. */
  187. void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver,
  188. struct pci_driver *pci_driver)
  189. {
  190. pci_unregister_driver(pci_driver);
  191. comedi_driver_unregister(comedi_driver);
  192. }
  193. EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister);
  194. static int __init comedi_pci_init(void)
  195. {
  196. return 0;
  197. }
  198. module_init(comedi_pci_init);
  199. static void __exit comedi_pci_exit(void)
  200. {
  201. }
  202. module_exit(comedi_pci_exit);
  203. MODULE_AUTHOR("https://www.comedi.org");
  204. MODULE_DESCRIPTION("Comedi PCI interface module");
  205. MODULE_LICENSE("GPL");