diff --git a/drivers/gpu/nvgpu/hal/mm/mmu_fault/mmu_fault_gv11b_fusa.c b/drivers/gpu/nvgpu/hal/mm/mmu_fault/mmu_fault_gv11b_fusa.c index f1adda07e..b2b409610 100644 --- a/drivers/gpu/nvgpu/hal/mm/mmu_fault/mmu_fault_gv11b_fusa.c +++ b/drivers/gpu/nvgpu/hal/mm/mmu_fault/mmu_fault_gv11b_fusa.c @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -480,6 +481,18 @@ void gv11b_mm_mmu_fault_handle_mmu_fault_common(struct gk20a *g, gv11b_fb_mmu_fault_info_dump(g, mmufault); + /** + * If nvgpu power-on is yet to complete, don't attempt further fault + * handling. Access to fault buffers is synchronized as nvgpu driver + * reads the fault buffer registers before proceeding with fault + * handling. + * However, MMU fault handling needs to be synchronized with GR/FIFO/ + * quiesce/recovery related setup through nvgpu power-on state. + */ + if (!nvgpu_is_powered_on(g)) { + return; + } + num_lce = g->ops.top.get_num_lce(g); if (mmufault->mmu_engine_id >= gmmu_fault_mmu_eng_id_ce0_v()) { diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c index 1d943f1c3..820f9fac0 100644 --- a/drivers/gpu/nvgpu/os/linux/module.c +++ b/drivers/gpu/nvgpu/os/linux/module.c @@ -454,6 +454,12 @@ int gk20a_pm_finalize_poweron(struct device *dev) } } + err = nvgpu_enable_irqs(g); + if (err) { + nvgpu_err(g, "failed to enable irqs %d", err); + goto done; + } + err = nvgpu_finalize_poweron(g); if (err) goto done; @@ -489,12 +495,6 @@ int gk20a_pm_finalize_poweron(struct device *dev) trace_gk20a_finalize_poweron_done(dev_name(dev)); #endif - err = nvgpu_enable_irqs(g); - if (err) { - nvgpu_err(g, "failed to enable irqs %d", err); - goto done; - } - gk20a_scale_resume(dev_from_gk20a(g)); #ifdef CONFIG_NVGPU_SUPPORT_CDE @@ -513,6 +513,10 @@ int gk20a_pm_finalize_poweron(struct device *dev) nvgpu_set_power_state(g, NVGPU_STATE_POWERED_ON); done: + if (err != 0) { + nvgpu_disable_irqs(g); + } + nvgpu_mutex_release(&g->power_lock); return err; }