summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/nvgpu/gk20a/tsg_gk20a.c29
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
31struct tsg_private {
32 struct gk20a *g;
33 struct tsg_gk20a *tsg;
34};
35
31bool gk20a_is_channel_marked_as_tsg(struct channel_gk20a *ch) 36bool 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
401int gk20a_tsg_open(struct gk20a *g, struct file *filp) 406int 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
496int gk20a_tsg_dev_release(struct inode *inode, struct file *filp) 510int 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:
578long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd, 598long 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;