diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/tsg_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c index e1424f2b..270fed85 100644 --- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | |||
@@ -259,15 +259,23 @@ static int gk20a_tsg_event_id_enable(struct tsg_gk20a *tsg, | |||
259 | struct file *file; | 259 | struct file *file; |
260 | char *name; | 260 | char *name; |
261 | struct gk20a_event_id_data *event_id_data; | 261 | struct gk20a_event_id_data *event_id_data; |
262 | struct gk20a *g; | ||
263 | |||
264 | g = gk20a_get(tsg->g); | ||
265 | if (!g) | ||
266 | return -ENODEV; | ||
262 | 267 | ||
263 | err = gk20a_tsg_get_event_data_from_id(tsg, | 268 | err = gk20a_tsg_get_event_data_from_id(tsg, |
264 | event_id, &event_id_data); | 269 | event_id, &event_id_data); |
265 | if (err == 0) /* We already have event enabled */ | 270 | if (err == 0) { |
266 | return -EINVAL; | 271 | /* We already have event enabled */ |
272 | err = -EINVAL; | ||
273 | goto free_ref; | ||
274 | } | ||
267 | 275 | ||
268 | err = get_unused_fd_flags(O_RDWR); | 276 | err = get_unused_fd_flags(O_RDWR); |
269 | if (err < 0) | 277 | if (err < 0) |
270 | return err; | 278 | goto free_ref; |
271 | local_fd = err; | 279 | local_fd = err; |
272 | 280 | ||
273 | name = kasprintf(GFP_KERNEL, "nvgpu-event%d-fd%d", | 281 | name = kasprintf(GFP_KERNEL, "nvgpu-event%d-fd%d", |
@@ -286,7 +294,7 @@ static int gk20a_tsg_event_id_enable(struct tsg_gk20a *tsg, | |||
286 | err = -ENOMEM; | 294 | err = -ENOMEM; |
287 | goto clean_up_file; | 295 | goto clean_up_file; |
288 | } | 296 | } |
289 | event_id_data->g = tsg->g; | 297 | event_id_data->g = g; |
290 | event_id_data->id = tsg->tsgid; | 298 | event_id_data->id = tsg->tsgid; |
291 | event_id_data->is_tsg = true; | 299 | event_id_data->is_tsg = true; |
292 | event_id_data->event_id = event_id; | 300 | event_id_data->event_id = event_id; |
@@ -315,6 +323,8 @@ clean_up_file: | |||
315 | fput(file); | 323 | fput(file); |
316 | clean_up: | 324 | clean_up: |
317 | put_unused_fd(local_fd); | 325 | put_unused_fd(local_fd); |
326 | free_ref: | ||
327 | gk20a_put(g); | ||
318 | return err; | 328 | return err; |
319 | } | 329 | } |
320 | 330 | ||
@@ -410,18 +420,25 @@ int gk20a_tsg_open(struct gk20a *g, struct file *filp) | |||
410 | struct device *dev; | 420 | struct device *dev; |
411 | int err; | 421 | int err; |
412 | 422 | ||
423 | g = gk20a_get(g); | ||
424 | if (!g) | ||
425 | return -ENODEV; | ||
426 | |||
413 | dev = dev_from_gk20a(g); | 427 | dev = dev_from_gk20a(g); |
414 | 428 | ||
415 | gk20a_dbg(gpu_dbg_fn, "tsg: %s", dev_name(dev)); | 429 | gk20a_dbg(gpu_dbg_fn, "tsg: %s", dev_name(dev)); |
416 | 430 | ||
417 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); | 431 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); |
418 | if (!priv) | 432 | if (!priv) { |
419 | return -ENOMEM; | 433 | err = -ENOMEM; |
434 | goto free_ref; | ||
435 | } | ||
420 | 436 | ||
421 | tsg = acquire_unused_tsg(&g->fifo); | 437 | tsg = acquire_unused_tsg(&g->fifo); |
422 | if (!tsg) { | 438 | if (!tsg) { |
423 | kfree(priv); | 439 | kfree(priv); |
424 | return -ENOMEM; | 440 | err = -ENOMEM; |
441 | goto free_ref; | ||
425 | } | 442 | } |
426 | 443 | ||
427 | tsg->g = g; | 444 | tsg->g = g; |
@@ -458,6 +475,8 @@ int gk20a_tsg_open(struct gk20a *g, struct file *filp) | |||
458 | 475 | ||
459 | clean_up: | 476 | clean_up: |
460 | kref_put(&tsg->refcount, gk20a_tsg_release); | 477 | kref_put(&tsg->refcount, gk20a_tsg_release); |
478 | free_ref: | ||
479 | gk20a_put(g); | ||
461 | return err; | 480 | return err; |
462 | } | 481 | } |
463 | 482 | ||
@@ -505,16 +524,13 @@ void gk20a_tsg_release(struct kref *ref) | |||
505 | tsg->runlist_id = ~0; | 524 | tsg->runlist_id = ~0; |
506 | 525 | ||
507 | gk20a_dbg(gpu_dbg_fn, "tsg released %d\n", tsg->tsgid); | 526 | gk20a_dbg(gpu_dbg_fn, "tsg released %d\n", tsg->tsgid); |
527 | gk20a_put(g); | ||
508 | } | 528 | } |
509 | 529 | ||
510 | int gk20a_tsg_dev_release(struct inode *inode, struct file *filp) | 530 | int gk20a_tsg_dev_release(struct inode *inode, struct file *filp) |
511 | { | 531 | { |
512 | struct tsg_private *priv = filp->private_data; | 532 | struct tsg_private *priv = filp->private_data; |
513 | struct tsg_gk20a *tsg = priv->tsg; | 533 | struct tsg_gk20a *tsg = priv->tsg; |
514 | struct gk20a *g = priv->g; | ||
515 | |||
516 | if (g->driver_is_dying) | ||
517 | return -ENODEV; | ||
518 | 534 | ||
519 | kref_put(&tsg->refcount, gk20a_tsg_release); | 535 | kref_put(&tsg->refcount, gk20a_tsg_release); |
520 | kfree(priv); | 536 | kfree(priv); |