xref: /OK3568_Linux_fs/kernel/drivers/fpga/fpga-bridge.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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