summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c32
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.h9
2 files changed, 41 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index eaea5a77..58dde415 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -674,6 +674,9 @@ void gk20a_free_channel(struct channel_gk20a *ch, bool finish)
674 else 674 else
675 gk20a_vm_put(ch_vm); 675 gk20a_vm_put(ch_vm);
676 676
677 ch->update_fn = NULL;
678 ch->update_fn_data = NULL;
679
677unbind: 680unbind:
678 if (gk20a_is_channel_marked_as_tsg(ch)) 681 if (gk20a_is_channel_marked_as_tsg(ch))
679 gk20a_tsg_unbind_channel(ch); 682 gk20a_tsg_unbind_channel(ch);
@@ -730,6 +733,27 @@ int gk20a_channel_release(struct inode *inode, struct file *filp)
730 return 0; 733 return 0;
731} 734}
732 735
736static void gk20a_channel_update_runcb_fn(struct work_struct *work)
737{
738 struct channel_gk20a *ch =
739 container_of(work, struct channel_gk20a, update_fn_work);
740 ch->update_fn(ch, ch->update_fn_data);
741}
742
743struct channel_gk20a *gk20a_open_new_channel_with_cb(struct gk20a *g,
744 void (*update_fn)(struct channel_gk20a *, void *),
745 void *update_fn_data)
746{
747 struct channel_gk20a *ch = gk20a_open_new_channel(g);
748
749 if (ch) {
750 ch->update_fn = update_fn;
751 ch->update_fn_data = update_fn_data;
752 }
753
754 return ch;
755}
756
733struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g) 757struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g)
734{ 758{
735 struct fifo_gk20a *f = &g->fifo; 759 struct fifo_gk20a *f = &g->fifo;
@@ -777,6 +801,11 @@ struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g)
777 ch->poll_events.events_enabled = false; 801 ch->poll_events.events_enabled = false;
778 ch->poll_events.num_pending_events = 0; 802 ch->poll_events.num_pending_events = 0;
779 803
804 ch->update_fn = NULL;
805 ch->update_fn_data = NULL;
806
807 INIT_WORK(&ch->update_fn_work, gk20a_channel_update_runcb_fn);
808
780 return ch; 809 return ch;
781} 810}
782 811
@@ -1473,6 +1502,9 @@ void gk20a_channel_update(struct channel_gk20a *c, int nr_completed)
1473 } 1502 }
1474 mutex_unlock(&c->jobs_lock); 1503 mutex_unlock(&c->jobs_lock);
1475 mutex_unlock(&c->submit_lock); 1504 mutex_unlock(&c->submit_lock);
1505
1506 if (c->update_fn)
1507 schedule_work(&c->update_fn_work);
1476} 1508}
1477 1509
1478void add_wait_cmd(u32 *ptr, u32 id, u32 thresh) 1510void add_wait_cmd(u32 *ptr, u32 id, u32 thresh)
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
index a17e6ea9..aa87464b 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
@@ -157,6 +157,12 @@ struct channel_gk20a {
157 157
158 /* event support */ 158 /* event support */
159 struct channel_gk20a_poll_events poll_events; 159 struct channel_gk20a_poll_events poll_events;
160
161 /* signal channel owner via a callback, if set, in gk20a_channel_update
162 * via schedule_work */
163 void (*update_fn)(struct channel_gk20a *, void *);
164 void *update_fn_data;
165 struct work_struct update_fn_work;
160}; 166};
161 167
162static inline bool gk20a_channel_as_bound(struct channel_gk20a *ch) 168static inline bool gk20a_channel_as_bound(struct channel_gk20a *ch)
@@ -196,6 +202,9 @@ void gk20a_init_channel(struct gpu_ops *gops);
196 202
197int gk20a_wait_channel_idle(struct channel_gk20a *ch); 203int gk20a_wait_channel_idle(struct channel_gk20a *ch);
198struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g); 204struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g);
205struct channel_gk20a *gk20a_open_new_channel_with_cb(struct gk20a *g,
206 void (*update_fn)(struct channel_gk20a *, void *),
207 void *update_fn_data);
199void channel_gk20a_unbind(struct channel_gk20a *ch_gk20a); 208void channel_gk20a_unbind(struct channel_gk20a *ch_gk20a);
200 209
201int gk20a_submit_channel_gpfifo(struct channel_gk20a *c, 210int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,