PageRenderTime 60ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/fpga/fpga-bridge.c

https://github.com/gby/linux
C | 388 lines | 221 code | 67 blank | 100 comment | 23 complexity | 8c94bd6c26b10957ec4620b4f054ec38 MD5 | raw file
  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. static 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. int ret;
  128. list_for_each_entry(bridge, bridge_list, node) {
  129. ret = fpga_bridge_enable(bridge);
  130. if (ret)
  131. return ret;
  132. }
  133. return 0;
  134. }
  135. EXPORT_SYMBOL_GPL(fpga_bridges_enable);
  136. /**
  137. * fpga_bridges_disable - disable bridges in a list
  138. *
  139. * @bridge_list: list of FPGA bridges
  140. *
  141. * Disable each bridge in the list. If list is empty, do nothing.
  142. *
  143. * Return 0 for success or empty bridge list; return error code otherwise.
  144. */
  145. int fpga_bridges_disable(struct list_head *bridge_list)
  146. {
  147. struct fpga_bridge *bridge;
  148. int ret;
  149. list_for_each_entry(bridge, bridge_list, node) {
  150. ret = fpga_bridge_disable(bridge);
  151. if (ret)
  152. return ret;
  153. }
  154. return 0;
  155. }
  156. EXPORT_SYMBOL_GPL(fpga_bridges_disable);
  157. /**
  158. * fpga_bridges_put - put bridges
  159. *
  160. * @bridge_list: list of FPGA bridges
  161. *
  162. * For each bridge in the list, put the bridge and remove it from the list.
  163. * If list is empty, do nothing.
  164. */
  165. void fpga_bridges_put(struct list_head *bridge_list)
  166. {
  167. struct fpga_bridge *bridge, *next;
  168. unsigned long flags;
  169. list_for_each_entry_safe(bridge, next, bridge_list, node) {
  170. fpga_bridge_put(bridge);
  171. spin_lock_irqsave(&bridge_list_lock, flags);
  172. list_del(&bridge->node);
  173. spin_unlock_irqrestore(&bridge_list_lock, flags);
  174. }
  175. }
  176. EXPORT_SYMBOL_GPL(fpga_bridges_put);
  177. /**
  178. * fpga_bridges_get_to_list - get a bridge, add it to a list
  179. *
  180. * @np: node pointer of a FPGA bridge
  181. * @info: fpga image specific information
  182. * @bridge_list: list of FPGA bridges
  183. *
  184. * Get an exclusive reference to the bridge and and it to the list.
  185. *
  186. * Return 0 for success, error code from of_fpga_bridge_get() othewise.
  187. */
  188. int fpga_bridge_get_to_list(struct device_node *np,
  189. struct fpga_image_info *info,
  190. struct list_head *bridge_list)
  191. {
  192. struct fpga_bridge *bridge;
  193. unsigned long flags;
  194. bridge = of_fpga_bridge_get(np, info);
  195. if (IS_ERR(bridge))
  196. return PTR_ERR(bridge);
  197. spin_lock_irqsave(&bridge_list_lock, flags);
  198. list_add(&bridge->node, bridge_list);
  199. spin_unlock_irqrestore(&bridge_list_lock, flags);
  200. return 0;
  201. }
  202. EXPORT_SYMBOL_GPL(fpga_bridge_get_to_list);
  203. static ssize_t name_show(struct device *dev,
  204. struct device_attribute *attr, char *buf)
  205. {
  206. struct fpga_bridge *bridge = to_fpga_bridge(dev);
  207. return sprintf(buf, "%s\n", bridge->name);
  208. }
  209. static ssize_t state_show(struct device *dev,
  210. struct device_attribute *attr, char *buf)
  211. {
  212. struct fpga_bridge *bridge = to_fpga_bridge(dev);
  213. int enable = 1;
  214. if (bridge->br_ops && bridge->br_ops->enable_show)
  215. enable = bridge->br_ops->enable_show(bridge);
  216. return sprintf(buf, "%s\n", enable ? "enabled" : "disabled");
  217. }
  218. static DEVICE_ATTR_RO(name);
  219. static DEVICE_ATTR_RO(state);
  220. static struct attribute *fpga_bridge_attrs[] = {
  221. &dev_attr_name.attr,
  222. &dev_attr_state.attr,
  223. NULL,
  224. };
  225. ATTRIBUTE_GROUPS(fpga_bridge);
  226. /**
  227. * fpga_bridge_register - register a fpga bridge driver
  228. * @dev: FPGA bridge device from pdev
  229. * @name: FPGA bridge name
  230. * @br_ops: pointer to structure of fpga bridge ops
  231. * @priv: FPGA bridge private data
  232. *
  233. * Return: 0 for success, error code otherwise.
  234. */
  235. int fpga_bridge_register(struct device *dev, const char *name,
  236. const struct fpga_bridge_ops *br_ops, void *priv)
  237. {
  238. struct fpga_bridge *bridge;
  239. int id, ret = 0;
  240. if (!name || !strlen(name)) {
  241. dev_err(dev, "Attempt to register with no name!\n");
  242. return -EINVAL;
  243. }
  244. bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
  245. if (!bridge)
  246. return -ENOMEM;
  247. id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL);
  248. if (id < 0) {
  249. ret = id;
  250. goto error_kfree;
  251. }
  252. mutex_init(&bridge->mutex);
  253. INIT_LIST_HEAD(&bridge->node);
  254. bridge->name = name;
  255. bridge->br_ops = br_ops;
  256. bridge->priv = priv;
  257. device_initialize(&bridge->dev);
  258. bridge->dev.class = fpga_bridge_class;
  259. bridge->dev.parent = dev;
  260. bridge->dev.of_node = dev->of_node;
  261. bridge->dev.id = id;
  262. dev_set_drvdata(dev, bridge);
  263. ret = dev_set_name(&bridge->dev, "br%d", id);
  264. if (ret)
  265. goto error_device;
  266. ret = device_add(&bridge->dev);
  267. if (ret)
  268. goto error_device;
  269. of_platform_populate(dev->of_node, NULL, NULL, dev);
  270. dev_info(bridge->dev.parent, "fpga bridge [%s] registered\n",
  271. bridge->name);
  272. return 0;
  273. error_device:
  274. ida_simple_remove(&fpga_bridge_ida, id);
  275. error_kfree:
  276. kfree(bridge);
  277. return ret;
  278. }
  279. EXPORT_SYMBOL_GPL(fpga_bridge_register);
  280. /**
  281. * fpga_bridge_unregister - unregister a fpga bridge driver
  282. * @dev: FPGA bridge device from pdev
  283. */
  284. void fpga_bridge_unregister(struct device *dev)
  285. {
  286. struct fpga_bridge *bridge = dev_get_drvdata(dev);
  287. /*
  288. * If the low level driver provides a method for putting bridge into
  289. * a desired state upon unregister, do it.
  290. */
  291. if (bridge->br_ops && bridge->br_ops->fpga_bridge_remove)
  292. bridge->br_ops->fpga_bridge_remove(bridge);
  293. device_unregister(&bridge->dev);
  294. }
  295. EXPORT_SYMBOL_GPL(fpga_bridge_unregister);
  296. static void fpga_bridge_dev_release(struct device *dev)
  297. {
  298. struct fpga_bridge *bridge = to_fpga_bridge(dev);
  299. ida_simple_remove(&fpga_bridge_ida, bridge->dev.id);
  300. kfree(bridge);
  301. }
  302. static int __init fpga_bridge_dev_init(void)
  303. {
  304. spin_lock_init(&bridge_list_lock);
  305. fpga_bridge_class = class_create(THIS_MODULE, "fpga_bridge");
  306. if (IS_ERR(fpga_bridge_class))
  307. return PTR_ERR(fpga_bridge_class);
  308. fpga_bridge_class->dev_groups = fpga_bridge_groups;
  309. fpga_bridge_class->dev_release = fpga_bridge_dev_release;
  310. return 0;
  311. }
  312. static void __exit fpga_bridge_dev_exit(void)
  313. {
  314. class_destroy(fpga_bridge_class);
  315. ida_destroy(&fpga_bridge_ida);
  316. }
  317. MODULE_DESCRIPTION("FPGA Bridge Driver");
  318. MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
  319. MODULE_LICENSE("GPL v2");
  320. subsys_initcall(fpga_bridge_dev_init);
  321. module_exit(fpga_bridge_dev_exit);