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