WIP FPC-III support
[linux/fpc-iii.git] / drivers / pci / endpoint / pci-ep-cfs.c
blob3710adf51912de68207fa021ee5325eb8af9782a
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * configfs to configure the PCI endpoint
5 * Copyright (C) 2017 Texas Instruments
6 * Author: Kishon Vijay Abraham I <kishon@ti.com>
7 */
9 #include <linux/module.h>
10 #include <linux/idr.h>
11 #include <linux/slab.h>
13 #include <linux/pci-epc.h>
14 #include <linux/pci-epf.h>
15 #include <linux/pci-ep-cfs.h>
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;
22 struct pci_epf_group {
23 struct config_group group;
24 struct pci_epf *epf;
25 int index;
28 struct pci_epc_group {
29 struct config_group group;
30 struct pci_epc *epc;
31 bool start;
34 static inline struct pci_epf_group *to_pci_epf_group(struct config_item *item)
36 return container_of(to_config_group(item), struct pci_epf_group, group);
39 static inline struct pci_epc_group *to_pci_epc_group(struct config_item *item)
41 return container_of(to_config_group(item), struct pci_epc_group, group);
44 static ssize_t pci_epc_start_store(struct config_item *item, const char *page,
45 size_t len)
47 int ret;
48 bool start;
49 struct pci_epc *epc;
50 struct pci_epc_group *epc_group = to_pci_epc_group(item);
52 epc = epc_group->epc;
54 ret = kstrtobool(page, &start);
55 if (ret)
56 return ret;
58 if (!start) {
59 pci_epc_stop(epc);
60 epc_group->start = 0;
61 return len;
64 ret = pci_epc_start(epc);
65 if (ret) {
66 dev_err(&epc->dev, "failed to start endpoint controller\n");
67 return -EINVAL;
70 epc_group->start = start;
72 return len;
75 static ssize_t pci_epc_start_show(struct config_item *item, char *page)
77 return sprintf(page, "%d\n",
78 to_pci_epc_group(item)->start);
81 CONFIGFS_ATTR(pci_epc_, start);
83 static struct configfs_attribute *pci_epc_attrs[] = {
84 &pci_epc_attr_start,
85 NULL,
88 static int pci_epc_epf_link(struct config_item *epc_item,
89 struct config_item *epf_item)
91 int ret;
92 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
93 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
94 struct pci_epc *epc = epc_group->epc;
95 struct pci_epf *epf = epf_group->epf;
97 ret = pci_epc_add_epf(epc, epf);
98 if (ret)
99 return ret;
101 ret = pci_epf_bind(epf);
102 if (ret) {
103 pci_epc_remove_epf(epc, epf);
104 return ret;
107 return 0;
110 static void pci_epc_epf_unlink(struct config_item *epc_item,
111 struct config_item *epf_item)
113 struct pci_epc *epc;
114 struct pci_epf *epf;
115 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
116 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
118 WARN_ON_ONCE(epc_group->start);
120 epc = epc_group->epc;
121 epf = epf_group->epf;
122 pci_epf_unbind(epf);
123 pci_epc_remove_epf(epc, epf);
126 static struct configfs_item_operations pci_epc_item_ops = {
127 .allow_link = pci_epc_epf_link,
128 .drop_link = pci_epc_epf_unlink,
131 static const struct config_item_type pci_epc_type = {
132 .ct_item_ops = &pci_epc_item_ops,
133 .ct_attrs = pci_epc_attrs,
134 .ct_owner = THIS_MODULE,
137 struct config_group *pci_ep_cfs_add_epc_group(const char *name)
139 int ret;
140 struct pci_epc *epc;
141 struct config_group *group;
142 struct pci_epc_group *epc_group;
144 epc_group = kzalloc(sizeof(*epc_group), GFP_KERNEL);
145 if (!epc_group) {
146 ret = -ENOMEM;
147 goto err;
150 group = &epc_group->group;
152 config_group_init_type_name(group, name, &pci_epc_type);
153 ret = configfs_register_group(controllers_group, group);
154 if (ret) {
155 pr_err("failed to register configfs group for %s\n", name);
156 goto err_register_group;
159 epc = pci_epc_get(name);
160 if (IS_ERR(epc)) {
161 ret = PTR_ERR(epc);
162 goto err_epc_get;
165 epc_group->epc = epc;
167 return group;
169 err_epc_get:
170 configfs_unregister_group(group);
172 err_register_group:
173 kfree(epc_group);
175 err:
176 return ERR_PTR(ret);
178 EXPORT_SYMBOL(pci_ep_cfs_add_epc_group);
180 void pci_ep_cfs_remove_epc_group(struct config_group *group)
182 struct pci_epc_group *epc_group;
184 if (!group)
185 return;
187 epc_group = container_of(group, struct pci_epc_group, group);
188 pci_epc_put(epc_group->epc);
189 configfs_unregister_group(&epc_group->group);
190 kfree(epc_group);
192 EXPORT_SYMBOL(pci_ep_cfs_remove_epc_group);
194 #define PCI_EPF_HEADER_R(_name) \
195 static ssize_t pci_epf_##_name##_show(struct config_item *item, char *page) \
197 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
198 if (WARN_ON_ONCE(!epf->header)) \
199 return -EINVAL; \
200 return sprintf(page, "0x%04x\n", epf->header->_name); \
203 #define PCI_EPF_HEADER_W_u32(_name) \
204 static ssize_t pci_epf_##_name##_store(struct config_item *item, \
205 const char *page, size_t len) \
207 u32 val; \
208 int ret; \
209 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
210 if (WARN_ON_ONCE(!epf->header)) \
211 return -EINVAL; \
212 ret = kstrtou32(page, 0, &val); \
213 if (ret) \
214 return ret; \
215 epf->header->_name = val; \
216 return len; \
219 #define PCI_EPF_HEADER_W_u16(_name) \
220 static ssize_t pci_epf_##_name##_store(struct config_item *item, \
221 const char *page, size_t len) \
223 u16 val; \
224 int ret; \
225 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
226 if (WARN_ON_ONCE(!epf->header)) \
227 return -EINVAL; \
228 ret = kstrtou16(page, 0, &val); \
229 if (ret) \
230 return ret; \
231 epf->header->_name = val; \
232 return len; \
235 #define PCI_EPF_HEADER_W_u8(_name) \
236 static ssize_t pci_epf_##_name##_store(struct config_item *item, \
237 const char *page, size_t len) \
239 u8 val; \
240 int ret; \
241 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
242 if (WARN_ON_ONCE(!epf->header)) \
243 return -EINVAL; \
244 ret = kstrtou8(page, 0, &val); \
245 if (ret) \
246 return ret; \
247 epf->header->_name = val; \
248 return len; \
251 static ssize_t pci_epf_msi_interrupts_store(struct config_item *item,
252 const char *page, size_t len)
254 u8 val;
255 int ret;
257 ret = kstrtou8(page, 0, &val);
258 if (ret)
259 return ret;
261 to_pci_epf_group(item)->epf->msi_interrupts = val;
263 return len;
266 static ssize_t pci_epf_msi_interrupts_show(struct config_item *item,
267 char *page)
269 return sprintf(page, "%d\n",
270 to_pci_epf_group(item)->epf->msi_interrupts);
273 static ssize_t pci_epf_msix_interrupts_store(struct config_item *item,
274 const char *page, size_t len)
276 u16 val;
277 int ret;
279 ret = kstrtou16(page, 0, &val);
280 if (ret)
281 return ret;
283 to_pci_epf_group(item)->epf->msix_interrupts = val;
285 return len;
288 static ssize_t pci_epf_msix_interrupts_show(struct config_item *item,
289 char *page)
291 return sprintf(page, "%d\n",
292 to_pci_epf_group(item)->epf->msix_interrupts);
295 PCI_EPF_HEADER_R(vendorid)
296 PCI_EPF_HEADER_W_u16(vendorid)
298 PCI_EPF_HEADER_R(deviceid)
299 PCI_EPF_HEADER_W_u16(deviceid)
301 PCI_EPF_HEADER_R(revid)
302 PCI_EPF_HEADER_W_u8(revid)
304 PCI_EPF_HEADER_R(progif_code)
305 PCI_EPF_HEADER_W_u8(progif_code)
307 PCI_EPF_HEADER_R(subclass_code)
308 PCI_EPF_HEADER_W_u8(subclass_code)
310 PCI_EPF_HEADER_R(baseclass_code)
311 PCI_EPF_HEADER_W_u8(baseclass_code)
313 PCI_EPF_HEADER_R(cache_line_size)
314 PCI_EPF_HEADER_W_u8(cache_line_size)
316 PCI_EPF_HEADER_R(subsys_vendor_id)
317 PCI_EPF_HEADER_W_u16(subsys_vendor_id)
319 PCI_EPF_HEADER_R(subsys_id)
320 PCI_EPF_HEADER_W_u16(subsys_id)
322 PCI_EPF_HEADER_R(interrupt_pin)
323 PCI_EPF_HEADER_W_u8(interrupt_pin)
325 CONFIGFS_ATTR(pci_epf_, vendorid);
326 CONFIGFS_ATTR(pci_epf_, deviceid);
327 CONFIGFS_ATTR(pci_epf_, revid);
328 CONFIGFS_ATTR(pci_epf_, progif_code);
329 CONFIGFS_ATTR(pci_epf_, subclass_code);
330 CONFIGFS_ATTR(pci_epf_, baseclass_code);
331 CONFIGFS_ATTR(pci_epf_, cache_line_size);
332 CONFIGFS_ATTR(pci_epf_, subsys_vendor_id);
333 CONFIGFS_ATTR(pci_epf_, subsys_id);
334 CONFIGFS_ATTR(pci_epf_, interrupt_pin);
335 CONFIGFS_ATTR(pci_epf_, msi_interrupts);
336 CONFIGFS_ATTR(pci_epf_, msix_interrupts);
338 static struct configfs_attribute *pci_epf_attrs[] = {
339 &pci_epf_attr_vendorid,
340 &pci_epf_attr_deviceid,
341 &pci_epf_attr_revid,
342 &pci_epf_attr_progif_code,
343 &pci_epf_attr_subclass_code,
344 &pci_epf_attr_baseclass_code,
345 &pci_epf_attr_cache_line_size,
346 &pci_epf_attr_subsys_vendor_id,
347 &pci_epf_attr_subsys_id,
348 &pci_epf_attr_interrupt_pin,
349 &pci_epf_attr_msi_interrupts,
350 &pci_epf_attr_msix_interrupts,
351 NULL,
354 static void pci_epf_release(struct config_item *item)
356 struct pci_epf_group *epf_group = to_pci_epf_group(item);
358 mutex_lock(&functions_mutex);
359 idr_remove(&functions_idr, epf_group->index);
360 mutex_unlock(&functions_mutex);
361 pci_epf_destroy(epf_group->epf);
362 kfree(epf_group);
365 static struct configfs_item_operations pci_epf_ops = {
366 .release = pci_epf_release,
369 static const struct config_item_type pci_epf_type = {
370 .ct_item_ops = &pci_epf_ops,
371 .ct_attrs = pci_epf_attrs,
372 .ct_owner = THIS_MODULE,
375 static struct config_group *pci_epf_make(struct config_group *group,
376 const char *name)
378 struct pci_epf_group *epf_group;
379 struct pci_epf *epf;
380 char *epf_name;
381 int index, err;
383 epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL);
384 if (!epf_group)
385 return ERR_PTR(-ENOMEM);
387 mutex_lock(&functions_mutex);
388 index = idr_alloc(&functions_idr, epf_group, 0, 0, GFP_KERNEL);
389 mutex_unlock(&functions_mutex);
390 if (index < 0) {
391 err = index;
392 goto free_group;
395 epf_group->index = index;
397 config_group_init_type_name(&epf_group->group, name, &pci_epf_type);
399 epf_name = kasprintf(GFP_KERNEL, "%s.%d",
400 group->cg_item.ci_name, epf_group->index);
401 if (!epf_name) {
402 err = -ENOMEM;
403 goto remove_idr;
406 epf = pci_epf_create(epf_name);
407 if (IS_ERR(epf)) {
408 pr_err("failed to create endpoint function device\n");
409 err = -EINVAL;
410 goto free_name;
413 epf_group->epf = epf;
415 kfree(epf_name);
417 return &epf_group->group;
419 free_name:
420 kfree(epf_name);
422 remove_idr:
423 mutex_lock(&functions_mutex);
424 idr_remove(&functions_idr, epf_group->index);
425 mutex_unlock(&functions_mutex);
427 free_group:
428 kfree(epf_group);
430 return ERR_PTR(err);
433 static void pci_epf_drop(struct config_group *group, struct config_item *item)
435 config_item_put(item);
438 static struct configfs_group_operations pci_epf_group_ops = {
439 .make_group = &pci_epf_make,
440 .drop_item = &pci_epf_drop,
443 static const struct config_item_type pci_epf_group_type = {
444 .ct_group_ops = &pci_epf_group_ops,
445 .ct_owner = THIS_MODULE,
448 struct config_group *pci_ep_cfs_add_epf_group(const char *name)
450 struct config_group *group;
452 group = configfs_register_default_group(functions_group, name,
453 &pci_epf_group_type);
454 if (IS_ERR(group))
455 pr_err("failed to register configfs group for %s function\n",
456 name);
458 return group;
460 EXPORT_SYMBOL(pci_ep_cfs_add_epf_group);
462 void pci_ep_cfs_remove_epf_group(struct config_group *group)
464 if (IS_ERR_OR_NULL(group))
465 return;
467 configfs_unregister_default_group(group);
469 EXPORT_SYMBOL(pci_ep_cfs_remove_epf_group);
471 static const struct config_item_type pci_functions_type = {
472 .ct_owner = THIS_MODULE,
475 static const struct config_item_type pci_controllers_type = {
476 .ct_owner = THIS_MODULE,
479 static const struct config_item_type pci_ep_type = {
480 .ct_owner = THIS_MODULE,
483 static struct configfs_subsystem pci_ep_cfs_subsys = {
484 .su_group = {
485 .cg_item = {
486 .ci_namebuf = "pci_ep",
487 .ci_type = &pci_ep_type,
490 .su_mutex = __MUTEX_INITIALIZER(pci_ep_cfs_subsys.su_mutex),
493 static int __init pci_ep_cfs_init(void)
495 int ret;
496 struct config_group *root = &pci_ep_cfs_subsys.su_group;
498 config_group_init(root);
500 ret = configfs_register_subsystem(&pci_ep_cfs_subsys);
501 if (ret) {
502 pr_err("Error %d while registering subsystem %s\n",
503 ret, root->cg_item.ci_namebuf);
504 goto err;
507 functions_group = configfs_register_default_group(root, "functions",
508 &pci_functions_type);
509 if (IS_ERR(functions_group)) {
510 ret = PTR_ERR(functions_group);
511 pr_err("Error %d while registering functions group\n",
512 ret);
513 goto err_functions_group;
516 controllers_group =
517 configfs_register_default_group(root, "controllers",
518 &pci_controllers_type);
519 if (IS_ERR(controllers_group)) {
520 ret = PTR_ERR(controllers_group);
521 pr_err("Error %d while registering controllers group\n",
522 ret);
523 goto err_controllers_group;
526 return 0;
528 err_controllers_group:
529 configfs_unregister_default_group(functions_group);
531 err_functions_group:
532 configfs_unregister_subsystem(&pci_ep_cfs_subsys);
534 err:
535 return ret;
537 module_init(pci_ep_cfs_init);
539 static void __exit pci_ep_cfs_exit(void)
541 configfs_unregister_default_group(controllers_group);
542 configfs_unregister_default_group(functions_group);
543 configfs_unregister_subsystem(&pci_ep_cfs_subsys);
545 module_exit(pci_ep_cfs_exit);
547 MODULE_DESCRIPTION("PCI EP CONFIGFS");
548 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
549 MODULE_LICENSE("GPL v2");