Merge tag 'powerpc-5.2-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[sfrench/cifs-2.6.git] / drivers / misc / cxl / sysfs.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright 2014 IBM Corp.
4  */
5
6 #include <linux/kernel.h>
7 #include <linux/device.h>
8 #include <linux/sysfs.h>
9 #include <linux/pci_regs.h>
10
11 #include "cxl.h"
12
13 #define to_afu_chardev_m(d) dev_get_drvdata(d)
14
15 /*********  Adapter attributes  **********************************************/
16
17 static ssize_t caia_version_show(struct device *device,
18                                  struct device_attribute *attr,
19                                  char *buf)
20 {
21         struct cxl *adapter = to_cxl_adapter(device);
22
23         return scnprintf(buf, PAGE_SIZE, "%i.%i\n", adapter->caia_major,
24                          adapter->caia_minor);
25 }
26
27 static ssize_t psl_revision_show(struct device *device,
28                                  struct device_attribute *attr,
29                                  char *buf)
30 {
31         struct cxl *adapter = to_cxl_adapter(device);
32
33         return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->psl_rev);
34 }
35
36 static ssize_t base_image_show(struct device *device,
37                                struct device_attribute *attr,
38                                char *buf)
39 {
40         struct cxl *adapter = to_cxl_adapter(device);
41
42         return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->base_image);
43 }
44
45 static ssize_t image_loaded_show(struct device *device,
46                                  struct device_attribute *attr,
47                                  char *buf)
48 {
49         struct cxl *adapter = to_cxl_adapter(device);
50
51         if (adapter->user_image_loaded)
52                 return scnprintf(buf, PAGE_SIZE, "user\n");
53         return scnprintf(buf, PAGE_SIZE, "factory\n");
54 }
55
56 static ssize_t psl_timebase_synced_show(struct device *device,
57                                         struct device_attribute *attr,
58                                         char *buf)
59 {
60         struct cxl *adapter = to_cxl_adapter(device);
61         u64 psl_tb, delta;
62
63         /* Recompute the status only in native mode */
64         if (cpu_has_feature(CPU_FTR_HVMODE)) {
65                 psl_tb = adapter->native->sl_ops->timebase_read(adapter);
66                 delta = abs(mftb() - psl_tb);
67
68                 /* CORE TB and PSL TB difference <= 16usecs ? */
69                 adapter->psl_timebase_synced = (tb_to_ns(delta) < 16000) ? true : false;
70                 pr_devel("PSL timebase %s - delta: 0x%016llx\n",
71                          (tb_to_ns(delta) < 16000) ? "synchronized" :
72                          "not synchronized", tb_to_ns(delta));
73         }
74         return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->psl_timebase_synced);
75 }
76
77 static ssize_t tunneled_ops_supported_show(struct device *device,
78                                         struct device_attribute *attr,
79                                         char *buf)
80 {
81         struct cxl *adapter = to_cxl_adapter(device);
82
83         return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->tunneled_ops_supported);
84 }
85
86 static ssize_t reset_adapter_store(struct device *device,
87                                    struct device_attribute *attr,
88                                    const char *buf, size_t count)
89 {
90         struct cxl *adapter = to_cxl_adapter(device);
91         int rc;
92         int val;
93
94         rc = sscanf(buf, "%i", &val);
95         if ((rc != 1) || (val != 1 && val != -1))
96                 return -EINVAL;
97
98         /*
99          * See if we can lock the context mapping that's only allowed
100          * when there are no contexts attached to the adapter. Once
101          * taken this will also prevent any context from getting activated.
102          */
103         if (val == 1) {
104                 rc =  cxl_adapter_context_lock(adapter);
105                 if (rc)
106                         goto out;
107
108                 rc = cxl_ops->adapter_reset(adapter);
109                 /* In case reset failed release context lock */
110                 if (rc)
111                         cxl_adapter_context_unlock(adapter);
112
113         } else if (val == -1) {
114                 /* Perform a forced adapter reset */
115                 rc = cxl_ops->adapter_reset(adapter);
116         }
117
118 out:
119         return rc ? rc : count;
120 }
121
122 static ssize_t load_image_on_perst_show(struct device *device,
123                                  struct device_attribute *attr,
124                                  char *buf)
125 {
126         struct cxl *adapter = to_cxl_adapter(device);
127
128         if (!adapter->perst_loads_image)
129                 return scnprintf(buf, PAGE_SIZE, "none\n");
130
131         if (adapter->perst_select_user)
132                 return scnprintf(buf, PAGE_SIZE, "user\n");
133         return scnprintf(buf, PAGE_SIZE, "factory\n");
134 }
135
136 static ssize_t load_image_on_perst_store(struct device *device,
137                                  struct device_attribute *attr,
138                                  const char *buf, size_t count)
139 {
140         struct cxl *adapter = to_cxl_adapter(device);
141         int rc;
142
143         if (!strncmp(buf, "none", 4))
144                 adapter->perst_loads_image = false;
145         else if (!strncmp(buf, "user", 4)) {
146                 adapter->perst_select_user = true;
147                 adapter->perst_loads_image = true;
148         } else if (!strncmp(buf, "factory", 7)) {
149                 adapter->perst_select_user = false;
150                 adapter->perst_loads_image = true;
151         } else
152                 return -EINVAL;
153
154         if ((rc = cxl_update_image_control(adapter)))
155                 return rc;
156
157         return count;
158 }
159
160 static ssize_t perst_reloads_same_image_show(struct device *device,
161                                  struct device_attribute *attr,
162                                  char *buf)
163 {
164         struct cxl *adapter = to_cxl_adapter(device);
165
166         return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->perst_same_image);
167 }
168
169 static ssize_t perst_reloads_same_image_store(struct device *device,
170                                  struct device_attribute *attr,
171                                  const char *buf, size_t count)
172 {
173         struct cxl *adapter = to_cxl_adapter(device);
174         int rc;
175         int val;
176
177         rc = sscanf(buf, "%i", &val);
178         if ((rc != 1) || !(val == 1 || val == 0))
179                 return -EINVAL;
180
181         adapter->perst_same_image = (val == 1 ? true : false);
182         return count;
183 }
184
185 static struct device_attribute adapter_attrs[] = {
186         __ATTR_RO(caia_version),
187         __ATTR_RO(psl_revision),
188         __ATTR_RO(base_image),
189         __ATTR_RO(image_loaded),
190         __ATTR_RO(psl_timebase_synced),
191         __ATTR_RO(tunneled_ops_supported),
192         __ATTR_RW(load_image_on_perst),
193         __ATTR_RW(perst_reloads_same_image),
194         __ATTR(reset, S_IWUSR, NULL, reset_adapter_store),
195 };
196
197
198 /*********  AFU master specific attributes  **********************************/
199
200 static ssize_t mmio_size_show_master(struct device *device,
201                                      struct device_attribute *attr,
202                                      char *buf)
203 {
204         struct cxl_afu *afu = to_afu_chardev_m(device);
205
206         return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->adapter->ps_size);
207 }
208
209 static ssize_t pp_mmio_off_show(struct device *device,
210                                 struct device_attribute *attr,
211                                 char *buf)
212 {
213         struct cxl_afu *afu = to_afu_chardev_m(device);
214
215         return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->native->pp_offset);
216 }
217
218 static ssize_t pp_mmio_len_show(struct device *device,
219                                 struct device_attribute *attr,
220                                 char *buf)
221 {
222         struct cxl_afu *afu = to_afu_chardev_m(device);
223
224         return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_size);
225 }
226
227 static struct device_attribute afu_master_attrs[] = {
228         __ATTR(mmio_size, S_IRUGO, mmio_size_show_master, NULL),
229         __ATTR_RO(pp_mmio_off),
230         __ATTR_RO(pp_mmio_len),
231 };
232
233
234 /*********  AFU attributes  **************************************************/
235
236 static ssize_t mmio_size_show(struct device *device,
237                               struct device_attribute *attr,
238                               char *buf)
239 {
240         struct cxl_afu *afu = to_cxl_afu(device);
241
242         if (afu->pp_size)
243                 return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_size);
244         return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->adapter->ps_size);
245 }
246
247 static ssize_t reset_store_afu(struct device *device,
248                                struct device_attribute *attr,
249                                const char *buf, size_t count)
250 {
251         struct cxl_afu *afu = to_cxl_afu(device);
252         int rc;
253
254         /* Not safe to reset if it is currently in use */
255         mutex_lock(&afu->contexts_lock);
256         if (!idr_is_empty(&afu->contexts_idr)) {
257                 rc = -EBUSY;
258                 goto err;
259         }
260
261         if ((rc = cxl_ops->afu_reset(afu)))
262                 goto err;
263
264         rc = count;
265 err:
266         mutex_unlock(&afu->contexts_lock);
267         return rc;
268 }
269
270 static ssize_t irqs_min_show(struct device *device,
271                              struct device_attribute *attr,
272                              char *buf)
273 {
274         struct cxl_afu *afu = to_cxl_afu(device);
275
276         return scnprintf(buf, PAGE_SIZE, "%i\n", afu->pp_irqs);
277 }
278
279 static ssize_t irqs_max_show(struct device *device,
280                                   struct device_attribute *attr,
281                                   char *buf)
282 {
283         struct cxl_afu *afu = to_cxl_afu(device);
284
285         return scnprintf(buf, PAGE_SIZE, "%i\n", afu->irqs_max);
286 }
287
288 static ssize_t irqs_max_store(struct device *device,
289                                   struct device_attribute *attr,
290                                   const char *buf, size_t count)
291 {
292         struct cxl_afu *afu = to_cxl_afu(device);
293         ssize_t ret;
294         int irqs_max;
295
296         ret = sscanf(buf, "%i", &irqs_max);
297         if (ret != 1)
298                 return -EINVAL;
299
300         if (irqs_max < afu->pp_irqs)
301                 return -EINVAL;
302
303         if (cpu_has_feature(CPU_FTR_HVMODE)) {
304                 if (irqs_max > afu->adapter->user_irqs)
305                         return -EINVAL;
306         } else {
307                 /* pHyp sets a per-AFU limit */
308                 if (irqs_max > afu->guest->max_ints)
309                         return -EINVAL;
310         }
311
312         afu->irqs_max = irqs_max;
313         return count;
314 }
315
316 static ssize_t modes_supported_show(struct device *device,
317                                     struct device_attribute *attr, char *buf)
318 {
319         struct cxl_afu *afu = to_cxl_afu(device);
320         char *p = buf, *end = buf + PAGE_SIZE;
321
322         if (afu->modes_supported & CXL_MODE_DEDICATED)
323                 p += scnprintf(p, end - p, "dedicated_process\n");
324         if (afu->modes_supported & CXL_MODE_DIRECTED)
325                 p += scnprintf(p, end - p, "afu_directed\n");
326         return (p - buf);
327 }
328
329 static ssize_t prefault_mode_show(struct device *device,
330                                   struct device_attribute *attr,
331                                   char *buf)
332 {
333         struct cxl_afu *afu = to_cxl_afu(device);
334
335         switch (afu->prefault_mode) {
336         case CXL_PREFAULT_WED:
337                 return scnprintf(buf, PAGE_SIZE, "work_element_descriptor\n");
338         case CXL_PREFAULT_ALL:
339                 return scnprintf(buf, PAGE_SIZE, "all\n");
340         default:
341                 return scnprintf(buf, PAGE_SIZE, "none\n");
342         }
343 }
344
345 static ssize_t prefault_mode_store(struct device *device,
346                           struct device_attribute *attr,
347                           const char *buf, size_t count)
348 {
349         struct cxl_afu *afu = to_cxl_afu(device);
350         enum prefault_modes mode = -1;
351
352         if (!strncmp(buf, "none", 4))
353                 mode = CXL_PREFAULT_NONE;
354         else {
355                 if (!radix_enabled()) {
356
357                         /* only allowed when not in radix mode */
358                         if (!strncmp(buf, "work_element_descriptor", 23))
359                                 mode = CXL_PREFAULT_WED;
360                         if (!strncmp(buf, "all", 3))
361                                 mode = CXL_PREFAULT_ALL;
362                 } else {
363                         dev_err(device, "Cannot prefault with radix enabled\n");
364                 }
365         }
366
367         if (mode == -1)
368                 return -EINVAL;
369
370         afu->prefault_mode = mode;
371         return count;
372 }
373
374 static ssize_t mode_show(struct device *device,
375                          struct device_attribute *attr,
376                          char *buf)
377 {
378         struct cxl_afu *afu = to_cxl_afu(device);
379
380         if (afu->current_mode == CXL_MODE_DEDICATED)
381                 return scnprintf(buf, PAGE_SIZE, "dedicated_process\n");
382         if (afu->current_mode == CXL_MODE_DIRECTED)
383                 return scnprintf(buf, PAGE_SIZE, "afu_directed\n");
384         return scnprintf(buf, PAGE_SIZE, "none\n");
385 }
386
387 static ssize_t mode_store(struct device *device, struct device_attribute *attr,
388                           const char *buf, size_t count)
389 {
390         struct cxl_afu *afu = to_cxl_afu(device);
391         int old_mode, mode = -1;
392         int rc = -EBUSY;
393
394         /* can't change this if we have a user */
395         mutex_lock(&afu->contexts_lock);
396         if (!idr_is_empty(&afu->contexts_idr))
397                 goto err;
398
399         if (!strncmp(buf, "dedicated_process", 17))
400                 mode = CXL_MODE_DEDICATED;
401         if (!strncmp(buf, "afu_directed", 12))
402                 mode = CXL_MODE_DIRECTED;
403         if (!strncmp(buf, "none", 4))
404                 mode = 0;
405
406         if (mode == -1) {
407                 rc = -EINVAL;
408                 goto err;
409         }
410
411         /*
412          * afu_deactivate_mode needs to be done outside the lock, prevent
413          * other contexts coming in before we are ready:
414          */
415         old_mode = afu->current_mode;
416         afu->current_mode = 0;
417         afu->num_procs = 0;
418
419         mutex_unlock(&afu->contexts_lock);
420
421         if ((rc = cxl_ops->afu_deactivate_mode(afu, old_mode)))
422                 return rc;
423         if ((rc = cxl_ops->afu_activate_mode(afu, mode)))
424                 return rc;
425
426         return count;
427 err:
428         mutex_unlock(&afu->contexts_lock);
429         return rc;
430 }
431
432 static ssize_t api_version_show(struct device *device,
433                                 struct device_attribute *attr,
434                                 char *buf)
435 {
436         return scnprintf(buf, PAGE_SIZE, "%i\n", CXL_API_VERSION);
437 }
438
439 static ssize_t api_version_compatible_show(struct device *device,
440                                            struct device_attribute *attr,
441                                            char *buf)
442 {
443         return scnprintf(buf, PAGE_SIZE, "%i\n", CXL_API_VERSION_COMPATIBLE);
444 }
445
446 static ssize_t afu_eb_read(struct file *filp, struct kobject *kobj,
447                                struct bin_attribute *bin_attr, char *buf,
448                                loff_t off, size_t count)
449 {
450         struct cxl_afu *afu = to_cxl_afu(kobj_to_dev(kobj));
451
452         return cxl_ops->afu_read_err_buffer(afu, buf, off, count);
453 }
454
455 static struct device_attribute afu_attrs[] = {
456         __ATTR_RO(mmio_size),
457         __ATTR_RO(irqs_min),
458         __ATTR_RW(irqs_max),
459         __ATTR_RO(modes_supported),
460         __ATTR_RW(mode),
461         __ATTR_RW(prefault_mode),
462         __ATTR_RO(api_version),
463         __ATTR_RO(api_version_compatible),
464         __ATTR(reset, S_IWUSR, NULL, reset_store_afu),
465 };
466
467 int cxl_sysfs_adapter_add(struct cxl *adapter)
468 {
469         struct device_attribute *dev_attr;
470         int i, rc;
471
472         for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) {
473                 dev_attr = &adapter_attrs[i];
474                 if (cxl_ops->support_attributes(dev_attr->attr.name,
475                                                 CXL_ADAPTER_ATTRS)) {
476                         if ((rc = device_create_file(&adapter->dev, dev_attr)))
477                                 goto err;
478                 }
479         }
480         return 0;
481 err:
482         for (i--; i >= 0; i--) {
483                 dev_attr = &adapter_attrs[i];
484                 if (cxl_ops->support_attributes(dev_attr->attr.name,
485                                                 CXL_ADAPTER_ATTRS))
486                         device_remove_file(&adapter->dev, dev_attr);
487         }
488         return rc;
489 }
490
491 void cxl_sysfs_adapter_remove(struct cxl *adapter)
492 {
493         struct device_attribute *dev_attr;
494         int i;
495
496         for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) {
497                 dev_attr = &adapter_attrs[i];
498                 if (cxl_ops->support_attributes(dev_attr->attr.name,
499                                                 CXL_ADAPTER_ATTRS))
500                         device_remove_file(&adapter->dev, dev_attr);
501         }
502 }
503
504 struct afu_config_record {
505         struct kobject kobj;
506         struct bin_attribute config_attr;
507         struct list_head list;
508         int cr;
509         u16 device;
510         u16 vendor;
511         u32 class;
512 };
513
514 #define to_cr(obj) container_of(obj, struct afu_config_record, kobj)
515
516 static ssize_t vendor_show(struct kobject *kobj,
517                            struct kobj_attribute *attr, char *buf)
518 {
519         struct afu_config_record *cr = to_cr(kobj);
520
521         return scnprintf(buf, PAGE_SIZE, "0x%.4x\n", cr->vendor);
522 }
523
524 static ssize_t device_show(struct kobject *kobj,
525                            struct kobj_attribute *attr, char *buf)
526 {
527         struct afu_config_record *cr = to_cr(kobj);
528
529         return scnprintf(buf, PAGE_SIZE, "0x%.4x\n", cr->device);
530 }
531
532 static ssize_t class_show(struct kobject *kobj,
533                           struct kobj_attribute *attr, char *buf)
534 {
535         struct afu_config_record *cr = to_cr(kobj);
536
537         return scnprintf(buf, PAGE_SIZE, "0x%.6x\n", cr->class);
538 }
539
540 static ssize_t afu_read_config(struct file *filp, struct kobject *kobj,
541                                struct bin_attribute *bin_attr, char *buf,
542                                loff_t off, size_t count)
543 {
544         struct afu_config_record *cr = to_cr(kobj);
545         struct cxl_afu *afu = to_cxl_afu(kobj_to_dev(kobj->parent));
546
547         u64 i, j, val, rc;
548
549         for (i = 0; i < count;) {
550                 rc = cxl_ops->afu_cr_read64(afu, cr->cr, off & ~0x7, &val);
551                 if (rc)
552                         val = ~0ULL;
553                 for (j = off & 0x7; j < 8 && i < count; i++, j++, off++)
554                         buf[i] = (val >> (j * 8)) & 0xff;
555         }
556
557         return count;
558 }
559
560 static struct kobj_attribute vendor_attribute =
561         __ATTR_RO(vendor);
562 static struct kobj_attribute device_attribute =
563         __ATTR_RO(device);
564 static struct kobj_attribute class_attribute =
565         __ATTR_RO(class);
566
567 static struct attribute *afu_cr_attrs[] = {
568         &vendor_attribute.attr,
569         &device_attribute.attr,
570         &class_attribute.attr,
571         NULL,
572 };
573
574 static void release_afu_config_record(struct kobject *kobj)
575 {
576         struct afu_config_record *cr = to_cr(kobj);
577
578         kfree(cr);
579 }
580
581 static struct kobj_type afu_config_record_type = {
582         .sysfs_ops = &kobj_sysfs_ops,
583         .release = release_afu_config_record,
584         .default_attrs = afu_cr_attrs,
585 };
586
587 static struct afu_config_record *cxl_sysfs_afu_new_cr(struct cxl_afu *afu, int cr_idx)
588 {
589         struct afu_config_record *cr;
590         int rc;
591
592         cr = kzalloc(sizeof(struct afu_config_record), GFP_KERNEL);
593         if (!cr)
594                 return ERR_PTR(-ENOMEM);
595
596         cr->cr = cr_idx;
597
598         rc = cxl_ops->afu_cr_read16(afu, cr_idx, PCI_DEVICE_ID, &cr->device);
599         if (rc)
600                 goto err;
601         rc = cxl_ops->afu_cr_read16(afu, cr_idx, PCI_VENDOR_ID, &cr->vendor);
602         if (rc)
603                 goto err;
604         rc = cxl_ops->afu_cr_read32(afu, cr_idx, PCI_CLASS_REVISION, &cr->class);
605         if (rc)
606                 goto err;
607         cr->class >>= 8;
608
609         /*
610          * Export raw AFU PCIe like config record. For now this is read only by
611          * root - we can expand that later to be readable by non-root and maybe
612          * even writable provided we have a good use-case. Once we support
613          * exposing AFUs through a virtual PHB they will get that for free from
614          * Linux' PCI infrastructure, but until then it's not clear that we
615          * need it for anything since the main use case is just identifying
616          * AFUs, which can be done via the vendor, device and class attributes.
617          */
618         sysfs_bin_attr_init(&cr->config_attr);
619         cr->config_attr.attr.name = "config";
620         cr->config_attr.attr.mode = S_IRUSR;
621         cr->config_attr.size = afu->crs_len;
622         cr->config_attr.read = afu_read_config;
623
624         rc = kobject_init_and_add(&cr->kobj, &afu_config_record_type,
625                                   &afu->dev.kobj, "cr%i", cr->cr);
626         if (rc)
627                 goto err;
628
629         rc = sysfs_create_bin_file(&cr->kobj, &cr->config_attr);
630         if (rc)
631                 goto err1;
632
633         rc = kobject_uevent(&cr->kobj, KOBJ_ADD);
634         if (rc)
635                 goto err2;
636
637         return cr;
638 err2:
639         sysfs_remove_bin_file(&cr->kobj, &cr->config_attr);
640 err1:
641         kobject_put(&cr->kobj);
642         return ERR_PTR(rc);
643 err:
644         kfree(cr);
645         return ERR_PTR(rc);
646 }
647
648 void cxl_sysfs_afu_remove(struct cxl_afu *afu)
649 {
650         struct device_attribute *dev_attr;
651         struct afu_config_record *cr, *tmp;
652         int i;
653
654         /* remove the err buffer bin attribute */
655         if (afu->eb_len)
656                 device_remove_bin_file(&afu->dev, &afu->attr_eb);
657
658         for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) {
659                 dev_attr = &afu_attrs[i];
660                 if (cxl_ops->support_attributes(dev_attr->attr.name,
661                                                 CXL_AFU_ATTRS))
662                         device_remove_file(&afu->dev, &afu_attrs[i]);
663         }
664
665         list_for_each_entry_safe(cr, tmp, &afu->crs, list) {
666                 sysfs_remove_bin_file(&cr->kobj, &cr->config_attr);
667                 kobject_put(&cr->kobj);
668         }
669 }
670
671 int cxl_sysfs_afu_add(struct cxl_afu *afu)
672 {
673         struct device_attribute *dev_attr;
674         struct afu_config_record *cr;
675         int i, rc;
676
677         INIT_LIST_HEAD(&afu->crs);
678
679         for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) {
680                 dev_attr = &afu_attrs[i];
681                 if (cxl_ops->support_attributes(dev_attr->attr.name,
682                                                 CXL_AFU_ATTRS)) {
683                         if ((rc = device_create_file(&afu->dev, &afu_attrs[i])))
684                                 goto err;
685                 }
686         }
687
688         /* conditionally create the add the binary file for error info buffer */
689         if (afu->eb_len) {
690                 sysfs_attr_init(&afu->attr_eb.attr);
691
692                 afu->attr_eb.attr.name = "afu_err_buff";
693                 afu->attr_eb.attr.mode = S_IRUGO;
694                 afu->attr_eb.size = afu->eb_len;
695                 afu->attr_eb.read = afu_eb_read;
696
697                 rc = device_create_bin_file(&afu->dev, &afu->attr_eb);
698                 if (rc) {
699                         dev_err(&afu->dev,
700                                 "Unable to create eb attr for the afu. Err(%d)\n",
701                                 rc);
702                         goto err;
703                 }
704         }
705
706         for (i = 0; i < afu->crs_num; i++) {
707                 cr = cxl_sysfs_afu_new_cr(afu, i);
708                 if (IS_ERR(cr)) {
709                         rc = PTR_ERR(cr);
710                         goto err1;
711                 }
712                 list_add(&cr->list, &afu->crs);
713         }
714
715         return 0;
716
717 err1:
718         cxl_sysfs_afu_remove(afu);
719         return rc;
720 err:
721         /* reset the eb_len as we havent created the bin attr */
722         afu->eb_len = 0;
723
724         for (i--; i >= 0; i--) {
725                 dev_attr = &afu_attrs[i];
726                 if (cxl_ops->support_attributes(dev_attr->attr.name,
727                                                 CXL_AFU_ATTRS))
728                 device_remove_file(&afu->dev, &afu_attrs[i]);
729         }
730         return rc;
731 }
732
733 int cxl_sysfs_afu_m_add(struct cxl_afu *afu)
734 {
735         struct device_attribute *dev_attr;
736         int i, rc;
737
738         for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) {
739                 dev_attr = &afu_master_attrs[i];
740                 if (cxl_ops->support_attributes(dev_attr->attr.name,
741                                                 CXL_AFU_MASTER_ATTRS)) {
742                         if ((rc = device_create_file(afu->chardev_m, &afu_master_attrs[i])))
743                                 goto err;
744                 }
745         }
746
747         return 0;
748
749 err:
750         for (i--; i >= 0; i--) {
751                 dev_attr = &afu_master_attrs[i];
752                 if (cxl_ops->support_attributes(dev_attr->attr.name,
753                                                 CXL_AFU_MASTER_ATTRS))
754                         device_remove_file(afu->chardev_m, &afu_master_attrs[i]);
755         }
756         return rc;
757 }
758
759 void cxl_sysfs_afu_m_remove(struct cxl_afu *afu)
760 {
761         struct device_attribute *dev_attr;
762         int i;
763
764         for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) {
765                 dev_attr = &afu_master_attrs[i];
766                 if (cxl_ops->support_attributes(dev_attr->attr.name,
767                                                 CXL_AFU_MASTER_ATTRS))
768                         device_remove_file(afu->chardev_m, &afu_master_attrs[i]);
769         }
770 }