xref: /linux/drivers/pci/endpoint/pci-ep-cfs.c (revision 8754dd7639ab0fd68c3ab9d91c7bdecc3e5740a8)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * configfs to configure the PCI endpoint
4  *
5  * Copyright (C) 2017 Texas Instruments
6  * Author: Kishon Vijay Abraham I <kishon@ti.com>
7  */
8 
9 #include <linux/module.h>
10 #include <linux/idr.h>
11 #include <linux/slab.h>
12 
13 #include <linux/pci-epc.h>
14 #include <linux/pci-epf.h>
15 #include <linux/pci-ep-cfs.h>
16 
17 static DEFINE_IDR(functions_idr);
18 static DEFINE_MUTEX(functions_mutex);
19 static struct config_group *functions_group;
20 static struct config_group *controllers_group;
21 
22 struct pci_epf_group {
23 	struct config_group group;
24 	struct config_group primary_epc_group;
25 	struct config_group secondary_epc_group;
26 	struct pci_epf *epf;
27 	int index;
28 };
29 
30 struct pci_epc_group {
31 	struct config_group group;
32 	struct pci_epc *epc;
33 	bool start;
34 };
35 
36 static inline struct pci_epf_group *to_pci_epf_group(struct config_item *item)
37 {
38 	return container_of(to_config_group(item), struct pci_epf_group, group);
39 }
40 
41 static inline struct pci_epc_group *to_pci_epc_group(struct config_item *item)
42 {
43 	return container_of(to_config_group(item), struct pci_epc_group, group);
44 }
45 
46 static int pci_secondary_epc_epf_link(struct config_item *epf_item,
47 				      struct config_item *epc_item)
48 {
49 	int ret;
50 	struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
51 	struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
52 	struct pci_epc *epc = epc_group->epc;
53 	struct pci_epf *epf = epf_group->epf;
54 
55 	ret = pci_epc_add_epf(epc, epf, SECONDARY_INTERFACE);
56 	if (ret)
57 		return ret;
58 
59 	ret = pci_epf_bind(epf);
60 	if (ret) {
61 		pci_epc_remove_epf(epc, epf, SECONDARY_INTERFACE);
62 		return ret;
63 	}
64 
65 	/* Send any pending EPC initialization complete to the EPF driver */
66 	pci_epc_notify_pending_init(epc, epf);
67 
68 	return 0;
69 }
70 
71 static void pci_secondary_epc_epf_unlink(struct config_item *epf_item,
72 					 struct config_item *epc_item)
73 {
74 	struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
75 	struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
76 	struct pci_epc *epc;
77 	struct pci_epf *epf;
78 
79 	WARN_ON_ONCE(epc_group->start);
80 
81 	epc = epc_group->epc;
82 	epf = epf_group->epf;
83 	pci_epf_unbind(epf);
84 	pci_epc_remove_epf(epc, epf, SECONDARY_INTERFACE);
85 }
86 
87 static struct configfs_item_operations pci_secondary_epc_item_ops = {
88 	.allow_link	= pci_secondary_epc_epf_link,
89 	.drop_link	= pci_secondary_epc_epf_unlink,
90 };
91 
92 static const struct config_item_type pci_secondary_epc_type = {
93 	.ct_item_ops	= &pci_secondary_epc_item_ops,
94 	.ct_owner	= THIS_MODULE,
95 };
96 
97 static struct config_group
98 *pci_ep_cfs_add_secondary_group(struct pci_epf_group *epf_group)
99 {
100 	struct config_group *secondary_epc_group;
101 
102 	secondary_epc_group = &epf_group->secondary_epc_group;
103 	config_group_init_type_name(secondary_epc_group, "secondary",
104 				    &pci_secondary_epc_type);
105 	configfs_add_default_group(secondary_epc_group, &epf_group->group);
106 
107 	return secondary_epc_group;
108 }
109 
110 static int pci_primary_epc_epf_link(struct config_item *epf_item,
111 				    struct config_item *epc_item)
112 {
113 	int ret;
114 	struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
115 	struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
116 	struct pci_epc *epc = epc_group->epc;
117 	struct pci_epf *epf = epf_group->epf;
118 
119 	ret = pci_epc_add_epf(epc, epf, PRIMARY_INTERFACE);
120 	if (ret)
121 		return ret;
122 
123 	ret = pci_epf_bind(epf);
124 	if (ret) {
125 		pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
126 		return ret;
127 	}
128 
129 	/* Send any pending EPC initialization complete to the EPF driver */
130 	pci_epc_notify_pending_init(epc, epf);
131 
132 	return 0;
133 }
134 
135 static void pci_primary_epc_epf_unlink(struct config_item *epf_item,
136 				       struct config_item *epc_item)
137 {
138 	struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
139 	struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
140 	struct pci_epc *epc;
141 	struct pci_epf *epf;
142 
143 	WARN_ON_ONCE(epc_group->start);
144 
145 	epc = epc_group->epc;
146 	epf = epf_group->epf;
147 	pci_epf_unbind(epf);
148 	pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
149 }
150 
151 static struct configfs_item_operations pci_primary_epc_item_ops = {
152 	.allow_link	= pci_primary_epc_epf_link,
153 	.drop_link	= pci_primary_epc_epf_unlink,
154 };
155 
156 static const struct config_item_type pci_primary_epc_type = {
157 	.ct_item_ops	= &pci_primary_epc_item_ops,
158 	.ct_owner	= THIS_MODULE,
159 };
160 
161 static struct config_group
162 *pci_ep_cfs_add_primary_group(struct pci_epf_group *epf_group)
163 {
164 	struct config_group *primary_epc_group = &epf_group->primary_epc_group;
165 
166 	config_group_init_type_name(primary_epc_group, "primary",
167 				    &pci_primary_epc_type);
168 	configfs_add_default_group(primary_epc_group, &epf_group->group);
169 
170 	return primary_epc_group;
171 }
172 
173 static ssize_t pci_epc_start_store(struct config_item *item, const char *page,
174 				   size_t len)
175 {
176 	int ret;
177 	bool start;
178 	struct pci_epc *epc;
179 	struct pci_epc_group *epc_group = to_pci_epc_group(item);
180 
181 	epc = epc_group->epc;
182 
183 	if (kstrtobool(page, &start) < 0)
184 		return -EINVAL;
185 
186 	if (start == epc_group->start)
187 		return -EALREADY;
188 
189 	if (!start) {
190 		pci_epc_stop(epc);
191 		epc_group->start = 0;
192 		return len;
193 	}
194 
195 	ret = pci_epc_start(epc);
196 	if (ret) {
197 		dev_err(&epc->dev, "failed to start endpoint controller\n");
198 		return -EINVAL;
199 	}
200 
201 	epc_group->start = start;
202 
203 	return len;
204 }
205 
206 static ssize_t pci_epc_start_show(struct config_item *item, char *page)
207 {
208 	return sysfs_emit(page, "%d\n", to_pci_epc_group(item)->start);
209 }
210 
211 CONFIGFS_ATTR(pci_epc_, start);
212 
213 static struct configfs_attribute *pci_epc_attrs[] = {
214 	&pci_epc_attr_start,
215 	NULL,
216 };
217 
218 static int pci_epc_epf_link(struct config_item *epc_item,
219 			    struct config_item *epf_item)
220 {
221 	int ret;
222 	struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
223 	struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
224 	struct pci_epc *epc = epc_group->epc;
225 	struct pci_epf *epf = epf_group->epf;
226 
227 	ret = pci_epc_add_epf(epc, epf, PRIMARY_INTERFACE);
228 	if (ret)
229 		return ret;
230 
231 	ret = pci_epf_bind(epf);
232 	if (ret) {
233 		pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
234 		return ret;
235 	}
236 
237 	/* Send any pending EPC initialization complete to the EPF driver */
238 	pci_epc_notify_pending_init(epc, epf);
239 
240 	return 0;
241 }
242 
243 static void pci_epc_epf_unlink(struct config_item *epc_item,
244 			       struct config_item *epf_item)
245 {
246 	struct pci_epc *epc;
247 	struct pci_epf *epf;
248 	struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
249 	struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
250 
251 	WARN_ON_ONCE(epc_group->start);
252 
253 	epc = epc_group->epc;
254 	epf = epf_group->epf;
255 	pci_epf_unbind(epf);
256 	pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
257 }
258 
259 static struct configfs_item_operations pci_epc_item_ops = {
260 	.allow_link	= pci_epc_epf_link,
261 	.drop_link	= pci_epc_epf_unlink,
262 };
263 
264 static const struct config_item_type pci_epc_type = {
265 	.ct_item_ops	= &pci_epc_item_ops,
266 	.ct_attrs	= pci_epc_attrs,
267 	.ct_owner	= THIS_MODULE,
268 };
269 
270 struct config_group *pci_ep_cfs_add_epc_group(const char *name)
271 {
272 	int ret;
273 	struct pci_epc *epc;
274 	struct config_group *group;
275 	struct pci_epc_group *epc_group;
276 
277 	epc_group = kzalloc(sizeof(*epc_group), GFP_KERNEL);
278 	if (!epc_group) {
279 		ret = -ENOMEM;
280 		goto err;
281 	}
282 
283 	group = &epc_group->group;
284 
285 	config_group_init_type_name(group, name, &pci_epc_type);
286 	ret = configfs_register_group(controllers_group, group);
287 	if (ret) {
288 		pr_err("failed to register configfs group for %s\n", name);
289 		goto err_register_group;
290 	}
291 
292 	epc = pci_epc_get(name);
293 	if (IS_ERR(epc)) {
294 		ret = PTR_ERR(epc);
295 		goto err_epc_get;
296 	}
297 
298 	epc_group->epc = epc;
299 
300 	return group;
301 
302 err_epc_get:
303 	configfs_unregister_group(group);
304 
305 err_register_group:
306 	kfree(epc_group);
307 
308 err:
309 	return ERR_PTR(ret);
310 }
311 EXPORT_SYMBOL(pci_ep_cfs_add_epc_group);
312 
313 void pci_ep_cfs_remove_epc_group(struct config_group *group)
314 {
315 	struct pci_epc_group *epc_group;
316 
317 	if (!group)
318 		return;
319 
320 	epc_group = container_of(group, struct pci_epc_group, group);
321 	pci_epc_put(epc_group->epc);
322 	configfs_unregister_group(&epc_group->group);
323 	kfree(epc_group);
324 }
325 EXPORT_SYMBOL(pci_ep_cfs_remove_epc_group);
326 
327 #define PCI_EPF_HEADER_R(_name)						       \
328 static ssize_t pci_epf_##_name##_show(struct config_item *item,	char *page)    \
329 {									       \
330 	struct pci_epf *epf = to_pci_epf_group(item)->epf;		       \
331 	if (WARN_ON_ONCE(!epf->header))					       \
332 		return -EINVAL;						       \
333 	return sysfs_emit(page, "0x%04x\n", epf->header->_name);	       \
334 }
335 
336 #define PCI_EPF_HEADER_W_u32(_name)					       \
337 static ssize_t pci_epf_##_name##_store(struct config_item *item,	       \
338 				       const char *page, size_t len)	       \
339 {									       \
340 	u32 val;							       \
341 	struct pci_epf *epf = to_pci_epf_group(item)->epf;		       \
342 	if (WARN_ON_ONCE(!epf->header))					       \
343 		return -EINVAL;						       \
344 	if (kstrtou32(page, 0, &val) < 0)				       \
345 		return -EINVAL;						       \
346 	epf->header->_name = val;					       \
347 	return len;							       \
348 }
349 
350 #define PCI_EPF_HEADER_W_u16(_name)					       \
351 static ssize_t pci_epf_##_name##_store(struct config_item *item,	       \
352 				       const char *page, size_t len)	       \
353 {									       \
354 	u16 val;							       \
355 	struct pci_epf *epf = to_pci_epf_group(item)->epf;		       \
356 	if (WARN_ON_ONCE(!epf->header))					       \
357 		return -EINVAL;						       \
358 	if (kstrtou16(page, 0, &val) < 0)				       \
359 		return -EINVAL;						       \
360 	epf->header->_name = val;					       \
361 	return len;							       \
362 }
363 
364 #define PCI_EPF_HEADER_W_u8(_name)					       \
365 static ssize_t pci_epf_##_name##_store(struct config_item *item,	       \
366 				       const char *page, size_t len)	       \
367 {									       \
368 	u8 val;								       \
369 	struct pci_epf *epf = to_pci_epf_group(item)->epf;		       \
370 	if (WARN_ON_ONCE(!epf->header))					       \
371 		return -EINVAL;						       \
372 	if (kstrtou8(page, 0, &val) < 0)				       \
373 		return -EINVAL;						       \
374 	epf->header->_name = val;					       \
375 	return len;							       \
376 }
377 
378 static ssize_t pci_epf_msi_interrupts_store(struct config_item *item,
379 					    const char *page, size_t len)
380 {
381 	u8 val;
382 
383 	if (kstrtou8(page, 0, &val) < 0)
384 		return -EINVAL;
385 
386 	to_pci_epf_group(item)->epf->msi_interrupts = val;
387 
388 	return len;
389 }
390 
391 static ssize_t pci_epf_msi_interrupts_show(struct config_item *item,
392 					   char *page)
393 {
394 	return sysfs_emit(page, "%d\n",
395 			  to_pci_epf_group(item)->epf->msi_interrupts);
396 }
397 
398 static ssize_t pci_epf_msix_interrupts_store(struct config_item *item,
399 					     const char *page, size_t len)
400 {
401 	u16 val;
402 
403 	if (kstrtou16(page, 0, &val) < 0)
404 		return -EINVAL;
405 
406 	to_pci_epf_group(item)->epf->msix_interrupts = val;
407 
408 	return len;
409 }
410 
411 static ssize_t pci_epf_msix_interrupts_show(struct config_item *item,
412 					    char *page)
413 {
414 	return sysfs_emit(page, "%d\n",
415 			  to_pci_epf_group(item)->epf->msix_interrupts);
416 }
417 
418 PCI_EPF_HEADER_R(vendorid)
419 PCI_EPF_HEADER_W_u16(vendorid)
420 
421 PCI_EPF_HEADER_R(deviceid)
422 PCI_EPF_HEADER_W_u16(deviceid)
423 
424 PCI_EPF_HEADER_R(revid)
425 PCI_EPF_HEADER_W_u8(revid)
426 
427 PCI_EPF_HEADER_R(progif_code)
428 PCI_EPF_HEADER_W_u8(progif_code)
429 
430 PCI_EPF_HEADER_R(subclass_code)
431 PCI_EPF_HEADER_W_u8(subclass_code)
432 
433 PCI_EPF_HEADER_R(baseclass_code)
434 PCI_EPF_HEADER_W_u8(baseclass_code)
435 
436 PCI_EPF_HEADER_R(cache_line_size)
437 PCI_EPF_HEADER_W_u8(cache_line_size)
438 
439 PCI_EPF_HEADER_R(subsys_vendor_id)
440 PCI_EPF_HEADER_W_u16(subsys_vendor_id)
441 
442 PCI_EPF_HEADER_R(subsys_id)
443 PCI_EPF_HEADER_W_u16(subsys_id)
444 
445 PCI_EPF_HEADER_R(interrupt_pin)
446 PCI_EPF_HEADER_W_u8(interrupt_pin)
447 
448 CONFIGFS_ATTR(pci_epf_, vendorid);
449 CONFIGFS_ATTR(pci_epf_, deviceid);
450 CONFIGFS_ATTR(pci_epf_, revid);
451 CONFIGFS_ATTR(pci_epf_, progif_code);
452 CONFIGFS_ATTR(pci_epf_, subclass_code);
453 CONFIGFS_ATTR(pci_epf_, baseclass_code);
454 CONFIGFS_ATTR(pci_epf_, cache_line_size);
455 CONFIGFS_ATTR(pci_epf_, subsys_vendor_id);
456 CONFIGFS_ATTR(pci_epf_, subsys_id);
457 CONFIGFS_ATTR(pci_epf_, interrupt_pin);
458 CONFIGFS_ATTR(pci_epf_, msi_interrupts);
459 CONFIGFS_ATTR(pci_epf_, msix_interrupts);
460 
461 static struct configfs_attribute *pci_epf_attrs[] = {
462 	&pci_epf_attr_vendorid,
463 	&pci_epf_attr_deviceid,
464 	&pci_epf_attr_revid,
465 	&pci_epf_attr_progif_code,
466 	&pci_epf_attr_subclass_code,
467 	&pci_epf_attr_baseclass_code,
468 	&pci_epf_attr_cache_line_size,
469 	&pci_epf_attr_subsys_vendor_id,
470 	&pci_epf_attr_subsys_id,
471 	&pci_epf_attr_interrupt_pin,
472 	&pci_epf_attr_msi_interrupts,
473 	&pci_epf_attr_msix_interrupts,
474 	NULL,
475 };
476 
477 static int pci_epf_vepf_link(struct config_item *epf_pf_item,
478 			     struct config_item *epf_vf_item)
479 {
480 	struct pci_epf_group *epf_vf_group = to_pci_epf_group(epf_vf_item);
481 	struct pci_epf_group *epf_pf_group = to_pci_epf_group(epf_pf_item);
482 	struct pci_epf *epf_pf = epf_pf_group->epf;
483 	struct pci_epf *epf_vf = epf_vf_group->epf;
484 
485 	return pci_epf_add_vepf(epf_pf, epf_vf);
486 }
487 
488 static void pci_epf_vepf_unlink(struct config_item *epf_pf_item,
489 				struct config_item *epf_vf_item)
490 {
491 	struct pci_epf_group *epf_vf_group = to_pci_epf_group(epf_vf_item);
492 	struct pci_epf_group *epf_pf_group = to_pci_epf_group(epf_pf_item);
493 	struct pci_epf *epf_pf = epf_pf_group->epf;
494 	struct pci_epf *epf_vf = epf_vf_group->epf;
495 
496 	pci_epf_remove_vepf(epf_pf, epf_vf);
497 }
498 
499 static void pci_epf_release(struct config_item *item)
500 {
501 	struct pci_epf_group *epf_group = to_pci_epf_group(item);
502 
503 	mutex_lock(&functions_mutex);
504 	idr_remove(&functions_idr, epf_group->index);
505 	mutex_unlock(&functions_mutex);
506 	pci_epf_destroy(epf_group->epf);
507 	kfree(epf_group);
508 }
509 
510 static struct configfs_item_operations pci_epf_ops = {
511 	.allow_link		= pci_epf_vepf_link,
512 	.drop_link		= pci_epf_vepf_unlink,
513 	.release		= pci_epf_release,
514 };
515 
516 static const struct config_item_type pci_epf_type = {
517 	.ct_item_ops	= &pci_epf_ops,
518 	.ct_attrs	= pci_epf_attrs,
519 	.ct_owner	= THIS_MODULE,
520 };
521 
522 /**
523  * pci_epf_type_add_cfs() - Help function drivers to expose function specific
524  *                          attributes in configfs
525  * @epf: the EPF device that has to be configured using configfs
526  * @group: the parent configfs group (corresponding to entries in
527  *         pci_epf_device_id)
528  *
529  * Invoke to expose function specific attributes in configfs.
530  *
531  * Return: A pointer to a config_group structure or NULL if the function driver
532  * does not have anything to expose (attributes configured by user) or if
533  * the function driver does not implement the add_cfs() method.
534  *
535  * Returns an error pointer if this function is called for an unbound EPF device
536  * or if the EPF driver add_cfs() method fails.
537  */
538 static struct config_group *pci_epf_type_add_cfs(struct pci_epf *epf,
539 						 struct config_group *group)
540 {
541 	struct config_group *epf_type_group;
542 
543 	if (!epf->driver) {
544 		dev_err(&epf->dev, "epf device not bound to driver\n");
545 		return ERR_PTR(-ENODEV);
546 	}
547 
548 	if (!epf->driver->ops->add_cfs)
549 		return NULL;
550 
551 	mutex_lock(&epf->lock);
552 	epf_type_group = epf->driver->ops->add_cfs(epf, group);
553 	mutex_unlock(&epf->lock);
554 
555 	return epf_type_group;
556 }
557 
558 static void pci_ep_cfs_add_type_group(struct pci_epf_group *epf_group)
559 {
560 	struct config_group *group;
561 
562 	group = pci_epf_type_add_cfs(epf_group->epf, &epf_group->group);
563 	if (!group)
564 		return;
565 
566 	if (IS_ERR(group)) {
567 		dev_err(&epf_group->epf->dev,
568 			"failed to create epf type specific attributes\n");
569 		return;
570 	}
571 
572 	configfs_add_default_group(group, &epf_group->group);
573 }
574 
575 static void pci_epf_cfs_add_sub_groups(struct pci_epf_group *epf_group)
576 {
577 	struct config_group *group;
578 
579 	group = pci_ep_cfs_add_primary_group(epf_group);
580 	if (IS_ERR(group)) {
581 		pr_err("failed to create 'primary' EPC interface\n");
582 		return;
583 	}
584 
585 	group = pci_ep_cfs_add_secondary_group(epf_group);
586 	if (IS_ERR(group)) {
587 		pr_err("failed to create 'secondary' EPC interface\n");
588 		return;
589 	}
590 
591 	pci_ep_cfs_add_type_group(epf_group);
592 }
593 
594 static struct config_group *pci_epf_make(struct config_group *group,
595 					 const char *name)
596 {
597 	struct pci_epf_group *epf_group;
598 	struct pci_epf *epf;
599 	char *epf_name;
600 	int index, err;
601 
602 	epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL);
603 	if (!epf_group)
604 		return ERR_PTR(-ENOMEM);
605 
606 	mutex_lock(&functions_mutex);
607 	index = idr_alloc(&functions_idr, epf_group, 0, 0, GFP_KERNEL);
608 	mutex_unlock(&functions_mutex);
609 	if (index < 0) {
610 		err = index;
611 		goto free_group;
612 	}
613 
614 	epf_group->index = index;
615 
616 	config_group_init_type_name(&epf_group->group, name, &pci_epf_type);
617 
618 	epf_name = kasprintf(GFP_KERNEL, "%s.%d",
619 			     group->cg_item.ci_name, epf_group->index);
620 	if (!epf_name) {
621 		err = -ENOMEM;
622 		goto remove_idr;
623 	}
624 
625 	epf = pci_epf_create(epf_name);
626 	if (IS_ERR(epf)) {
627 		pr_err("failed to create endpoint function device\n");
628 		err = -EINVAL;
629 		goto free_name;
630 	}
631 
632 	epf->group = &epf_group->group;
633 	epf_group->epf = epf;
634 
635 	kfree(epf_name);
636 
637 	pci_epf_cfs_add_sub_groups(epf_group);
638 
639 	return &epf_group->group;
640 
641 free_name:
642 	kfree(epf_name);
643 
644 remove_idr:
645 	mutex_lock(&functions_mutex);
646 	idr_remove(&functions_idr, epf_group->index);
647 	mutex_unlock(&functions_mutex);
648 
649 free_group:
650 	kfree(epf_group);
651 
652 	return ERR_PTR(err);
653 }
654 
655 static void pci_epf_drop(struct config_group *group, struct config_item *item)
656 {
657 	config_item_put(item);
658 }
659 
660 static struct configfs_group_operations pci_epf_group_ops = {
661 	.make_group     = &pci_epf_make,
662 	.drop_item      = &pci_epf_drop,
663 };
664 
665 static const struct config_item_type pci_epf_group_type = {
666 	.ct_group_ops	= &pci_epf_group_ops,
667 	.ct_owner	= THIS_MODULE,
668 };
669 
670 struct config_group *pci_ep_cfs_add_epf_group(const char *name)
671 {
672 	struct config_group *group;
673 
674 	group = configfs_register_default_group(functions_group, name,
675 						&pci_epf_group_type);
676 	if (IS_ERR(group))
677 		pr_err("failed to register configfs group for %s function\n",
678 		       name);
679 
680 	return group;
681 }
682 EXPORT_SYMBOL(pci_ep_cfs_add_epf_group);
683 
684 void pci_ep_cfs_remove_epf_group(struct config_group *group)
685 {
686 	if (IS_ERR_OR_NULL(group))
687 		return;
688 
689 	list_del(&group->group_entry);
690 	configfs_unregister_default_group(group);
691 }
692 EXPORT_SYMBOL(pci_ep_cfs_remove_epf_group);
693 
694 static const struct config_item_type pci_functions_type = {
695 	.ct_owner	= THIS_MODULE,
696 };
697 
698 static const struct config_item_type pci_controllers_type = {
699 	.ct_owner	= THIS_MODULE,
700 };
701 
702 static const struct config_item_type pci_ep_type = {
703 	.ct_owner	= THIS_MODULE,
704 };
705 
706 static struct configfs_subsystem pci_ep_cfs_subsys = {
707 	.su_group = {
708 		.cg_item = {
709 			.ci_namebuf = "pci_ep",
710 			.ci_type = &pci_ep_type,
711 		},
712 	},
713 	.su_mutex = __MUTEX_INITIALIZER(pci_ep_cfs_subsys.su_mutex),
714 };
715 
716 static int __init pci_ep_cfs_init(void)
717 {
718 	int ret;
719 	struct config_group *root = &pci_ep_cfs_subsys.su_group;
720 
721 	config_group_init(root);
722 
723 	ret = configfs_register_subsystem(&pci_ep_cfs_subsys);
724 	if (ret) {
725 		pr_err("Error %d while registering subsystem %s\n",
726 		       ret, root->cg_item.ci_namebuf);
727 		goto err;
728 	}
729 
730 	functions_group = configfs_register_default_group(root, "functions",
731 							  &pci_functions_type);
732 	if (IS_ERR(functions_group)) {
733 		ret = PTR_ERR(functions_group);
734 		pr_err("Error %d while registering functions group\n",
735 		       ret);
736 		goto err_functions_group;
737 	}
738 
739 	controllers_group =
740 		configfs_register_default_group(root, "controllers",
741 						&pci_controllers_type);
742 	if (IS_ERR(controllers_group)) {
743 		ret = PTR_ERR(controllers_group);
744 		pr_err("Error %d while registering controllers group\n",
745 		       ret);
746 		goto err_controllers_group;
747 	}
748 
749 	return 0;
750 
751 err_controllers_group:
752 	configfs_unregister_default_group(functions_group);
753 
754 err_functions_group:
755 	configfs_unregister_subsystem(&pci_ep_cfs_subsys);
756 
757 err:
758 	return ret;
759 }
760 module_init(pci_ep_cfs_init);
761 
762 static void __exit pci_ep_cfs_exit(void)
763 {
764 	configfs_unregister_default_group(controllers_group);
765 	configfs_unregister_default_group(functions_group);
766 	configfs_unregister_subsystem(&pci_ep_cfs_subsys);
767 }
768 module_exit(pci_ep_cfs_exit);
769 
770 MODULE_DESCRIPTION("PCI EP CONFIGFS");
771 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
772