mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 09:12:24 +03:00
gpu: nvgpu: add update callback to gk20a channel
Add support for a callback function with user data pointer to be scheduled from the end of gk20a_channel_update. The function and its private data are supplied when opening a new channel. Change-Id: Ib6b408855ea60d46a6a114a69c01904703019572 Signed-off-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-on: http://git-master/r/552014 Reviewed-by: Arto Merilainen <amerilainen@nvidia.com> Tested-by: Arto Merilainen <amerilainen@nvidia.com>
This commit is contained in:
committed by
Dan Willemsen
parent
5ce4438380
commit
b564dc87b6
@@ -674,6 +674,9 @@ void gk20a_free_channel(struct channel_gk20a *ch, bool finish)
|
||||
else
|
||||
gk20a_vm_put(ch_vm);
|
||||
|
||||
ch->update_fn = NULL;
|
||||
ch->update_fn_data = NULL;
|
||||
|
||||
unbind:
|
||||
if (gk20a_is_channel_marked_as_tsg(ch))
|
||||
gk20a_tsg_unbind_channel(ch);
|
||||
@@ -730,6 +733,27 @@ int gk20a_channel_release(struct inode *inode, struct file *filp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gk20a_channel_update_runcb_fn(struct work_struct *work)
|
||||
{
|
||||
struct channel_gk20a *ch =
|
||||
container_of(work, struct channel_gk20a, update_fn_work);
|
||||
ch->update_fn(ch, ch->update_fn_data);
|
||||
}
|
||||
|
||||
struct channel_gk20a *gk20a_open_new_channel_with_cb(struct gk20a *g,
|
||||
void (*update_fn)(struct channel_gk20a *, void *),
|
||||
void *update_fn_data)
|
||||
{
|
||||
struct channel_gk20a *ch = gk20a_open_new_channel(g);
|
||||
|
||||
if (ch) {
|
||||
ch->update_fn = update_fn;
|
||||
ch->update_fn_data = update_fn_data;
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g)
|
||||
{
|
||||
struct fifo_gk20a *f = &g->fifo;
|
||||
@@ -777,6 +801,11 @@ struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g)
|
||||
ch->poll_events.events_enabled = false;
|
||||
ch->poll_events.num_pending_events = 0;
|
||||
|
||||
ch->update_fn = NULL;
|
||||
ch->update_fn_data = NULL;
|
||||
|
||||
INIT_WORK(&ch->update_fn_work, gk20a_channel_update_runcb_fn);
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
@@ -1473,6 +1502,9 @@ void gk20a_channel_update(struct channel_gk20a *c, int nr_completed)
|
||||
}
|
||||
mutex_unlock(&c->jobs_lock);
|
||||
mutex_unlock(&c->submit_lock);
|
||||
|
||||
if (c->update_fn)
|
||||
schedule_work(&c->update_fn_work);
|
||||
}
|
||||
|
||||
void add_wait_cmd(u32 *ptr, u32 id, u32 thresh)
|
||||
|
||||
@@ -157,6 +157,12 @@ struct channel_gk20a {
|
||||
|
||||
/* event support */
|
||||
struct channel_gk20a_poll_events poll_events;
|
||||
|
||||
/* signal channel owner via a callback, if set, in gk20a_channel_update
|
||||
* via schedule_work */
|
||||
void (*update_fn)(struct channel_gk20a *, void *);
|
||||
void *update_fn_data;
|
||||
struct work_struct update_fn_work;
|
||||
};
|
||||
|
||||
static inline bool gk20a_channel_as_bound(struct channel_gk20a *ch)
|
||||
@@ -196,6 +202,9 @@ void gk20a_init_channel(struct gpu_ops *gops);
|
||||
|
||||
int gk20a_wait_channel_idle(struct channel_gk20a *ch);
|
||||
struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g);
|
||||
struct channel_gk20a *gk20a_open_new_channel_with_cb(struct gk20a *g,
|
||||
void (*update_fn)(struct channel_gk20a *, void *),
|
||||
void *update_fn_data);
|
||||
void channel_gk20a_unbind(struct channel_gk20a *ch_gk20a);
|
||||
|
||||
int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
|
||||
|
||||
Reference in New Issue
Block a user