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.c53
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.h4
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c28
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.h5
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c7
5 files changed, 38 insertions, 59 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index f64bda9b6dc5..3065e8403559 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -3,7 +3,7 @@
*
* GK20A Graphics channel
*
- * Copyright (c) 2011-2015, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -552,8 +552,7 @@ static int gk20a_init_error_notifier(struct channel_gk20a *ch,
dmabuf = dma_buf_get(args->mem);
- if (ch->error_notifier_ref)
- gk20a_free_error_notifiers(ch);
+ gk20a_free_error_notifiers(ch);
if (IS_ERR(dmabuf)) {
pr_err("Invalid handle: %d\n", args->mem);
@@ -574,16 +573,23 @@ static int gk20a_init_error_notifier(struct channel_gk20a *ch,
return -ENOMEM;
}
- /* set channel notifiers pointer */
- ch->error_notifier_ref = dmabuf;
ch->error_notifier = va + args->offset;
ch->error_notifier_va = va;
memset(ch->error_notifier, 0, sizeof(struct nvhost_notification));
+
+ /* set channel notifiers pointer */
+ mutex_lock(&ch->error_notifier_mutex);
+ ch->error_notifier_ref = dmabuf;
+ mutex_unlock(&ch->error_notifier_mutex);
+
return 0;
}
void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error)
{
+ bool notifier_set = false;
+
+ mutex_lock(&ch->error_notifier_mutex);
if (ch->error_notifier_ref) {
struct timespec time_data;
u64 nsec;
@@ -596,20 +602,27 @@ void gk20a_set_error_notifier(struct channel_gk20a *ch, __u32 error)
(u32)(nsec >> 32);
ch->error_notifier->info32 = error;
ch->error_notifier->status = 0xffff;
- gk20a_err(dev_from_gk20a(ch->g),
- "error notifier set to %d\n", error);
+
+ notifier_set = true;
}
+ mutex_unlock(&ch->error_notifier_mutex);
+
+ if (notifier_set)
+ gk20a_err(dev_from_gk20a(ch->g),
+ "error notifier set to %d for ch %d", error, ch->hw_chid);
}
static void gk20a_free_error_notifiers(struct channel_gk20a *ch)
{
+ mutex_lock(&ch->error_notifier_mutex);
if (ch->error_notifier_ref) {
dma_buf_vunmap(ch->error_notifier_ref, ch->error_notifier_va);
dma_buf_put(ch->error_notifier_ref);
- ch->error_notifier_ref = 0;
- ch->error_notifier = 0;
- ch->error_notifier_va = 0;
+ ch->error_notifier_ref = NULL;
+ ch->error_notifier = NULL;
+ ch->error_notifier_va = NULL;
}
+ mutex_unlock(&ch->error_notifier_mutex);
}
void gk20a_free_channel(struct channel_gk20a *ch, bool finish)
@@ -706,9 +719,12 @@ unbind:
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;
+ struct gk20a *g = ch ? ch->g : NULL;
int err;
+ if (!ch)
+ return 0;
+
trace_gk20a_channel_release(dev_name(&g->dev->dev));
err = gk20a_busy(ch->g->dev);
@@ -1630,6 +1646,7 @@ int gk20a_init_channel_support(struct gk20a *g, u32 chid)
c->bound = false;
c->remove_support = gk20a_remove_channel_support;
mutex_init(&c->jobs_lock);
+ mutex_init(&c->error_notifier_mutex);
INIT_LIST_HEAD(&c->jobs);
#if defined(CONFIG_GK20A_CYCLE_STATS)
mutex_init(&c->cyclestate.cyclestate_buffer_mutex);
@@ -1982,7 +1999,7 @@ long gk20a_channel_ioctl(struct file *filp,
{
struct channel_gk20a *ch = filp->private_data;
struct platform_device *dev = ch->g->dev;
- u8 buf[NVHOST_IOCTL_CHANNEL_MAX_ARG_SIZE];
+ u8 buf[NVHOST_IOCTL_CHANNEL_MAX_ARG_SIZE] = {0};
int err = 0;
if ((_IOC_TYPE(cmd) != NVHOST_IOCTL_MAGIC) ||
@@ -2049,18 +2066,6 @@ long gk20a_channel_ioctl(struct file *filp,
(struct nvhost_alloc_obj_ctx_args *)buf);
gk20a_idle(dev);
break;
- case NVHOST_IOCTL_CHANNEL_FREE_OBJ_CTX:
- err = gk20a_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_idle(dev);
- break;
case NVHOST_IOCTL_CHANNEL_ALLOC_GPFIFO:
err = gk20a_busy(dev);
if (err) {
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
index 320ada62a965..831db0f4986a 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
@@ -3,7 +3,7 @@
*
* GK20A graphics channel
*
- * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -98,7 +98,6 @@ struct channel_gk20a {
u64 userd_iova;
u64 userd_gpu_va;
- s32 num_objects;
u32 obj_class; /* we support only one obj per channel */
struct priv_cmd_queue priv_cmd_q;
@@ -132,6 +131,7 @@ struct channel_gk20a {
struct dma_buf *error_notifier_ref;
struct nvhost_notification *error_notifier;
void *error_notifier_va;
+ struct mutex error_notifier_mutex;
struct gk20a_channel_sync *sync;
};
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index 9e032e03a153..d5a3bbd34a78 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -1,7 +1,7 @@
/*
* GK20A Graphics
*
- * Copyright (c) 2011-2015, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -2697,7 +2697,6 @@ void gk20a_free_channel_ctx(struct channel_gk20a *c)
memset(&c->ch_ctx, 0, sizeof(struct channel_ctx_gk20a));
- c->num_objects = 0;
c->first_init = false;
}
@@ -2848,8 +2847,6 @@ int gk20a_alloc_obj_ctx(struct channel_gk20a *c,
c->first_init = true;
}
- c->num_objects++;
-
gk20a_dbg_fn("done");
return 0;
out:
@@ -2861,29 +2858,6 @@ out:
return err;
}
-int gk20a_free_obj_ctx(struct channel_gk20a *c,
- struct nvhost_free_obj_ctx_args *args)
-{
- unsigned long timeout = gk20a_get_gr_idle_timeout(c->g);
-
- gk20a_dbg_fn("");
-
- if (c->num_objects == 0)
- return 0;
-
- c->num_objects--;
-
- if (c->num_objects == 0) {
- c->first_init = false;
- gk20a_disable_channel(c,
- !c->has_timedout,
- timeout);
- gr_gk20a_unmap_channel_patch_ctx(c);
- }
-
- return 0;
-}
-
static void gk20a_remove_gr_support(struct gr_gk20a *gr)
{
struct gk20a *g = gr->g;
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h
index 2a31aa0b830f..526eefb46b6f 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h
@@ -1,7 +1,7 @@
/*
* GK20A Graphics Engine
*
- * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -324,12 +324,9 @@ int gk20a_init_gr_channel(struct channel_gk20a *ch_gk20a);
int gr_gk20a_init_ctx_vars(struct gk20a *g, struct gr_gk20a *gr);
struct nvhost_alloc_obj_ctx_args;
-struct nvhost_free_obj_ctx_args;
int gk20a_alloc_obj_ctx(struct channel_gk20a *c,
struct nvhost_alloc_obj_ctx_args *args);
-int gk20a_free_obj_ctx(struct channel_gk20a *c,
- struct nvhost_free_obj_ctx_args *args);
void gk20a_free_channel_ctx(struct channel_gk20a *c);
int gk20a_gr_isr(struct gk20a *g);
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index d94755bbdf33..2bbd973ad0b1 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -3,7 +3,7 @@
*
* GK20A memory management
*
- * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -2318,7 +2318,7 @@ int gk20a_vm_alloc_space(struct gk20a_as_share *as_share,
va_node->vaddr_start = vaddr_start;
va_node->size = (u64)args->page_size * (u64)args->pages;
- va_node->pgsz_idx = args->page_size;
+ va_node->pgsz_idx = pgsz_idx;
INIT_LIST_HEAD(&va_node->va_buffers_list);
INIT_LIST_HEAD(&va_node->reserved_va_list);
@@ -2488,6 +2488,9 @@ int gk20a_vm_map_buffer(struct gk20a_as_share *as_share,
/* get ref to the mem handle (released on unmap_locked) */
dmabuf = dma_buf_get(dmabuf_fd);
+ if (IS_ERR(dmabuf))
+ return PTR_ERR(dmabuf);
+
if (!dmabuf)
return 0;