• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
to_pci_epf_group(struct config_item * item)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 
to_pci_epc_group(struct config_item * item)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 
pci_secondary_epc_epf_link(struct config_item * epf_item,struct config_item * epc_item)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 
pci_secondary_epc_epf_unlink(struct config_item * epc_item,struct config_item * epf_item)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
pci_ep_cfs_add_secondary_group(struct pci_epf_group * epf_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 
pci_primary_epc_epf_link(struct config_item * epf_item,struct config_item * epc_item)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 
pci_primary_epc_epf_unlink(struct config_item * epc_item,struct config_item * epf_item)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
pci_ep_cfs_add_primary_group(struct pci_epf_group * epf_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 
pci_epc_start_store(struct config_item * item,const char * page,size_t len)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 
pci_epc_start_show(struct config_item * item,char * page)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 
pci_epc_epf_link(struct config_item * epc_item,struct config_item * epf_item)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 
pci_epc_epf_unlink(struct config_item * epc_item,struct config_item * epf_item)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 
pci_ep_cfs_add_epc_group(const char * name)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 
pci_ep_cfs_remove_epc_group(struct config_group * group)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 
pci_epf_msi_interrupts_store(struct config_item * item,const char * page,size_t len)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 
pci_epf_msi_interrupts_show(struct config_item * item,char * page)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 
pci_epf_msix_interrupts_store(struct config_item * item,const char * page,size_t len)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 
pci_epf_msix_interrupts_show(struct config_item * item,char * page)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 
pci_epf_vepf_link(struct config_item * epf_pf_item,struct config_item * epf_vf_item)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 
pci_epf_vepf_unlink(struct config_item * epf_pf_item,struct config_item * epf_vf_item)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 
pci_epf_release(struct config_item * item)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  */
pci_epf_type_add_cfs(struct pci_epf * epf,struct config_group * group)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 
pci_ep_cfs_add_type_group(struct pci_epf_group * epf_group)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 
pci_epf_cfs_work(struct work_struct * work)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 
pci_epf_make(struct config_group * group,const char * name)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 
pci_epf_drop(struct config_group * group,struct config_item * item)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 
pci_ep_cfs_add_epf_group(const char * name)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 
pci_ep_cfs_remove_epf_group(struct config_group * group)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 
pci_ep_cfs_init(void)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 
pci_ep_cfs_exit(void)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>");
768