diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c index fc36c0c7..d98b78ea 100644 --- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c | |||
@@ -28,6 +28,11 @@ | |||
28 | #define NVGPU_TSG_MIN_TIMESLICE_US 1000 | 28 | #define NVGPU_TSG_MIN_TIMESLICE_US 1000 |
29 | #define NVGPU_TSG_MAX_TIMESLICE_US 50000 | 29 | #define NVGPU_TSG_MAX_TIMESLICE_US 50000 |
30 | 30 | ||
31 | struct tsg_private { | ||
32 | struct gk20a *g; | ||
33 | struct tsg_gk20a *tsg; | ||
34 | }; | ||
35 | |||
31 | bool gk20a_is_channel_marked_as_tsg(struct channel_gk20a *ch) | 36 | bool gk20a_is_channel_marked_as_tsg(struct channel_gk20a *ch) |
32 | { | 37 | { |
33 | return !(ch->tsgid == NVGPU_INVALID_TSG_ID); | 38 | return !(ch->tsgid == NVGPU_INVALID_TSG_ID); |
@@ -400,6 +405,7 @@ static struct tsg_gk20a *acquire_unused_tsg(struct fifo_gk20a *f) | |||
400 | 405 | ||
401 | int gk20a_tsg_open(struct gk20a *g, struct file *filp) | 406 | int gk20a_tsg_open(struct gk20a *g, struct file *filp) |
402 | { | 407 | { |
408 | struct tsg_private *priv; | ||
403 | struct tsg_gk20a *tsg; | 409 | struct tsg_gk20a *tsg; |
404 | struct device *dev; | 410 | struct device *dev; |
405 | int err; | 411 | int err; |
@@ -408,9 +414,15 @@ int gk20a_tsg_open(struct gk20a *g, struct file *filp) | |||
408 | 414 | ||
409 | gk20a_dbg(gpu_dbg_fn, "tsg: %s", dev_name(dev)); | 415 | gk20a_dbg(gpu_dbg_fn, "tsg: %s", dev_name(dev)); |
410 | 416 | ||
417 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); | ||
418 | if (!priv) | ||
419 | return -ENOMEM; | ||
420 | |||
411 | tsg = acquire_unused_tsg(&g->fifo); | 421 | tsg = acquire_unused_tsg(&g->fifo); |
412 | if (!tsg) | 422 | if (!tsg) { |
423 | kfree(priv); | ||
413 | return -ENOMEM; | 424 | return -ENOMEM; |
425 | } | ||
414 | 426 | ||
415 | tsg->g = g; | 427 | tsg->g = g; |
416 | tsg->num_active_channels = 0; | 428 | tsg->num_active_channels = 0; |
@@ -425,7 +437,9 @@ int gk20a_tsg_open(struct gk20a *g, struct file *filp) | |||
425 | tsg->runlist_id = ~0; | 437 | tsg->runlist_id = ~0; |
426 | tsg->tgid = current->tgid; | 438 | tsg->tgid = current->tgid; |
427 | 439 | ||
428 | filp->private_data = tsg; | 440 | priv->g = g; |
441 | priv->tsg = tsg; | ||
442 | filp->private_data = priv; | ||
429 | 443 | ||
430 | if (g->ops.fifo.tsg_open) { | 444 | if (g->ops.fifo.tsg_open) { |
431 | err = g->ops.fifo.tsg_open(tsg); | 445 | err = g->ops.fifo.tsg_open(tsg); |
@@ -495,7 +509,13 @@ void gk20a_tsg_release(struct kref *ref) | |||
495 | 509 | ||
496 | int gk20a_tsg_dev_release(struct inode *inode, struct file *filp) | 510 | int gk20a_tsg_dev_release(struct inode *inode, struct file *filp) |
497 | { | 511 | { |
498 | struct tsg_gk20a *tsg = filp->private_data; | 512 | struct tsg_private *priv = filp->private_data; |
513 | struct tsg_gk20a *tsg = priv->tsg; | ||
514 | struct gk20a *g = priv->g; | ||
515 | |||
516 | if (g->driver_is_dying) | ||
517 | return -ENODEV; | ||
518 | |||
499 | kref_put(&tsg->refcount, gk20a_tsg_release); | 519 | kref_put(&tsg->refcount, gk20a_tsg_release); |
500 | return 0; | 520 | return 0; |
501 | } | 521 | } |
@@ -578,7 +598,8 @@ done: | |||
578 | long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd, | 598 | long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd, |
579 | unsigned long arg) | 599 | unsigned long arg) |
580 | { | 600 | { |
581 | struct tsg_gk20a *tsg = filp->private_data; | 601 | struct tsg_private *priv = filp->private_data; |
602 | struct tsg_gk20a *tsg = priv->tsg; | ||
582 | struct gk20a *g = tsg->g; | 603 | struct gk20a *g = tsg->g; |
583 | u8 __maybe_unused buf[NVGPU_TSG_IOCTL_MAX_ARG_SIZE]; | 604 | u8 __maybe_unused buf[NVGPU_TSG_IOCTL_MAX_ARG_SIZE]; |
584 | int err = 0; | 605 | int err = 0; |