1f204e0b8SIan Munsie /* 2f204e0b8SIan Munsie * Copyright 2014 IBM Corp. 3f204e0b8SIan Munsie * 4f204e0b8SIan Munsie * This program is free software; you can redistribute it and/or 5f204e0b8SIan Munsie * modify it under the terms of the GNU General Public License 6f204e0b8SIan Munsie * as published by the Free Software Foundation; either version 7f204e0b8SIan Munsie * 2 of the License, or (at your option) any later version. 8f204e0b8SIan Munsie */ 9f204e0b8SIan Munsie 10f204e0b8SIan Munsie #include <linux/kernel.h> 11f204e0b8SIan Munsie #include <linux/device.h> 12f204e0b8SIan Munsie #include <linux/sysfs.h> 13f204e0b8SIan Munsie 14f204e0b8SIan Munsie #include "cxl.h" 15f204e0b8SIan Munsie 16f204e0b8SIan Munsie #define to_afu_chardev_m(d) dev_get_drvdata(d) 17f204e0b8SIan Munsie 18f204e0b8SIan Munsie /********* Adapter attributes **********************************************/ 19f204e0b8SIan Munsie 20f204e0b8SIan Munsie static ssize_t caia_version_show(struct device *device, 21f204e0b8SIan Munsie struct device_attribute *attr, 22f204e0b8SIan Munsie char *buf) 23f204e0b8SIan Munsie { 24f204e0b8SIan Munsie struct cxl *adapter = to_cxl_adapter(device); 25f204e0b8SIan Munsie 26f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "%i.%i\n", adapter->caia_major, 27f204e0b8SIan Munsie adapter->caia_minor); 28f204e0b8SIan Munsie } 29f204e0b8SIan Munsie 30f204e0b8SIan Munsie static ssize_t psl_revision_show(struct device *device, 31f204e0b8SIan Munsie struct device_attribute *attr, 32f204e0b8SIan Munsie char *buf) 33f204e0b8SIan Munsie { 34f204e0b8SIan Munsie struct cxl *adapter = to_cxl_adapter(device); 35f204e0b8SIan Munsie 36f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->psl_rev); 37f204e0b8SIan Munsie } 38f204e0b8SIan Munsie 39f204e0b8SIan Munsie static ssize_t base_image_show(struct device *device, 40f204e0b8SIan Munsie struct device_attribute *attr, 41f204e0b8SIan Munsie char *buf) 42f204e0b8SIan Munsie { 43f204e0b8SIan Munsie struct cxl *adapter = to_cxl_adapter(device); 44f204e0b8SIan Munsie 45f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->base_image); 46f204e0b8SIan Munsie } 47f204e0b8SIan Munsie 48f204e0b8SIan Munsie static ssize_t image_loaded_show(struct device *device, 49f204e0b8SIan Munsie struct device_attribute *attr, 50f204e0b8SIan Munsie char *buf) 51f204e0b8SIan Munsie { 52f204e0b8SIan Munsie struct cxl *adapter = to_cxl_adapter(device); 53f204e0b8SIan Munsie 54f204e0b8SIan Munsie if (adapter->user_image_loaded) 55f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "user\n"); 56f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "factory\n"); 57f204e0b8SIan Munsie } 58f204e0b8SIan Munsie 59*95bc11bcSRyan Grimm static ssize_t load_image_on_perst_show(struct device *device, 60*95bc11bcSRyan Grimm struct device_attribute *attr, 61*95bc11bcSRyan Grimm char *buf) 62*95bc11bcSRyan Grimm { 63*95bc11bcSRyan Grimm struct cxl *adapter = to_cxl_adapter(device); 64*95bc11bcSRyan Grimm 65*95bc11bcSRyan Grimm if (!adapter->perst_loads_image) 66*95bc11bcSRyan Grimm return scnprintf(buf, PAGE_SIZE, "none\n"); 67*95bc11bcSRyan Grimm 68*95bc11bcSRyan Grimm if (adapter->perst_select_user) 69*95bc11bcSRyan Grimm return scnprintf(buf, PAGE_SIZE, "user\n"); 70*95bc11bcSRyan Grimm return scnprintf(buf, PAGE_SIZE, "factory\n"); 71*95bc11bcSRyan Grimm } 72*95bc11bcSRyan Grimm 73*95bc11bcSRyan Grimm static ssize_t load_image_on_perst_store(struct device *device, 74*95bc11bcSRyan Grimm struct device_attribute *attr, 75*95bc11bcSRyan Grimm const char *buf, size_t count) 76*95bc11bcSRyan Grimm { 77*95bc11bcSRyan Grimm struct cxl *adapter = to_cxl_adapter(device); 78*95bc11bcSRyan Grimm int rc; 79*95bc11bcSRyan Grimm 80*95bc11bcSRyan Grimm if (!strncmp(buf, "none", 4)) 81*95bc11bcSRyan Grimm adapter->perst_loads_image = false; 82*95bc11bcSRyan Grimm else if (!strncmp(buf, "user", 4)) { 83*95bc11bcSRyan Grimm adapter->perst_select_user = true; 84*95bc11bcSRyan Grimm adapter->perst_loads_image = true; 85*95bc11bcSRyan Grimm } else if (!strncmp(buf, "factory", 7)) { 86*95bc11bcSRyan Grimm adapter->perst_select_user = false; 87*95bc11bcSRyan Grimm adapter->perst_loads_image = true; 88*95bc11bcSRyan Grimm } else 89*95bc11bcSRyan Grimm return -EINVAL; 90*95bc11bcSRyan Grimm 91*95bc11bcSRyan Grimm if ((rc = cxl_update_image_control(adapter))) 92*95bc11bcSRyan Grimm return rc; 93*95bc11bcSRyan Grimm 94*95bc11bcSRyan Grimm return count; 95*95bc11bcSRyan Grimm } 96*95bc11bcSRyan Grimm 97f204e0b8SIan Munsie static struct device_attribute adapter_attrs[] = { 98f204e0b8SIan Munsie __ATTR_RO(caia_version), 99f204e0b8SIan Munsie __ATTR_RO(psl_revision), 100f204e0b8SIan Munsie __ATTR_RO(base_image), 101f204e0b8SIan Munsie __ATTR_RO(image_loaded), 102*95bc11bcSRyan Grimm __ATTR_RW(load_image_on_perst), 103f204e0b8SIan Munsie }; 104f204e0b8SIan Munsie 105f204e0b8SIan Munsie 106f204e0b8SIan Munsie /********* AFU master specific attributes **********************************/ 107f204e0b8SIan Munsie 108f204e0b8SIan Munsie static ssize_t mmio_size_show_master(struct device *device, 109f204e0b8SIan Munsie struct device_attribute *attr, 110f204e0b8SIan Munsie char *buf) 111f204e0b8SIan Munsie { 112f204e0b8SIan Munsie struct cxl_afu *afu = to_afu_chardev_m(device); 113f204e0b8SIan Munsie 114f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->adapter->ps_size); 115f204e0b8SIan Munsie } 116f204e0b8SIan Munsie 117f204e0b8SIan Munsie static ssize_t pp_mmio_off_show(struct device *device, 118f204e0b8SIan Munsie struct device_attribute *attr, 119f204e0b8SIan Munsie char *buf) 120f204e0b8SIan Munsie { 121f204e0b8SIan Munsie struct cxl_afu *afu = to_afu_chardev_m(device); 122f204e0b8SIan Munsie 123f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_offset); 124f204e0b8SIan Munsie } 125f204e0b8SIan Munsie 126f204e0b8SIan Munsie static ssize_t pp_mmio_len_show(struct device *device, 127f204e0b8SIan Munsie struct device_attribute *attr, 128f204e0b8SIan Munsie char *buf) 129f204e0b8SIan Munsie { 130f204e0b8SIan Munsie struct cxl_afu *afu = to_afu_chardev_m(device); 131f204e0b8SIan Munsie 132f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_size); 133f204e0b8SIan Munsie } 134f204e0b8SIan Munsie 135f204e0b8SIan Munsie static struct device_attribute afu_master_attrs[] = { 136f204e0b8SIan Munsie __ATTR(mmio_size, S_IRUGO, mmio_size_show_master, NULL), 137f204e0b8SIan Munsie __ATTR_RO(pp_mmio_off), 138f204e0b8SIan Munsie __ATTR_RO(pp_mmio_len), 139f204e0b8SIan Munsie }; 140f204e0b8SIan Munsie 141f204e0b8SIan Munsie 142f204e0b8SIan Munsie /********* AFU attributes **************************************************/ 143f204e0b8SIan Munsie 144f204e0b8SIan Munsie static ssize_t mmio_size_show(struct device *device, 145f204e0b8SIan Munsie struct device_attribute *attr, 146f204e0b8SIan Munsie char *buf) 147f204e0b8SIan Munsie { 148f204e0b8SIan Munsie struct cxl_afu *afu = to_cxl_afu(device); 149f204e0b8SIan Munsie 150f204e0b8SIan Munsie if (afu->pp_size) 151f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_size); 152f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->adapter->ps_size); 153f204e0b8SIan Munsie } 154f204e0b8SIan Munsie 155f204e0b8SIan Munsie static ssize_t reset_store_afu(struct device *device, 156f204e0b8SIan Munsie struct device_attribute *attr, 157f204e0b8SIan Munsie const char *buf, size_t count) 158f204e0b8SIan Munsie { 159f204e0b8SIan Munsie struct cxl_afu *afu = to_cxl_afu(device); 160f204e0b8SIan Munsie int rc; 161f204e0b8SIan Munsie 162f204e0b8SIan Munsie /* Not safe to reset if it is currently in use */ 163ee41d11dSIan Munsie mutex_lock(&afu->contexts_lock); 164f204e0b8SIan Munsie if (!idr_is_empty(&afu->contexts_idr)) { 165f204e0b8SIan Munsie rc = -EBUSY; 166f204e0b8SIan Munsie goto err; 167f204e0b8SIan Munsie } 168f204e0b8SIan Munsie 169f204e0b8SIan Munsie if ((rc = cxl_afu_reset(afu))) 170f204e0b8SIan Munsie goto err; 171f204e0b8SIan Munsie 172f204e0b8SIan Munsie rc = count; 173f204e0b8SIan Munsie err: 174ee41d11dSIan Munsie mutex_unlock(&afu->contexts_lock); 175f204e0b8SIan Munsie return rc; 176f204e0b8SIan Munsie } 177f204e0b8SIan Munsie 178f204e0b8SIan Munsie static ssize_t irqs_min_show(struct device *device, 179f204e0b8SIan Munsie struct device_attribute *attr, 180f204e0b8SIan Munsie char *buf) 181f204e0b8SIan Munsie { 182f204e0b8SIan Munsie struct cxl_afu *afu = to_cxl_afu(device); 183f204e0b8SIan Munsie 184f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "%i\n", afu->pp_irqs); 185f204e0b8SIan Munsie } 186f204e0b8SIan Munsie 187f204e0b8SIan Munsie static ssize_t irqs_max_show(struct device *device, 188f204e0b8SIan Munsie struct device_attribute *attr, 189f204e0b8SIan Munsie char *buf) 190f204e0b8SIan Munsie { 191f204e0b8SIan Munsie struct cxl_afu *afu = to_cxl_afu(device); 192f204e0b8SIan Munsie 193f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "%i\n", afu->irqs_max); 194f204e0b8SIan Munsie } 195f204e0b8SIan Munsie 196f204e0b8SIan Munsie static ssize_t irqs_max_store(struct device *device, 197f204e0b8SIan Munsie struct device_attribute *attr, 198f204e0b8SIan Munsie const char *buf, size_t count) 199f204e0b8SIan Munsie { 200f204e0b8SIan Munsie struct cxl_afu *afu = to_cxl_afu(device); 201f204e0b8SIan Munsie ssize_t ret; 202f204e0b8SIan Munsie int irqs_max; 203f204e0b8SIan Munsie 204f204e0b8SIan Munsie ret = sscanf(buf, "%i", &irqs_max); 205f204e0b8SIan Munsie if (ret != 1) 206f204e0b8SIan Munsie return -EINVAL; 207f204e0b8SIan Munsie 208f204e0b8SIan Munsie if (irqs_max < afu->pp_irqs) 209f204e0b8SIan Munsie return -EINVAL; 210f204e0b8SIan Munsie 211f204e0b8SIan Munsie if (irqs_max > afu->adapter->user_irqs) 212f204e0b8SIan Munsie return -EINVAL; 213f204e0b8SIan Munsie 214f204e0b8SIan Munsie afu->irqs_max = irqs_max; 215f204e0b8SIan Munsie return count; 216f204e0b8SIan Munsie } 217f204e0b8SIan Munsie 218f204e0b8SIan Munsie static ssize_t modes_supported_show(struct device *device, 219f204e0b8SIan Munsie struct device_attribute *attr, char *buf) 220f204e0b8SIan Munsie { 221f204e0b8SIan Munsie struct cxl_afu *afu = to_cxl_afu(device); 222f204e0b8SIan Munsie char *p = buf, *end = buf + PAGE_SIZE; 223f204e0b8SIan Munsie 224f204e0b8SIan Munsie if (afu->modes_supported & CXL_MODE_DEDICATED) 225f204e0b8SIan Munsie p += scnprintf(p, end - p, "dedicated_process\n"); 226f204e0b8SIan Munsie if (afu->modes_supported & CXL_MODE_DIRECTED) 227f204e0b8SIan Munsie p += scnprintf(p, end - p, "afu_directed\n"); 228f204e0b8SIan Munsie return (p - buf); 229f204e0b8SIan Munsie } 230f204e0b8SIan Munsie 231f204e0b8SIan Munsie static ssize_t prefault_mode_show(struct device *device, 232f204e0b8SIan Munsie struct device_attribute *attr, 233f204e0b8SIan Munsie char *buf) 234f204e0b8SIan Munsie { 235f204e0b8SIan Munsie struct cxl_afu *afu = to_cxl_afu(device); 236f204e0b8SIan Munsie 237f204e0b8SIan Munsie switch (afu->prefault_mode) { 238f204e0b8SIan Munsie case CXL_PREFAULT_WED: 239f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "work_element_descriptor\n"); 240f204e0b8SIan Munsie case CXL_PREFAULT_ALL: 241f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "all\n"); 242f204e0b8SIan Munsie default: 243f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "none\n"); 244f204e0b8SIan Munsie } 245f204e0b8SIan Munsie } 246f204e0b8SIan Munsie 247f204e0b8SIan Munsie static ssize_t prefault_mode_store(struct device *device, 248f204e0b8SIan Munsie struct device_attribute *attr, 249f204e0b8SIan Munsie const char *buf, size_t count) 250f204e0b8SIan Munsie { 251f204e0b8SIan Munsie struct cxl_afu *afu = to_cxl_afu(device); 252f204e0b8SIan Munsie enum prefault_modes mode = -1; 253f204e0b8SIan Munsie 254f204e0b8SIan Munsie if (!strncmp(buf, "work_element_descriptor", 23)) 255f204e0b8SIan Munsie mode = CXL_PREFAULT_WED; 256f204e0b8SIan Munsie if (!strncmp(buf, "all", 3)) 257f204e0b8SIan Munsie mode = CXL_PREFAULT_ALL; 258f204e0b8SIan Munsie if (!strncmp(buf, "none", 4)) 259f204e0b8SIan Munsie mode = CXL_PREFAULT_NONE; 260f204e0b8SIan Munsie 261f204e0b8SIan Munsie if (mode == -1) 262f204e0b8SIan Munsie return -EINVAL; 263f204e0b8SIan Munsie 264f204e0b8SIan Munsie afu->prefault_mode = mode; 265f204e0b8SIan Munsie return count; 266f204e0b8SIan Munsie } 267f204e0b8SIan Munsie 268f204e0b8SIan Munsie static ssize_t mode_show(struct device *device, 269f204e0b8SIan Munsie struct device_attribute *attr, 270f204e0b8SIan Munsie char *buf) 271f204e0b8SIan Munsie { 272f204e0b8SIan Munsie struct cxl_afu *afu = to_cxl_afu(device); 273f204e0b8SIan Munsie 274f204e0b8SIan Munsie if (afu->current_mode == CXL_MODE_DEDICATED) 275f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "dedicated_process\n"); 276f204e0b8SIan Munsie if (afu->current_mode == CXL_MODE_DIRECTED) 277f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "afu_directed\n"); 278f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "none\n"); 279f204e0b8SIan Munsie } 280f204e0b8SIan Munsie 281f204e0b8SIan Munsie static ssize_t mode_store(struct device *device, struct device_attribute *attr, 282f204e0b8SIan Munsie const char *buf, size_t count) 283f204e0b8SIan Munsie { 284f204e0b8SIan Munsie struct cxl_afu *afu = to_cxl_afu(device); 285f204e0b8SIan Munsie int old_mode, mode = -1; 286f204e0b8SIan Munsie int rc = -EBUSY; 287f204e0b8SIan Munsie 288f204e0b8SIan Munsie /* can't change this if we have a user */ 289ee41d11dSIan Munsie mutex_lock(&afu->contexts_lock); 290f204e0b8SIan Munsie if (!idr_is_empty(&afu->contexts_idr)) 291f204e0b8SIan Munsie goto err; 292f204e0b8SIan Munsie 293f204e0b8SIan Munsie if (!strncmp(buf, "dedicated_process", 17)) 294f204e0b8SIan Munsie mode = CXL_MODE_DEDICATED; 295f204e0b8SIan Munsie if (!strncmp(buf, "afu_directed", 12)) 296f204e0b8SIan Munsie mode = CXL_MODE_DIRECTED; 297f204e0b8SIan Munsie if (!strncmp(buf, "none", 4)) 298f204e0b8SIan Munsie mode = 0; 299f204e0b8SIan Munsie 300f204e0b8SIan Munsie if (mode == -1) { 301f204e0b8SIan Munsie rc = -EINVAL; 302f204e0b8SIan Munsie goto err; 303f204e0b8SIan Munsie } 304f204e0b8SIan Munsie 305f204e0b8SIan Munsie /* 306f204e0b8SIan Munsie * cxl_afu_deactivate_mode needs to be done outside the lock, prevent 307f204e0b8SIan Munsie * other contexts coming in before we are ready: 308f204e0b8SIan Munsie */ 309f204e0b8SIan Munsie old_mode = afu->current_mode; 310f204e0b8SIan Munsie afu->current_mode = 0; 311f204e0b8SIan Munsie afu->num_procs = 0; 312f204e0b8SIan Munsie 313ee41d11dSIan Munsie mutex_unlock(&afu->contexts_lock); 314f204e0b8SIan Munsie 315f204e0b8SIan Munsie if ((rc = _cxl_afu_deactivate_mode(afu, old_mode))) 316f204e0b8SIan Munsie return rc; 317f204e0b8SIan Munsie if ((rc = cxl_afu_activate_mode(afu, mode))) 318f204e0b8SIan Munsie return rc; 319f204e0b8SIan Munsie 320f204e0b8SIan Munsie return count; 321f204e0b8SIan Munsie err: 322ee41d11dSIan Munsie mutex_unlock(&afu->contexts_lock); 323f204e0b8SIan Munsie return rc; 324f204e0b8SIan Munsie } 325f204e0b8SIan Munsie 326f204e0b8SIan Munsie static ssize_t api_version_show(struct device *device, 327f204e0b8SIan Munsie struct device_attribute *attr, 328f204e0b8SIan Munsie char *buf) 329f204e0b8SIan Munsie { 330f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "%i\n", CXL_API_VERSION); 331f204e0b8SIan Munsie } 332f204e0b8SIan Munsie 333f204e0b8SIan Munsie static ssize_t api_version_compatible_show(struct device *device, 334f204e0b8SIan Munsie struct device_attribute *attr, 335f204e0b8SIan Munsie char *buf) 336f204e0b8SIan Munsie { 337f204e0b8SIan Munsie return scnprintf(buf, PAGE_SIZE, "%i\n", CXL_API_VERSION_COMPATIBLE); 338f204e0b8SIan Munsie } 339f204e0b8SIan Munsie 340f204e0b8SIan Munsie static struct device_attribute afu_attrs[] = { 341f204e0b8SIan Munsie __ATTR_RO(mmio_size), 342f204e0b8SIan Munsie __ATTR_RO(irqs_min), 343f204e0b8SIan Munsie __ATTR_RW(irqs_max), 344f204e0b8SIan Munsie __ATTR_RO(modes_supported), 345f204e0b8SIan Munsie __ATTR_RW(mode), 346f204e0b8SIan Munsie __ATTR_RW(prefault_mode), 347f204e0b8SIan Munsie __ATTR_RO(api_version), 348f204e0b8SIan Munsie __ATTR_RO(api_version_compatible), 349f204e0b8SIan Munsie __ATTR(reset, S_IWUSR, NULL, reset_store_afu), 350f204e0b8SIan Munsie }; 351f204e0b8SIan Munsie 352f204e0b8SIan Munsie 353f204e0b8SIan Munsie 354f204e0b8SIan Munsie int cxl_sysfs_adapter_add(struct cxl *adapter) 355f204e0b8SIan Munsie { 356f204e0b8SIan Munsie int i, rc; 357f204e0b8SIan Munsie 358f204e0b8SIan Munsie for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) { 359f204e0b8SIan Munsie if ((rc = device_create_file(&adapter->dev, &adapter_attrs[i]))) 360f204e0b8SIan Munsie goto err; 361f204e0b8SIan Munsie } 362f204e0b8SIan Munsie return 0; 363f204e0b8SIan Munsie err: 364f204e0b8SIan Munsie for (i--; i >= 0; i--) 365f204e0b8SIan Munsie device_remove_file(&adapter->dev, &adapter_attrs[i]); 366f204e0b8SIan Munsie return rc; 367f204e0b8SIan Munsie } 368f204e0b8SIan Munsie void cxl_sysfs_adapter_remove(struct cxl *adapter) 369f204e0b8SIan Munsie { 370f204e0b8SIan Munsie int i; 371f204e0b8SIan Munsie 372f204e0b8SIan Munsie for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) 373f204e0b8SIan Munsie device_remove_file(&adapter->dev, &adapter_attrs[i]); 374f204e0b8SIan Munsie } 375f204e0b8SIan Munsie 376f204e0b8SIan Munsie int cxl_sysfs_afu_add(struct cxl_afu *afu) 377f204e0b8SIan Munsie { 378f204e0b8SIan Munsie int i, rc; 379f204e0b8SIan Munsie 380f204e0b8SIan Munsie for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) { 381f204e0b8SIan Munsie if ((rc = device_create_file(&afu->dev, &afu_attrs[i]))) 382f204e0b8SIan Munsie goto err; 383f204e0b8SIan Munsie } 384f204e0b8SIan Munsie 385f204e0b8SIan Munsie return 0; 386f204e0b8SIan Munsie 387f204e0b8SIan Munsie err: 388f204e0b8SIan Munsie for (i--; i >= 0; i--) 389f204e0b8SIan Munsie device_remove_file(&afu->dev, &afu_attrs[i]); 390f204e0b8SIan Munsie return rc; 391f204e0b8SIan Munsie } 392f204e0b8SIan Munsie 393f204e0b8SIan Munsie void cxl_sysfs_afu_remove(struct cxl_afu *afu) 394f204e0b8SIan Munsie { 395f204e0b8SIan Munsie int i; 396f204e0b8SIan Munsie 397f204e0b8SIan Munsie for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) 398f204e0b8SIan Munsie device_remove_file(&afu->dev, &afu_attrs[i]); 399f204e0b8SIan Munsie } 400f204e0b8SIan Munsie 401f204e0b8SIan Munsie int cxl_sysfs_afu_m_add(struct cxl_afu *afu) 402f204e0b8SIan Munsie { 403f204e0b8SIan Munsie int i, rc; 404f204e0b8SIan Munsie 405f204e0b8SIan Munsie for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) { 406f204e0b8SIan Munsie if ((rc = device_create_file(afu->chardev_m, &afu_master_attrs[i]))) 407f204e0b8SIan Munsie goto err; 408f204e0b8SIan Munsie } 409f204e0b8SIan Munsie 410f204e0b8SIan Munsie return 0; 411f204e0b8SIan Munsie 412f204e0b8SIan Munsie err: 413f204e0b8SIan Munsie for (i--; i >= 0; i--) 414f204e0b8SIan Munsie device_remove_file(afu->chardev_m, &afu_master_attrs[i]); 415f204e0b8SIan Munsie return rc; 416f204e0b8SIan Munsie } 417f204e0b8SIan Munsie 418f204e0b8SIan Munsie void cxl_sysfs_afu_m_remove(struct cxl_afu *afu) 419f204e0b8SIan Munsie { 420f204e0b8SIan Munsie int i; 421f204e0b8SIan Munsie 422f204e0b8SIan Munsie for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) 423f204e0b8SIan Munsie device_remove_file(afu->chardev_m, &afu_master_attrs[i]); 424f204e0b8SIan Munsie } 425