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