]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/fpga/fpga-bridge.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[karo-tx-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  *
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 static 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         int ret;
150
151         list_for_each_entry(bridge, bridge_list, node) {
152                 ret = fpga_bridge_enable(bridge);
153                 if (ret)
154                         return ret;
155         }
156
157         return 0;
158 }
159 EXPORT_SYMBOL_GPL(fpga_bridges_enable);
160
161 /**
162  * fpga_bridges_disable - disable bridges in a list
163  *
164  * @bridge_list: list of FPGA bridges
165  *
166  * Disable each bridge in the list.  If list is empty, do nothing.
167  *
168  * Return 0 for success or empty bridge list; return error code otherwise.
169  */
170 int fpga_bridges_disable(struct list_head *bridge_list)
171 {
172         struct fpga_bridge *bridge;
173         int ret;
174
175         list_for_each_entry(bridge, bridge_list, node) {
176                 ret = fpga_bridge_disable(bridge);
177                 if (ret)
178                         return ret;
179         }
180
181         return 0;
182 }
183 EXPORT_SYMBOL_GPL(fpga_bridges_disable);
184
185 /**
186  * fpga_bridges_put - put bridges
187  *
188  * @bridge_list: list of FPGA bridges
189  *
190  * For each bridge in the list, put the bridge and remove it from the list.
191  * If list is empty, do nothing.
192  */
193 void fpga_bridges_put(struct list_head *bridge_list)
194 {
195         struct fpga_bridge *bridge, *next;
196         unsigned long flags;
197
198         list_for_each_entry_safe(bridge, next, bridge_list, node) {
199                 fpga_bridge_put(bridge);
200
201                 spin_lock_irqsave(&bridge_list_lock, flags);
202                 list_del(&bridge->node);
203                 spin_unlock_irqrestore(&bridge_list_lock, flags);
204         }
205 }
206 EXPORT_SYMBOL_GPL(fpga_bridges_put);
207
208 /**
209  * fpga_bridges_get_to_list - get a bridge, add it to a list
210  *
211  * @np: node pointer of a FPGA bridge
212  * @info: fpga image specific information
213  * @bridge_list: list of FPGA bridges
214  *
215  * Get an exclusive reference to the bridge and and it to the list.
216  *
217  * Return 0 for success, error code from of_fpga_bridge_get() othewise.
218  */
219 int fpga_bridge_get_to_list(struct device_node *np,
220                             struct fpga_image_info *info,
221                             struct list_head *bridge_list)
222 {
223         struct fpga_bridge *bridge;
224         unsigned long flags;
225
226         bridge = of_fpga_bridge_get(np, info);
227         if (IS_ERR(bridge))
228                 return PTR_ERR(bridge);
229
230         spin_lock_irqsave(&bridge_list_lock, flags);
231         list_add(&bridge->node, bridge_list);
232         spin_unlock_irqrestore(&bridge_list_lock, flags);
233
234         return 0;
235 }
236 EXPORT_SYMBOL_GPL(fpga_bridge_get_to_list);
237
238 static ssize_t name_show(struct device *dev,
239                          struct device_attribute *attr, char *buf)
240 {
241         struct fpga_bridge *bridge = to_fpga_bridge(dev);
242
243         return sprintf(buf, "%s\n", bridge->name);
244 }
245
246 static ssize_t state_show(struct device *dev,
247                           struct device_attribute *attr, char *buf)
248 {
249         struct fpga_bridge *bridge = to_fpga_bridge(dev);
250         int enable = 1;
251
252         if (bridge->br_ops && bridge->br_ops->enable_show)
253                 enable = bridge->br_ops->enable_show(bridge);
254
255         return sprintf(buf, "%s\n", enable ? "enabled" : "disabled");
256 }
257
258 static DEVICE_ATTR_RO(name);
259 static DEVICE_ATTR_RO(state);
260
261 static struct attribute *fpga_bridge_attrs[] = {
262         &dev_attr_name.attr,
263         &dev_attr_state.attr,
264         NULL,
265 };
266 ATTRIBUTE_GROUPS(fpga_bridge);
267
268 /**
269  * fpga_bridge_register - register a fpga bridge driver
270  * @dev:        FPGA bridge device from pdev
271  * @name:       FPGA bridge name
272  * @br_ops:     pointer to structure of fpga bridge ops
273  * @priv:       FPGA bridge private data
274  *
275  * Return: 0 for success, error code otherwise.
276  */
277 int fpga_bridge_register(struct device *dev, const char *name,
278                          const struct fpga_bridge_ops *br_ops, void *priv)
279 {
280         struct fpga_bridge *bridge;
281         int id, ret = 0;
282
283         if (!name || !strlen(name)) {
284                 dev_err(dev, "Attempt to register with no name!\n");
285                 return -EINVAL;
286         }
287
288         bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
289         if (!bridge)
290                 return -ENOMEM;
291
292         id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL);
293         if (id < 0) {
294                 ret = id;
295                 goto error_kfree;
296         }
297
298         mutex_init(&bridge->mutex);
299         INIT_LIST_HEAD(&bridge->node);
300
301         bridge->name = name;
302         bridge->br_ops = br_ops;
303         bridge->priv = priv;
304
305         device_initialize(&bridge->dev);
306         bridge->dev.class = fpga_bridge_class;
307         bridge->dev.parent = dev;
308         bridge->dev.of_node = dev->of_node;
309         bridge->dev.id = id;
310         dev_set_drvdata(dev, bridge);
311
312         ret = dev_set_name(&bridge->dev, "br%d", id);
313         if (ret)
314                 goto error_device;
315
316         ret = device_add(&bridge->dev);
317         if (ret)
318                 goto error_device;
319
320         of_platform_populate(dev->of_node, NULL, NULL, dev);
321
322         dev_info(bridge->dev.parent, "fpga bridge [%s] registered\n",
323                  bridge->name);
324
325         return 0;
326
327 error_device:
328         ida_simple_remove(&fpga_bridge_ida, id);
329 error_kfree:
330         kfree(bridge);
331
332         return ret;
333 }
334 EXPORT_SYMBOL_GPL(fpga_bridge_register);
335
336 /**
337  * fpga_bridge_unregister - unregister a fpga bridge driver
338  * @dev: FPGA bridge device from pdev
339  */
340 void fpga_bridge_unregister(struct device *dev)
341 {
342         struct fpga_bridge *bridge = dev_get_drvdata(dev);
343
344         /*
345          * If the low level driver provides a method for putting bridge into
346          * a desired state upon unregister, do it.
347          */
348         if (bridge->br_ops && bridge->br_ops->fpga_bridge_remove)
349                 bridge->br_ops->fpga_bridge_remove(bridge);
350
351         device_unregister(&bridge->dev);
352 }
353 EXPORT_SYMBOL_GPL(fpga_bridge_unregister);
354
355 static void fpga_bridge_dev_release(struct device *dev)
356 {
357         struct fpga_bridge *bridge = to_fpga_bridge(dev);
358
359         ida_simple_remove(&fpga_bridge_ida, bridge->dev.id);
360         kfree(bridge);
361 }
362
363 static int __init fpga_bridge_dev_init(void)
364 {
365         spin_lock_init(&bridge_list_lock);
366
367         fpga_bridge_class = class_create(THIS_MODULE, "fpga_bridge");
368         if (IS_ERR(fpga_bridge_class))
369                 return PTR_ERR(fpga_bridge_class);
370
371         fpga_bridge_class->dev_groups = fpga_bridge_groups;
372         fpga_bridge_class->dev_release = fpga_bridge_dev_release;
373
374         return 0;
375 }
376
377 static void __exit fpga_bridge_dev_exit(void)
378 {
379         class_destroy(fpga_bridge_class);
380         ida_destroy(&fpga_bridge_ida);
381 }
382
383 MODULE_DESCRIPTION("FPGA Bridge Driver");
384 MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
385 MODULE_LICENSE("GPL v2");
386
387 subsys_initcall(fpga_bridge_dev_init);
388 module_exit(fpga_bridge_dev_exit);