diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index d0d5c41f..0b8422a6 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -82,9 +82,6 @@ static void channel_gk20a_joblist_delete(struct channel_gk20a *c, | |||
82 | static struct channel_gk20a_job *channel_gk20a_joblist_peek( | 82 | static struct channel_gk20a_job *channel_gk20a_joblist_peek( |
83 | struct channel_gk20a *c); | 83 | struct channel_gk20a *c); |
84 | 84 | ||
85 | static int channel_gk20a_update_runlist(struct channel_gk20a *c, | ||
86 | bool add); | ||
87 | |||
88 | static u32 gk20a_get_channel_watchdog_timeout(struct channel_gk20a *ch); | 85 | static u32 gk20a_get_channel_watchdog_timeout(struct channel_gk20a *ch); |
89 | 86 | ||
90 | static void gk20a_channel_clean_up_jobs(struct channel_gk20a *c, | 87 | static void gk20a_channel_clean_up_jobs(struct channel_gk20a *c, |
@@ -189,7 +186,7 @@ int gk20a_channel_get_timescale_from_timeslice(struct gk20a *g, | |||
189 | return 0; | 186 | return 0; |
190 | } | 187 | } |
191 | 188 | ||
192 | static int channel_gk20a_update_runlist(struct channel_gk20a *c, bool add) | 189 | int channel_gk20a_update_runlist(struct channel_gk20a *c, bool add) |
193 | { | 190 | { |
194 | return c->g->ops.fifo.update_runlist(c->g, c->runlist_id, c->chid, add, true); | 191 | return c->g->ops.fifo.update_runlist(c->g, c->runlist_id, c->chid, add, true); |
195 | } | 192 | } |
@@ -459,6 +456,8 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force) | |||
459 | struct dbg_session_gk20a *dbg_s; | 456 | struct dbg_session_gk20a *dbg_s; |
460 | struct dbg_session_data *session_data, *tmp_s; | 457 | struct dbg_session_data *session_data, *tmp_s; |
461 | struct dbg_session_channel_data *ch_data, *tmp; | 458 | struct dbg_session_channel_data *ch_data, *tmp; |
459 | bool was_tsg = false; | ||
460 | int err; | ||
462 | 461 | ||
463 | gk20a_dbg_fn(""); | 462 | gk20a_dbg_fn(""); |
464 | 463 | ||
@@ -467,7 +466,19 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force) | |||
467 | trace_gk20a_free_channel(ch->chid); | 466 | trace_gk20a_free_channel(ch->chid); |
468 | 467 | ||
469 | /* abort channel and remove from runlist */ | 468 | /* abort channel and remove from runlist */ |
470 | gk20a_disable_channel(ch); | 469 | if (gk20a_is_channel_marked_as_tsg(ch)) { |
470 | err = g->ops.fifo.tsg_unbind_channel(ch); | ||
471 | if (err) | ||
472 | nvgpu_err(g, "failed to unbind channel %d from TSG", ch->chid); | ||
473 | /* | ||
474 | * Channel is not a part of TSG this point onwards | ||
475 | * So stash its status and use it whenever necessary | ||
476 | * e.g. while releasing gr_ctx in g->ops.gr.free_channel_ctx() | ||
477 | */ | ||
478 | was_tsg = true; | ||
479 | } else { | ||
480 | gk20a_disable_channel(ch); | ||
481 | } | ||
471 | 482 | ||
472 | /* wait until there's only our ref to the channel */ | 483 | /* wait until there's only our ref to the channel */ |
473 | if (!force) | 484 | if (!force) |
@@ -524,7 +535,7 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force) | |||
524 | g->ops.fecs_trace.unbind_channel(g, ch); | 535 | g->ops.fecs_trace.unbind_channel(g, ch); |
525 | 536 | ||
526 | /* release channel ctx */ | 537 | /* release channel ctx */ |
527 | g->ops.gr.free_channel_ctx(ch); | 538 | g->ops.gr.free_channel_ctx(ch, was_tsg); |
528 | 539 | ||
529 | gk20a_gr_flush_channel_tlb(gr); | 540 | gk20a_gr_flush_channel_tlb(gr); |
530 | 541 | ||
@@ -571,9 +582,6 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force) | |||
571 | nvgpu_wait_for_deferred_interrupts(g); | 582 | nvgpu_wait_for_deferred_interrupts(g); |
572 | 583 | ||
573 | unbind: | 584 | unbind: |
574 | if (gk20a_is_channel_marked_as_tsg(ch)) | ||
575 | g->ops.fifo.tsg_unbind_channel(ch); | ||
576 | |||
577 | g->ops.fifo.unbind_channel(ch); | 585 | g->ops.fifo.unbind_channel(ch); |
578 | g->ops.fifo.free_inst(g, ch); | 586 | g->ops.fifo.free_inst(g, ch); |
579 | 587 | ||