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