fpga-region.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  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. int fpga_region_register(struct device *dev, struct fpga_region *region)
  146. {
  147. int id, ret = 0;
  148. id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL);
  149. if (id < 0)
  150. return id;
  151. mutex_init(&region->mutex);
  152. INIT_LIST_HEAD(&region->bridge_list);
  153. device_initialize(&region->dev);
  154. region->dev.groups = region->groups;
  155. region->dev.class = fpga_region_class;
  156. region->dev.parent = dev;
  157. region->dev.of_node = dev->of_node;
  158. region->dev.id = id;
  159. ret = dev_set_name(&region->dev, "region%d", id);
  160. if (ret)
  161. goto err_remove;
  162. ret = device_add(&region->dev);
  163. if (ret)
  164. goto err_remove;
  165. return 0;
  166. err_remove:
  167. ida_simple_remove(&fpga_region_ida, id);
  168. return ret;
  169. }
  170. EXPORT_SYMBOL_GPL(fpga_region_register);
  171. int fpga_region_unregister(struct fpga_region *region)
  172. {
  173. device_unregister(&region->dev);
  174. return 0;
  175. }
  176. EXPORT_SYMBOL_GPL(fpga_region_unregister);
  177. static void fpga_region_dev_release(struct device *dev)
  178. {
  179. struct fpga_region *region = to_fpga_region(dev);
  180. ida_simple_remove(&fpga_region_ida, region->dev.id);
  181. }
  182. /**
  183. * fpga_region_init - init function for fpga_region class
  184. * Creates the fpga_region class and registers a reconfig notifier.
  185. */
  186. static int __init fpga_region_init(void)
  187. {
  188. fpga_region_class = class_create(THIS_MODULE, "fpga_region");
  189. if (IS_ERR(fpga_region_class))
  190. return PTR_ERR(fpga_region_class);
  191. fpga_region_class->dev_release = fpga_region_dev_release;
  192. return 0;
  193. }
  194. static void __exit fpga_region_exit(void)
  195. {
  196. class_destroy(fpga_region_class);
  197. ida_destroy(&fpga_region_ida);
  198. }
  199. subsys_initcall(fpga_region_init);
  200. module_exit(fpga_region_exit);
  201. MODULE_DESCRIPTION("FPGA Region");
  202. MODULE_AUTHOR("Alan Tull <atull@kernel.org>");
  203. MODULE_LICENSE("GPL v2");