]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/fpga/fpga-bridge.c
Merge tag 'for-linus-4.11-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git...
[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 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);