Merge tag 'for-5.9-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[linux-2.6-microblaze.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 pci_epf *epf;
25         int index;
26 };
27
28 struct pci_epc_group {
29         struct config_group group;
30         struct pci_epc *epc;
31         bool start;
32 };
33
34 static inline struct pci_epf_group *to_pci_epf_group(struct config_item *item)
35 {
36         return container_of(to_config_group(item), struct pci_epf_group, group);
37 }
38
39 static inline struct pci_epc_group *to_pci_epc_group(struct config_item *item)
40 {
41         return container_of(to_config_group(item), struct pci_epc_group, group);
42 }
43
44 static ssize_t pci_epc_start_store(struct config_item *item, const char *page,
45                                    size_t len)
46 {
47         int ret;
48         bool start;
49         struct pci_epc *epc;
50         struct pci_epc_group *epc_group = to_pci_epc_group(item);
51
52         epc = epc_group->epc;
53
54         ret = kstrtobool(page, &start);
55         if (ret)
56                 return ret;
57
58         if (!start) {
59                 pci_epc_stop(epc);
60                 epc_group->start = 0;
61                 return len;
62         }
63
64         ret = pci_epc_start(epc);
65         if (ret) {
66                 dev_err(&epc->dev, "failed to start endpoint controller\n");
67                 return -EINVAL;
68         }
69
70         epc_group->start = start;
71
72         return len;
73 }
74
75 static ssize_t pci_epc_start_show(struct config_item *item, char *page)
76 {
77         return sprintf(page, "%d\n",
78                        to_pci_epc_group(item)->start);
79 }
80
81 CONFIGFS_ATTR(pci_epc_, start);
82
83 static struct configfs_attribute *pci_epc_attrs[] = {
84         &pci_epc_attr_start,
85         NULL,
86 };
87
88 static int pci_epc_epf_link(struct config_item *epc_item,
89                             struct config_item *epf_item)
90 {
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;
96
97         ret = pci_epc_add_epf(epc, epf);
98         if (ret)
99                 return ret;
100
101         ret = pci_epf_bind(epf);
102         if (ret) {
103                 pci_epc_remove_epf(epc, epf);
104                 return ret;
105         }
106
107         return 0;
108 }
109
110 static void pci_epc_epf_unlink(struct config_item *epc_item,
111                                struct config_item *epf_item)
112 {
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);
117
118         WARN_ON_ONCE(epc_group->start);
119
120         epc = epc_group->epc;
121         epf = epf_group->epf;
122         pci_epf_unbind(epf);
123         pci_epc_remove_epf(epc, epf);
124 }
125
126 static struct configfs_item_operations pci_epc_item_ops = {
127         .allow_link     = pci_epc_epf_link,
128         .drop_link      = pci_epc_epf_unlink,
129 };
130
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,
135 };
136
137 struct config_group *pci_ep_cfs_add_epc_group(const char *name)
138 {
139         int ret;
140         struct pci_epc *epc;
141         struct config_group *group;
142         struct pci_epc_group *epc_group;
143
144         epc_group = kzalloc(sizeof(*epc_group), GFP_KERNEL);
145         if (!epc_group) {
146                 ret = -ENOMEM;
147                 goto err;
148         }
149
150         group = &epc_group->group;
151
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;
157         }
158
159         epc = pci_epc_get(name);
160         if (IS_ERR(epc)) {
161                 ret = PTR_ERR(epc);
162                 goto err_epc_get;
163         }
164
165         epc_group->epc = epc;
166
167         return group;
168
169 err_epc_get:
170         configfs_unregister_group(group);
171
172 err_register_group:
173         kfree(epc_group);
174
175 err:
176         return ERR_PTR(ret);
177 }
178 EXPORT_SYMBOL(pci_ep_cfs_add_epc_group);
179
180 void pci_ep_cfs_remove_epc_group(struct config_group *group)
181 {
182         struct pci_epc_group *epc_group;
183
184         if (!group)
185                 return;
186
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);
191 }
192 EXPORT_SYMBOL(pci_ep_cfs_remove_epc_group);
193
194 #define PCI_EPF_HEADER_R(_name)                                                \
195 static ssize_t pci_epf_##_name##_show(struct config_item *item, char *page)    \
196 {                                                                              \
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);                  \
201 }
202
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)           \
206 {                                                                              \
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;                                                            \
217 }
218
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)           \
222 {                                                                              \
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;                                                            \
233 }
234
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)           \
238 {                                                                              \
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;                                                            \
249 }
250
251 static ssize_t pci_epf_msi_interrupts_store(struct config_item *item,
252                                             const char *page, size_t len)
253 {
254         u8 val;
255         int ret;
256
257         ret = kstrtou8(page, 0, &val);
258         if (ret)
259                 return ret;
260
261         to_pci_epf_group(item)->epf->msi_interrupts = val;
262
263         return len;
264 }
265
266 static ssize_t pci_epf_msi_interrupts_show(struct config_item *item,
267                                            char *page)
268 {
269         return sprintf(page, "%d\n",
270                        to_pci_epf_group(item)->epf->msi_interrupts);
271 }
272
273 static ssize_t pci_epf_msix_interrupts_store(struct config_item *item,
274                                              const char *page, size_t len)
275 {
276         u16 val;
277         int ret;
278
279         ret = kstrtou16(page, 0, &val);
280         if (ret)
281                 return ret;
282
283         to_pci_epf_group(item)->epf->msix_interrupts = val;
284
285         return len;
286 }
287
288 static ssize_t pci_epf_msix_interrupts_show(struct config_item *item,
289                                             char *page)
290 {
291         return sprintf(page, "%d\n",
292                        to_pci_epf_group(item)->epf->msix_interrupts);
293 }
294
295 PCI_EPF_HEADER_R(vendorid)
296 PCI_EPF_HEADER_W_u16(vendorid)
297
298 PCI_EPF_HEADER_R(deviceid)
299 PCI_EPF_HEADER_W_u16(deviceid)
300
301 PCI_EPF_HEADER_R(revid)
302 PCI_EPF_HEADER_W_u8(revid)
303
304 PCI_EPF_HEADER_R(progif_code)
305 PCI_EPF_HEADER_W_u8(progif_code)
306
307 PCI_EPF_HEADER_R(subclass_code)
308 PCI_EPF_HEADER_W_u8(subclass_code)
309
310 PCI_EPF_HEADER_R(baseclass_code)
311 PCI_EPF_HEADER_W_u8(baseclass_code)
312
313 PCI_EPF_HEADER_R(cache_line_size)
314 PCI_EPF_HEADER_W_u8(cache_line_size)
315
316 PCI_EPF_HEADER_R(subsys_vendor_id)
317 PCI_EPF_HEADER_W_u16(subsys_vendor_id)
318
319 PCI_EPF_HEADER_R(subsys_id)
320 PCI_EPF_HEADER_W_u16(subsys_id)
321
322 PCI_EPF_HEADER_R(interrupt_pin)
323 PCI_EPF_HEADER_W_u8(interrupt_pin)
324
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);
337
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,
352 };
353
354 static void pci_epf_release(struct config_item *item)
355 {
356         struct pci_epf_group *epf_group = to_pci_epf_group(item);
357
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);
363 }
364
365 static struct configfs_item_operations pci_epf_ops = {
366         .release                = pci_epf_release,
367 };
368
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,
373 };
374
375 static struct config_group *pci_epf_make(struct config_group *group,
376                                          const char *name)
377 {
378         struct pci_epf_group *epf_group;
379         struct pci_epf *epf;
380         char *epf_name;
381         int index, err;
382
383         epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL);
384         if (!epf_group)
385                 return ERR_PTR(-ENOMEM);
386
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;
393         }
394
395         epf_group->index = index;
396
397         config_group_init_type_name(&epf_group->group, name, &pci_epf_type);
398
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;
404         }
405
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;
411         }
412
413         epf_group->epf = epf;
414
415         kfree(epf_name);
416
417         return &epf_group->group;
418
419 free_name:
420         kfree(epf_name);
421
422 remove_idr:
423         mutex_lock(&functions_mutex);
424         idr_remove(&functions_idr, epf_group->index);
425         mutex_unlock(&functions_mutex);
426
427 free_group:
428         kfree(epf_group);
429
430         return ERR_PTR(err);
431 }
432
433 static void pci_epf_drop(struct config_group *group, struct config_item *item)
434 {
435         config_item_put(item);
436 }
437
438 static struct configfs_group_operations pci_epf_group_ops = {
439         .make_group     = &pci_epf_make,
440         .drop_item      = &pci_epf_drop,
441 };
442
443 static const struct config_item_type pci_epf_group_type = {
444         .ct_group_ops   = &pci_epf_group_ops,
445         .ct_owner       = THIS_MODULE,
446 };
447
448 struct config_group *pci_ep_cfs_add_epf_group(const char *name)
449 {
450         struct config_group *group;
451
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);
457
458         return group;
459 }
460 EXPORT_SYMBOL(pci_ep_cfs_add_epf_group);
461
462 void pci_ep_cfs_remove_epf_group(struct config_group *group)
463 {
464         if (IS_ERR_OR_NULL(group))
465                 return;
466
467         configfs_unregister_default_group(group);
468 }
469 EXPORT_SYMBOL(pci_ep_cfs_remove_epf_group);
470
471 static const struct config_item_type pci_functions_type = {
472         .ct_owner       = THIS_MODULE,
473 };
474
475 static const struct config_item_type pci_controllers_type = {
476         .ct_owner       = THIS_MODULE,
477 };
478
479 static const struct config_item_type pci_ep_type = {
480         .ct_owner       = THIS_MODULE,
481 };
482
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,
488                 },
489         },
490         .su_mutex = __MUTEX_INITIALIZER(pci_ep_cfs_subsys.su_mutex),
491 };
492
493 static int __init pci_ep_cfs_init(void)
494 {
495         int ret;
496         struct config_group *root = &pci_ep_cfs_subsys.su_group;
497
498         config_group_init(root);
499
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;
505         }
506
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;
514         }
515
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;
524         }
525
526         return 0;
527
528 err_controllers_group:
529         configfs_unregister_default_group(functions_group);
530
531 err_functions_group:
532         configfs_unregister_subsystem(&pci_ep_cfs_subsys);
533
534 err:
535         return ret;
536 }
537 module_init(pci_ep_cfs_init);
538
539 static void __exit pci_ep_cfs_exit(void)
540 {
541         configfs_unregister_default_group(controllers_group);
542         configfs_unregister_default_group(functions_group);
543         configfs_unregister_subsystem(&pci_ep_cfs_subsys);
544 }
545 module_exit(pci_ep_cfs_exit);
546
547 MODULE_DESCRIPTION("PCI EP CONFIGFS");
548 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
549 MODULE_LICENSE("GPL v2");