1
2
3
4
5
6
7#include "ai-engine-internal.h"
8
9
10
11
12
13
14
15
16
17
18
19ssize_t aie_sysfs_read_handler(struct file *filp, struct kobject *kobj,
20 struct bin_attribute *attr, char *buf,
21 loff_t offset, size_t max_size)
22{
23 ssize_t len = max_size;
24 struct aie_sysfs_prop *prop;
25
26 prop = attr->private;
27 if (!prop->data)
28 return 0;
29
30 if (!offset)
31 prop->size = prop->read_callback(kobj, prop->data,
32 prop->max_size);
33
34 if (offset >= prop->size)
35 return 0;
36
37 if (offset + max_size > prop->size)
38 len = prop->size - offset;
39
40 memcpy(buf, prop->data + offset, len);
41 return len;
42}
43
44
45
46
47
48
49
50
51static struct device_attribute *
52aie_sysfs_create_dev_attr(struct device *dev, const struct aie_dev_attr *attr)
53{
54 struct device_attribute *node;
55
56 node = devm_kzalloc(dev, sizeof(struct device_attribute), GFP_KERNEL);
57 if (!node)
58 return ERR_PTR(-ENOMEM);
59
60 sysfs_attr_init(node);
61
62 node->attr.name = attr->name;
63 node->attr.mode = attr->mode;
64 node->show = attr->show;
65 return node;
66}
67
68
69
70
71
72
73
74
75static struct bin_attribute *
76aie_sysfs_create_bin_attr(struct device *dev, const struct aie_bin_attr *attr)
77{
78 struct bin_attribute *node;
79 struct aie_sysfs_prop *prop;
80
81 node = devm_kzalloc(dev, sizeof(struct bin_attribute), GFP_KERNEL);
82 if (!node)
83 return ERR_PTR(-ENOMEM);
84
85 sysfs_bin_attr_init(node);
86
87 node->attr.name = attr->name;
88 node->attr.mode = attr->mode;
89 node->size = attr->size;
90 node->read = attr->read;
91
92 prop = devm_kzalloc(dev, sizeof(struct aie_sysfs_prop), GFP_KERNEL);
93 if (!prop)
94 return ERR_PTR(-ENOMEM);
95
96 prop->data = devm_kzalloc(dev, node->size, GFP_KERNEL);
97 if (!prop->data)
98 return ERR_PTR(-ENOMEM);
99
100 prop->max_size = node->size;
101 prop->read_callback = attr->read_callback;
102 node->private = prop;
103 return node;
104}
105
106
107
108
109
110
111static int aie_tile_sysfs_create(struct aie_tile *atile)
112{
113 struct attribute_group *attr_grp;
114 struct bin_attribute **bin_attrs;
115 struct attribute **dev_attrs;
116 const struct aie_sysfs_attr *attr;
117 int ret = 0;
118 u32 ttype;
119 u32 index, i = 0, j = 0;
120
121 attr = atile->apart->adev->tile_sysfs_attr;
122 ttype = atile->apart->adev->ops->get_tile_type(&atile->loc);
123
124 if (attr->num_dev_attrs) {
125 dev_attrs = devm_kzalloc(&atile->dev, sizeof(*dev_attrs) *
126 (attr->num_dev_attrs + 1), GFP_KERNEL);
127 if (!dev_attrs)
128 return -ENOMEM;
129
130 for (index = 0; index < attr->num_dev_attrs; index++) {
131 struct device_attribute *node;
132 const struct aie_dev_attr *dev_attr;
133
134 dev_attr = &attr->dev_attr[index];
135
136 if (!(BIT(ttype) & attr->dev_attr[index].tile_type))
137 continue;
138
139 node = aie_sysfs_create_dev_attr(&atile->dev, dev_attr);
140 if (IS_ERR_VALUE(node))
141 return PTR_ERR(node);
142
143 dev_attrs[i++] = &node->attr;
144 }
145 }
146
147 if (attr->num_bin_attrs) {
148 bin_attrs = devm_kzalloc(&atile->dev, sizeof(*bin_attrs) *
149 (attr->num_bin_attrs + 1), GFP_KERNEL);
150 if (!bin_attrs)
151 return -ENOMEM;
152
153 for (index = 0; index < attr->num_bin_attrs; index++) {
154 struct bin_attribute *node;
155 const struct aie_bin_attr *bin_attr;
156
157 bin_attr = &attr->bin_attr[index];
158
159 if (!(BIT(ttype) & attr->bin_attr[index].tile_type))
160 continue;
161
162 node = aie_sysfs_create_bin_attr(&atile->dev, bin_attr);
163 if (IS_ERR_VALUE(node))
164 return PTR_ERR(node);
165
166 bin_attrs[j++] = node;
167 }
168 }
169
170 if (attr->num_dev_attrs || attr->num_bin_attrs) {
171 attr_grp = devm_kzalloc(&atile->dev,
172 sizeof(struct attribute_group),
173 GFP_KERNEL);
174 if (!attr_grp)
175 return -ENOMEM;
176
177 if (attr->num_dev_attrs)
178 attr_grp->attrs = dev_attrs;
179
180 if (attr->num_bin_attrs)
181 attr_grp->bin_attrs = bin_attrs;
182
183 ret = devm_device_add_group(&atile->dev, attr_grp);
184 if (ret) {
185 dev_err(&atile->dev,
186 "Failed to add sysfs attributes group\n");
187 }
188 }
189 return ret;
190}
191
192
193
194
195
196
197static int aie_part_sysfs_create(struct aie_partition *apart)
198{
199 const struct aie_sysfs_attr *attr;
200 struct attribute_group *attr_grp;
201 struct bin_attribute **bin_attrs;
202 struct attribute **dev_attrs;
203 int ret = 0;
204 u32 index;
205
206 attr = apart->adev->part_sysfs_attr;
207
208 if (attr->num_dev_attrs) {
209 dev_attrs = devm_kzalloc(&apart->dev, sizeof(*dev_attrs) *
210 (attr->num_dev_attrs + 1), GFP_KERNEL);
211 if (!dev_attrs)
212 return -ENOMEM;
213
214 for (index = 0; index < attr->num_dev_attrs; index++) {
215 struct device_attribute *node;
216 const struct aie_dev_attr *dev_attr;
217
218 dev_attr = &attr->dev_attr[index];
219
220 node = aie_sysfs_create_dev_attr(&apart->dev, dev_attr);
221 if (IS_ERR_VALUE(node))
222 return PTR_ERR(node);
223
224 dev_attrs[index] = &node->attr;
225 }
226 }
227
228 if (attr->num_bin_attrs) {
229 bin_attrs = devm_kzalloc(&apart->dev, sizeof(*bin_attrs) *
230 (attr->num_bin_attrs + 1), GFP_KERNEL);
231 if (!bin_attrs)
232 return -ENOMEM;
233
234 for (index = 0; index < attr->num_bin_attrs; index++) {
235 struct bin_attribute *node;
236 const struct aie_bin_attr *bin_attr;
237
238 bin_attr = &attr->bin_attr[index];
239
240 node = aie_sysfs_create_bin_attr(&apart->dev, bin_attr);
241 if (IS_ERR_VALUE(node))
242 return PTR_ERR(node);
243
244 bin_attrs[index] = node;
245 }
246 }
247
248 if (attr->num_dev_attrs || attr->num_bin_attrs) {
249 attr_grp = devm_kzalloc(&apart->dev,
250 sizeof(struct attribute_group),
251 GFP_KERNEL);
252 if (!attr_grp)
253 return -ENOMEM;
254
255 if (attr->num_dev_attrs)
256 attr_grp->attrs = dev_attrs;
257
258 if (attr->num_bin_attrs)
259 attr_grp->bin_attrs = bin_attrs;
260
261 ret = devm_device_add_group(&apart->dev, attr_grp);
262 if (ret) {
263 dev_err(&apart->dev,
264 "Failed to add sysfs attributes group\n");
265 }
266 }
267 return ret;
268}
269
270
271
272
273
274
275
276int aie_part_sysfs_init(struct aie_partition *apart)
277{
278 struct aie_tile *atile = apart->atiles;
279 u32 index;
280 int ret;
281
282 ret = aie_part_sysfs_create(apart);
283 if (ret < 0) {
284 dev_err(&apart->dev,
285 "Failed to create partition level sysfs nodes\n");
286 return ret;
287 }
288
289 for (index = 0; index < apart->range.size.col * apart->range.size.row;
290 index++) {
291 ret = aie_tile_sysfs_create(atile);
292 if (ret < 0) {
293 dev_err(&atile->dev,
294 "Failed to create tile level sysfs nodes\n");
295 return ret;
296 }
297 atile++;
298 }
299 return ret;
300}
301