xref: /linux/drivers/misc/cxl/sysfs.c (revision 95bc11bcd1428afdb48400ec84dc6d5a83926138)
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