diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 80 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c | 4 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c | 6 |
3 files changed, 77 insertions, 13 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 4cce72603481..8f850abac886 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -687,10 +687,16 @@ int gk20a_channel_release(struct inode *inode, struct file *filp) { struct channel_gk20a *ch = (struct channel_gk20a *)filp->private_data; struct gk20a *g = ch->g; + int err; trace_gk20a_channel_release(dev_name(&g->dev->dev)); - gk20a_channel_busy(ch->g->dev); + err = gk20a_channel_busy(ch->g->dev); + if (err) { + gk20a_err(dev_from_gk20a(g), "failed to release channel %d", + ch->hw_chid); + return err; + } gk20a_free_channel(ch, true); gk20a_channel_idle(ch->g->dev); @@ -1412,7 +1418,7 @@ static int gk20a_submit_channel_gpfifo(struct channel_gk20a *c, { struct gk20a *g = c->g; struct device *d = dev_from_gk20a(g); - u32 err = 0; + int err = 0; int i; struct priv_cmd_entry *wait_cmd = NULL; struct priv_cmd_entry *incr_cmd = NULL; @@ -1443,7 +1449,11 @@ static int gk20a_submit_channel_gpfifo(struct channel_gk20a *c, gk20a_dbg_info("channel %d", c->hw_chid); /* gk20a_channel_update releases this ref. */ - gk20a_channel_busy(g->dev); + err = gk20a_channel_busy(g->dev); + if (err) { + gk20a_err(d, "failed to host gk20a to submit gpfifo"); + return err; + } trace_gk20a_channel_submit_gpfifo(c->g->dev->name, c->hw_chid, @@ -2019,19 +2029,37 @@ long gk20a_channel_ioctl(struct file *filp, case NVHOST_IOCTL_CHANNEL_SET_NVMAP_FD: break; case NVHOST_IOCTL_CHANNEL_ALLOC_OBJ_CTX: - gk20a_channel_busy(dev); + err = gk20a_channel_busy(dev); + if (err) { + dev_err(&dev->dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + return err; + } err = gk20a_alloc_obj_ctx(ch, (struct nvhost_alloc_obj_ctx_args *)buf); gk20a_channel_idle(dev); break; case NVHOST_IOCTL_CHANNEL_FREE_OBJ_CTX: - gk20a_channel_busy(dev); + err = gk20a_channel_busy(dev); + if (err) { + dev_err(&dev->dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + return err; + } err = gk20a_free_obj_ctx(ch, (struct nvhost_free_obj_ctx_args *)buf); gk20a_channel_idle(dev); break; case NVHOST_IOCTL_CHANNEL_ALLOC_GPFIFO: - gk20a_channel_busy(dev); + err = gk20a_channel_busy(dev); + if (err) { + dev_err(&dev->dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + return err; + } err = gk20a_alloc_channel_gpfifo(ch, (struct nvhost_alloc_gpfifo_args *)buf); gk20a_channel_idle(dev); @@ -2041,26 +2069,50 @@ long gk20a_channel_ioctl(struct file *filp, (struct nvhost_submit_gpfifo_args *)buf); break; case NVHOST_IOCTL_CHANNEL_WAIT: - gk20a_channel_busy(dev); + err = gk20a_channel_busy(dev); + if (err) { + dev_err(&dev->dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + return err; + } err = gk20a_channel_wait(ch, (struct nvhost_wait_args *)buf); gk20a_channel_idle(dev); break; case NVHOST_IOCTL_CHANNEL_ZCULL_BIND: - gk20a_channel_busy(dev); + err = gk20a_channel_busy(dev); + if (err) { + dev_err(&dev->dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + return err; + } err = gk20a_channel_zcull_bind(ch, (struct nvhost_zcull_bind_args *)buf); gk20a_channel_idle(dev); break; case NVHOST_IOCTL_CHANNEL_SET_ERROR_NOTIFIER: - gk20a_channel_busy(dev); + err = gk20a_channel_busy(dev); + if (err) { + dev_err(&dev->dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + return err; + } err = gk20a_init_error_notifier(ch, (struct nvhost_set_error_notifier *)buf); gk20a_channel_idle(dev); break; #ifdef CONFIG_GK20A_CYCLE_STATS case NVHOST_IOCTL_CHANNEL_CYCLE_STATS: - gk20a_channel_busy(dev); + err = gk20a_channel_busy(dev); + if (err) { + dev_err(&dev->dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + return err; + } err = gk20a_channel_cycle_stats(ch, (struct nvhost_cycle_stats_args *)buf); gk20a_channel_idle(dev); @@ -2093,7 +2145,13 @@ long gk20a_channel_ioctl(struct file *filp, ch->has_timedout; break; case NVHOST_IOCTL_CHANNEL_SET_PRIORITY: - gk20a_channel_busy(dev); + err = gk20a_channel_busy(dev); + if (err) { + dev_err(&dev->dev, + "%s: failed to host gk20a for ioctl cmd: 0x%x", + __func__, cmd); + return err; + } gk20a_channel_set_priority(ch, ((struct nvhost_set_priority_args *)buf)->priority); gk20a_channel_idle(dev); diff --git a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c index da7d733e3fd0..bc5dc4c1f048 100644 --- a/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c @@ -555,7 +555,9 @@ static int dbg_set_powergate(struct dbg_session_gk20a *dbg_s, gk20a_dbg(gpu_dbg_gpu_dbg | gpu_dbg_fn, "module busy"); gk20a_busy(g->dev); - gk20a_channel_busy(dbg_s->pdev); + err = gk20a_channel_busy(dbg_s->pdev); + if (err) + return -EPERM; g->ops.clock_gating.slcg_gr_load_gating_prod(g, false); diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c index f6b43f506bd0..14629fbeecaf 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c @@ -268,6 +268,7 @@ static ssize_t elpg_enable_store(struct device *device, struct platform_device *ndev = to_platform_device(device); struct gk20a *g = get_gk20a(ndev); unsigned long val = 0; + int err; if (kstrtoul(buf, 10, &val) < 0) return -EINVAL; @@ -276,7 +277,10 @@ static ssize_t elpg_enable_store(struct device *device, * Since elpg is refcounted, we should not unnecessarily call * enable/disable if it is already so. */ - gk20a_channel_busy(g->dev); + err = gk20a_channel_busy(g->dev); + if (err) + return -EAGAIN; + if (val && !g->elpg_enabled) { g->elpg_enabled = true; gk20a_pmu_enable_elpg(g); |