summaryrefslogtreecommitdiff
path: root/drivers/gpu/nvgpu/gk20a
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c80
-rw-r--r--drivers/gpu/nvgpu/gk20a/dbg_gpu_gk20a.c4
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a_sysfs.c6
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);