summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/tsg_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/tsg_gk20a.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
index b41cca08..a0232a69 100644
--- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
@@ -153,6 +153,9 @@ int gk20a_init_tsg_support(struct gk20a *g, u32 tsgid)
153 INIT_LIST_HEAD(&tsg->ch_list); 153 INIT_LIST_HEAD(&tsg->ch_list);
154 mutex_init(&tsg->ch_list_lock); 154 mutex_init(&tsg->ch_list_lock);
155 155
156 INIT_LIST_HEAD(&tsg->event_id_list);
157 mutex_init(&tsg->event_id_list_lock);
158
156 return 0; 159 return 0;
157} 160}
158 161
@@ -184,6 +187,122 @@ static int gk20a_tsg_set_priority(struct gk20a *g, struct tsg_gk20a *tsg,
184 return 0; 187 return 0;
185} 188}
186 189
190static int gk20a_tsg_get_event_data_from_id(struct tsg_gk20a *tsg,
191 int event_id,
192 struct gk20a_event_id_data **event_id_data)
193{
194 struct gk20a_event_id_data *local_event_id_data;
195 bool event_found = false;
196
197 mutex_lock(&tsg->event_id_list_lock);
198 list_for_each_entry(local_event_id_data, &tsg->event_id_list,
199 event_id_node) {
200 if (local_event_id_data->event_id == event_id) {
201 event_found = true;
202 break;
203 }
204 }
205 mutex_unlock(&tsg->event_id_list_lock);
206
207 if (event_found) {
208 *event_id_data = local_event_id_data;
209 return 0;
210 } else {
211 return -1;
212 }
213}
214
215static int gk20a_tsg_event_id_enable(struct tsg_gk20a *tsg,
216 int event_id,
217 int *fd)
218{
219 int err = 0;
220 int local_fd;
221 struct file *file;
222 char *name;
223 struct gk20a_event_id_data *event_id_data;
224
225 err = gk20a_tsg_get_event_data_from_id(tsg,
226 event_id, &event_id_data);
227 if (err == 0) /* We already have event enabled */
228 return -EINVAL;
229
230 err = get_unused_fd_flags(O_RDWR);
231 if (err < 0)
232 return err;
233 local_fd = err;
234
235 name = kasprintf(GFP_KERNEL, "nvgpu-event%d-fd%d",
236 event_id, local_fd);
237
238 file = anon_inode_getfile(name, &gk20a_event_id_ops,
239 NULL, O_RDWR);
240 kfree(name);
241 if (IS_ERR(file)) {
242 err = PTR_ERR(file);
243 goto clean_up;
244 }
245
246 event_id_data = kzalloc(sizeof(*event_id_data), GFP_KERNEL);
247 if (!event_id_data) {
248 err = -ENOMEM;
249 goto clean_up_file;
250 }
251 event_id_data->g = tsg->g;
252 event_id_data->id = tsg->tsgid;
253 event_id_data->is_tsg = true;
254 event_id_data->event_id = event_id;
255
256 init_waitqueue_head(&event_id_data->event_id_wq);
257 mutex_init(&event_id_data->lock);
258 INIT_LIST_HEAD(&event_id_data->event_id_node);
259
260 mutex_lock(&tsg->event_id_list_lock);
261 list_add_tail(&event_id_data->event_id_node, &tsg->event_id_list);
262 mutex_unlock(&tsg->event_id_list_lock);
263
264 fd_install(local_fd, file);
265 file->private_data = event_id_data;
266
267 *fd = local_fd;
268
269 return 0;
270
271clean_up_file:
272 fput(file);
273clean_up:
274 put_unused_fd(local_fd);
275 return err;
276}
277
278static int gk20a_tsg_event_id_ctrl(struct gk20a *g, struct tsg_gk20a *tsg,
279 struct nvgpu_event_id_ctrl_args *args)
280{
281 int err = 0;
282 int fd = -1;
283
284 if (args->event_id < 0 ||
285 args->event_id >= NVGPU_IOCTL_CHANNEL_EVENT_ID_MAX)
286 return -EINVAL;
287
288 switch (args->cmd) {
289 case NVGPU_IOCTL_CHANNEL_EVENT_ID_CMD_ENABLE:
290 err = gk20a_tsg_event_id_enable(tsg, args->event_id, &fd);
291 if (!err)
292 args->event_fd = fd;
293 break;
294
295 default:
296 gk20a_err(dev_from_gk20a(tsg->g),
297 "unrecognized tsg event id cmd: 0x%x",
298 args->cmd);
299 err = -EINVAL;
300 break;
301 }
302
303 return err;
304}
305
187static void release_used_tsg(struct fifo_gk20a *f, struct tsg_gk20a *tsg) 306static void release_used_tsg(struct fifo_gk20a *f, struct tsg_gk20a *tsg)
188{ 307{
189 mutex_lock(&f->tsg_inuse_mutex); 308 mutex_lock(&f->tsg_inuse_mutex);
@@ -372,6 +491,13 @@ long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd,
372 break; 491 break;
373 } 492 }
374 493
494 case NVGPU_IOCTL_TSG_EVENT_ID_CTRL:
495 {
496 err = gk20a_tsg_event_id_ctrl(g, tsg,
497 (struct nvgpu_event_id_ctrl_args *)buf);
498 break;
499 }
500
375 default: 501 default:
376 gk20a_err(dev_from_gk20a(g), 502 gk20a_err(dev_from_gk20a(g),
377 "unrecognized tsg gpu ioctl cmd: 0x%x", 503 "unrecognized tsg gpu ioctl cmd: 0x%x",