fpga-region.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * FPGA Region - Support for FPGA programming under Linux
  4. *
  5. * Copyright (C) 2013-2016 Altera Corporation
  6. * Copyright (C) 2017 Intel Corporation
  7. */
  8. #include <linux/fpga/fpga-bridge.h>
  9. #include <linux/fpga/fpga-mgr.h>
  10. #include <linux/fpga/fpga-region.h>
  11. #include <linux/idr.h>
  12. #include <linux/kernel.h>
  13. #include <linux/list.h>
  14. #include <linux/module.h>
  15. #include <linux/slab.h>
  16. #include <linux/spinlock.h>
  17. static DEFINE_IDA(fpga_region_ida);
  18. static struct class *fpga_region_class;
  19. struct fpga_region *fpga_region_class_find(
  20. struct device *start, const void *data,
  21. int (*match)(struct device *, const void *))
  22. {
  23. struct device *dev;
  24. dev = class_find_device(fpga_region_class, start, data, match);
  25. if (!dev)
  26. return NULL;
  27. return to_fpga_region(dev);
  28. }
  29. EXPORT_SYMBOL_GPL(fpga_region_class_find);
  30. /**
  31. * fpga_region_get - get an exclusive reference to a fpga region
  32. * @region: FPGA Region struct
  33. *
  34. * Caller should call fpga_region_put() when done with region.
  35. *
  36. * Return fpga_region struct if successful.
  37. * Return -EBUSY if someone already has a reference to the region.
  38. * Return -ENODEV if @np is not a FPGA Region.
  39. */
  40. static struct fpga_region *fpga_region_get(struct fpga_region *region)
  41. {
  42. struct device *dev = &region->dev;
  43. if (!mutex_trylock(&region->mutex)) {
  44. dev_dbg(dev, "%s: FPGA Region already in use\n", __func__);
  45. return ERR_PTR(-EBUSY);
  46. }
  47. get_device(dev);
  48. if (!try_module_get(dev->parent->driver->owner)) {
  49. put_device(dev);
  50. mutex_unlock(&region->mutex);
  51. return ERR_PTR(-ENODEV);
  52. }
  53. dev_dbg(dev, "get\n");
  54. return region;
  55. }
  56. /**
  57. * fpga_region_put - release a reference to a region
  58. *
  59. * @region: FPGA region
  60. */
  61. static void fpga_region_put(struct fpga_region *region)
  62. {
  63. struct device *dev = &region->dev;
  64. dev_dbg(dev, "put\n");
  65. module_put(dev->parent->driver->owner);
  66. put_device(dev);
  67. mutex_unlock(&region->mutex);
  68. }
  69. /**
  70. * fpga_region_program_fpga - program FPGA
  71. *
  72. * @region: FPGA region
  73. *
  74. * Program an FPGA using fpga image info (region->info).
  75. * If the region has a get_bridges function, the exclusive reference for the
  76. * bridges will be held if programming succeeds. This is intended to prevent
  77. * reprogramming the region until the caller considers it safe to do so.
  78. * The caller will need to call fpga_bridges_put() before attempting to
  79. * reprogram the region.
  80. *
  81. * Return 0 for success or negative error code.
  82. */
  83. int fpga_region_program_fpga(struct fpga_region *region)
  84. {
  85. struct device *dev = &region->dev;
  86. struct fpga_image_info *info = region->info;
  87. int ret;
  88. region = fpga_region_get(region);
  89. if (IS_ERR(region)) {
  90. dev_err(dev, "failed to get FPGA region\n");
  91. return PTR_ERR(region);
  92. }
  93. ret = fpga_mgr_lock(region->mgr);
  94. if (ret) {
  95. dev_err(dev, "FPGA manager is busy\n");
  96. goto err_put_region;
  97. }
  98. /*
  99. * In some cases, we already have a list of bridges in the
  100. * fpga region struct. Or we don't have any bridges.
  101. */
  102. if (region->get_bridges) {
  103. ret = region->get_bridges(region);
  104. if (ret) {
  105. dev_err(dev, "failed to get fpga region bridges\n");
  106. goto err_unlock_mgr;
  107. }
  108. }
  109. ret = fpga_bridges_disable(&region->bridge_list);
  110. if (ret) {
  111. dev_err(dev, "failed to disable bridges\n");
  112. goto err_put_br;
  113. }
  114. ret = fpga_mgr_load(region->mgr, info);
  115. if (ret) {
  116. dev_err(dev, "failed to load FPGA image\n");
  117. goto err_put_br;
  118. }
  119. ret = fpga_bridges_enable(&region->bridge_list);
  120. if (ret) {
  121. dev_err(dev, "failed to enable region bridges\n");
  122. goto err_put_br;
  123. }
  124. fpga_mgr_unlock(region->mgr);
  125. fpga_region_put(region);
  126. return 0;
  127. err_put_br:
  128. if (region->get_bridges)
  129. fpga_bridges_put(&region->bridge_list);
  130. err_unlock_mgr:
  131. fpga_mgr_unlock(region->mgr);
  132. err_put_region:
  133. fpga_region_put(region);
  134. return ret;
  135. }
  136. EXPORT_SYMBOL_GPL(fpga_region_program_fpga);
  137. static ssize_t compat_id_show(struct device *dev,
  138. struct device_attribute *attr, char *buf)
  139. {
  140. struct fpga_region *region = to_fpga_region(dev);
  141. if (!region->compat_id)
  142. return -ENOENT;
  143. return sprintf(buf, "%016llx%016llx\n",
  144. (unsigned long long)region->compat_id->id_h,
  145. (unsigned long long)region->compat_id->id_l);
  146. }
  147. static DEVICE_ATTR_RO(compat_id);
  148. static struct attribute *fpga_region_attrs[] = {
  149. &dev_attr_compat_id.attr,
  150. NULL,
  151. };
  152. ATTRIBUTE_GROUPS(fpga_region);
  153. /**
  154. * fpga_region_create - alloc and init a struct fpga_region
  155. * @dev: device parent
  156. * @mgr: manager that programs this region
  157. * @get_bridges: optional function to get bridges to a list
  158. *
  159. * The caller of this function is responsible for freeing the resulting region
  160. * struct with fpga_region_free(). Using devm_fpga_region_create() instead is
  161. * recommended.
  162. *
  163. * Return: struct fpga_region or NULL
  164. */
  165. struct fpga_region
  166. *fpga_region_create(struct device *dev,
  167. struct fpga_manager *mgr,
  168. int (*get_bridges)(struct fpga_region *))
  169. {
  170. struct fpga_region *region;
  171. int id, ret = 0;
  172. region = kzalloc(sizeof(*region), GFP_KERNEL);
  173. if (!region)
  174. return NULL;
  175. id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL);
  176. if (id < 0)
  177. goto err_free;
  178. region->mgr = mgr;
  179. region->get_bridges = get_bridges;
  180. mutex_init(&region->mutex);
  181. INIT_LIST_HEAD(&region->bridge_list);
  182. device_initialize(&region->dev);
  183. region->dev.class = fpga_region_class;
  184. region->dev.parent = dev;
  185. region->dev.of_node = dev->of_node;
  186. region->dev.id = id;
  187. ret = dev_set_name(&region->dev, "region%d", id);
  188. if (ret)
  189. goto err_remove;
  190. return region;
  191. err_remove:
  192. ida_simple_remove(&fpga_region_ida, id);
  193. err_free:
  194. kfree(region);
  195. return NULL;
  196. }
  197. EXPORT_SYMBOL_GPL(fpga_region_create);
  198. /**
  199. * fpga_region_free - free a FPGA region created by fpga_region_create()
  200. * @region: FPGA region
  201. */
  202. void fpga_region_free(struct fpga_region *region)
  203. {
  204. ida_simple_remove(&fpga_region_ida, region->dev.id);
  205. kfree(region);
  206. }
  207. EXPORT_SYMBOL_GPL(fpga_region_free);
  208. static void devm_fpga_region_release(struct device *dev, void *res)
  209. {
  210. struct fpga_region *region = *(struct fpga_region **)res;
  211. fpga_region_free(region);
  212. }
  213. /**
  214. * devm_fpga_region_create - create and initialize a managed FPGA region struct
  215. * @dev: device parent
  216. * @mgr: manager that programs this region
  217. * @get_bridges: optional function to get bridges to a list
  218. *
  219. * This function is intended for use in a FPGA region driver's probe function.
  220. * After the region driver creates the region struct with
  221. * devm_fpga_region_create(), it should register it with fpga_region_register().
  222. * The region driver's remove function should call fpga_region_unregister().
  223. * The region struct allocated with this function will be freed automatically on
  224. * driver detach. This includes the case of a probe function returning error
  225. * before calling fpga_region_register(), the struct will still get cleaned up.
  226. *
  227. * Return: struct fpga_region or NULL
  228. */
  229. struct fpga_region
  230. *devm_fpga_region_create(struct device *dev,
  231. struct fpga_manager *mgr,
  232. int (*get_bridges)(struct fpga_region *))
  233. {
  234. struct fpga_region **ptr, *region;
  235. ptr = devres_alloc(devm_fpga_region_release, sizeof(*ptr), GFP_KERNEL);
  236. if (!ptr)
  237. return NULL;
  238. region = fpga_region_create(dev, mgr, get_bridges);
  239. if (!region) {
  240. devres_free(ptr);
  241. } else {
  242. *ptr = region;
  243. devres_add(dev, ptr);
  244. }
  245. return region;
  246. }
  247. EXPORT_SYMBOL_GPL(devm_fpga_region_create);
  248. /**
  249. * fpga_region_register - register a FPGA region
  250. * @region: FPGA region
  251. *
  252. * Return: 0 or -errno
  253. */
  254. int fpga_region_register(struct fpga_region *region)
  255. {
  256. return device_add(&region->dev);
  257. }
  258. EXPORT_SYMBOL_GPL(fpga_region_register);
  259. /**
  260. * fpga_region_unregister - unregister a FPGA region
  261. * @region: FPGA region
  262. *
  263. * This function is intended for use in a FPGA region driver's remove function.
  264. */
  265. void fpga_region_unregister(struct fpga_region *region)
  266. {
  267. device_unregister(&region->dev);
  268. }
  269. EXPORT_SYMBOL_GPL(fpga_region_unregister);
  270. static void fpga_region_dev_release(struct device *dev)
  271. {
  272. }
  273. /**
  274. * fpga_region_init - init function for fpga_region class
  275. * Creates the fpga_region class and registers a reconfig notifier.
  276. */
  277. static int __init fpga_region_init(void)
  278. {
  279. fpga_region_class = class_create(THIS_MODULE, "fpga_region");
  280. if (IS_ERR(fpga_region_class))
  281. return PTR_ERR(fpga_region_class);
  282. fpga_region_class->dev_groups = fpga_region_groups;
  283. fpga_region_class->dev_release = fpga_region_dev_release;
  284. return 0;
  285. }
  286. static void __exit fpga_region_exit(void)
  287. {
  288. class_destroy(fpga_region_class);
  289. ida_destroy(&fpga_region_ida);
  290. }
  291. subsys_initcall(fpga_region_init);
  292. module_exit(fpga_region_exit);
  293. MODULE_DESCRIPTION("FPGA Region");
  294. MODULE_AUTHOR("Alan Tull <atull@kernel.org>");
  295. MODULE_LICENSE("GPL v2");