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