Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * configfs to configure the PCI endpoint
0004  *
0005  * Copyright (C) 2017 Texas Instruments
0006  * Author: Kishon Vijay Abraham I <kishon@ti.com>
0007  */
0008 
0009 #include <linux/module.h>
0010 #include <linux/idr.h>
0011 #include <linux/slab.h>
0012 
0013 #include <linux/pci-epc.h>
0014 #include <linux/pci-epf.h>
0015 #include <linux/pci-ep-cfs.h>
0016 
0017 static DEFINE_IDR(functions_idr);
0018 static DEFINE_MUTEX(functions_mutex);
0019 static struct config_group *functions_group;
0020 static struct config_group *controllers_group;
0021 
0022 struct pci_epf_group {
0023     struct config_group group;
0024     struct config_group primary_epc_group;
0025     struct config_group secondary_epc_group;
0026     struct delayed_work cfs_work;
0027     struct pci_epf *epf;
0028     int index;
0029 };
0030 
0031 struct pci_epc_group {
0032     struct config_group group;
0033     struct pci_epc *epc;
0034     bool start;
0035 };
0036 
0037 static inline struct pci_epf_group *to_pci_epf_group(struct config_item *item)
0038 {
0039     return container_of(to_config_group(item), struct pci_epf_group, group);
0040 }
0041 
0042 static inline struct pci_epc_group *to_pci_epc_group(struct config_item *item)
0043 {
0044     return container_of(to_config_group(item), struct pci_epc_group, group);
0045 }
0046 
0047 static int pci_secondary_epc_epf_link(struct config_item *epf_item,
0048                       struct config_item *epc_item)
0049 {
0050     int ret;
0051     struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
0052     struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
0053     struct pci_epc *epc = epc_group->epc;
0054     struct pci_epf *epf = epf_group->epf;
0055 
0056     ret = pci_epc_add_epf(epc, epf, SECONDARY_INTERFACE);
0057     if (ret)
0058         return ret;
0059 
0060     ret = pci_epf_bind(epf);
0061     if (ret) {
0062         pci_epc_remove_epf(epc, epf, SECONDARY_INTERFACE);
0063         return ret;
0064     }
0065 
0066     return 0;
0067 }
0068 
0069 static void pci_secondary_epc_epf_unlink(struct config_item *epc_item,
0070                      struct config_item *epf_item)
0071 {
0072     struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
0073     struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
0074     struct pci_epc *epc;
0075     struct pci_epf *epf;
0076 
0077     WARN_ON_ONCE(epc_group->start);
0078 
0079     epc = epc_group->epc;
0080     epf = epf_group->epf;
0081     pci_epf_unbind(epf);
0082     pci_epc_remove_epf(epc, epf, SECONDARY_INTERFACE);
0083 }
0084 
0085 static struct configfs_item_operations pci_secondary_epc_item_ops = {
0086     .allow_link = pci_secondary_epc_epf_link,
0087     .drop_link  = pci_secondary_epc_epf_unlink,
0088 };
0089 
0090 static const struct config_item_type pci_secondary_epc_type = {
0091     .ct_item_ops    = &pci_secondary_epc_item_ops,
0092     .ct_owner   = THIS_MODULE,
0093 };
0094 
0095 static struct config_group
0096 *pci_ep_cfs_add_secondary_group(struct pci_epf_group *epf_group)
0097 {
0098     struct config_group *secondary_epc_group;
0099 
0100     secondary_epc_group = &epf_group->secondary_epc_group;
0101     config_group_init_type_name(secondary_epc_group, "secondary",
0102                     &pci_secondary_epc_type);
0103     configfs_register_group(&epf_group->group, secondary_epc_group);
0104 
0105     return secondary_epc_group;
0106 }
0107 
0108 static int pci_primary_epc_epf_link(struct config_item *epf_item,
0109                     struct config_item *epc_item)
0110 {
0111     int ret;
0112     struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
0113     struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
0114     struct pci_epc *epc = epc_group->epc;
0115     struct pci_epf *epf = epf_group->epf;
0116 
0117     ret = pci_epc_add_epf(epc, epf, PRIMARY_INTERFACE);
0118     if (ret)
0119         return ret;
0120 
0121     ret = pci_epf_bind(epf);
0122     if (ret) {
0123         pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
0124         return ret;
0125     }
0126 
0127     return 0;
0128 }
0129 
0130 static void pci_primary_epc_epf_unlink(struct config_item *epc_item,
0131                        struct config_item *epf_item)
0132 {
0133     struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
0134     struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
0135     struct pci_epc *epc;
0136     struct pci_epf *epf;
0137 
0138     WARN_ON_ONCE(epc_group->start);
0139 
0140     epc = epc_group->epc;
0141     epf = epf_group->epf;
0142     pci_epf_unbind(epf);
0143     pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
0144 }
0145 
0146 static struct configfs_item_operations pci_primary_epc_item_ops = {
0147     .allow_link = pci_primary_epc_epf_link,
0148     .drop_link  = pci_primary_epc_epf_unlink,
0149 };
0150 
0151 static const struct config_item_type pci_primary_epc_type = {
0152     .ct_item_ops    = &pci_primary_epc_item_ops,
0153     .ct_owner   = THIS_MODULE,
0154 };
0155 
0156 static struct config_group
0157 *pci_ep_cfs_add_primary_group(struct pci_epf_group *epf_group)
0158 {
0159     struct config_group *primary_epc_group = &epf_group->primary_epc_group;
0160 
0161     config_group_init_type_name(primary_epc_group, "primary",
0162                     &pci_primary_epc_type);
0163     configfs_register_group(&epf_group->group, primary_epc_group);
0164 
0165     return primary_epc_group;
0166 }
0167 
0168 static ssize_t pci_epc_start_store(struct config_item *item, const char *page,
0169                    size_t len)
0170 {
0171     int ret;
0172     bool start;
0173     struct pci_epc *epc;
0174     struct pci_epc_group *epc_group = to_pci_epc_group(item);
0175 
0176     epc = epc_group->epc;
0177 
0178     if (kstrtobool(page, &start) < 0)
0179         return -EINVAL;
0180 
0181     if (!start) {
0182         pci_epc_stop(epc);
0183         epc_group->start = 0;
0184         return len;
0185     }
0186 
0187     ret = pci_epc_start(epc);
0188     if (ret) {
0189         dev_err(&epc->dev, "failed to start endpoint controller\n");
0190         return -EINVAL;
0191     }
0192 
0193     epc_group->start = start;
0194 
0195     return len;
0196 }
0197 
0198 static ssize_t pci_epc_start_show(struct config_item *item, char *page)
0199 {
0200     return sysfs_emit(page, "%d\n", to_pci_epc_group(item)->start);
0201 }
0202 
0203 CONFIGFS_ATTR(pci_epc_, start);
0204 
0205 static struct configfs_attribute *pci_epc_attrs[] = {
0206     &pci_epc_attr_start,
0207     NULL,
0208 };
0209 
0210 static int pci_epc_epf_link(struct config_item *epc_item,
0211                 struct config_item *epf_item)
0212 {
0213     int ret;
0214     struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
0215     struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
0216     struct pci_epc *epc = epc_group->epc;
0217     struct pci_epf *epf = epf_group->epf;
0218 
0219     ret = pci_epc_add_epf(epc, epf, PRIMARY_INTERFACE);
0220     if (ret)
0221         return ret;
0222 
0223     ret = pci_epf_bind(epf);
0224     if (ret) {
0225         pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
0226         return ret;
0227     }
0228 
0229     return 0;
0230 }
0231 
0232 static void pci_epc_epf_unlink(struct config_item *epc_item,
0233                    struct config_item *epf_item)
0234 {
0235     struct pci_epc *epc;
0236     struct pci_epf *epf;
0237     struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
0238     struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
0239 
0240     WARN_ON_ONCE(epc_group->start);
0241 
0242     epc = epc_group->epc;
0243     epf = epf_group->epf;
0244     pci_epf_unbind(epf);
0245     pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
0246 }
0247 
0248 static struct configfs_item_operations pci_epc_item_ops = {
0249     .allow_link = pci_epc_epf_link,
0250     .drop_link  = pci_epc_epf_unlink,
0251 };
0252 
0253 static const struct config_item_type pci_epc_type = {
0254     .ct_item_ops    = &pci_epc_item_ops,
0255     .ct_attrs   = pci_epc_attrs,
0256     .ct_owner   = THIS_MODULE,
0257 };
0258 
0259 struct config_group *pci_ep_cfs_add_epc_group(const char *name)
0260 {
0261     int ret;
0262     struct pci_epc *epc;
0263     struct config_group *group;
0264     struct pci_epc_group *epc_group;
0265 
0266     epc_group = kzalloc(sizeof(*epc_group), GFP_KERNEL);
0267     if (!epc_group) {
0268         ret = -ENOMEM;
0269         goto err;
0270     }
0271 
0272     group = &epc_group->group;
0273 
0274     config_group_init_type_name(group, name, &pci_epc_type);
0275     ret = configfs_register_group(controllers_group, group);
0276     if (ret) {
0277         pr_err("failed to register configfs group for %s\n", name);
0278         goto err_register_group;
0279     }
0280 
0281     epc = pci_epc_get(name);
0282     if (IS_ERR(epc)) {
0283         ret = PTR_ERR(epc);
0284         goto err_epc_get;
0285     }
0286 
0287     epc_group->epc = epc;
0288 
0289     return group;
0290 
0291 err_epc_get:
0292     configfs_unregister_group(group);
0293 
0294 err_register_group:
0295     kfree(epc_group);
0296 
0297 err:
0298     return ERR_PTR(ret);
0299 }
0300 EXPORT_SYMBOL(pci_ep_cfs_add_epc_group);
0301 
0302 void pci_ep_cfs_remove_epc_group(struct config_group *group)
0303 {
0304     struct pci_epc_group *epc_group;
0305 
0306     if (!group)
0307         return;
0308 
0309     epc_group = container_of(group, struct pci_epc_group, group);
0310     pci_epc_put(epc_group->epc);
0311     configfs_unregister_group(&epc_group->group);
0312     kfree(epc_group);
0313 }
0314 EXPORT_SYMBOL(pci_ep_cfs_remove_epc_group);
0315 
0316 #define PCI_EPF_HEADER_R(_name)                            \
0317 static ssize_t pci_epf_##_name##_show(struct config_item *item, char *page)    \
0318 {                                          \
0319     struct pci_epf *epf = to_pci_epf_group(item)->epf;             \
0320     if (WARN_ON_ONCE(!epf->header))                        \
0321         return -EINVAL;                            \
0322     return sysfs_emit(page, "0x%04x\n", epf->header->_name);           \
0323 }
0324 
0325 #define PCI_EPF_HEADER_W_u32(_name)                        \
0326 static ssize_t pci_epf_##_name##_store(struct config_item *item,           \
0327                        const char *page, size_t len)           \
0328 {                                          \
0329     u32 val;                                   \
0330     struct pci_epf *epf = to_pci_epf_group(item)->epf;             \
0331     if (WARN_ON_ONCE(!epf->header))                        \
0332         return -EINVAL;                            \
0333     if (kstrtou32(page, 0, &val) < 0)                      \
0334         return -EINVAL;                            \
0335     epf->header->_name = val;                          \
0336     return len;                                \
0337 }
0338 
0339 #define PCI_EPF_HEADER_W_u16(_name)                        \
0340 static ssize_t pci_epf_##_name##_store(struct config_item *item,           \
0341                        const char *page, size_t len)           \
0342 {                                          \
0343     u16 val;                                   \
0344     struct pci_epf *epf = to_pci_epf_group(item)->epf;             \
0345     if (WARN_ON_ONCE(!epf->header))                        \
0346         return -EINVAL;                            \
0347     if (kstrtou16(page, 0, &val) < 0)                      \
0348         return -EINVAL;                            \
0349     epf->header->_name = val;                          \
0350     return len;                                \
0351 }
0352 
0353 #define PCI_EPF_HEADER_W_u8(_name)                         \
0354 static ssize_t pci_epf_##_name##_store(struct config_item *item,           \
0355                        const char *page, size_t len)           \
0356 {                                          \
0357     u8 val;                                    \
0358     struct pci_epf *epf = to_pci_epf_group(item)->epf;             \
0359     if (WARN_ON_ONCE(!epf->header))                        \
0360         return -EINVAL;                            \
0361     if (kstrtou8(page, 0, &val) < 0)                       \
0362         return -EINVAL;                            \
0363     epf->header->_name = val;                          \
0364     return len;                                \
0365 }
0366 
0367 static ssize_t pci_epf_msi_interrupts_store(struct config_item *item,
0368                         const char *page, size_t len)
0369 {
0370     u8 val;
0371 
0372     if (kstrtou8(page, 0, &val) < 0)
0373         return -EINVAL;
0374 
0375     to_pci_epf_group(item)->epf->msi_interrupts = val;
0376 
0377     return len;
0378 }
0379 
0380 static ssize_t pci_epf_msi_interrupts_show(struct config_item *item,
0381                        char *page)
0382 {
0383     return sysfs_emit(page, "%d\n",
0384               to_pci_epf_group(item)->epf->msi_interrupts);
0385 }
0386 
0387 static ssize_t pci_epf_msix_interrupts_store(struct config_item *item,
0388                          const char *page, size_t len)
0389 {
0390     u16 val;
0391 
0392     if (kstrtou16(page, 0, &val) < 0)
0393         return -EINVAL;
0394 
0395     to_pci_epf_group(item)->epf->msix_interrupts = val;
0396 
0397     return len;
0398 }
0399 
0400 static ssize_t pci_epf_msix_interrupts_show(struct config_item *item,
0401                         char *page)
0402 {
0403     return sysfs_emit(page, "%d\n",
0404               to_pci_epf_group(item)->epf->msix_interrupts);
0405 }
0406 
0407 PCI_EPF_HEADER_R(vendorid)
0408 PCI_EPF_HEADER_W_u16(vendorid)
0409 
0410 PCI_EPF_HEADER_R(deviceid)
0411 PCI_EPF_HEADER_W_u16(deviceid)
0412 
0413 PCI_EPF_HEADER_R(revid)
0414 PCI_EPF_HEADER_W_u8(revid)
0415 
0416 PCI_EPF_HEADER_R(progif_code)
0417 PCI_EPF_HEADER_W_u8(progif_code)
0418 
0419 PCI_EPF_HEADER_R(subclass_code)
0420 PCI_EPF_HEADER_W_u8(subclass_code)
0421 
0422 PCI_EPF_HEADER_R(baseclass_code)
0423 PCI_EPF_HEADER_W_u8(baseclass_code)
0424 
0425 PCI_EPF_HEADER_R(cache_line_size)
0426 PCI_EPF_HEADER_W_u8(cache_line_size)
0427 
0428 PCI_EPF_HEADER_R(subsys_vendor_id)
0429 PCI_EPF_HEADER_W_u16(subsys_vendor_id)
0430 
0431 PCI_EPF_HEADER_R(subsys_id)
0432 PCI_EPF_HEADER_W_u16(subsys_id)
0433 
0434 PCI_EPF_HEADER_R(interrupt_pin)
0435 PCI_EPF_HEADER_W_u8(interrupt_pin)
0436 
0437 CONFIGFS_ATTR(pci_epf_, vendorid);
0438 CONFIGFS_ATTR(pci_epf_, deviceid);
0439 CONFIGFS_ATTR(pci_epf_, revid);
0440 CONFIGFS_ATTR(pci_epf_, progif_code);
0441 CONFIGFS_ATTR(pci_epf_, subclass_code);
0442 CONFIGFS_ATTR(pci_epf_, baseclass_code);
0443 CONFIGFS_ATTR(pci_epf_, cache_line_size);
0444 CONFIGFS_ATTR(pci_epf_, subsys_vendor_id);
0445 CONFIGFS_ATTR(pci_epf_, subsys_id);
0446 CONFIGFS_ATTR(pci_epf_, interrupt_pin);
0447 CONFIGFS_ATTR(pci_epf_, msi_interrupts);
0448 CONFIGFS_ATTR(pci_epf_, msix_interrupts);
0449 
0450 static struct configfs_attribute *pci_epf_attrs[] = {
0451     &pci_epf_attr_vendorid,
0452     &pci_epf_attr_deviceid,
0453     &pci_epf_attr_revid,
0454     &pci_epf_attr_progif_code,
0455     &pci_epf_attr_subclass_code,
0456     &pci_epf_attr_baseclass_code,
0457     &pci_epf_attr_cache_line_size,
0458     &pci_epf_attr_subsys_vendor_id,
0459     &pci_epf_attr_subsys_id,
0460     &pci_epf_attr_interrupt_pin,
0461     &pci_epf_attr_msi_interrupts,
0462     &pci_epf_attr_msix_interrupts,
0463     NULL,
0464 };
0465 
0466 static int pci_epf_vepf_link(struct config_item *epf_pf_item,
0467                  struct config_item *epf_vf_item)
0468 {
0469     struct pci_epf_group *epf_vf_group = to_pci_epf_group(epf_vf_item);
0470     struct pci_epf_group *epf_pf_group = to_pci_epf_group(epf_pf_item);
0471     struct pci_epf *epf_pf = epf_pf_group->epf;
0472     struct pci_epf *epf_vf = epf_vf_group->epf;
0473 
0474     return pci_epf_add_vepf(epf_pf, epf_vf);
0475 }
0476 
0477 static void pci_epf_vepf_unlink(struct config_item *epf_pf_item,
0478                 struct config_item *epf_vf_item)
0479 {
0480     struct pci_epf_group *epf_vf_group = to_pci_epf_group(epf_vf_item);
0481     struct pci_epf_group *epf_pf_group = to_pci_epf_group(epf_pf_item);
0482     struct pci_epf *epf_pf = epf_pf_group->epf;
0483     struct pci_epf *epf_vf = epf_vf_group->epf;
0484 
0485     pci_epf_remove_vepf(epf_pf, epf_vf);
0486 }
0487 
0488 static void pci_epf_release(struct config_item *item)
0489 {
0490     struct pci_epf_group *epf_group = to_pci_epf_group(item);
0491 
0492     mutex_lock(&functions_mutex);
0493     idr_remove(&functions_idr, epf_group->index);
0494     mutex_unlock(&functions_mutex);
0495     pci_epf_destroy(epf_group->epf);
0496     kfree(epf_group);
0497 }
0498 
0499 static struct configfs_item_operations pci_epf_ops = {
0500     .allow_link     = pci_epf_vepf_link,
0501     .drop_link      = pci_epf_vepf_unlink,
0502     .release        = pci_epf_release,
0503 };
0504 
0505 static struct config_group *pci_epf_type_make(struct config_group *group,
0506                           const char *name)
0507 {
0508     struct pci_epf_group *epf_group = to_pci_epf_group(&group->cg_item);
0509     struct config_group *epf_type_group;
0510 
0511     epf_type_group = pci_epf_type_add_cfs(epf_group->epf, group);
0512     return epf_type_group;
0513 }
0514 
0515 static void pci_epf_type_drop(struct config_group *group,
0516                   struct config_item *item)
0517 {
0518     config_item_put(item);
0519 }
0520 
0521 static struct configfs_group_operations pci_epf_type_group_ops = {
0522     .make_group     = &pci_epf_type_make,
0523     .drop_item      = &pci_epf_type_drop,
0524 };
0525 
0526 static const struct config_item_type pci_epf_type = {
0527     .ct_group_ops   = &pci_epf_type_group_ops,
0528     .ct_item_ops    = &pci_epf_ops,
0529     .ct_attrs   = pci_epf_attrs,
0530     .ct_owner   = THIS_MODULE,
0531 };
0532 
0533 static void pci_epf_cfs_work(struct work_struct *work)
0534 {
0535     struct pci_epf_group *epf_group;
0536     struct config_group *group;
0537 
0538     epf_group = container_of(work, struct pci_epf_group, cfs_work.work);
0539     group = pci_ep_cfs_add_primary_group(epf_group);
0540     if (IS_ERR(group)) {
0541         pr_err("failed to create 'primary' EPC interface\n");
0542         return;
0543     }
0544 
0545     group = pci_ep_cfs_add_secondary_group(epf_group);
0546     if (IS_ERR(group)) {
0547         pr_err("failed to create 'secondary' EPC interface\n");
0548         return;
0549     }
0550 }
0551 
0552 static struct config_group *pci_epf_make(struct config_group *group,
0553                      const char *name)
0554 {
0555     struct pci_epf_group *epf_group;
0556     struct pci_epf *epf;
0557     char *epf_name;
0558     int index, err;
0559 
0560     epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL);
0561     if (!epf_group)
0562         return ERR_PTR(-ENOMEM);
0563 
0564     mutex_lock(&functions_mutex);
0565     index = idr_alloc(&functions_idr, epf_group, 0, 0, GFP_KERNEL);
0566     mutex_unlock(&functions_mutex);
0567     if (index < 0) {
0568         err = index;
0569         goto free_group;
0570     }
0571 
0572     epf_group->index = index;
0573 
0574     config_group_init_type_name(&epf_group->group, name, &pci_epf_type);
0575 
0576     epf_name = kasprintf(GFP_KERNEL, "%s.%d",
0577                  group->cg_item.ci_name, epf_group->index);
0578     if (!epf_name) {
0579         err = -ENOMEM;
0580         goto remove_idr;
0581     }
0582 
0583     epf = pci_epf_create(epf_name);
0584     if (IS_ERR(epf)) {
0585         pr_err("failed to create endpoint function device\n");
0586         err = -EINVAL;
0587         goto free_name;
0588     }
0589 
0590     epf->group = &epf_group->group;
0591     epf_group->epf = epf;
0592 
0593     kfree(epf_name);
0594 
0595     INIT_DELAYED_WORK(&epf_group->cfs_work, pci_epf_cfs_work);
0596     queue_delayed_work(system_wq, &epf_group->cfs_work,
0597                msecs_to_jiffies(1));
0598 
0599     return &epf_group->group;
0600 
0601 free_name:
0602     kfree(epf_name);
0603 
0604 remove_idr:
0605     mutex_lock(&functions_mutex);
0606     idr_remove(&functions_idr, epf_group->index);
0607     mutex_unlock(&functions_mutex);
0608 
0609 free_group:
0610     kfree(epf_group);
0611 
0612     return ERR_PTR(err);
0613 }
0614 
0615 static void pci_epf_drop(struct config_group *group, struct config_item *item)
0616 {
0617     config_item_put(item);
0618 }
0619 
0620 static struct configfs_group_operations pci_epf_group_ops = {
0621     .make_group     = &pci_epf_make,
0622     .drop_item      = &pci_epf_drop,
0623 };
0624 
0625 static const struct config_item_type pci_epf_group_type = {
0626     .ct_group_ops   = &pci_epf_group_ops,
0627     .ct_owner   = THIS_MODULE,
0628 };
0629 
0630 struct config_group *pci_ep_cfs_add_epf_group(const char *name)
0631 {
0632     struct config_group *group;
0633 
0634     group = configfs_register_default_group(functions_group, name,
0635                         &pci_epf_group_type);
0636     if (IS_ERR(group))
0637         pr_err("failed to register configfs group for %s function\n",
0638                name);
0639 
0640     return group;
0641 }
0642 EXPORT_SYMBOL(pci_ep_cfs_add_epf_group);
0643 
0644 void pci_ep_cfs_remove_epf_group(struct config_group *group)
0645 {
0646     if (IS_ERR_OR_NULL(group))
0647         return;
0648 
0649     configfs_unregister_default_group(group);
0650 }
0651 EXPORT_SYMBOL(pci_ep_cfs_remove_epf_group);
0652 
0653 static const struct config_item_type pci_functions_type = {
0654     .ct_owner   = THIS_MODULE,
0655 };
0656 
0657 static const struct config_item_type pci_controllers_type = {
0658     .ct_owner   = THIS_MODULE,
0659 };
0660 
0661 static const struct config_item_type pci_ep_type = {
0662     .ct_owner   = THIS_MODULE,
0663 };
0664 
0665 static struct configfs_subsystem pci_ep_cfs_subsys = {
0666     .su_group = {
0667         .cg_item = {
0668             .ci_namebuf = "pci_ep",
0669             .ci_type = &pci_ep_type,
0670         },
0671     },
0672     .su_mutex = __MUTEX_INITIALIZER(pci_ep_cfs_subsys.su_mutex),
0673 };
0674 
0675 static int __init pci_ep_cfs_init(void)
0676 {
0677     int ret;
0678     struct config_group *root = &pci_ep_cfs_subsys.su_group;
0679 
0680     config_group_init(root);
0681 
0682     ret = configfs_register_subsystem(&pci_ep_cfs_subsys);
0683     if (ret) {
0684         pr_err("Error %d while registering subsystem %s\n",
0685                ret, root->cg_item.ci_namebuf);
0686         goto err;
0687     }
0688 
0689     functions_group = configfs_register_default_group(root, "functions",
0690                               &pci_functions_type);
0691     if (IS_ERR(functions_group)) {
0692         ret = PTR_ERR(functions_group);
0693         pr_err("Error %d while registering functions group\n",
0694                ret);
0695         goto err_functions_group;
0696     }
0697 
0698     controllers_group =
0699         configfs_register_default_group(root, "controllers",
0700                         &pci_controllers_type);
0701     if (IS_ERR(controllers_group)) {
0702         ret = PTR_ERR(controllers_group);
0703         pr_err("Error %d while registering controllers group\n",
0704                ret);
0705         goto err_controllers_group;
0706     }
0707 
0708     return 0;
0709 
0710 err_controllers_group:
0711     configfs_unregister_default_group(functions_group);
0712 
0713 err_functions_group:
0714     configfs_unregister_subsystem(&pci_ep_cfs_subsys);
0715 
0716 err:
0717     return ret;
0718 }
0719 module_init(pci_ep_cfs_init);
0720 
0721 static void __exit pci_ep_cfs_exit(void)
0722 {
0723     configfs_unregister_default_group(controllers_group);
0724     configfs_unregister_default_group(functions_group);
0725     configfs_unregister_subsystem(&pci_ep_cfs_subsys);
0726 }
0727 module_exit(pci_ep_cfs_exit);
0728 
0729 MODULE_DESCRIPTION("PCI EP CONFIGFS");
0730 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
0731 MODULE_LICENSE("GPL v2");