fpga-bridge.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. /*
  2. * FPGA Bridge Framework Driver
  3. *
  4. * Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms and conditions of the GNU General Public License,
  8. * version 2, as published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope it will be useful, but WITHOUT
  11. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13. * more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along with
  16. * this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <linux/fpga/fpga-bridge.h>
  19. #include <linux/idr.h>
  20. #include <linux/kernel.h>
  21. #include <linux/module.h>
  22. #include <linux/of_platform.h>
  23. #include <linux/slab.h>
  24. #include <linux/spinlock.h>
  25. static DEFINE_IDA(fpga_bridge_ida);
  26. static struct class *fpga_bridge_class;
  27. /* Lock for adding/removing bridges to linked lists*/
  28. spinlock_t bridge_list_lock;
  29. static int fpga_bridge_of_node_match(struct device *dev, const void *data)
  30. {
  31. return dev->of_node == data;
  32. }
  33. /**
  34. * fpga_bridge_enable - Enable transactions on the bridge
  35. *
  36. * @bridge: FPGA bridge
  37. *
  38. * Return: 0 for success, error code otherwise.
  39. */
  40. int fpga_bridge_enable(struct fpga_bridge *bridge)
  41. {
  42. dev_dbg(&bridge->dev, "enable\n");
  43. if (bridge->br_ops && bridge->br_ops->enable_set)
  44. return bridge->br_ops->enable_set(bridge, 1);
  45. return 0;
  46. }
  47. EXPORT_SYMBOL_GPL(fpga_bridge_enable);
  48. /**
  49. * fpga_bridge_disable - Disable transactions on the bridge
  50. *
  51. * @bridge: FPGA bridge
  52. *
  53. * Return: 0 for success, error code otherwise.
  54. */
  55. int fpga_bridge_disable(struct fpga_bridge *bridge)
  56. {
  57. dev_dbg(&bridge->dev, "disable\n");
  58. if (bridge->br_ops && bridge->br_ops->enable_set)
  59. return bridge->br_ops->enable_set(bridge, 0);
  60. return 0;
  61. }
  62. EXPORT_SYMBOL_GPL(fpga_bridge_disable);
  63. /**
  64. * of_fpga_bridge_get - get an exclusive reference to a fpga bridge
  65. *
  66. * @np: node pointer of a FPGA bridge
  67. * @info: fpga image specific information
  68. *
  69. * Return fpga_bridge struct if successful.
  70. * Return -EBUSY if someone already has a reference to the bridge.
  71. * Return -ENODEV if @np is not a FPGA Bridge.
  72. */
  73. struct fpga_bridge *of_fpga_bridge_get(struct device_node *np,
  74. struct fpga_image_info *info)
  75. {
  76. struct device *dev;
  77. struct fpga_bridge *bridge;
  78. int ret = -ENODEV;
  79. dev = class_find_device(fpga_bridge_class, NULL, np,
  80. fpga_bridge_of_node_match);
  81. if (!dev)
  82. goto err_dev;
  83. bridge = to_fpga_bridge(dev);
  84. if (!bridge)
  85. goto err_dev;
  86. bridge->info = info;
  87. if (!mutex_trylock(&bridge->mutex)) {
  88. ret = -EBUSY;
  89. goto err_dev;
  90. }
  91. if (!try_module_get(dev->parent->driver->owner))
  92. goto err_ll_mod;
  93. dev_dbg(&bridge->dev, "get\n");
  94. return bridge;
  95. err_ll_mod:
  96. mutex_unlock(&bridge->mutex);
  97. err_dev:
  98. put_device(dev);
  99. return ERR_PTR(ret);
  100. }
  101. EXPORT_SYMBOL_GPL(of_fpga_bridge_get);
  102. /**
  103. * fpga_bridge_put - release a reference to a bridge
  104. *
  105. * @bridge: FPGA bridge
  106. */
  107. void fpga_bridge_put(struct fpga_bridge *bridge)
  108. {
  109. dev_dbg(&bridge->dev, "put\n");
  110. bridge->info = NULL;
  111. module_put(bridge->dev.parent->driver->owner);
  112. mutex_unlock(&bridge->mutex);
  113. put_device(&bridge->dev);
  114. }
  115. EXPORT_SYMBOL_GPL(fpga_bridge_put);
  116. /**
  117. * fpga_bridges_enable - enable bridges in a list
  118. * @bridge_list: list of FPGA bridges
  119. *
  120. * Enable each bridge in the list. If list is empty, do nothing.
  121. *
  122. * Return 0 for success or empty bridge list; return error code otherwise.
  123. */
  124. int fpga_bridges_enable(struct list_head *bridge_list)
  125. {
  126. struct fpga_bridge *bridge;
  127. struct list_head *node;
  128. int ret;
  129. list_for_each(node, bridge_list) {
  130. bridge = list_entry(node, struct fpga_bridge, node);
  131. ret = fpga_bridge_enable(bridge);
  132. if (ret)
  133. return ret;
  134. }
  135. return 0;
  136. }
  137. EXPORT_SYMBOL_GPL(fpga_bridges_enable);
  138. /**
  139. * fpga_bridges_disable - disable bridges in a list
  140. *
  141. * @bridge_list: list of FPGA bridges
  142. *
  143. * Disable each bridge in the list. If list is empty, do nothing.
  144. *
  145. * Return 0 for success or empty bridge list; return error code otherwise.
  146. */
  147. int fpga_bridges_disable(struct list_head *bridge_list)
  148. {
  149. struct fpga_bridge *bridge;
  150. struct list_head *node;
  151. int ret;
  152. list_for_each(node, bridge_list) {
  153. bridge = list_entry(node, struct fpga_bridge, node);
  154. ret = fpga_bridge_disable(bridge);
  155. if (ret)
  156. return ret;
  157. }
  158. return 0;
  159. }
  160. EXPORT_SYMBOL_GPL(fpga_bridges_disable);
  161. /**
  162. * fpga_bridges_put - put bridges
  163. *
  164. * @bridge_list: list of FPGA bridges
  165. *
  166. * For each bridge in the list, put the bridge and remove it from the list.
  167. * If list is empty, do nothing.
  168. */
  169. void fpga_bridges_put(struct list_head *bridge_list)
  170. {
  171. struct fpga_bridge *bridge;
  172. struct list_head *node, *next;
  173. unsigned long flags;
  174. list_for_each_safe(node, next, bridge_list) {
  175. bridge = list_entry(node, struct fpga_bridge, node);
  176. fpga_bridge_put(bridge);
  177. spin_lock_irqsave(&bridge_list_lock, flags);
  178. list_del(&bridge->node);
  179. spin_unlock_irqrestore(&bridge_list_lock, flags);
  180. }
  181. }
  182. EXPORT_SYMBOL_GPL(fpga_bridges_put);
  183. /**
  184. * fpga_bridges_get_to_list - get a bridge, add it to a list
  185. *
  186. * @np: node pointer of a FPGA bridge
  187. * @info: fpga image specific information
  188. * @bridge_list: list of FPGA bridges
  189. *
  190. * Get an exclusive reference to the bridge and and it to the list.
  191. *
  192. * Return 0 for success, error code from of_fpga_bridge_get() othewise.
  193. */
  194. int fpga_bridge_get_to_list(struct device_node *np,
  195. struct fpga_image_info *info,
  196. struct list_head *bridge_list)
  197. {
  198. struct fpga_bridge *bridge;
  199. unsigned long flags;
  200. bridge = of_fpga_bridge_get(np, info);
  201. if (IS_ERR(bridge))
  202. return PTR_ERR(bridge);
  203. spin_lock_irqsave(&bridge_list_lock, flags);
  204. list_add(&bridge->node, bridge_list);
  205. spin_unlock_irqrestore(&bridge_list_lock, flags);
  206. return 0;
  207. }
  208. EXPORT_SYMBOL_GPL(fpga_bridge_get_to_list);
  209. static ssize_t name_show(struct device *dev,
  210. struct device_attribute *attr, char *buf)
  211. {
  212. struct fpga_bridge *bridge = to_fpga_bridge(dev);
  213. return sprintf(buf, "%s\n", bridge->name);
  214. }
  215. static ssize_t state_show(struct device *dev,
  216. struct device_attribute *attr, char *buf)
  217. {
  218. struct fpga_bridge *bridge = to_fpga_bridge(dev);
  219. int enable = 1;
  220. if (bridge->br_ops && bridge->br_ops->enable_show)
  221. enable = bridge->br_ops->enable_show(bridge);
  222. return sprintf(buf, "%s\n", enable ? "enabled" : "disabled");
  223. }
  224. static DEVICE_ATTR_RO(name);
  225. static DEVICE_ATTR_RO(state);
  226. static struct attribute *fpga_bridge_attrs[] = {
  227. &dev_attr_name.attr,
  228. &dev_attr_state.attr,
  229. NULL,
  230. };
  231. ATTRIBUTE_GROUPS(fpga_bridge);
  232. /**
  233. * fpga_bridge_register - register a fpga bridge driver
  234. * @dev: FPGA bridge device from pdev
  235. * @name: FPGA bridge name
  236. * @br_ops: pointer to structure of fpga bridge ops
  237. * @priv: FPGA bridge private data
  238. *
  239. * Return: 0 for success, error code otherwise.
  240. */
  241. int fpga_bridge_register(struct device *dev, const char *name,
  242. const struct fpga_bridge_ops *br_ops, void *priv)
  243. {
  244. struct fpga_bridge *bridge;
  245. int id, ret = 0;
  246. if (!name || !strlen(name)) {
  247. dev_err(dev, "Attempt to register with no name!\n");
  248. return -EINVAL;
  249. }
  250. bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
  251. if (!bridge)
  252. return -ENOMEM;
  253. id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL);
  254. if (id < 0) {
  255. ret = id;
  256. goto error_kfree;
  257. }
  258. mutex_init(&bridge->mutex);
  259. INIT_LIST_HEAD(&bridge->node);
  260. bridge->name = name;
  261. bridge->br_ops = br_ops;
  262. bridge->priv = priv;
  263. device_initialize(&bridge->dev);
  264. bridge->dev.class = fpga_bridge_class;
  265. bridge->dev.parent = dev;
  266. bridge->dev.of_node = dev->of_node;
  267. bridge->dev.id = id;
  268. dev_set_drvdata(dev, bridge);
  269. ret = dev_set_name(&bridge->dev, "br%d", id);
  270. if (ret)
  271. goto error_device;
  272. ret = device_add(&bridge->dev);
  273. if (ret)
  274. goto error_device;
  275. of_platform_populate(dev->of_node, NULL, NULL, dev);
  276. dev_info(bridge->dev.parent, "fpga bridge [%s] registered\n",
  277. bridge->name);
  278. return 0;
  279. error_device:
  280. ida_simple_remove(&fpga_bridge_ida, id);
  281. error_kfree:
  282. kfree(bridge);
  283. return ret;
  284. }
  285. EXPORT_SYMBOL_GPL(fpga_bridge_register);
  286. /**
  287. * fpga_bridge_unregister - unregister a fpga bridge driver
  288. * @dev: FPGA bridge device from pdev
  289. */
  290. void fpga_bridge_unregister(struct device *dev)
  291. {
  292. struct fpga_bridge *bridge = dev_get_drvdata(dev);
  293. /*
  294. * If the low level driver provides a method for putting bridge into
  295. * a desired state upon unregister, do it.
  296. */
  297. if (bridge->br_ops && bridge->br_ops->fpga_bridge_remove)
  298. bridge->br_ops->fpga_bridge_remove(bridge);
  299. device_unregister(&bridge->dev);
  300. }
  301. EXPORT_SYMBOL_GPL(fpga_bridge_unregister);
  302. static void fpga_bridge_dev_release(struct device *dev)
  303. {
  304. struct fpga_bridge *bridge = to_fpga_bridge(dev);
  305. ida_simple_remove(&fpga_bridge_ida, bridge->dev.id);
  306. kfree(bridge);
  307. }
  308. static int __init fpga_bridge_dev_init(void)
  309. {
  310. spin_lock_init(&bridge_list_lock);
  311. fpga_bridge_class = class_create(THIS_MODULE, "fpga_bridge");
  312. if (IS_ERR(fpga_bridge_class))
  313. return PTR_ERR(fpga_bridge_class);
  314. fpga_bridge_class->dev_groups = fpga_bridge_groups;
  315. fpga_bridge_class->dev_release = fpga_bridge_dev_release;
  316. return 0;
  317. }
  318. static void __exit fpga_bridge_dev_exit(void)
  319. {
  320. class_destroy(fpga_bridge_class);
  321. ida_destroy(&fpga_bridge_ida);
  322. }
  323. MODULE_DESCRIPTION("FPGA Bridge Driver");
  324. MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
  325. MODULE_LICENSE("GPL v2");
  326. subsys_initcall(fpga_bridge_dev_init);
  327. module_exit(fpga_bridge_dev_exit);