GNU Linux-libre 4.14.251-gnu1
[releases.git] / drivers / pci / endpoint / pci-ep-cfs.c
1 /**
2  * configfs to configure the PCI endpoint
3  *
4  * Copyright (C) 2017 Texas Instruments
5  * Author: Kishon Vijay Abraham I <kishon@ti.com>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 of
9  * the License as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <linux/module.h>
21 #include <linux/slab.h>
22
23 #include <linux/pci-epc.h>
24 #include <linux/pci-epf.h>
25 #include <linux/pci-ep-cfs.h>
26
27 static struct config_group *functions_group;
28 static struct config_group *controllers_group;
29
30 struct pci_epf_group {
31         struct config_group group;
32         struct pci_epf *epf;
33 };
34
35 struct pci_epc_group {
36         struct config_group group;
37         struct pci_epc *epc;
38         bool start;
39         unsigned long function_num_map;
40 };
41
42 static inline struct pci_epf_group *to_pci_epf_group(struct config_item *item)
43 {
44         return container_of(to_config_group(item), struct pci_epf_group, group);
45 }
46
47 static inline struct pci_epc_group *to_pci_epc_group(struct config_item *item)
48 {
49         return container_of(to_config_group(item), struct pci_epc_group, group);
50 }
51
52 static ssize_t pci_epc_start_store(struct config_item *item, const char *page,
53                                    size_t len)
54 {
55         int ret;
56         bool start;
57         struct pci_epc *epc;
58         struct pci_epc_group *epc_group = to_pci_epc_group(item);
59
60         epc = epc_group->epc;
61
62         ret = kstrtobool(page, &start);
63         if (ret)
64                 return ret;
65
66         if (!start) {
67                 pci_epc_stop(epc);
68                 return len;
69         }
70
71         ret = pci_epc_start(epc);
72         if (ret) {
73                 dev_err(&epc->dev, "failed to start endpoint controller\n");
74                 return -EINVAL;
75         }
76
77         epc_group->start = start;
78
79         return len;
80 }
81
82 static ssize_t pci_epc_start_show(struct config_item *item, char *page)
83 {
84         return sprintf(page, "%d\n",
85                        to_pci_epc_group(item)->start);
86 }
87
88 CONFIGFS_ATTR(pci_epc_, start);
89
90 static struct configfs_attribute *pci_epc_attrs[] = {
91         &pci_epc_attr_start,
92         NULL,
93 };
94
95 static int pci_epc_epf_link(struct config_item *epc_item,
96                             struct config_item *epf_item)
97 {
98         int ret;
99         u32 func_no = 0;
100         struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
101         struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
102         struct pci_epc *epc = epc_group->epc;
103         struct pci_epf *epf = epf_group->epf;
104
105         func_no = find_first_zero_bit(&epc_group->function_num_map,
106                                       BITS_PER_LONG);
107         if (func_no >= BITS_PER_LONG)
108                 return -EINVAL;
109
110         set_bit(func_no, &epc_group->function_num_map);
111         epf->func_no = func_no;
112
113         ret = pci_epc_add_epf(epc, epf);
114         if (ret)
115                 goto err_add_epf;
116
117         ret = pci_epf_bind(epf);
118         if (ret)
119                 goto err_epf_bind;
120
121         return 0;
122
123 err_epf_bind:
124         pci_epc_remove_epf(epc, epf);
125
126 err_add_epf:
127         clear_bit(func_no, &epc_group->function_num_map);
128
129         return ret;
130 }
131
132 static void pci_epc_epf_unlink(struct config_item *epc_item,
133                                struct config_item *epf_item)
134 {
135         struct pci_epc *epc;
136         struct pci_epf *epf;
137         struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
138         struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
139
140         WARN_ON_ONCE(epc_group->start);
141
142         epc = epc_group->epc;
143         epf = epf_group->epf;
144         clear_bit(epf->func_no, &epc_group->function_num_map);
145         pci_epf_unbind(epf);
146         pci_epc_remove_epf(epc, epf);
147 }
148
149 static struct configfs_item_operations pci_epc_item_ops = {
150         .allow_link     = pci_epc_epf_link,
151         .drop_link      = pci_epc_epf_unlink,
152 };
153
154 static struct config_item_type pci_epc_type = {
155         .ct_item_ops    = &pci_epc_item_ops,
156         .ct_attrs       = pci_epc_attrs,
157         .ct_owner       = THIS_MODULE,
158 };
159
160 struct config_group *pci_ep_cfs_add_epc_group(const char *name)
161 {
162         int ret;
163         struct pci_epc *epc;
164         struct config_group *group;
165         struct pci_epc_group *epc_group;
166
167         epc_group = kzalloc(sizeof(*epc_group), GFP_KERNEL);
168         if (!epc_group) {
169                 ret = -ENOMEM;
170                 goto err;
171         }
172
173         group = &epc_group->group;
174
175         config_group_init_type_name(group, name, &pci_epc_type);
176         ret = configfs_register_group(controllers_group, group);
177         if (ret) {
178                 pr_err("failed to register configfs group for %s\n", name);
179                 goto err_register_group;
180         }
181
182         epc = pci_epc_get(name);
183         if (IS_ERR(epc)) {
184                 ret = PTR_ERR(epc);
185                 goto err_epc_get;
186         }
187
188         epc_group->epc = epc;
189
190         return group;
191
192 err_epc_get:
193         configfs_unregister_group(group);
194
195 err_register_group:
196         kfree(epc_group);
197
198 err:
199         return ERR_PTR(ret);
200 }
201 EXPORT_SYMBOL(pci_ep_cfs_add_epc_group);
202
203 void pci_ep_cfs_remove_epc_group(struct config_group *group)
204 {
205         struct pci_epc_group *epc_group;
206
207         if (!group)
208                 return;
209
210         epc_group = container_of(group, struct pci_epc_group, group);
211         pci_epc_put(epc_group->epc);
212         configfs_unregister_group(&epc_group->group);
213         kfree(epc_group);
214 }
215 EXPORT_SYMBOL(pci_ep_cfs_remove_epc_group);
216
217 #define PCI_EPF_HEADER_R(_name)                                                \
218 static ssize_t pci_epf_##_name##_show(struct config_item *item, char *page)    \
219 {                                                                              \
220         struct pci_epf *epf = to_pci_epf_group(item)->epf;                     \
221         if (WARN_ON_ONCE(!epf->header))                                        \
222                 return -EINVAL;                                                \
223         return sprintf(page, "0x%04x\n", epf->header->_name);                  \
224 }
225
226 #define PCI_EPF_HEADER_W_u32(_name)                                            \
227 static ssize_t pci_epf_##_name##_store(struct config_item *item,               \
228                                        const char *page, size_t len)           \
229 {                                                                              \
230         u32 val;                                                               \
231         int ret;                                                               \
232         struct pci_epf *epf = to_pci_epf_group(item)->epf;                     \
233         if (WARN_ON_ONCE(!epf->header))                                        \
234                 return -EINVAL;                                                \
235         ret = kstrtou32(page, 0, &val);                                        \
236         if (ret)                                                               \
237                 return ret;                                                    \
238         epf->header->_name = val;                                              \
239         return len;                                                            \
240 }
241
242 #define PCI_EPF_HEADER_W_u16(_name)                                            \
243 static ssize_t pci_epf_##_name##_store(struct config_item *item,               \
244                                        const char *page, size_t len)           \
245 {                                                                              \
246         u16 val;                                                               \
247         int ret;                                                               \
248         struct pci_epf *epf = to_pci_epf_group(item)->epf;                     \
249         if (WARN_ON_ONCE(!epf->header))                                        \
250                 return -EINVAL;                                                \
251         ret = kstrtou16(page, 0, &val);                                        \
252         if (ret)                                                               \
253                 return ret;                                                    \
254         epf->header->_name = val;                                              \
255         return len;                                                            \
256 }
257
258 #define PCI_EPF_HEADER_W_u8(_name)                                             \
259 static ssize_t pci_epf_##_name##_store(struct config_item *item,               \
260                                        const char *page, size_t len)           \
261 {                                                                              \
262         u8 val;                                                                \
263         int ret;                                                               \
264         struct pci_epf *epf = to_pci_epf_group(item)->epf;                     \
265         if (WARN_ON_ONCE(!epf->header))                                        \
266                 return -EINVAL;                                                \
267         ret = kstrtou8(page, 0, &val);                                         \
268         if (ret)                                                               \
269                 return ret;                                                    \
270         epf->header->_name = val;                                              \
271         return len;                                                            \
272 }
273
274 static ssize_t pci_epf_msi_interrupts_store(struct config_item *item,
275                                             const char *page, size_t len)
276 {
277         u8 val;
278         int ret;
279
280         ret = kstrtou8(page, 0, &val);
281         if (ret)
282                 return ret;
283
284         to_pci_epf_group(item)->epf->msi_interrupts = val;
285
286         return len;
287 }
288
289 static ssize_t pci_epf_msi_interrupts_show(struct config_item *item,
290                                            char *page)
291 {
292         return sprintf(page, "%d\n",
293                        to_pci_epf_group(item)->epf->msi_interrupts);
294 }
295
296 PCI_EPF_HEADER_R(vendorid)
297 PCI_EPF_HEADER_W_u16(vendorid)
298
299 PCI_EPF_HEADER_R(deviceid)
300 PCI_EPF_HEADER_W_u16(deviceid)
301
302 PCI_EPF_HEADER_R(revid)
303 PCI_EPF_HEADER_W_u8(revid)
304
305 PCI_EPF_HEADER_R(progif_code)
306 PCI_EPF_HEADER_W_u8(progif_code)
307
308 PCI_EPF_HEADER_R(subclass_code)
309 PCI_EPF_HEADER_W_u8(subclass_code)
310
311 PCI_EPF_HEADER_R(baseclass_code)
312 PCI_EPF_HEADER_W_u8(baseclass_code)
313
314 PCI_EPF_HEADER_R(cache_line_size)
315 PCI_EPF_HEADER_W_u8(cache_line_size)
316
317 PCI_EPF_HEADER_R(subsys_vendor_id)
318 PCI_EPF_HEADER_W_u16(subsys_vendor_id)
319
320 PCI_EPF_HEADER_R(subsys_id)
321 PCI_EPF_HEADER_W_u16(subsys_id)
322
323 PCI_EPF_HEADER_R(interrupt_pin)
324 PCI_EPF_HEADER_W_u8(interrupt_pin)
325
326 CONFIGFS_ATTR(pci_epf_, vendorid);
327 CONFIGFS_ATTR(pci_epf_, deviceid);
328 CONFIGFS_ATTR(pci_epf_, revid);
329 CONFIGFS_ATTR(pci_epf_, progif_code);
330 CONFIGFS_ATTR(pci_epf_, subclass_code);
331 CONFIGFS_ATTR(pci_epf_, baseclass_code);
332 CONFIGFS_ATTR(pci_epf_, cache_line_size);
333 CONFIGFS_ATTR(pci_epf_, subsys_vendor_id);
334 CONFIGFS_ATTR(pci_epf_, subsys_id);
335 CONFIGFS_ATTR(pci_epf_, interrupt_pin);
336 CONFIGFS_ATTR(pci_epf_, msi_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         NULL,
351 };
352
353 static void pci_epf_release(struct config_item *item)
354 {
355         struct pci_epf_group *epf_group = to_pci_epf_group(item);
356
357         pci_epf_destroy(epf_group->epf);
358         kfree(epf_group);
359 }
360
361 static struct configfs_item_operations pci_epf_ops = {
362         .release                = pci_epf_release,
363 };
364
365 static struct config_item_type pci_epf_type = {
366         .ct_item_ops    = &pci_epf_ops,
367         .ct_attrs       = pci_epf_attrs,
368         .ct_owner       = THIS_MODULE,
369 };
370
371 static struct config_group *pci_epf_make(struct config_group *group,
372                                          const char *name)
373 {
374         struct pci_epf_group *epf_group;
375         struct pci_epf *epf;
376
377         epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL);
378         if (!epf_group)
379                 return ERR_PTR(-ENOMEM);
380
381         config_group_init_type_name(&epf_group->group, name, &pci_epf_type);
382
383         epf = pci_epf_create(group->cg_item.ci_name);
384         if (IS_ERR(epf)) {
385                 pr_err("failed to create endpoint function device\n");
386                 return ERR_PTR(-EINVAL);
387         }
388
389         epf_group->epf = epf;
390
391         return &epf_group->group;
392 }
393
394 static void pci_epf_drop(struct config_group *group, struct config_item *item)
395 {
396         config_item_put(item);
397 }
398
399 static struct configfs_group_operations pci_epf_group_ops = {
400         .make_group     = &pci_epf_make,
401         .drop_item      = &pci_epf_drop,
402 };
403
404 static struct config_item_type pci_epf_group_type = {
405         .ct_group_ops   = &pci_epf_group_ops,
406         .ct_owner       = THIS_MODULE,
407 };
408
409 struct config_group *pci_ep_cfs_add_epf_group(const char *name)
410 {
411         struct config_group *group;
412
413         group = configfs_register_default_group(functions_group, name,
414                                                 &pci_epf_group_type);
415         if (IS_ERR(group))
416                 pr_err("failed to register configfs group for %s function\n",
417                        name);
418
419         return group;
420 }
421 EXPORT_SYMBOL(pci_ep_cfs_add_epf_group);
422
423 void pci_ep_cfs_remove_epf_group(struct config_group *group)
424 {
425         if (IS_ERR_OR_NULL(group))
426                 return;
427
428         configfs_unregister_default_group(group);
429 }
430 EXPORT_SYMBOL(pci_ep_cfs_remove_epf_group);
431
432 static struct config_item_type pci_functions_type = {
433         .ct_owner       = THIS_MODULE,
434 };
435
436 static struct config_item_type pci_controllers_type = {
437         .ct_owner       = THIS_MODULE,
438 };
439
440 static struct config_item_type pci_ep_type = {
441         .ct_owner       = THIS_MODULE,
442 };
443
444 static struct configfs_subsystem pci_ep_cfs_subsys = {
445         .su_group = {
446                 .cg_item = {
447                         .ci_namebuf = "pci_ep",
448                         .ci_type = &pci_ep_type,
449                 },
450         },
451         .su_mutex = __MUTEX_INITIALIZER(pci_ep_cfs_subsys.su_mutex),
452 };
453
454 static int __init pci_ep_cfs_init(void)
455 {
456         int ret;
457         struct config_group *root = &pci_ep_cfs_subsys.su_group;
458
459         config_group_init(root);
460
461         ret = configfs_register_subsystem(&pci_ep_cfs_subsys);
462         if (ret) {
463                 pr_err("Error %d while registering subsystem %s\n",
464                        ret, root->cg_item.ci_namebuf);
465                 goto err;
466         }
467
468         functions_group = configfs_register_default_group(root, "functions",
469                                                           &pci_functions_type);
470         if (IS_ERR(functions_group)) {
471                 ret = PTR_ERR(functions_group);
472                 pr_err("Error %d while registering functions group\n",
473                        ret);
474                 goto err_functions_group;
475         }
476
477         controllers_group =
478                 configfs_register_default_group(root, "controllers",
479                                                 &pci_controllers_type);
480         if (IS_ERR(controllers_group)) {
481                 ret = PTR_ERR(controllers_group);
482                 pr_err("Error %d while registering controllers group\n",
483                        ret);
484                 goto err_controllers_group;
485         }
486
487         return 0;
488
489 err_controllers_group:
490         configfs_unregister_default_group(functions_group);
491
492 err_functions_group:
493         configfs_unregister_subsystem(&pci_ep_cfs_subsys);
494
495 err:
496         return ret;
497 }
498 module_init(pci_ep_cfs_init);
499
500 static void __exit pci_ep_cfs_exit(void)
501 {
502         configfs_unregister_default_group(controllers_group);
503         configfs_unregister_default_group(functions_group);
504         configfs_unregister_subsystem(&pci_ep_cfs_subsys);
505 }
506 module_exit(pci_ep_cfs_exit);
507
508 MODULE_DESCRIPTION("PCI EP CONFIGFS");
509 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
510 MODULE_LICENSE("GPL v2");