xref: /openbmc/linux/drivers/fpga/fpga-bridge.c (revision 4f6cce39)
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 
26 static DEFINE_IDA(fpga_bridge_ida);
27 static struct class *fpga_bridge_class;
28 
29 /* Lock for adding/removing bridges to linked lists*/
30 spinlock_t bridge_list_lock;
31 
32 static int fpga_bridge_of_node_match(struct device *dev, const void *data)
33 {
34 	return dev->of_node == data;
35 }
36 
37 /**
38  * fpga_bridge_enable - Enable transactions on the bridge
39  *
40  * @bridge: FPGA bridge
41  *
42  * Return: 0 for success, error code otherwise.
43  */
44 int fpga_bridge_enable(struct fpga_bridge *bridge)
45 {
46 	dev_dbg(&bridge->dev, "enable\n");
47 
48 	if (bridge->br_ops && bridge->br_ops->enable_set)
49 		return bridge->br_ops->enable_set(bridge, 1);
50 
51 	return 0;
52 }
53 EXPORT_SYMBOL_GPL(fpga_bridge_enable);
54 
55 /**
56  * fpga_bridge_disable - Disable transactions on the bridge
57  *
58  * @bridge: FPGA bridge
59  *
60  * Return: 0 for success, error code otherwise.
61  */
62 int fpga_bridge_disable(struct fpga_bridge *bridge)
63 {
64 	dev_dbg(&bridge->dev, "disable\n");
65 
66 	if (bridge->br_ops && bridge->br_ops->enable_set)
67 		return bridge->br_ops->enable_set(bridge, 0);
68 
69 	return 0;
70 }
71 EXPORT_SYMBOL_GPL(fpga_bridge_disable);
72 
73 /**
74  * of_fpga_bridge_get - get an exclusive reference to a fpga bridge
75  *
76  * @np: node pointer of a FPGA bridge
77  * @info: fpga image specific information
78  *
79  * Return fpga_bridge struct if successful.
80  * Return -EBUSY if someone already has a reference to the bridge.
81  * Return -ENODEV if @np is not a FPGA Bridge.
82  */
83 struct fpga_bridge *of_fpga_bridge_get(struct device_node *np,
84 				       struct fpga_image_info *info)
85 
86 {
87 	struct device *dev;
88 	struct fpga_bridge *bridge;
89 	int ret = -ENODEV;
90 
91 	dev = class_find_device(fpga_bridge_class, NULL, np,
92 				fpga_bridge_of_node_match);
93 	if (!dev)
94 		goto err_dev;
95 
96 	bridge = to_fpga_bridge(dev);
97 	if (!bridge)
98 		goto err_dev;
99 
100 	bridge->info = info;
101 
102 	if (!mutex_trylock(&bridge->mutex)) {
103 		ret = -EBUSY;
104 		goto err_dev;
105 	}
106 
107 	if (!try_module_get(dev->parent->driver->owner))
108 		goto err_ll_mod;
109 
110 	dev_dbg(&bridge->dev, "get\n");
111 
112 	return bridge;
113 
114 err_ll_mod:
115 	mutex_unlock(&bridge->mutex);
116 err_dev:
117 	put_device(dev);
118 	return ERR_PTR(ret);
119 }
120 EXPORT_SYMBOL_GPL(of_fpga_bridge_get);
121 
122 /**
123  * fpga_bridge_put - release a reference to a bridge
124  *
125  * @bridge: FPGA bridge
126  */
127 void fpga_bridge_put(struct fpga_bridge *bridge)
128 {
129 	dev_dbg(&bridge->dev, "put\n");
130 
131 	bridge->info = NULL;
132 	module_put(bridge->dev.parent->driver->owner);
133 	mutex_unlock(&bridge->mutex);
134 	put_device(&bridge->dev);
135 }
136 EXPORT_SYMBOL_GPL(fpga_bridge_put);
137 
138 /**
139  * fpga_bridges_enable - enable bridges in a list
140  * @bridge_list: list of FPGA bridges
141  *
142  * Enable each bridge in the list.  If list is empty, do nothing.
143  *
144  * Return 0 for success or empty bridge list; return error code otherwise.
145  */
146 int fpga_bridges_enable(struct list_head *bridge_list)
147 {
148 	struct fpga_bridge *bridge;
149 	struct list_head *node;
150 	int ret;
151 
152 	list_for_each(node, bridge_list) {
153 		bridge = list_entry(node, struct fpga_bridge, node);
154 		ret = fpga_bridge_enable(bridge);
155 		if (ret)
156 			return ret;
157 	}
158 
159 	return 0;
160 }
161 EXPORT_SYMBOL_GPL(fpga_bridges_enable);
162 
163 /**
164  * fpga_bridges_disable - disable bridges in a list
165  *
166  * @bridge_list: list of FPGA bridges
167  *
168  * Disable each bridge in the list.  If list is empty, do nothing.
169  *
170  * Return 0 for success or empty bridge list; return error code otherwise.
171  */
172 int fpga_bridges_disable(struct list_head *bridge_list)
173 {
174 	struct fpga_bridge *bridge;
175 	struct list_head *node;
176 	int ret;
177 
178 	list_for_each(node, bridge_list) {
179 		bridge = list_entry(node, struct fpga_bridge, node);
180 		ret = fpga_bridge_disable(bridge);
181 		if (ret)
182 			return ret;
183 	}
184 
185 	return 0;
186 }
187 EXPORT_SYMBOL_GPL(fpga_bridges_disable);
188 
189 /**
190  * fpga_bridges_put - put bridges
191  *
192  * @bridge_list: list of FPGA bridges
193  *
194  * For each bridge in the list, put the bridge and remove it from the list.
195  * If list is empty, do nothing.
196  */
197 void fpga_bridges_put(struct list_head *bridge_list)
198 {
199 	struct fpga_bridge *bridge;
200 	struct list_head *node, *next;
201 	unsigned long flags;
202 
203 	list_for_each_safe(node, next, bridge_list) {
204 		bridge = list_entry(node, struct fpga_bridge, node);
205 
206 		fpga_bridge_put(bridge);
207 
208 		spin_lock_irqsave(&bridge_list_lock, flags);
209 		list_del(&bridge->node);
210 		spin_unlock_irqrestore(&bridge_list_lock, flags);
211 	}
212 }
213 EXPORT_SYMBOL_GPL(fpga_bridges_put);
214 
215 /**
216  * fpga_bridges_get_to_list - get a bridge, add it to a list
217  *
218  * @np: node pointer of a FPGA bridge
219  * @info: fpga image specific information
220  * @bridge_list: list of FPGA bridges
221  *
222  * Get an exclusive reference to the bridge and and it to the list.
223  *
224  * Return 0 for success, error code from of_fpga_bridge_get() othewise.
225  */
226 int fpga_bridge_get_to_list(struct device_node *np,
227 			    struct fpga_image_info *info,
228 			    struct list_head *bridge_list)
229 {
230 	struct fpga_bridge *bridge;
231 	unsigned long flags;
232 
233 	bridge = of_fpga_bridge_get(np, info);
234 	if (IS_ERR(bridge))
235 		return PTR_ERR(bridge);
236 
237 	spin_lock_irqsave(&bridge_list_lock, flags);
238 	list_add(&bridge->node, bridge_list);
239 	spin_unlock_irqrestore(&bridge_list_lock, flags);
240 
241 	return 0;
242 }
243 EXPORT_SYMBOL_GPL(fpga_bridge_get_to_list);
244 
245 static ssize_t name_show(struct device *dev,
246 			 struct device_attribute *attr, char *buf)
247 {
248 	struct fpga_bridge *bridge = to_fpga_bridge(dev);
249 
250 	return sprintf(buf, "%s\n", bridge->name);
251 }
252 
253 static ssize_t state_show(struct device *dev,
254 			  struct device_attribute *attr, char *buf)
255 {
256 	struct fpga_bridge *bridge = to_fpga_bridge(dev);
257 	int enable = 1;
258 
259 	if (bridge->br_ops && bridge->br_ops->enable_show)
260 		enable = bridge->br_ops->enable_show(bridge);
261 
262 	return sprintf(buf, "%s\n", enable ? "enabled" : "disabled");
263 }
264 
265 static DEVICE_ATTR_RO(name);
266 static DEVICE_ATTR_RO(state);
267 
268 static struct attribute *fpga_bridge_attrs[] = {
269 	&dev_attr_name.attr,
270 	&dev_attr_state.attr,
271 	NULL,
272 };
273 ATTRIBUTE_GROUPS(fpga_bridge);
274 
275 /**
276  * fpga_bridge_register - register a fpga bridge driver
277  * @dev:	FPGA bridge device from pdev
278  * @name:	FPGA bridge name
279  * @br_ops:	pointer to structure of fpga bridge ops
280  * @priv:	FPGA bridge private data
281  *
282  * Return: 0 for success, error code otherwise.
283  */
284 int fpga_bridge_register(struct device *dev, const char *name,
285 			 const struct fpga_bridge_ops *br_ops, void *priv)
286 {
287 	struct fpga_bridge *bridge;
288 	int id, ret = 0;
289 
290 	if (!name || !strlen(name)) {
291 		dev_err(dev, "Attempt to register with no name!\n");
292 		return -EINVAL;
293 	}
294 
295 	bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
296 	if (!bridge)
297 		return -ENOMEM;
298 
299 	id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL);
300 	if (id < 0) {
301 		ret = id;
302 		goto error_kfree;
303 	}
304 
305 	mutex_init(&bridge->mutex);
306 	INIT_LIST_HEAD(&bridge->node);
307 
308 	bridge->name = name;
309 	bridge->br_ops = br_ops;
310 	bridge->priv = priv;
311 
312 	device_initialize(&bridge->dev);
313 	bridge->dev.class = fpga_bridge_class;
314 	bridge->dev.parent = dev;
315 	bridge->dev.of_node = dev->of_node;
316 	bridge->dev.id = id;
317 	dev_set_drvdata(dev, bridge);
318 
319 	ret = dev_set_name(&bridge->dev, "br%d", id);
320 	if (ret)
321 		goto error_device;
322 
323 	ret = device_add(&bridge->dev);
324 	if (ret)
325 		goto error_device;
326 
327 	of_platform_populate(dev->of_node, NULL, NULL, dev);
328 
329 	dev_info(bridge->dev.parent, "fpga bridge [%s] registered\n",
330 		 bridge->name);
331 
332 	return 0;
333 
334 error_device:
335 	ida_simple_remove(&fpga_bridge_ida, id);
336 error_kfree:
337 	kfree(bridge);
338 
339 	return ret;
340 }
341 EXPORT_SYMBOL_GPL(fpga_bridge_register);
342 
343 /**
344  * fpga_bridge_unregister - unregister a fpga bridge driver
345  * @dev: FPGA bridge device from pdev
346  */
347 void fpga_bridge_unregister(struct device *dev)
348 {
349 	struct fpga_bridge *bridge = dev_get_drvdata(dev);
350 
351 	/*
352 	 * If the low level driver provides a method for putting bridge into
353 	 * a desired state upon unregister, do it.
354 	 */
355 	if (bridge->br_ops && bridge->br_ops->fpga_bridge_remove)
356 		bridge->br_ops->fpga_bridge_remove(bridge);
357 
358 	device_unregister(&bridge->dev);
359 }
360 EXPORT_SYMBOL_GPL(fpga_bridge_unregister);
361 
362 static void fpga_bridge_dev_release(struct device *dev)
363 {
364 	struct fpga_bridge *bridge = to_fpga_bridge(dev);
365 
366 	ida_simple_remove(&fpga_bridge_ida, bridge->dev.id);
367 	kfree(bridge);
368 }
369 
370 static int __init fpga_bridge_dev_init(void)
371 {
372 	spin_lock_init(&bridge_list_lock);
373 
374 	fpga_bridge_class = class_create(THIS_MODULE, "fpga_bridge");
375 	if (IS_ERR(fpga_bridge_class))
376 		return PTR_ERR(fpga_bridge_class);
377 
378 	fpga_bridge_class->dev_groups = fpga_bridge_groups;
379 	fpga_bridge_class->dev_release = fpga_bridge_dev_release;
380 
381 	return 0;
382 }
383 
384 static void __exit fpga_bridge_dev_exit(void)
385 {
386 	class_destroy(fpga_bridge_class);
387 	ida_destroy(&fpga_bridge_ida);
388 }
389 
390 MODULE_DESCRIPTION("FPGA Bridge Driver");
391 MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
392 MODULE_LICENSE("GPL v2");
393 
394 subsys_initcall(fpga_bridge_dev_init);
395 module_exit(fpga_bridge_dev_exit);
396