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