From cbda0b2b7172bc9f0a3310ed9fe08e9f384b69c0 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Mon, 30 Nov 2015 15:07:08 -0800 Subject: gpu: nvgpu: Handle interrupt even if no channel If we could not find the channel for GR interrupt we skipped resetting it. Change the logic to do the reset, and find the channel via FIFO engine status. Bug 1706962 Change-Id: I8a0d283b36d88ea1cec541dbf90db7929104ad7c Signed-off-by: Terje Bergstrom Reviewed-on: http://git-master/r/839465 --- drivers/gpu/nvgpu/gk20a/gr_gk20a.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a/gr_gk20a.c') diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c index ef24e078..9eea0a0c 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c @@ -4832,17 +4832,16 @@ static int gk20a_gr_handle_illegal_class(struct gk20a *g, return -EINVAL; } -static int gk20a_gr_handle_fecs_error(struct gk20a *g, +static int gk20a_gr_handle_fecs_error(struct gk20a *g, struct channel_gk20a *ch, struct gr_isr_data *isr_data) { - struct fifo_gk20a *f = &g->fifo; - struct channel_gk20a *ch = &f->channel[isr_data->chid]; u32 gr_fecs_intr = gk20a_readl(g, gr_fecs_host_int_status_r()); + gk20a_dbg_fn(""); gk20a_err(dev_from_gk20a(g), "unhandled fecs error interrupt 0x%08x for channel %u", - gr_fecs_intr, ch->hw_chid); + gr_fecs_intr, isr_data->chid); if (gr_fecs_intr & gr_fecs_host_int_status_umimp_firmware_method_f(1)) { gk20a_err(dev_from_gk20a(g), @@ -5360,12 +5359,10 @@ int gk20a_gr_isr(struct gk20a *g) isr_data.class_num = gr_fe_object_table_nvclass_v(obj_table); ch = gk20a_gr_get_channel_from_ctx(g, isr_data.curr_ctx, &tsgid); - if (!ch) { - gk20a_err(dev_from_gk20a(g), "invalid channel ctx 0x%08x", - isr_data.curr_ctx); - goto clean_up; - } - isr_data.chid = ch->hw_chid; + if (ch) + isr_data.chid = ch->hw_chid; + else + isr_data.chid = 0xffffffff; gk20a_dbg(gpu_dbg_intr | gpu_dbg_gpu_dbg, "channel %d: addr 0x%08x, " @@ -5422,7 +5419,7 @@ int gk20a_gr_isr(struct gk20a *g) } if (gr_intr & gr_intr_fecs_error_pending_f()) { - need_reset |= gk20a_gr_handle_fecs_error(g, &isr_data); + need_reset |= gk20a_gr_handle_fecs_error(g, ch, &isr_data); gk20a_writel(g, gr_intr_r(), gr_intr_fecs_error_reset_f()); gr_intr &= ~gr_intr_fecs_error_pending_f(); @@ -5509,12 +5506,14 @@ int gk20a_gr_isr(struct gk20a *g) if (tsgid != NVGPU_INVALID_TSG_ID) gk20a_fifo_recover(g, BIT(ENGINE_GR_GK20A), tsgid, true, true, true); - else + else if (ch) gk20a_fifo_recover(g, BIT(ENGINE_GR_GK20A), ch->hw_chid, false, true, true); + else + gk20a_fifo_recover(g, BIT(ENGINE_GR_GK20A), + 0, false, false, true); } -clean_up: if (gr_intr && !ch) { /* Clear interrupts for unused channel. This is probably an interrupt during gk20a_free_channel() */ -- cgit v1.2.2