mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +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
|
else
|
||||||
gk20a_vm_put(ch_vm);
|
gk20a_vm_put(ch_vm);
|
||||||
|
|
||||||
|
ch->update_fn = NULL;
|
||||||
|
ch->update_fn_data = NULL;
|
||||||
|
|
||||||
unbind:
|
unbind:
|
||||||
if (gk20a_is_channel_marked_as_tsg(ch))
|
if (gk20a_is_channel_marked_as_tsg(ch))
|
||||||
gk20a_tsg_unbind_channel(ch);
|
gk20a_tsg_unbind_channel(ch);
|
||||||
@@ -730,6 +733,27 @@ int gk20a_channel_release(struct inode *inode, struct file *filp)
|
|||||||
return 0;
|
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 channel_gk20a *gk20a_open_new_channel(struct gk20a *g)
|
||||||
{
|
{
|
||||||
struct fifo_gk20a *f = &g->fifo;
|
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.events_enabled = false;
|
||||||
ch->poll_events.num_pending_events = 0;
|
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;
|
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->jobs_lock);
|
||||||
mutex_unlock(&c->submit_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)
|
void add_wait_cmd(u32 *ptr, u32 id, u32 thresh)
|
||||||
|
|||||||
@@ -157,6 +157,12 @@ struct channel_gk20a {
|
|||||||
|
|
||||||
/* event support */
|
/* event support */
|
||||||
struct channel_gk20a_poll_events poll_events;
|
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)
|
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);
|
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(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);
|
void channel_gk20a_unbind(struct channel_gk20a *ch_gk20a);
|
||||||
|
|
||||||
int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
|
int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
|
||||||
|
|||||||
Reference in New Issue
Block a user