fpga-region.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. * FPGA Region - Device Tree support for FPGA programming under Linux
  3. *
  4. * Copyright (C) 2013-2016 Altera Corporation
  5. * Copyright (C) 2017 Intel Corporation
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms and conditions of the GNU General Public License,
  9. * version 2, as published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  14. * more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along with
  17. * this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <linux/fpga/fpga-bridge.h>
  20. #include <linux/fpga/fpga-mgr.h>
  21. #include <linux/fpga/fpga-region.h>
  22. #include <linux/idr.h>
  23. #include <linux/kernel.h>
  24. #include <linux/list.h>
  25. #include <linux/module.h>
  26. #include <linux/slab.h>
  27. #include <linux/spinlock.h>
  28. static DEFINE_IDA(fpga_region_ida);
  29. static struct class *fpga_region_class;
  30. struct fpga_region *fpga_region_class_find(
  31. struct device *start, const void *data,
  32. int (*match)(struct device *, const void *))
  33. {
  34. struct device *dev;
  35. dev = class_find_device(fpga_region_class, start, data, match);
  36. if (!dev)
  37. return NULL;
  38. return to_fpga_region(dev);
  39. }
  40. EXPORT_SYMBOL_GPL(fpga_region_class_find);
  41. /**
  42. * fpga_region_get - get an exclusive reference to a fpga region
  43. * @region: FPGA Region struct
  44. *
  45. * Caller should call fpga_region_put() when done with region.
  46. *
  47. * Return fpga_region struct if successful.
  48. * Return -EBUSY if someone already has a reference to the region.
  49. * Return -ENODEV if @np is not a FPGA Region.
  50. */
  51. static struct fpga_region *fpga_region_get(struct fpga_region *region)
  52. {
  53. struct device *dev = &region->dev;
  54. if (!mutex_trylock(&region->mutex)) {
  55. dev_dbg(dev, "%s: FPGA Region already in use\n", __func__);
  56. return ERR_PTR(-EBUSY);
  57. }
  58. get_device(dev);
  59. if (!try_module_get(dev->parent->driver->owner)) {
  60. put_device(dev);
  61. mutex_unlock(&region->mutex);
  62. return ERR_PTR(-ENODEV);
  63. }
  64. dev_dbg(dev, "get\n");
  65. return region;
  66. }
  67. /**
  68. * fpga_region_put - release a reference to a region
  69. *
  70. * @region: FPGA region
  71. */
  72. static void fpga_region_put(struct fpga_region *region)
  73. {
  74. struct device *dev = &region->dev;
  75. dev_dbg(dev, "put\n");
  76. module_put(dev->parent->driver->owner);
  77. put_device(dev);
  78. mutex_unlock(&region->mutex);
  79. }
  80. /**
  81. * fpga_region_program_fpga - program FPGA
  82. * @region: FPGA region
  83. * Program an FPGA using fpga image info (region->info).
  84. * If the region has a get_bridges function, the exclusive reference for the
  85. * bridges will be held if programming succeeds. This is intended to prevent
  86. * reprogramming the region until the caller considers it safe to do so.
  87. * The caller will need to call fpga_bridges_put() before attempting to
  88. * reprogram the region.
  89. * Return 0 for success or negative error code.
  90. */
  91. int fpga_region_program_fpga(struct fpga_region *region)
  92. {
  93. struct device *dev = &region->dev;
  94. struct fpga_image_info *info = region->info;
  95. int ret;
  96. region = fpga_region_get(region);
  97. if (IS_ERR(region)) {
  98. dev_err(dev, "failed to get FPGA region\n");
  99. return PTR_ERR(region);
  100. }
  101. ret = fpga_mgr_lock(region->mgr);
  102. if (ret) {
  103. dev_err(dev, "FPGA manager is busy\n");
  104. goto err_put_region;
  105. }
  106. /*
  107. * In some cases, we already have a list of bridges in the
  108. * fpga region struct. Or we don't have any bridges.
  109. */
  110. if (region->get_bridges) {
  111. ret = region->get_bridges(region);
  112. if (ret) {
  113. dev_err(dev, "failed to get fpga region bridges\n");
  114. goto err_unlock_mgr;
  115. }
  116. }
  117. ret = fpga_bridges_disable(&region->bridge_list);
  118. if (ret) {
  119. dev_err(dev, "failed to disable bridges\n");
  120. goto err_put_br;
  121. }
  122. ret = fpga_mgr_load(region->mgr, info);
  123. if (ret) {
  124. dev_err(dev, "failed to load FPGA image\n");
  125. goto err_put_br;
  126. }
  127. ret = fpga_bridges_enable(&region->bridge_list);
  128. if (ret) {
  129. dev_err(dev, "failed to enable region bridges\n");
  130. goto err_put_br;
  131. }
  132. fpga_mgr_unlock(region->mgr);
  133. fpga_region_put(region);
  134. return 0;
  135. err_put_br:
  136. if (region->get_bridges)
  137. fpga_bridges_put(&region->bridge_list);
  138. err_unlock_mgr:
  139. fpga_mgr_unlock(region->mgr);
  140. err_put_region:
  141. fpga_region_put(region);
  142. return ret;
  143. }
  144. EXPORT_SYMBOL_GPL(fpga_region_program_fpga);
  145. /**
  146. * fpga_region_create - alloc and init a struct fpga_region
  147. * @dev: device parent
  148. * @mgr: manager that programs this region
  149. * @get_bridges: optional function to get bridges to a list
  150. *
  151. * Return: struct fpga_region or NULL
  152. */
  153. struct fpga_region
  154. *fpga_region_create(struct device *dev,
  155. struct fpga_manager *mgr,
  156. int (*get_bridges)(struct fpga_region *))
  157. {
  158. struct fpga_region *region;
  159. int id, ret = 0;
  160. region = kzalloc(sizeof(*region), GFP_KERNEL);
  161. if (!region)
  162. return NULL;
  163. id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL);
  164. if (id < 0)
  165. goto err_free;
  166. region->mgr = mgr;
  167. region->get_bridges = get_bridges;
  168. mutex_init(&region->mutex);
  169. INIT_LIST_HEAD(&region->bridge_list);
  170. device_initialize(&region->dev);
  171. region->dev.class = fpga_region_class;
  172. region->dev.parent = dev;
  173. region->dev.of_node = dev->of_node;
  174. region->dev.id = id;
  175. ret = dev_set_name(&region->dev, "region%d", id);
  176. if (ret)
  177. goto err_remove;
  178. return region;
  179. err_remove:
  180. ida_simple_remove(&fpga_region_ida, id);
  181. err_free:
  182. kfree(region);
  183. return NULL;
  184. }
  185. EXPORT_SYMBOL_GPL(fpga_region_create);
  186. /**
  187. * fpga_region_free - free a struct fpga_region
  188. * @region: FPGA region created by fpga_region_create
  189. */
  190. void fpga_region_free(struct fpga_region *region)
  191. {
  192. ida_simple_remove(&fpga_region_ida, region->dev.id);
  193. kfree(region);
  194. }
  195. EXPORT_SYMBOL_GPL(fpga_region_free);
  196. /*
  197. * fpga_region_register - register a FPGA region
  198. * @region: FPGA region created by fpga_region_create
  199. * Return: 0 or -errno
  200. */
  201. int fpga_region_register(struct fpga_region *region)
  202. {
  203. return device_add(&region->dev);
  204. }
  205. EXPORT_SYMBOL_GPL(fpga_region_register);
  206. /*
  207. * fpga_region_unregister - unregister a FPGA region
  208. * @region: FPGA region
  209. */
  210. void fpga_region_unregister(struct fpga_region *region)
  211. {
  212. device_unregister(&region->dev);
  213. }
  214. EXPORT_SYMBOL_GPL(fpga_region_unregister);
  215. static void fpga_region_dev_release(struct device *dev)
  216. {
  217. struct fpga_region *region = to_fpga_region(dev);
  218. fpga_region_free(region);
  219. }
  220. /**
  221. * fpga_region_init - init function for fpga_region class
  222. * Creates the fpga_region class and registers a reconfig notifier.
  223. */
  224. static int __init fpga_region_init(void)
  225. {
  226. fpga_region_class = class_create(THIS_MODULE, "fpga_region");
  227. if (IS_ERR(fpga_region_class))
  228. return PTR_ERR(fpga_region_class);
  229. fpga_region_class->dev_release = fpga_region_dev_release;
  230. return 0;
  231. }
  232. static void __exit fpga_region_exit(void)
  233. {
  234. class_destroy(fpga_region_class);
  235. ida_destroy(&fpga_region_ida);
  236. }
  237. subsys_initcall(fpga_region_init);
  238. module_exit(fpga_region_exit);
  239. MODULE_DESCRIPTION("FPGA Region");
  240. MODULE_AUTHOR("Alan Tull <atull@kernel.org>");
  241. MODULE_LICENSE("GPL v2");